rendered paste body#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, 2004, 2005 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): msalter// Contributors: msalter// Date: 2004-09-05// Purpose: Intel XScale IXDP465 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 <cyg/hal/hal_ixp425.h> // Variant specific hardware definitions#include <cyg/hal/hal_mmu.h> // MMU definitions#include <cyg/hal/hal_mm.h> // more MMU definitions#include <cyg/hal/ixdp465.h> // Platform specific hardware definitions// ------------------------------------------------------------------------// Convenience macros for setting up page table//.macro IXP_MAP_SDRAM va, c, b, x, p XSCALE_MMU_SECTION SDRAM_PHYS_BASE>>20, \va>>20, SDRAM_SIZE>>20, \c, \b, 3, \x, \p.endm.macro IXP_MAP_EXP_V n, va, sz, c, b, x, p XSCALE_MMU_SECTION (0x500 + ((IXP425_EXP_CS_SIZE * \n) >> 20)), \va>>20, \sz>>20, \c, \b, 3, \x, \p.endm.macro IXP_MAP_EXP n, sz, c, b, x, p IXP_MAP_EXP_V \n, (0x50000000 + (IXP425_EXP_CS_SIZE * \n)), \sz, \c, \b, \x, \p.endm.macro IXP_MAP_IO addr, sz XSCALE_MMU_SECTION \addr>>20, \addr>>20, \sz>>20, 0, 0, 3, 0, 0.endm.macro IXP_MAP_IO_DC addr, sz XSCALE_MMU_SECTION \addr>>20, \addr>>20, \sz>>20, 0, 0, 3, 0, 1.endm#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)#define PLATFORM_SETUP1 _platform_setup1#define CYGHWR_HAL_ARM_HAS_MMU// ------------------------------------------------------------------------// Define macro used to diddle the LEDs during early initialization.// Can use r0+r1. Argument in \x.//#define CYGHWR_LED_MACRO DISPLAY \x, r0, r1#define CYGHWR_LED_MACRO GPOUT \x// ------------------------------------------------------------------------// LEDS debug// ------------------------------------------------------------------------#define LEDS_MASK 0xff// Delay a bit.macro DELAY cycles, reg0 ldr \reg0, =\cycles subs \reg0, \reg0, #1 subne pc, pc, #0xc.endm.macro FLUSH_ONE ldr r10, =IXP425_GPIO_CFG_BASE ldr r9, [r10, #IXP425_GPOUTR] bic r9, r9, #0x02 str r9, [r10, #IXP425_GPOUTR] ldr r9, [r10, #IXP425_GPOER] bic r9, r9, #0x02 str r9, [r10, #IXP425_GPOER] DELAY 0xA00000, r8 ldr r9, [r10, #IXP425_GPOUTR] orr r9, r9, #0x02 str r9, [r10, #IXP425_GPOUTR] ldr r9, [r10, #IXP425_GPOER] orr r9, r9, #0x02 str r9, [r10, #IXP425_GPOER] DELAY 0xA00000, r8.endm//.macro FLUSH_ONE// ldr r10, =IXP425_GPIO_CFG_BASE// ldr r9, [r10, #IXP425_GPOUTR]// bic r9, r9, #0xff// bic r9, r9, #0xff00// str r9, [r10, #IXP425_GPOUTR]// str r9, [r10, #IXP425_GPOER]//// DELAY 0xA00000, r8// orr r9, r9, #0xff// orr r9, r9, #0xff00// str r9, [r10, #IXP425_GPOUTR]// str r9, [r10, #IXP425_GPOER]// DELAY 0xA00000, r8// DELAY 0xA00000, r8// DELAY 0xA00000, r8//.endm.macro BOOTTEST ldr r10, =IXP425_GPIO_CFG_BASE 1: ldr r9, [r10, #IXP425_GPOUTR] bic r9, r9, #0xff bic r9, r9, #0xff00 str r9, [r10, #IXP425_GPOUTR] str r9, [r10, #IXP425_GPOER] DELAY 0xA00000, r8 ldr r8, =LEDS_MASK orr r9, r9, #0xff orr r9, r9, #0xff00 str r9, [r10, #IXP425_GPOUTR] str r9, [r10, #IXP425_GPOER] DELAY 0xA00000, r8 b 1b.endm// ------------------------------------------------------------------------ .macro GPOUT val ldr r10, =IXP425_GPIO_CFG_BASE ldr r9, [r10, #IXP425_GPOUTR] bic r9, r9, #0xff bic r9, r9, #0xff00 ldr r8, =\val orr r9, r9, r8 str r9, [r10, #IXP425_GPOUTR] .endm// ------------------------------------------------------------------------// This macro represents the initial startup code for the platform .macro _platform_setup1//#ifdef CYGHWR_HAL_ARM_BIGENDIAN // set big-endian mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #0x80 mcr p15, 0, r0, c1, c0, 0 CPWAIT r0//#endif ldr r0,=(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SUPERVISOR_MODE) msr cpsr, r0 // invalidate I & D caches & BTB mcr p15, 0, r0, c7, c7, 0 CPWAIT r0 // invalidate I & Data TLB mcr p15, 0, r0, c8, c7, 0 CPWAIT r0 // drain write and fill buffers mcr p15, 0, r0, c7, c10, 4 CPWAIT r0 // disable write buffer coalescing mrc p15, 0, r0, c1, c0, 1 orr r0, r0, #1 mcr p15, 0, r0, c1, c0, 1 CPWAIT r0 FLUSH_ONE// Setup chip selects ldr r1, =IXP425_EXP_CFG_BASE#ifdef IXP425_EXP_CS0_INIT ldr r0, =IXP425_EXP_CS0_INIT str r0, [r1, #IXP425_EXP_CS0]#endif#ifdef IXP425_EXP_CS1_INIT ldr r0, =IXP425_EXP_CS1_INIT str r0, [r1, #IXP425_EXP_CS1]#endif#ifdef IXP425_EXP_CS2_INIT ldr r0, =IXP425_EXP_CS2_INIT str r0, [r1, #IXP425_EXP_CS2]#endif#ifdef IXP425_EXP_CS3_INIT ldr r0, =IXP425_EXP_CS3_INIT str r0, [r1, #IXP425_EXP_CS3]#endif#ifdef IXP425_EXP_CS4_INIT ldr r0, =IXP425_EXP_CS4_INIT str r0, [r1, #IXP425_EXP_CS4]#endif#ifdef IXP425_EXP_CS5_INIT ldr r0, =IXP425_EXP_CS5_INIT str r0, [r1, #IXP425_EXP_CS5]#endif#ifdef IXP425_EXP_CS6_INIT ldr r0, =IXP425_EXP_CS6_INIT str r0, [r1, #IXP425_EXP_CS6]#endif#ifdef IXP425_EXP_CS7_INIT ldr r0, =IXP425_EXP_CS7_INIT str r0, [r1, #IXP425_EXP_CS7]#endif FLUSH_ONE // Enable the Icache mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #MMU_Control_I mcr p15, 0, r0, c1, c0, 0 CPWAIT r0 FLUSH_ONE // Setup SDRAM controller ldr r0, =IXP_DDR_CFG_BASE1 ldr r1, =IXDP465_SDCR0_INIT str r1, [r0, #IXP_DDR_SDCR0] ldr r1, =IXDP465_SDCR1_INIT str r1, [r0, #IXP_DDR_SDCR1] mov r1, #SDRAM_PHYS_BASE str r1, [r0, #IXP_DDR_SDBR] ldr r1, [r0, #IXP_DDR_SDBR] // readback ldr r1, =IXDP465_SBR0_INIT str r1, [r0, #IXP_DDR_SBR0] ldr r1, [r0, #IXP_DDR_SBR0] ldr r1, =IXDP465_SBR1_INIT str r1, [r0, #IXP_DDR_SBR1] ldr r1, [r0, #IXP_DDR_SBR1] // Step 5. Disable refresh cycles mov r1, #0 str r1, [r0, #IXP_DDR_RFR] // Step 6. Send NOP command mov r1, #DDR_SDIR_NOP str r1, [r0, #IXP_DDR_SDIR] DELAY 0x100000, r1 // Step 7. Issue precharge-all command to close all open banks mov r1, #DDR_SDIR_PRECHARGE_ALL str r1, [r0, #IXP_DDR_SDIR] DELAY 0x100000, r1 // Step 8. Issue extended mode register set to enable dll mov r1, #DDR_SDIR_EMRS_DLL_ENABLE str r1, [r0, #IXP_DDR_SDIR] DELAY 0x100000, r1 // Step 9. Issue mode register set w/ DLL reset mov r1, #DDR_SDIR_MODE_SET_RESET str r1, [r0, #IXP_DDR_SDIR] DELAY 0x100000, r1 // Step 10. Issue precharge-all command mov r1, #DDR_SDIR_PRECHARGE_ALL str r1, [r0, #IXP_DDR_SDIR] DELAY 0x100000, r1 // Step 11. provide 2 auto-refresh cycles mov r1, #DDR_SDIR_AUTO_REFRESH mov r2, #2 1: str r1, [r0, #IXP_DDR_SDIR] DELAY 0x800, r3 subs r2, r2, #1 bne 1b // Step 12. Issue mode register set w/o DLL reset mov r1, #DDR_SDIR_MODE_SET_NO_RESET str r1, [r0, #IXP_DDR_SDIR] DELAY 0x100000, r1 // start normal operation mov r1, #0xf str r1, [r0, #IXP_DDR_SDIR] DELAY 0x10000, r1 // Step 14. Set refresh val ldr r1, =(IXDP465_SDRAM_REFRESH_CNT >> 3) str r1, [r0, #IXP_DDR_RFR] DELAY 0x100000, r1 // Enable byte swapping control via page table P bit. ldr r2, =IXP425_EXP_CFG_BASE ldr r1, [r2, #IXP425_EXP_CNFG1] orr r1, r1, #EXP_CNFG1_BYTE_SWAP_EN str r1, [r2, #IXP425_EXP_CNFG1] // value to load into pc to jump to real runtime address ldr r0, =1f#if defined(CYG_HAL_STARTUP_ROMRAM) // R0 holds a RAM address for ROMRAM startup, // so convert to a flash address. orr r0, r0, #IXDP465_FLASH_BASE#endif // Setup EXP_CNFG0 value to switch EXP bus out of low memory ldr r2, =IXP425_EXP_CFG_BASE ldr r1, [r2, #IXP425_EXP_CNFG0] bic r1, r1, #EXP_CNFG0_MEM_MAP b icache_boundary .p2align 5icache_boundary: // Here is where we switch from boot address (0x000000000) to the // actual flash runtime address. We align to cache boundary so we // execute from cache during the switchover. Cachelines are 8 words. str r1, [r2, #IXP425_EXP_CNFG0] // make the EXP bus switch nop nop nop nop mov pc, r0 nop 0: b 0b 1: ldr r1, [r2, #IXP425_EXP_CNFG1] orr r1, r1, #EXP_CNFG1_MPI_EN str r1, [r2, #IXP425_EXP_CNFG1] ldr r3, [r2, #IXP425_EXP_CNFG1] // read back to ensure its been written/************************************************//************************************************//* Test all memory *//************************************************//************************************************/99: FLUSH_ONE#define MEM_TEST_MASK 0xa mov r1, #SDRAM_PHYS_BASE orr r1, r1, #0x4000 // RAM tables66: bic r0, r0, #0xff bic r0, r0, #0xff00 bic r0, r0, #0xff0000 bic r0, r0, #0xff000000 orr r0, r0, #0xaa orr r0, r0, #0xaa00 orr r0, r0, #0xaa0000 orr r0, r0, #0xaa000000 str r0, [r1] /* move test mask to memory */ ldr r3, [r1] /* readback */ cmp r0, r3 beq 95f /* compare */ bic r0, r0, #0xff bic r0, r0, #0xff00 bic r0, r0, #0xff0000 bic r0, r0, #0xff000000 orr r0, r0, #0x55 orr r0, r0, #0x5500 orr r0, r0, #0x550000 orr r0, r0, #0x55000000 str r0, [r1] /* move test mask to memory */ ldr r3, [r1] /* readback */ cmp r0, r3 beq 95f /* compare */ mov r1, #0x08000000 /* second bank */ orr r1, r1, #0x4000 // RAM tables bic r0, r0, #0xff bic r0, r0, #0xff00 bic r0, r0, #0xff0000 bic r0, r0, #0xff000000 orr r0, r0, #0xaa orr r0, r0, #0xaa00 orr r0, r0, #0xaa0000 orr r0, r0, #0xaa000000 str r0, [r1] /* move test mask to memory */ ldr r3, [r1] /* readback */ cmp r0, r3 beq 95f /* compare */ bic r0, r0, #0xff bic r0, r0, #0xff00 bic r0, r0, #0xff0000 bic r0, r0, #0xff000000 orr r0, r0, #0x55 orr r0, r0, #0x5500 orr r0, r0, #0x550000 orr r0, r0, #0x55000000 str r0, [r1] /* move test mask to memory */ ldr r3, [r1] /* readback */ cmp r0, r3 beq 95f /* compare */ b 99b /* back */ 95:/************************************************//************************************************//////////////* disable ECC in the FUSE register */ ldr r1, [r2, #IXP46X_EXP_FUSE] // read fuse register orr r1, r1, #0x8000 str r1, [r2, #IXP46X_EXP_FUSE] ldr r3, [r2, #IXP46X_EXP_FUSE] // read back to ensure its been written/////////////////// ldr r1, [r2, #IXP46X_EXP_FUSE] // read fuse register tst r1, #(1 << 15) // check for ECC capability bne 10f // skip ECC init if not needed // enable ECC, disable reporting ldr r0, =IXP_DDR_CFG_BASE1 mov r1, #0 str r1, [r0, #IXP_DDR_ECTST] mov r1, #DDR_ECCR_ENABLE str r1, [r0, #IXP_DDR_ECCR] // Now that we've uncovered all of RAM, its time to scrub. mov r11, #SDRAM_PHYS_BASE mov r12, #SDRAM_SIZE mov r0, #0 mov r1, #0 mov r2, #0 mov r3, #0 mov r4, #0 mov r5, #0 mov r6, #0 mov r7, #0 // scrub Loop 0: stmia r11!, {r0-r7} subs r12, r12, #32 bne 0b10:// DISPLAY 0x1005, r7, r8#if defined(CYG_HAL_STARTUP_ROMRAM) mov r0, #IXDP465_FLASH_BASE mov r1, #SDRAM_PHYS_BASE ldr r2, =__ram_data_end20: ldr r3, [r0],#4 str r3, [r1],#4 cmp r1, r2 bne 20b // start executing from RAM ldr r0, =30f mov pc, r030:#endif // Build mmu tables into RAM so page table walks by the cpu // don't interfere with FLASH programming. mov r1, #SDRAM_PHYS_BASE orr r1, r1, #0x4000 // RAM tables add r2, r1, #0x4000 // End of tables // First clear table mov r0, #0 1: str r0, [r1], #4 cmp r1, r2 bne 1b // Build section mappings C B X P IXP_MAP_SDRAM SDRAM_BASE, 1, 1, 0, 0 // Cached SDRAM IXP_MAP_SDRAM SDRAM_UNCACHED_BASE, 0, 0, 0, 0 // Uncached SDRAM IXP_MAP_SDRAM SDRAM_DC_BASE, 1, 1, 0, 1 // Cached data coherent SDRAM IXP_MAP_EXP 0, IXDP465_FLASH_SIZE, 1, 0, 0, 0 // Flash IXP_MAP_EXP 2, IXDP465_LED_SIZE, 0, 0, 0, 0 // LCD, fpga, cpld IXP_MAP_EXP 4, (1 << 20), 0, 0, 0, 0 IXP_MAP_EXP 5, (1 << 20), 0, 0, 0, 0 IXP_MAP_EXP 6, (1 << 20), 0, 0, 0, 0 IXP_MAP_EXP 7, (1 << 20), 0, 0, 0, 0 IXP_MAP_EXP_V 0, IXDP465_FLASH_DC_BASE, IXDP465_FLASH_SIZE, 1, 0, 0, 1 // data coherent flash// IXP_MAP_IO IXP425_PCI_WINDOW_BASE, IXP425_PCI_WINDOW_SIZE IXP_MAP_IO_DC IXP425_QMGR_BASE, IXP425_QMGR_SIZE// IXP_MAP_IO IXP425_PCI_CFG_BASE, IXP425_PCI_CFG_SIZE IXP_MAP_IO IXP425_EXP_CFG_BASE, IXP425_EXP_CFG_SIZE IXP_MAP_IO IXP425_MISC_CFG_BASE, IXP425_MISC_CFG_SIZE IXP_MAP_IO IXP425_SDRAM_CFG_BASE, IXP425_SDRAM_CFG_SIZE XSCALE_MMU_SECTION 0xE00, 0xE00, 1, 1, 1, 3, 0, 0 // cache flush region// DISPLAY 0x1007, r7, r8 FLUSH_ONE mcr p15, 0, r0, c7, c10, 4 // drain the write & fill buffers CPWAIT r0 // Set the TTB register to DRAM mmu_table ldr r0, =(SDRAM_PHYS_BASE | 0x4000) // RAM tables mcr p15, 0, r0, c2, c0, 0 // load page table pointer CPWAIT r0 // enable permission checks in all domains ldr r0, =0x55555555 mcr p15, 0, r0, c3, c0, 0 CPWAIT r0// DISPLAY 0x1008, r7, r8 FLUSH_ONE // enable mmu mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #MMU_Control_M orr r0, r0, #MMU_Control_R mcr p15, 0, r0, c1, c0, 0 CPWAIT r0// DISPLAY 0x1009, r7, r8 FLUSH_ONE // enable D cache mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #MMU_Control_C mcr p15, 0, r0, c1, c0, 0 CPWAIT r0// DISPLAY 0x100A, r7, r8 FLUSH_ONE // Enable branch target buffer mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #MMU_Control_BTB mcr p15, 0, r0, c1, c0, 0 CPWAIT r0// DISPLAY 0x100B, r7, r8 FLUSH_ONE mcr p15, 0, r0, c7, c10, 4 // drain the write & fill buffers CPWAIT r0 FLUSH_ONE mcr p15, 0, r0, c7, c7, 0 // flush Icache, Dcache and BTB CPWAIT r0 FLUSH_ONE mcr p15, 0, r0, c8, c7, 0 // flush instuction and data TLBs CPWAIT r0 FLUSH_ONE mcr p15, 0, r0, c7, c10, 4 // drain the write & fill buffers CPWAIT r0// DISPLAY 0x100C, r7, r8 FLUSH_ONE // save SDRAM size ldr r1, =hal_dram_size /* [see hal_intr.h] */ mov r8, #SDRAM_SIZE str r8, [r1] // save original value of fuse register ldr r0, =IXP425_EXP_CFG_BASE ldr r8, [r0, #IXP46X_EXP_FUSE] ldr r0, =_ixp4xx_fuse_val str r8, [r0]// tst r8, #(1 << 15) // check for ECC capability// bne 0f // turn on ECC if supported// ldr r0, =IXP_DDR_CFG_BASE1// mov r1, #(DDR_ECCR_ENABLE | DDR_ECCR_SBEC | DDR_ECCR_MBER | DDR_ECCR_SBER)// str r1, [r0, #IXP_DDR_ECCR] 0:// DISPLAY 0x100D, r7, r8 FLUSH_ONE .endm // _platform_setup1#else // defined(CYG_HAL_STARTUP_ROM)#define PLATFORM_SETUP1#endif#define PLATFORM_VECTORS _platform_vectors .macro _platform_vectors .globl _ixp4xx_fuse_val_ixp4xx_fuse_val: .long 0 .endm/*---------------------------------------------------------------------------*//* end of hal_platform_setup.h */#endif /* CYGONCE_HAL_PLATFORM_SETUP_H */