diff packages/hal/arm/arm9/excalibur/current/include/hal_platform_setup.h @ 208:e0c0827131d1 ecos

Merge from eCos master repository on 2002-05-20-20:11:54-BST
author jlarmour
date Mon, 20 May 2002 22:19:26 +0000
parents
children d2c90368aeef
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/arm9/excalibur/current/include/hal_platform_setup.h
@@ -0,0 +1,507 @@
+#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
+#define CYGONCE_HAL_PLATFORM_SETUP_H
+//=============================================================================
+//
+//      hal_platform_setup.h
+//
+//      Platform specific support for HAL (assembly code)
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    jskov
+// Contributors: jskov, gthomas
+// Date:         2001-08-06
+// Purpose:      ARM9/EXCALIBUR platform specific support routines
+// Description: 
+// Usage:        #include <cyg/hal/hal_platform_setup.h>
+//     Only used by "vectors.S"         
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/system.h>             // System-wide configuration info
+#include CYGBLD_HAL_VARIANT_H           // Variant specific configuration
+#include CYGBLD_HAL_PLATFORM_H          // Platform specific configuration
+#include CYGHWR_MEMORY_LAYOUT_H
+#include <cyg/hal/hal_mmu.h>            // MMU definitions
+#include <cyg/hal/excalibur.h>          // Platform specific hardware definitions
+
+#define nDEBUG
+#define n_ALTERA_CACHEHACK  // doesn't have any apparent effect
+
+#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_REDBOOT)
+#define PLATFORM_SETUP1 _platform_setup1
+#define CYGHWR_HAL_ARM_HAS_MMU
+#define CYGSEM_HAL_ROM_RESET_USES_JUMP
+
+#define CYG_DEVICE_SERIAL_BAUD_DIV (CYGNUM_HAL_ARM_EXCALIBUR_PERIPHERAL_CLOCK/CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD/16)
+#define CYG_DEVICE_SERIAL_BAUD_LSB (CYG_DEVICE_SERIAL_BAUD_DIV&0xff)
+#define CYG_DEVICE_SERIAL_BAUD_MSB ((CYG_DEVICE_SERIAL_BAUD_DIV>>8)&0xff)
+
+// We need this here - can't rely on a translation table until MMU has
+// been initialized
+        .macro RAW_LED_MACRO x
+#ifdef DEBUG
+        ldr     r0,=(EXCALIBUR_UART0_BASE+_UART_TD)
+        mov     r1,#(\x + 0x41)
+        str     r1,[r0]
+#endif
+        .endm
+
+// This macro represents the initial startup code for the platform        
+        .macro  _platform_setup1
+        // IO controller init
+        ldr     r1,=EXCALIBUR_IOCR_BASE
+        ldr     r2,=EXCALIBUR_IOCR_SDRAM_INIT
+        str     r2,[r1,#_IOCR_SDRAM]
+        ldr     r2,=EXCALIBUR_IOCR_EBI_INIT
+        str     r2,[r1,#_IOCR_EBI]
+        ldr     r2,=EXCALIBUR_IOCR_UART_INIT
+        str     r2,[r1,#_IOCR_UART]
+
+        // Expansion bus init
+        ldr     r1,=EXCALIBUR_EBI_CR
+        ldr     r2,=EXCALIBUR_EBI_CR_INIT
+        str     r2,[r1]
+
+#ifdef DEBUG
+        // Init UART for debug tracing
+        ldr     r4,=EXCALIBUR_UART0_BASE
+        ldr     r2,=(_UART_MC_8BIT | _UART_MC_1STOP | _UART_MC_PARITY_NONE)
+        str     r2,[r4,#_UART_MC]
+        ldr     r2,=CYG_DEVICE_SERIAL_BAUD_LSB
+        str     r2,[r4,#_UART_DIV_LO]
+        ldr     r2,=CYG_DEVICE_SERIAL_BAUD_MSB
+        str     r2,[r4,#_UART_DIV_HI]
+        ldr     r2,=(_UART_FCR_TC | _UART_FCR_RC | _UART_FCR_TX_THR_15 | _UART_FCR_RX_THR_1)
+        str     r2,[r4,#_UART_FCR]
+#endif
+
+        // Setup the PLLs see the label PLL_ADDR below for the input
+        // clock frequency and the desired output frequencies of PLL1
+        // and PLL2 Load the value into K,M,N for PLL 1 and 2
+        adr     r0,2f
+        ldmia   r0,{r0-r11}
+        str     r6,[r0]
+        str     r7,[r1]
+        str     r8,[r2]
+        str     r9,[r3]
+        str     r10,[r4]
+        str     r11,[r5]
+                
+        // Turn on the PLLs
+        ldr     r3,=EXCALIBUR_CLK_BASE
+        ldr     r1,=(0x1035 | _CLK_PLL1_CTRL_P)
+        str     r1,[r3, #_CLK_PLL1_CTRL]
+        str     r1,[r3, #_CLK_PLL2_CTRL]
+
+        // Ensure the PLLs are not in bypass
+        ldr     r1,=(0x10 | _CLK_DERIVE_BP1 | _CLK_DERIVE_BP2)
+        str     r1,[r3, #_CLK_DERIVE]
+        orr     r1,r1,#0x300 /* Use PLL2 for AHB and for the SDRAM */
+        str     r1,[r3, #_CLK_DERIVE]
+        ldr     r2,=(_CLK_DERIVE_BP1 | _CLK_DERIVE_BP2)
+        bic     r1,r1,r2
+        str     r1,[r3, #_CLK_DERIVE]
+
+        // Poll waiting for the PLL's to lock and the bits to not be
+        // in bypass mode
+        ldr     r2,=_CLK_STATUS_L2 /*_CLK_STATUS_L1 | _CLK_STATUS_L2*/
+1:      ldr     r1, [r3, #_CLK_STATUS]
+        and     r1, r1, r2
+        cmp     r1, r2
+        bne     1b
+
+        // Clear the interrupt caused by the change in lock status
+        ldr     r2, =(_CLK_STATUS_C1 | _CLK_STATUS_C2)
+        str     r2, [r3, #_CLK_STATUS]
+        
+        b       3f
+
+        // PLL Registers Addresses
+2:      .long EXCALIBUR_CLK_BASE+_CLK_PLL1_KCNT
+        .long EXCALIBUR_CLK_BASE+_CLK_PLL1_MCNT
+        .long EXCALIBUR_CLK_BASE+_CLK_PLL1_NCNT
+        .long EXCALIBUR_CLK_BASE+_CLK_PLL2_KCNT
+        .long EXCALIBUR_CLK_BASE+_CLK_PLL2_MCNT
+        .long EXCALIBUR_CLK_BASE+_CLK_PLL2_NCNT
+        // PLL Registers Values ensure this follows on from the
+        // addresses the code depends on it
+        .long 0x40000 // CLK_PLL1_KCNT_VAL  = 1
+        .long 0x20101 // CLK_PLL1_MCNT_VAL  = 2
+        .long 0x40000 // CLK_PLL1_NCNT_VAL  = 1
+        .long 0x40000 // CLK_PLL2_KCNT_VAL  = 1
+        .long 0x20303 // CLK_PLL2_MCNT_VAL  = 6
+        .long 0x40000 // CLK_PLL2_NCNT_VAL  = 1
+3:
+
+        RAW_LED_MACRO 0
+
+        // Jump to ROM
+        ldr     r1,=(EXCALIBUR_MMAP_BASE + _MMAP_EBI0)
+        ldr     r2,=_MMAP_EBI0_INIT
+        str     r2,[r1]
+        ldr     r1,=CYGMEM_REGION_rom
+        add     pc,pc,r1
+        nop
+        nop
+
+        // Disable ROM mapping
+        ldr     r1,=EXCALIBUR_BOOT_CR
+        ldr     r2,=EXCALIBUR_BOOT_CR_BM
+        str     r2,[r1]
+
+        RAW_LED_MACRO 1
+
+        // Disable and clear caches
+        
+        mrc  p15,0,r0,c1,c0,0
+        bic  r0,r0,#0x1000              // disable ICache
+        bic  r0,r0,#0x0007              // disable DCache,
+                                        // MMU and alignment faults
+        mcr  p15,0,r0,c1,c0,0
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        mov  r0,#0
+        mcr  p15,0,r0,c7,c6,0           // clear data cache
+        mcr  p15,0,r0,c7,c5,0           // clear instruction cache
+        
+#if 0
+        mrc  p15,0,r0,c15,c1,0          // disable streaming
+        orr  r0,r0,#0x80
+        mcr  p15,0,r0,c15,c1,0
+#endif
+
+        RAW_LED_MACRO 2
+
+        // Set memory mapping
+        ldr     r1,=EXCALIBUR_MMAP_BASE
+        ldr     r2,=_MMAP_REGISTERS_INIT
+        str     r2,[r1,#_MMAP_REGISTERS]
+        ldr     r2,=_MMAP_SRAM0_INIT
+        str     r2,[r1,#_MMAP_SRAM0]
+        ldr     r2,=_MMAP_SRAM1_INIT
+        str     r2,[r1,#_MMAP_SRAM1]
+        ldr     r2,=_MMAP_DPSRAM0_INIT
+        str     r2,[r1,#_MMAP_DPSRAM0]
+        ldr     r2,=_MMAP_DPSRAM1_INIT
+        str     r2,[r1,#_MMAP_DPSRAM1]
+        ldr     r2,=_MMAP_SDRAM0_INIT
+        str     r2,[r1,#_MMAP_SDRAM0]
+        ldr     r2,=_MMAP_SDRAM1_INIT
+        str     r2,[r1,#_MMAP_SDRAM1]
+        ldr     r2,=_MMAP_PLD0_INIT
+        str     r2,[r1,#_MMAP_PLD0]
+        ldr     r2,=_MMAP_PLD1_INIT
+        str     r2,[r1,#_MMAP_PLD1]
+        ldr     r2,=_MMAP_PLD2_INIT
+        str     r2,[r1,#_MMAP_PLD2]
+        ldr     r2,=_MMAP_PLD3_INIT
+        str     r2,[r1,#_MMAP_PLD3]
+        ldr     r2,=_MMAP_EBI1_INIT
+        str     r2,[r1,#_MMAP_EBI1]
+        ldr     r2,=_MMAP_EBI2_INIT
+        str     r2,[r1,#_MMAP_EBI2]
+        ldr     r2,=_MMAP_EBI3_INIT
+        str     r2,[r1,#_MMAP_EBI3]
+
+        RAW_LED_MACRO 3
+
+        // FIXME: Disable MMAP registers?
+
+        RAW_LED_MACRO 4
+
+        // DPSRAM init
+        ldr     r2,=EXCALIBUR_DPSRAM_BASE
+        ldr     r1,=_DPSRAM0_LCR_INIT
+        str     r1,[r2,#_DPSRAM0_LCR]
+        ldr     r1,=_DPSRAM1_LCR_INIT
+        str     r1,[r2,#_DPSRAM1_LCR]
+
+        RAW_LED_MACRO 5
+
+#ifdef _ALTERA_CACHEHACK
+        mrc     p15,0,r0,c1,c0,0
+        orr     r0,r0,#0x1000              // enable ICache
+        mcr     p15,0,r0,c1,c0,0
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+#endif //  _ALTERA_CACHEHACK
+
+        //  Setup the SDR
+
+        // All the clock values below assume the SDR is running @ 100 MHz
+
+        // 1. Wait for the PLL's to lock this was already done in
+        // Setup_plls Then wait another 100uS, which given we're
+        // running @ 150MHz is 15,000 clock cycles
+        mov     r3,#0x3b00 // (15104)
+1:      subs    r3,r3,#1
+        bne     1b
+
+
+        // 2. Set up all the SDRAM Controllers configuration settings
+        // These are done using LDMIA's as it's more efficient, they're
+        // done in the order they appear in the datasheet with the
+        // exception of SDRAM_INIT which has to be written last
+
+        // Load the address of the first seven SDRAM registers and the
+        // contents
+        adr     r0,SDRAM_REGS_ADDR
+        ldmia   r0,{r0-r5}
+
+        adr     r6,SDRAM_REGS_VALUE
+        ldmia   r6,{r6-r11}
+        str     r6,[r0]
+        str     r7,[r1]
+        str     r8,[r2]
+        str     r9,[r3]
+        str     r10,[r4]
+        str     r11,[r5]
+
+        ldr     r11,=EXCALIBUR_SDRAM_BASE
+        ldr     r0,=EXCALIBUR_SDRAM_WIDTH
+        ldr     r1,=(_SDRAM_WIDTH_W | _SDRAM_WIDTH_LK)  /* 32 bit wide */
+        str     r1,[r0]
+
+#ifdef _ALTERA_CACHEHACK
+        // OK we have a minor "feature/bug" in the chip which requires
+        // us to be a little clever now.  The code between the labels
+        // Cache_Start and Cache_stop starts the SDRAM controller and
+        // issues the pre_charge command
+ 
+        // It must execute within one refresh period, so we must load
+        // this code and the code it calls (Issue_SDRAM_Command) into
+        // cache, as typical flashes have a cycle time of ~100nS If we
+        // are doing byte loads that's ~400ns per instruction.  Depending
+        // upon the size of the DDR the refresh period can be as low as
+        // 7us (smallest we found).
+        adr     r1,SDR_Cache_Start
+        adr     r2,SDR_Cache_Stop       
+        adr     r3,Issue_SDRAM_Command
+        adr     r4,End_Issue_SDRAM_Command
+
+SDR_Load_Code:  
+        mcr     p15,0,r1,c7,c13,1
+        add     r1,r1,#32
+        cmp     r1,r2
+        ble     SDR_Load_Code
+        
+SDR_Load_Code2:         
+        mcr     p15,0,r3,c7,c13,1
+        add     r3,r3,#32
+        cmp     r3,r4
+        ble     SDR_Load_Code2
+#endif // _ALTERA_CACHEHACK
+
+        // setup the timer for later
+        ldr     r4,=EXCALIBUR_TIMER0_LIMIT
+        mvn     r5, #1
+        str     r5, [r4]
+
+        ldr     r4,=_SDRAM_INIT_PR
+        ldr     r5,=_SDRAM_INIT_RF
+        ldr     r6,=_SDRAM_INIT_LM
+        ldr     r9,=EXCALIBUR_TIMER0_READ
+        ldr     r10,=EXCALIBUR_TIMER0_CR
+
+        // Enable the controller by setting the EN bit in the
+        // SDRAM_INIT register
+        mov     r1,#_SDRAM_INIT_EN
+SDR_Cache_Start:
+        str     r1,[r11, #_SDRAM_INIT]
+
+        // Short delay
+        mov     r3, #EXCALIBUR_TIMER_CR_S
+        str     r3, [r10]
+        ldr     r3, [r9]
+        add     r3,r3,#200 
+short_delay:
+        ldr     r8, [r9]
+        cmp     r3, r8
+        bgt     short_delay
+        mov     r3, #0
+        str     r3, [r10]
+
+        // 4. Issue pre-charge all command
+        mov     r1,r4
+        bl      Issue_SDRAM_Command
+
+        // 5. Issue two Refresh Commands
+        mov     r1, r5
+        mov     r4,#2
+SDR_RF_Command:
+        bl      Issue_SDRAM_Command
+        subs    r4,r4,#1
+        bne     SDR_RF_Command
+
+        // 6. Issue a load mode command with the DLL being Reset
+        mov     r1, r6
+        bl      Issue_SDRAM_Command
+
+SDR_Cache_Stop:
+        b        10f
+
+
+        //--------------------------------------------
+        // Issue a command from the SDRAM controller
+        // Assumes:
+        // r1 is the command to be issued
+        // r2 and r3 are trashed
+Issue_SDRAM_Command:
+        mov     r2,#_SDRAM_INIT_EN
+        orr     r2,r2,r1
+        str     r2,[r11, #_SDRAM_INIT]
+ 
+        // OK chip bug, the busy bit does not work properly, so we need
+        // to insert a delay of 50 SDRAM clock cycles here NB Obviously
+        // this must change when either the SDRAM clock or the processor
+        // clock change
+        ldr     r2,=(EXCALIBUR_CLK_BASE+_CLK_AHB1_COUNT)
+        ldr     r3, [r2]
+        add     r3,r3,#200 // CPU 150 MHz SDRAM 75 MHz
+clock_cycles:
+        ldr     r8, [r2]
+        cmp     r3, r8
+        bgt     clock_cycles
+        mov     pc, lr
+End_Issue_SDRAM_Command:
+        
+
+        // SDRAM Register Addresses
+SDRAM_REGS_ADDR: 
+        .long EXCALIBUR_SDRAM_BASE+_SDRAM_TIMING1
+        .long EXCALIBUR_SDRAM_BASE+_SDRAM_TIMING2
+        .long EXCALIBUR_SDRAM_BASE+_SDRAM_CONFIG
+        .long EXCALIBUR_SDRAM_BASE+_SDRAM_REFRESH
+        .long EXCALIBUR_SDRAM_BASE+_SDRAM_ADDR
+        .long EXCALIBUR_SDRAM_BASE+_SDRAM_MODE0
+        .long EXCALIBUR_SDRAM_BASE+_SDRAM_MODE1
+
+SDRAM_REGS_VALUE:
+        .long 0x00004892 /* SDRAM_TIMING1_VAL */
+        .long 0x000007b0 /* SDRAM_TIMING2_VAL */
+        .long 0x00000000 /* DDR */
+        .long 0x00000492 /* SDRAM_REFRESH_VAL */
+        .long 0x0000Ca80 /* SDRAM_ADDR_VAL */
+        .long 0x00000023 /* SDRAM_MODE0_VAL */
+        .long 0x00000000 /* SDRAM_MODE1_VAL */
+10:
+#ifdef _ALTERA_CACHEHACK
+        mrc     p15,0,r0,c1,c0,0
+        bic     r0,r0,#0x1000              // disable ICache
+        mcr     p15,0,r0,c1,c0,0
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+        nop
+#endif // _ALTERA_CACHEHACK
+
+        RAW_LED_MACRO 6
+
+#if defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_REDBOOT)
+        ldr     r0,=__rom_vectors_lma   // Relocate FLASH/ROM to SDRAM
+        ldr     r1,=__rom_vectors_vma   // ram base & length
+        ldr     r2,=__ram_data_end
+20:     ldr     r3,[r0],#4
+        str     r3,[r1],#4
+        cmp     r1,r2
+        bne     20b
+        ldr     r0,=30f
+        nop
+        mov     pc,r0
+	nop
+30:	nop
+#endif
+
+        RAW_LED_MACRO 7
+
+        // Set up a stack [for calling C code]
+        ldr     r1,=__startup_stack
+        ldr     r2,=EXCALIBUR_SDRAM_PHYS_BASE
+        orr     sp,r1,r2
+
+        // Create MMU tables
+        bl      hal_mmu_init
+
+        RAW_LED_MACRO 8
+
+        // Enable MMU
+        ldr     r2,=10f
+        ldr     r1,=MMU_Control_Init|MMU_Control_M
+        mcr     MMU_CP,0,r1,MMU_Control,c0
+        mov     pc,r2    // Change address spaces
+        nop
+        nop
+        nop
+10:
+
+        RAW_LED_MACRO 9
+        .endm
+        
+#else // defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_REDBOOT)
+#define PLATFORM_SETUP1
+#endif
+
+//-----------------------------------------------------------------------------
+#ifdef DEBUG
+#define CYGHWR_LED_MACRO                                \
+        ldr     r0,=(EXCALIBUR_UART0_BASE+_UART_TD);    \
+        mov     r1,#((\x) + 0x61);                      \
+        str     r1,[r0];
+#endif
+
+//-----------------------------------------------------------------------------
+// end of hal_platform_setup.h
+#endif // CYGONCE_HAL_PLATFORM_SETUP_H