📄 ebsa285_misc.c
字号:
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
}
/*------------------------------------------------------------------------*/
//
// Memory layout
//
externC cyg_uint8 *
hal_arm_mem_real_region_top( cyg_uint8 *regionend )
{
CYG_ASSERT( hal_dram_size > 0, "Didn't detect DRAM size!" );
CYG_ASSERT( hal_dram_size <= 256<<20,
"More than 256MB reported - that can't be right" );
// is it the "normal" end of the DRAM region? If so, it should be
// replaced by the real size
if ( regionend ==
((cyg_uint8 *)CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE) ) {
regionend = (cyg_uint8 *)CYGMEM_REGION_ram + hal_dram_size;
}
return regionend;
} // hal_arm_mem_real_region_top()
// -------------------------------------------------------------------------
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;
}
//
// Delay for some number of micro-seconds
//
void hal_delay_us(cyg_int32 usecs)
{
int diff, diff2;
cyg_uint32 val1, val2;
while (usecs-- > 0) {
diff = 0;
val1 = *SA110_TIMER3_VALUE;
while (diff < 3) {
while ((val2 = *SA110_TIMER3_VALUE) == val1) ;
if (*SA110_TIMER3_LOAD) {
// A kernel is running, the counter may get reset as we watch
diff2 = val2 - val1;
if (diff2 < 0) diff2 += *SA110_TIMER3_LOAD;
diff += diff2;
} else {
diff += val2 - val1;
}
}
}
}
// -------------------------------------------------------------------------
// 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_NONE; // 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
}
#include CYGHWR_MEMORY_LAYOUT_H
typedef void code_fun(void);
void ebsa285_program_new_stack(void *func)
{
register CYG_ADDRESS stack_ptr asm("sp");
register CYG_ADDRESS old_stack asm("r4");
register code_fun *new_func asm("r0");
old_stack = stack_ptr;
stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
new_func = (code_fun*)func;
new_func();
stack_ptr = old_stack;
return;
}
/*------------------------------------------------------------------------*/
// EOF ebsa285_misc.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -