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

📄 em86xxapi.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
📖 第 1 页 / 共 2 页
字号:
        /* if the interrupt is detected by edge detector not level detector */ \        /* clear edge status */ \        if ((IRQMASKOF(irq) & (IRQMASK_RISINGEDGE | IRQMASK_FALLINGEDGE)) != 0) \            __raw_writel(reg, REG_BASE_CPU + CPU_edge_rawstat); \    }    #define EM86XX_X_UNMASK(x) \    void em86xx_unmask_##x##(unsigned int irq) \    { \        unsigned int reg; \        \        /* IRQ / FIQ enable */ \        reg = (1 << irq); \        __raw_writel(reg, REG_BASE_CPU + CPU_##x##_enableset); \    }#define EM86XX_X_STATUS(x) \    int em86xx_##x##_status(unsigned int irq) \    { \        unsigned int status = __raw_readl(REG_BASE_CPU + CPU_##x##_rawstat); \        \        return (status & IRQMASKOF(irq)) ? 1 : 0; \    }#define EM86XX_X_WAIT(x) \    void em86xx_##x##_wait(unsigned int irq) \    { \        unsigned int mask = IRQMASKOF(irq); \        \        while ((__raw_readl(REG_BASE_CPU + CPU_##x##_rawstat) & mask) == 0) \            ; \    }EM86XX_X_MASK(irq)EM86XX_X_UNMASK(irq)EM86XX_X_STATUS(irq)EM86XX_X_WAIT(irq)EM86XX_X_MASK(fiq)EM86XX_X_UNMASK(fiq)EM86XX_X_STATUS(fiq)EM86XX_X_WAIT(fiq)// // interrupt handler//static struct {    irq_handler_t handler;    void *pdata;} s_irq_info[NR_IRQS];void em86xx_sti(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs %0, cpsr\n"            // get CPSR        "bic %0, %0, #0x80\n"       // enable IRQ        "msr cpsr_c, %0\n"          // set CPSR        : "=r" (cpsr_reg) : : "memory");}void em86xx_cli(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs %0, cpsr\n"            // get CPSR        "orr %0, %0, #0x80\n"       // disable IRQ         "msr cpsr_c, %0\n"          // set CPSR        : "=r" (cpsr_reg) : : "memory");}int em86xx_irqenabled(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs %0, cpsr\n"            // get CPSR        : "=r" (cpsr_reg));    return (cpsr_reg & 0x80) ? 0 : 1;}void em86xx_request_irq(int irq, irq_handler_t handler, void *pdata){    s_irq_info[irq].handler = handler;    s_irq_info[irq].pdata = pdata;    em86xx_unmask_irq(irq);}void em86xx_free_irq(int irq){    em86xx_mask_irq(irq);    s_irq_info[irq].handler = NULL;    s_irq_info[irq].pdata = NULL;}void em86xx_irq_handler(void){    int i;    unsigned int mask;    unsigned int status = __raw_readl(REG_BASE_CPU + CPU_irq_status);    for (i = 0, mask = 1; status != 0; ++i, mask <<= 1) {        if (status & mask) {            status &= ~mask;            em86xx_mask_irq(i); /* If no handler, left it masked */            if (s_irq_info[i].handler) {                s_irq_info[i].handler(i, s_irq_info[i].pdata);            	em86xx_unmask_irq(i);	    }         }    }}// // fast interrupt handler//static struct {    fiq_handler_t handler;    void *pdata;} s_fiq_info[NR_IRQS];void em86xx_stf(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs %0, cpsr\n"            // get CPSR        "bic %0, %0, #0x40\n"       // enable FIQ        "msr cpsr_c, %0\n"          // set CPSR        : "=r" (cpsr_reg) : : "memory");}void em86xx_clf(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs %0, cpsr\n"            // get CPSR        "orr %0, %0, #0x40\n"       // disable FIQ        "msr cpsr_c, %0\n"          // set CPSR        : "=r" (cpsr_reg) : : "memory");}void em86xx_request_fiq(int fiq, fiq_handler_t handler, void *pdata){    s_fiq_info[fiq].handler = handler;    s_fiq_info[fiq].pdata = pdata;    em86xx_unmask_fiq(fiq);}void em86xx_free_fiq(int fiq){    em86xx_mask_fiq(fiq);    s_fiq_info[fiq].handler = NULL;    s_fiq_info[fiq].pdata = NULL;}void em86xx_fiq_handler(void){    int i;    unsigned int mask;    unsigned int status = __raw_readl(REG_BASE_CPU + CPU_fiq_status);    for (i = 0, mask = 1; status != 0; ++i, mask <<= 1) {        if (status & mask) {            status &= ~mask;            em86xx_mask_fiq(i); /* If no handler, left it masked */            if (s_fiq_info[i].handler) {                s_fiq_info[i].handler(i, s_fiq_info[i].pdata);                em86xx_unmask_fiq(i);	    }        }    }}//// Switcbox (Host interface)//static int g_sbox_map[SBOX_MAX + 1];static int g_sbox_used[2], g_sbox_lastmap[2];// Initialize SwitchBox int em86xx_sbox_init(void){#ifdef CONFIG_ARCH_MAMBO    em86xx_sbox_setup(SBOX_IDEFLASH, SBOX_PCIMASTER);#else#ifdef CONFIG_ENABLE_IDE_BM    em86xx_sbox_setup(SBOX_IDEDVD, SBOX_PCIMASTER);#else    em86xx_sbox_setup(SBOX_IDEFLASH, SBOX_PCIMASTER);#endif#endif    em86xx_sbox_reset();    return 0;}void em86xx_sbox_reset(void){#if defined(CONFIG_ARCH_MAMBO)    __raw_writel(0x1f1f1f1f, REG_BASE_HOST + SBOX_reset);    __raw_writel(0x1f001f00, REG_BASE_HOST + SBOX_reset);#elif defined(CONFIG_ARCH_TANGO)    __raw_writel(0x7f7fffff, REG_BASE_HOST + SBOX_reset);    __raw_writel(0x7f00ff00, REG_BASE_HOST + SBOX_reset);#endif}// connect R0/W0 and R1/W1 to specified interface if0, if1int em86xx_sbox_setup(int if0, int if1){    int i;    unsigned int data;#if defined(CONFIG_ARCH_MAMBO)    g_sbox_map[0] = if0;    g_sbox_map[1] = if1;    g_sbox_map[SBOX_IDEFLASH] = 7;    g_sbox_map[SBOX_PCIMASTER] = 7;    g_sbox_map[SBOX_PCISLAVE] = 7;    g_sbox_map[if0] = 0;    g_sbox_map[if1] = 1;#elif defined(CONFIG_ARCH_TANGO)    g_sbox_map[0] = if0 + 1;    g_sbox_map[1] = if1 + 1;    g_sbox_map[SBOX_PCIMASTER] = 0xf;    g_sbox_map[SBOX_PCISLAVE] = 0xf;    g_sbox_map[SBOX_CIPHER] = 0xf;    g_sbox_map[SBOX_IDEDVD] = 0xf;    g_sbox_map[SBOX_IDEFLASH] = 0xf;    g_sbox_map[SBOX_SFLASH] = 0xf;    g_sbox_map[if0] = 1;    g_sbox_map[if1] = 2;#else#error Unknown Architecture#endif    for (i = SBOX_MAX, data = 0; i >= 0; --i)        data = (data << 4) | g_sbox_map[i];    __raw_writel(data, REG_BASE_HOST + SBOX_route);    return 0;}int em86xx_sbox_connect(int iface){    int port = -1;#if defined(CONFIG_ARCH_MAMBO)    if (iface == g_sbox_map[0])        port = 0;    else if (iface == g_sbox_map[1])        port = 1;#elif defined(CONFIG_ARCH_TANGO)    if (iface + 1 == g_sbox_map[0])        port = 0;    else if (iface + 1 == g_sbox_map[1])        port = 1;#else#error Unknown Architecture#endif    else {        uart_printf("SBOX : Can't assign a channel\n");#if 0        int i, firstavail;        // check if last used slot is available        for (i = 0; i < 2; ++i) {            if (g_sbox_lastmap[i] == iface && !g_sbox_used[i]) {                port = i;                break;            }        }        // look for first available slot        if (port < 0) {            for (i = 0, firstavail = -1; i < 2; ++i) {                if (!g_sbox_used[i]) {                    if (firstavail < 0)                        firstavail = i;                    if (g_sbox_lastmap[i] == 0) {                        port = i;                        break;                    }                }            }            if (port < 0)                port = firstavail;        }        if (port >= 0) {            g_sbox_map[port] = iface;            em86xx_sbox_setup(g_sbox_map[0], g_sbox_map[1]);        }#endif    }        if (port >= 0) {        g_sbox_used[port] = 1;        g_sbox_lastmap[port] = iface;    }    return port;}void em86xx_sbox_disconnect(int port){    if (port >= 0)        g_sbox_used[port] = 0;}// // MBUS interface//unsigned int em86xx_mbus_init(void){    return 0;}// sbox : SBOX_xxx// fromdev : //   0 : EM86XX => device (writing) : use Wx port//   1 : device => EM86XX (reading) : use Rx portunsigned int em86xx_mbus_alloc_dma(int sbox, int fromdev, unsigned int *pregbase, int *pirq){    int port = em86xx_sbox_connect(sbox);        if (pirq)         *pirq = IRQ_MBUS_W0 + port + ((fromdev) ? 0 : 2);    if (pregbase) {        *pregbase = REG_BASE_HOST + MIF_w0_base;        if (!fromdev)            *pregbase += 0x80;        *pregbase += port * 0x40;    }    return port;}void em86xx_mbus_free_dma(int port){    em86xx_sbox_disconnect(port);}void em86xx_mbus_setup_dma_linear(unsigned int regbase, unsigned int addr, unsigned int count){    __raw_writel(addr, regbase + 0x00);    __raw_writel(count, regbase + 0x04);    __raw_writel(0x05, regbase + 0x0c);}void em86xx_mbus_setup_dma_double(unsigned int regbase, unsigned int addr, unsigned int count, unsigned int addr2, unsigned int count2){    __raw_writel(addr, regbase + 0x00);    __raw_writel((count2 << 16) | count, regbase + 0x04);    __raw_writel(addr2, regbase + 0x08);    __raw_writel(0x06, regbase + 0x0c);}void em86xx_mbus_setup_dma_rectangle(unsigned int regbase, unsigned int addr, unsigned int horiz, unsigned int lines, int skip){    __raw_writel(addr, regbase + 0x00);    __raw_writel((lines << 16) | horiz, regbase + 0x04);    __raw_writel(horiz, regbase + 0x08);    __raw_writel(0x07, regbase + 0x0c);}#define MBUS_LINEAR_MAX     (0x2000 - 0x200)int em86xx_mbus_setup_dma(unsigned int regbase, unsigned int addr, unsigned int count){    if ((__raw_readl(regbase + MIF_cmd_offset) & 0x07) != 0) {        uart_printf("MBUS error : previous command is pending\n");        return 1;    }    if (count <= MBUS_LINEAR_MAX) {        // try linear        // uart_printf("Linear\n");        em86xx_mbus_setup_dma_linear(regbase, addr, count);    } else if (count <= (MBUS_LINEAR_MAX * 2)) {        // try double        // uart_printf("Double (%04x, %04x)\n", MBUS_LINEAR_MAX, count - MBUS_LINEAR_MAX);        em86xx_mbus_setup_dma_double(regbase, addr, MBUS_LINEAR_MAX, addr + MBUS_LINEAR_MAX, count - MBUS_LINEAR_MAX);    } else {        int i, horiz, lines;        // try rectangle        for (i = 0, horiz = 1; i < 10 && ((count & 0x01) == 0); ++i, horiz <<= 1)             ;        lines = count >> i;        if (horiz > MBUS_LINEAR_MAX || lines > MBUS_LINEAR_MAX) {            uart_printf("MBUS error : too big to transfer (%d, %d)\n", horiz, lines);            return 1;        }        // uart_printf("Rectangle (%d x %d)\n", horiz, lines);        em86xx_mbus_setup_dma_rectangle(regbase, addr, horiz, lines, horiz);    }    return 0;}void em86xx_mbus_wait(unsigned int regbase){    while (__raw_readl(regbase + MIF_cmd_offset) != 0)        ;}//// PCI Master//void em86xx_pcimaster_setup_read(unsigned int addr, unsigned int count){    __raw_writel(0, REG_BASE_HOST + PCI_master_read_reverse);    __raw_writel(addr, REG_BASE_HOST + PCI_master_read_addr);    __raw_writel(count, REG_BASE_HOST + PCI_master_read_counter);}void em86xx_pcimaster_start_read(int start){    __raw_writel(start ? 1 : 0, REG_BASE_HOST + PCI_master_read_enable);}void em86xx_pcimaster_setup_write(unsigned int addr, unsigned int count){    __raw_writel(0, REG_BASE_HOST + PCI_master_read_reverse);    __raw_writel(addr, REG_BASE_HOST + PCI_master_write_addr);    __raw_writel(count, REG_BASE_HOST + PCI_master_write_counter);}void em86xx_pcimaster_start_write(int start){    __raw_writel(start ? 1 : 0, REG_BASE_HOST + PCI_master_write_enable);}//// GPIO//int em86xx_gpio_read(int gpio){    return (__raw_readl(REG_BASE_SYSTEM + SYS_gpio_data) >> gpio) & 1;}void em86xx_gpio_write(int gpio, int data){    __raw_writel(data ? GPIO_DATA_SET(gpio) : GPIO_DATA_CLEAR(gpio),        REG_BASE_SYSTEM + SYS_gpio_data);}void em86xx_gpio_setdirection(int gpio, int dir){    __raw_writel(dir ? GPIO_DIR_OUTPUT(gpio) : GPIO_DIR_INPUT(gpio),        REG_BASE_SYSTEM + SYS_gpio_dir);}//// Miscellaneous//unsigned int em86xx_random(void){    unsigned int sum;    sum = __raw_readl(REG_BASE_SYSTEM + SYS_clk_cnt);    sum = (sum << 8) | ((sum >> 24) & 0xff);    sum += __raw_readl(REG_BASE_SYSTEM + SYS_xtal_in_cnt);    sum = (sum << 8) | ((sum >> 24) & 0xff);    sum += __raw_readl(REG_BASE_SYSTEM + SYS_rclk_out_cnt);    sum = (sum << 8) | ((sum >> 24) & 0xff);    sum += __raw_readl(REG_BASE_SYSTEM + SYS_sel_clk_cnt);    return sum;}

⌨️ 快捷键说明

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