⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ebsa285_misc.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 2 页
字号:
                        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 + -