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

📄 em86xxapi.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************** Copyright (c) 2002-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* * em86xxapi.c * * by Ho Lee 01/23/2002 */#include "config.h"#include "uart.h"#include "io.h"#include "hardware.h"#include "irqs.h"#include "util.h"#include "vsprintf.h"#include "em86xxapi.h"extern int board_init(void);//// Intialization//int em86xx_init(void){    // setup remap register    __raw_writel(DRAMBASE, REG_BASE_CPU + CPU_remap);    // setup peripheral bus interface    // CS0 : IDE, 16/16 (addr/data)    // CS1 :     // CS2 : parallel flash / FlexROM, 24/8    // CS3 :     // default :     __raw_writel(DEFAULT_PB_DEFAULT_TIMING, REG_BASE_HOST + PB_default_timing);    __raw_writel(DEFAULT_PB_CS_CONFIG, REG_BASE_HOST + PB_cs_config);    // timing 0 :     __raw_writel(DEFAULT_PB_TIMING0, REG_BASE_HOST + PB_timing0);    __raw_writel(DEFAULT_PB_USE_TIMING0, REG_BASE_HOST + PB_use_timing0);    // timing 1 :     __raw_writel(DEFAULT_PB_TIMING1, REG_BASE_HOST + PB_timing1);    __raw_writel(DEFAULT_PB_USE_TIMING1, REG_BASE_HOST + PB_use_timing1);    // timing 2 :     __raw_writel(DEFAULT_PB_TIMING2, REG_BASE_HOST + PB_timing2);    __raw_writel(DEFAULT_PB_USE_TIMING2, REG_BASE_HOST + PB_use_timing2);    // timing 3 :     __raw_writel(DEFAULT_PB_TIMING3, REG_BASE_HOST + PB_timing3);    __raw_writel(DEFAULT_PB_USE_TIMING3, REG_BASE_HOST + PB_use_timing3);    // timing 4 :     __raw_writel(DEFAULT_PB_TIMING4, REG_BASE_HOST + PB_timing4);    __raw_writel(DEFAULT_PB_USE_TIMING4, REG_BASE_HOST + PB_use_timing4);    // timing 5 :     __raw_writel(DEFAULT_PB_TIMING5, REG_BASE_HOST + PB_timing5);    __raw_writel(DEFAULT_PB_USE_TIMING5, REG_BASE_HOST + PB_use_timing5);    // setup mapping between GPIO and IRQ    __raw_writel(DEFAULT_IRQ_GPIOMAP, REG_BASE_SYSTEM + SYS_gpio_int);    // setup default GPIO pins direction and value (if set to output)    __raw_writel(0xffff0000 | DEFAULT_GPIO_DIR, REG_BASE_SYSTEM + SYS_gpio_dir);    if (DEFAULT_GPIO_DIR != 0) /* Some pins are set to output */    	__raw_writel((DEFAULT_GPIO_DIR << 16) | DEFAULT_GPIO_OUTPUT, 			REG_BASE_SYSTEM + SYS_gpio_data);#ifdef CONFIG_ARCH_TANGO#ifdef CONFIG_ENABLE_IDE#ifdef CONFIG_ENABLE_IDE_ISA    // IDE configuration compatible with Mambo    // IDE pins are tristated    __raw_writel(0x10800, REG_BASE_HOST + IDECTRL_pri_idectl);#else    // Enable bus master IDE interface    __raw_writel(0x08400, REG_BASE_HOST + IDECTRL_pri_idectl);#endif#endif#endif        // Calling board specific initialization routine.    board_init();    return 0;}//// Clock//unsigned long em86xx_getclock(void){    unsigned int reg, mult, div;    unsigned long clock;    reg = __raw_readl(REG_BASE_SYSTEM + SYS_clkgen0_pll);    mult = reg & 0x03ff;    div = (reg >> 16) & 0x003f;    // clock = CPU_CLK_INPUT * (MULT + 2) / (DIV + 2)    clock = idivide(EM86XX_EXT_CLOCK, div + 2);    clock = clock * (mult + 2);    return clock;}unsigned int em86xx_getclockmhz(void){    unsigned long clock = em86xx_getclock();    clock /= 1000000;    clock >>= 1;    return (unsigned int) clock;}// MULT =  9, DIV = 1 =>  49.5 MHz// MULT = 20, DIV = 1 =>  99.0 MHz// MULT = 31, DIV = 1 => 148.5 MHz// MULT = 42, DIV = 1 => 198.0 MHzvoid em86xx_setclockmhz(int clock){    unsigned int reg, mult, div;    // clock = CPU_CLK_INPUT * (MULT + 2) / (DIV + 2)    // MULT = clock * (DIV + 2) / CPU_CLK_INPUT - 2    // fix DIV as 1        if (clock > 100)        div = 1;    else         div = 3;    mult = clock * (div + 2);    mult <<= 1;    mult /= (EM86XX_EXT_CLOCK / 1000000);    mult -= 2;    reg = __raw_readl(REG_BASE_SYSTEM + SYS_clkgen0_pll);    reg &= ~0x003f00ff;    reg |= ((mult) | (div << 16));    __raw_writel(reg, REG_BASE_SYSTEM + SYS_clkgen0_pll);}//// Delay//void em86xx_usleep(int usec){#if 0    int i;    unsigned long clock = em86xx_getclock();    clock >>= 20;    clock >>= 1;    clock /= 5;    clock *= usec;    for (i = 0; i < clock; ++i)        ;#else    unsigned int start, end;    start = __raw_readl(REG_BASE_SYSTEM + SYS_xtal_in_cnt);    end = start + (usec * 27);    if (end <= start)        while (__raw_readl(REG_BASE_SYSTEM + SYS_xtal_in_cnt) > start);    while (__raw_readl(REG_BASE_SYSTEM + SYS_xtal_in_cnt) < end);#endif}void em86xx_msleep(int msec){#if 0    while (msec-- > 0)         em86xx_usleep(990);#else    while (msec-- > 0)         em86xx_usleep(998);#endif}//// CPSR flag//// disable IRQ and FIQ and return original flagunsigned int em86xx_saveflag_clif(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs r1, cpsr\n"            // get CPSR        "mov %0, r1\n"              // save CPSR        "orr r1, r1, #0xc0\n"       // disable IRQ & FIQ        "msr cpsr_c, r1\n"          // set CPSR        : "=r" (cpsr_reg) : : "r1");    return cpsr_reg;}// disable FIQ and return original flagunsigned int em86xx_saveflag_clf(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs r1, cpsr\n"            // get CPSR        "mov %0, r1\n"              // save CPSR        "orr r1, r1, #0x40\n"       // disable FIQ        "msr cpsr_c, r1\n"          // set CPSR        : "=r" (cpsr_reg) : : "r1");    return cpsr_reg;}// disable IRQ and return original flagunsigned int em86xx_saveflag_cli(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs r1, cpsr\n"            // get CPSR        "mov %0, r1\n"              // save CPSR        "orr r1, r1, #0x80\n"       // disable IRQ        "msr cpsr_c, r1\n"          // set CPSR        : "=r" (cpsr_reg) : : "r1");    return cpsr_reg;}// return CPSRunsigned int em86xx_getflag(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs r1, cpsr\n"            // get CPSR        "mov %0, r1\n"                      : "=r" (cpsr_reg) : : "r1");    return cpsr_reg;}void em86xx_restoreflag(unsigned int cpsr_reg){    __asm__ __volatile__(        "mov r1, %0\n"        "msr cpsr_c, r1\n"        : : "r" (cpsr_reg));}//// Cache control//void em86xx_get_cache_state(int *picache, int *pdcache, int *pwriteback){    unsigned int reg;    __asm__ __volatile__ (        "mrc    p15, 0, %0, c1, c0, 0\n"        : "=r" (reg)    );    if (picache)        *picache = (reg & 0x1000);    if (pdcache)        *pdcache = (reg & 0x0004);    if (pwriteback)        *pwriteback = (reg & 0x0002);}void em86xx_enable_cache(int icache, int dcache, int writeback){    unsigned int reg;    __asm__ __volatile__ (        "mrc    p15, 0, %0, c1, c0, 0\n"        : "=r" (reg)    );    if (icache > 0)        reg |= 0x1000;    else if (icache == 0) {        reg &= ~0x1000;        em86xx_flush_cache_data();    }        if (dcache > 0)        reg |= 0x0004;    else if (dcache == 0) {        reg &= ~0x0004;        em86xx_flush_cache_data();    }        if (writeback > 0)        reg |= 0x0002;    else if (writeback == 0) {        reg &= ~0x0002;        em86xx_clean_cache_data();    }    __asm__ __volatile__ (        "mcr    p15, 0, %0, c1, c0, 0\n"        : : "r" (reg)    );}void em86xx_clean_cache_data(void){    __asm__(        "mcr    p15, 0, %0, c7, c10, 0\n"       // clean data        : : "r" (0)    );}void em86xx_clean_cache_data_region(unsigned int from, unsigned int to){    unsigned int flag;    from &= ~0x0f;    to &= ~0x0f;    flag = em86xx_saveflag_cli();    for (; from <= to; from += 0x10) {        __asm__ __volatile__ (            "mcr    p15, 0, %0, c7, c10, 1\n"   // clean data            : : "r" (from)        );    }    em86xx_restoreflag(flag);}void em86xx_invalidate_cache_instruction(void){    unsigned int flag;    flag = em86xx_saveflag_cli();    __asm__(        "mcr    p15, 0, %0, c7, c10, 0\n"       // clean data        "mcr    p15, 0, %0, c7, c5, 0\n"        // invalidate instruction        : : "r" (0)    );    em86xx_restoreflag(flag);}void em86xx_invalidate_cache_instruction_region(unsigned int from, unsigned int to){    unsigned int flag;    from &= ~0x0f;    to &= ~0x0f;    flag = em86xx_saveflag_cli();    for (; from <= to; from += 0x10) {        __asm__ __volatile__ (            "mcr    p15, 0, %0, c7, c10, 1\n"   // clean data            "mcr    p15, 0, %0, c7, c5, 1\n"    // invalidate instruction            : : "r" (from)        );    }    em86xx_restoreflag(flag);}void em86xx_invalidate_cache_data(void){    __asm__(        "mcr    p15, 0, %0, c7, c6, 0\n"        // invalidate data        : : "r" (0)    );}void em86xx_invalidate_cache_data_region(unsigned int from, unsigned int to){    unsigned int flag;    from &= ~0x0f;    to &= ~0x0f;    if (from < MEMORY_BASE_DRAMCTRL0)        return;    flag = em86xx_saveflag_cli();    for (; from <= to; from += 0x10) {        __asm__ __volatile__ (            "mcr    p15, 0, %0, c7, c6, 1\n"    // invalidate data            : : "r" (from)        );    }    em86xx_restoreflag(flag);}void em86xx_flush_cache_all(void){    unsigned int flag;    flag = em86xx_saveflag_cli();    __asm__ __volatile__ (        "mcr    p15, 0, %0, c7, c10, 0\n"       // clean data cache        "mcr    p15, 0, %0, c7, c5, 0\n"        // invalidate instruction cache        "mcr    p15, 0, %0, c7, c6, 0\n"        // invalidate data cache        : : "r" (0)    );    em86xx_restoreflag(flag);}void em86xx_flush_cache_data(void){    unsigned int flag;    flag = em86xx_saveflag_cli();    __asm__ __volatile__ (        "mcr    p15, 0, %0, c7, c10, 0\n"       // clean data cache        "mcr    p15, 0, %0, c7, c6, 0\n"        // invalidate data cache        : : "r" (0)    );    em86xx_restoreflag(flag);}void em86xx_flush_cache_data_region(unsigned int from, unsigned int to){    unsigned int flag;    from &= ~0x0f;    to &= ~0x0f;    if (from < MEMORY_BASE_DRAMCTRL0)        return;    flag = em86xx_saveflag_cli();    for (; from <= to; from += 0x10) {        __asm__ __volatile__ (            "mcr    p15, 0, %0, c7, c10, 1\n"   // clean data cache            "mcr    p15, 0, %0, c7, c6, 1\n"    // invalidate data cache            : : "r" (from)        );    }    em86xx_restoreflag(flag);}// // interrupt / fast interrupt control//void em86xx_irq_init(void){    /* Disable all interrupts initially. */    __raw_writel(0xffffffff, REG_BASE_CPU + CPU_irq_enableclr);    __raw_writel(0xffffffff, REG_BASE_CPU + CPU_fiq_enableclr);    /* Disable edge detector */    __raw_writel(IRQMASK_RISINGEDGE, REG_BASE_CPU + CPU_edge_config_rise);    __raw_writel(IRQMASK_FALLINGEDGE, REG_BASE_CPU + CPU_edge_config_fall);    __raw_writel(__raw_readl(REG_BASE_CPU + CPU_edge_rawstat), REG_BASE_CPU + CPU_edge_rawstat);#if defined(CONFIG_ARCH_TANGO15) && (CONFIG_ARCH_TANGO15_REV > 1) /* Tango15 Rev B or above */    /* Disable all high 32 interrupts. */    __raw_writel(0xffffffff, REG_BASE_CPU + CPU_irq_enableclr_hi);    __raw_writel(0xffffffff, REG_BASE_CPU + CPU_fiq_enableclr_hi);    /* Disable edge detector */    __raw_writel(IRQMASK_RISINGEDGE_HI, REG_BASE_CPU + CPU_edge_config_rise_hi);    __raw_writel(IRQMASK_FALLINGEDGE_HI, REG_BASE_CPU + CPU_edge_config_fall_hi);    __raw_writel(__raw_readl(REG_BASE_CPU + CPU_edge_rawstat_hi), REG_BASE_CPU + CPU_edge_rawstat_hi);#endif}#define EM86XX_X_MASK(x) \    void em86xx_mask_##x##(unsigned int irq) \    { \        unsigned int reg; \        \        /* IRQ / FIQ disable */ \        reg = (1 << irq); \        __raw_writel(reg, REG_BASE_CPU + CPU_##x##_enableclr); \        \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -