Mercurial > flash_v2
diff packages/hal/arm/ebsa285/current/src/ebsa285_misc.c @ 76:435cced73e2f ecos-v1_3_1-release
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
| author | jlarmour |
|---|---|
| date | Tue, 28 Mar 2000 14:10:45 +0000 |
| parents | |
| children | 84e4bde58b26 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/ebsa285/current/src/ebsa285_misc.c @@ -0,0 +1,425 @@ +//========================================================================== +// +// ebsa285_misc.c +// +// HAL misc board support code for StrongARM EBSA285-1 +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-20 +// Purpose: HAL board support +// Description: Implementations of HAL board interfaces +// +//####DESCRIPTIONEND#### +// +//========================================================================*/ + +#include <pkgconf/hal.h> +#include <pkgconf/system.h> +#include CYGBLD_HAL_PLATFORM_H + +#include <cyg/infra/cyg_type.h> // base types +#include <cyg/infra/cyg_trac.h> // tracing macros +#include <cyg/infra/cyg_ass.h> // assertion macros + +#include <cyg/hal/hal_io.h> // IO macros +#include <cyg/hal/hal_arch.h> // Register state info +#include <cyg/hal/hal_diag.h> +#include <cyg/hal/hal_intr.h> // Interrupt names +#include <cyg/hal/hal_cache.h> +#include <cyg/hal/hal_ebsa285.h> // Hardware definitions + +#include <cyg/infra/diag.h> // diag_printf + +/* + * Toggle LED for debugging purposes. + */ +/* + * EBSA-285 Soft I/O Register + */ +#define EBSA_285_SOFT_IO_REGISTER ((cyg_uint32 *)0x40012000) + +/* + * EBSA-285 Soft I/O Register Bit Field definitions + */ +#define EBSA_285_SOFT_IO_TOGGLE 0x80 +#define EBSA_285_SOFT_IO_RED_LED 0x04 +#define EBSA_285_SOFT_IO_GREEN_LED 0x02 +#define EBSA_285_SOFT_IO_AMBER_LED 0x01 +#define EBSA_285_SOFT_IO_J9_9_10_MASK 0x40 +#define EBSA_285_SOFT_IO_J9_11_12_MASK 0x20 +#define EBSA_285_SOFT_IO_J9_13_14_MASK 0x10 +#define EBSA_285_SOFT_IO_SWITCH_L_MASK 0x0F + +static void +hal_bsp_mmu_init(int sdram_size); + +// Some initialization has already been done before we get here. +// +// Set up the interrupt environment. +// Set up the MMU so that we can use caches. +// Enable caches. +// - All done! + + +void hal_hardware_init(void) +{ + // Disable all interrupt sources: + *SA110_IRQCONT_IRQENABLECLEAR = 0xffffffff; + *SA110_IRQCONT_FIQENABLECLEAR = 0xffffffff; // including FIQ + // Disable the timers + *SA110_TIMER1_CONTROL = 0; + *SA110_TIMER2_CONTROL = 0; + *SA110_TIMER3_CONTROL = 0; + *SA110_TIMER4_CONTROL = 0; + + *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt + *SA110_TIMER2_CLEAR = 0; // (Data: don't care) + *SA110_TIMER3_CLEAR = 0; + *SA110_TIMER4_CLEAR = 0; + + // Set up MMU so that we can use caches + hal_bsp_mmu_init( hal_dram_size ); + + // Enable caches + HAL_DCACHE_ENABLE(); + HAL_ICACHE_ENABLE(); + +#ifndef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +#ifdef CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT + // then enable the interrupt for incoming characters and break + // into the stub ROM if the char is a ^C. + HAL_INTERRUPT_UNMASK( CYG_DIAG_DEV_INT ); + // hal_diag.c: hal_ctrlc_isr( CYG_ADDRWORD vector, CYG_ADDRWORD data) + // is polled from the default ISR so it's OK just to enable this. +#endif +#endif +} + +// ------------------------------------------------------------------------- +// MMU initialization: + +static void +hal_bsp_mmu_init(int sdram_size) +{ + unsigned long ttb_base = ((unsigned long)0x4000); // could be external + unsigned long i; + + *EBSA_285_SOFT_IO_REGISTER = ~EBSA_285_SOFT_IO_RED_LED; // Red LED on + + +// For if we assign the ttb base dynamically: +// if ((ttb_base & ARM_TRANSLATION_TABLE_MASK) != ttb_base) { +// // we cannot do this: +// while ( 1 ) { +// *EBSA_285_SOFT_IO_REGISTER = 0; // All LEDs on +// for ( i = 100000; i > 0 ; i++ ) ; +// *EBSA_285_SOFT_IO_REGISTER = 7; // All LEDs off +// for ( i = 100000; i > 0 ; i++ ) ; +//#ifdef CYG_HAL_STARTUP_RAM +// return; // Do not bother looping forever... +//#endif +// } +// } + + /* + * Set the TTB register + */ + asm volatile ("mcr p15,0,%0,c2,c0,0" + : + : "r"(ttb_base) + /*:*/ + ); + /* + * Set the Domain Access Control Register + */ + i = ARM_ACCESS_TYPE_MANAGER(0) | + ARM_ACCESS_TYPE_NO_ACCESS(1) | + ARM_ACCESS_TYPE_NO_ACCESS(2) | + ARM_ACCESS_TYPE_NO_ACCESS(3) | + ARM_ACCESS_TYPE_NO_ACCESS(4) | + ARM_ACCESS_TYPE_NO_ACCESS(5) | + ARM_ACCESS_TYPE_NO_ACCESS(6) | + ARM_ACCESS_TYPE_NO_ACCESS(7) | + ARM_ACCESS_TYPE_NO_ACCESS(8) | + ARM_ACCESS_TYPE_NO_ACCESS(9) | + ARM_ACCESS_TYPE_NO_ACCESS(10) | + ARM_ACCESS_TYPE_NO_ACCESS(11) | + ARM_ACCESS_TYPE_NO_ACCESS(12) | + ARM_ACCESS_TYPE_NO_ACCESS(13) | + ARM_ACCESS_TYPE_NO_ACCESS(14) | + ARM_ACCESS_TYPE_NO_ACCESS(15); + + asm volatile ("mcr p15,0,%0,c3,c0,0" + : + : "r"(i) + /*:*/ + ); + + /* + * First clear all TT entries - ie Set them to Faulting + */ + memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE); + + /* + * We only do direct mapping for the EBSA board. That is, all + * virt_addr == phys_addr. + */ + + /* + * Actual Base = 0x000(00000) + * Virtual Base = 0x000(00000) + * Size = Max SDRAM + * SDRAM + */ + for (i = 0x000; i < (sdram_size >> 20); i++) { + ARM_MMU_SECTION(ttb_base, i, i, + ARM_CACHEABLE, ARM_BUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + } + +#ifdef CYGPKG_IO_PCI + /* + * Actual Base = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE + * Virtual Base = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE + * Size = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE + * Memory accessible from PCI space. Overrides part of the above mapping. + */ + for (i = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE >> 20; + i < ((CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE+CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE) >> 20); + i++) { + ARM_MMU_SECTION(ttb_base, i, i, + ARM_UNCACHEABLE, ARM_UNBUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + } +#endif + + /* + * Actual Base = 0x400(00000) + * Virtual Base = 0x400(00000) + * Size = 1M + * 21285 Registers + * + * Actual Base = 0x400(10000) + * Virtual Base = 0x400(10000) + * Size = 1M + * Soft I/O port and XBus IO + */ + ARM_MMU_SECTION(ttb_base, 0x400, 0x400, + ARM_UNCACHEABLE, ARM_UNBUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + + /* + * Actual Base = 0x410(00000) - 0x413(FFFFF) + * Virtual Base = 0x410(00000) - 0x413(FFFFF) + * Size = 4M + * FLASH ROM + */ + for (i = 0x410; i <= 0x413; i++) { + ARM_MMU_SECTION(ttb_base, i, i, + ARM_CACHEABLE, ARM_UNBUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + } + + /* + * Actual Base = 0x420(00000) + * Virtual Base = 0x420(00000) + * Size = 1M + * 21285 CSR Space + */ + ARM_MMU_SECTION(ttb_base, 0x420, 0x420, + ARM_UNCACHEABLE, ARM_UNBUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + + /* + * Actual Base = 0x500(00000)-0x50F(FFFFF) + * Virtual Base = 0x500(00000)-0x50F(FFFFF) + * Size = 16M + * Zeros (Cache Clean) Bank + */ + for (i = 0x500; i <= 0x50F; i++) { + ARM_MMU_SECTION(ttb_base, i, i, + ARM_CACHEABLE, ARM_BUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + } + + /* + * Actual Base = 0x780(00000)-0x78F(FFFFF) + * Virtual Base = 0x780(00000)-0x78F(FFFFF) + * Size = 16M + * Outbound Write Flush + */ + for (i = 0x780; i <= 0x78F; i++) { + ARM_MMU_SECTION(ttb_base, i, i, + ARM_UNCACHEABLE, ARM_UNBUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + } + + /* + * Actual Base = 0x790(00000)-0x7C0(FFFFF) + * Virtual Base = 0x790(00000)-0x7C0(FFFFF) + * Size = 65M + * PCI IACK/Config/IO Space + */ + for (i = 0x790; i <= 0x7C0; i++) { + ARM_MMU_SECTION(ttb_base, i, i, + ARM_UNCACHEABLE, ARM_UNBUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + } + + /* + * Actual Base = 0x800(00000) - 0xFFF(FFFFF) + * Virtual Base = 0x800(00000) - 0xFFF(FFFFF) + * Size = 2G + * PCI Memory Space + */ + for (i = 0x800; i <= 0xFFF; i++) { + ARM_MMU_SECTION(ttb_base, i, i, + ARM_UNCACHEABLE, ARM_BUFFERABLE, + ARM_ACCESS_PERM_RW_RW); + } + + *EBSA_285_SOFT_IO_REGISTER = ~EBSA_285_SOFT_IO_AMBER_LED; // AmberLED on + +} + +// ------------------------------------------------------------------------- +static cyg_uint32 _period; + +void hal_clock_initialize(cyg_uint32 period) +{ + _period = period; + + *SA110_TIMER3_CONTROL = 0; // Disable while we are setting up + + *SA110_TIMER3_LOAD = period; // Reload value + + *SA110_TIMER3_CLEAR = 0; // Clear any pending interrupt + // (Data: don't care) + + *SA110_TIMER3_CONTROL = 0x000000cc; // Enable, Periodic (auto-reload), + // External clock (3.68MHz on irq_in_l[2] for Timer 3) + + *SA110_TIMER3_CLEAR = 0; // Clear any pending interrupt again + + // That's all. +} + +// This routine is called during a clock interrupt. + +void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period) +{ + *SA110_TIMER3_CLEAR = period; // Clear any pending interrupt (Data: don't care) +} + +// Read the current value of the clock, returning the number of hardware +// "ticks" that have occurred (i.e. how far away the current value is from +// the start) + +void hal_clock_read(cyg_uint32 *pvalue) +{ + *pvalue = (cyg_uint32)(_period) - *SA110_TIMER3_VALUE; +} + +// ------------------------------------------------------------------------- + +// This routine is called to respond to a hardware interrupt (IRQ). It +// should interrogate the hardware and return the IRQ vector number. +int hal_IRQ_handler(void) +{ + int sources; + int index; + +#if 0 // test FIQ and print alert if active - really for debugging + sources = *SA110_IRQCONT_FIQSTATUS; + if ( 0 != sources ) + diag_printf( "FIQ source active!!! - fiqstatus %08x irqstatus %08x\n", + sources, *SA110_IRQCONT_IRQSTATUS ); + else +#endif // Scan FIQ sources also + + sources = *SA110_IRQCONT_IRQSTATUS; + +// if we come to support FIQ properly... +// if ( 0 == sources ) +// sources = *SA110_IRQCONT_FIQSTATUS; + + // Nothing wrong with scanning them in the order provided... + // and it'll make the serial device steal fewer cycles. + // So, knowing this is an ARM: + if ( sources & 0xff ) + index = 0; + else if ( sources & 0xff00 ) + index = 8; + else if ( sources & 0xff0000 ) + index = 16; + else // if ( sources & 0xff000000 ) + index = 24; + + do { + if ( (1 << index) & sources ) + return index; + index++; + } while ( index & 7 ); + + return CYGNUM_HAL_INTERRUPT_reserved0; // This shouldn't happen! +} + +// +// Interrupt control +// + +void hal_interrupt_mask(int vector) +{ + *SA110_IRQCONT_IRQENABLECLEAR = 1 << vector; +} + +void hal_interrupt_unmask(int vector) +{ + *SA110_IRQCONT_IRQENABLESET = 1 << vector; +} + +void hal_interrupt_acknowledge(int vector) +{ + // Nothing to do here. +} + +void hal_interrupt_configure(int vector, int level, int up) +{ + // No interrupts are configurable on this hardware +} + +void hal_interrupt_set_level(int vector, int level) +{ + // No interrupts are configurable on this hardware +} + +/*------------------------------------------------------------------------*/ +// EOF ebsa285_misc.c
