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

📄 pciem86xx.c

📁 em86xx 完整启动程序,支持网络下载与串通下载
💻 C
字号:
/***************************************** Copyright (c) 2003-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* * pciem86xx.c * * EM86XX as a PCI Host * * by Ho Lee 02/05/2003 */#include "config.h"#include "uart.h"#include "util.h"#include "hardware.h"#include "io.h"#include "irqs.h"#include "em86xxapi.h"#include "pciem86xx.h"//// global variables// static int g_pci_em86xx_inited = 0;static int g_pci_em86xx_lastidsel = 0;static unsigned int g_pcimem_busaddr = PCIBIOS_MIN_MEM_EM86XX - MEMORY_BASE_PCI_MEMORY;static unsigned int g_pcimem_phyaddr = DRAMBASE;static unsigned int g_pcimem_phyaddr_end = DRAMBASE;extern unsigned long loadaddr_pci_start;// static void pci_em86xx_busfault_irq(void *pdata);static unsigned int pci_em86xx_virt_to_bus(unsigned int virt);static unsigned int pci_em86xx_bus_to_virt(unsigned int bus);struct my_pci_op g_pciem86xx_op = {    idsel_start : PCI_EM86XX_IDSEL_FIRST,    idsel_end : PCI_EM86XX_IDSEL_MAX - 1,    mem_offset : MEMORY_BASE_PCI_MEMORY,    io_offset : MEMORY_BASE_PCI_CONFIG,    init : pci_em86xx_init,    info : pci_em86xx_info,    select : pci_em86xx_select,    virt_to_bus : pci_em86xx_virt_to_bus,    bus_to_virt : pci_em86xx_bus_to_virt,    pciio_base : pci_em86xx_pciio_base,    pcimemory_base : pci_em86xx_pcimemory_base,                 read_config_byte : pci_em86xx_read_config_byte,    read_config_word : pci_em86xx_read_config_word,    read_config_dword : pci_em86xx_read_config_dword,    write_config_byte : pci_em86xx_write_config_byte,    write_config_word : pci_em86xx_write_config_word,    write_config_dword : pci_em86xx_write_config_dword,    in_byte : pci_em86xx_read_byte,    in_word : pci_em86xx_read_word,    in_dword : pci_em86xx_read_dword,    out_byte : pci_em86xx_write_byte,    out_word : pci_em86xx_write_word,    out_dword : pci_em86xx_write_dword,    read_byte : pci_em86xx_read_byte,    read_word : pci_em86xx_read_word,    read_dword : pci_em86xx_read_dword,    write_byte : pci_em86xx_write_byte,    write_word : pci_em86xx_write_word,    write_dword : pci_em86xx_write_dword,#ifdef CONFIG_ENABLE_FULLFUNCTION    test : pci_em86xx_test,#endif};//// PCI bus initialization//int pci_em86xx_init(int verbose){    extern unsigned long dram0_size;    if (!g_pci_em86xx_inited) {	g_pcimem_phyaddr_end += dram0_size;        // EM86XX is Host        __raw_writel(1, REG_BASE_HOST + PCI_chip_is_host);#ifdef CONFIG_ARCH_TANGO        // select IDSEL 0        __raw_writew((0 << 8), REG_BASE_HOST + PCI_host_host_reg2);#endif#if (defined(CONFIG_ARCH_MAMBO) && (CONFIG_ARCH_MAMBO_REV == 1))        // PCI HOST registers initialization        __raw_writel(0x00ff0000, REG_BASE_HOST + PCI_host_host_reg1);#elif (defined(CONFIG_ARCH_MAMBO) && (CONFIG_ARCH_MAMBO_REV >= 2)) || defined(CONFIG_ARCH_TANGO)        // PCI HOST registers initialization        __raw_writel(0xffff0000, REG_BASE_HOST + PCI_host_host_reg1);#ifdef CONFIG_ARCH_TANGO#if 1        __raw_writel(0x00030000, REG_BASE_HOST + PCI_pcictrl_reg1);#else        __raw_writel(0x000700fc, REG_BASE_HOST + PCI_pcictrl_reg1);#endif#else        __raw_writel(0x000300fc, REG_BASE_HOST + PCI_pcictrl_reg1);#endif        __raw_writel(0x0003060d, REG_BASE_HOST + PCI_pcictrl_reg2);        __raw_writel(0x00000000, REG_BASE_HOST + PCI_pcictrl_reg3);        // PCI Arbiter registers initialization        __raw_writel(0x10101010, REG_BASE_HOST + PCI_host_host_reg3);        __raw_writel(0, REG_BASE_HOST + PCI_host_host_reg4);        // Initialize EM86XX as a PCI slave        {            int i;            unsigned int memsize, regsize, membase;            while (pci_em86xx_select(0) == 0)                ;		// __raw_writeb(0x07, REG_BASE_HOST + PCI_devcfg_reg3);            __raw_writew(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, MEMORY_BASE_PCI_CONFIG + PCI_COMMAND);            __raw_writel(PCIBIOS_MIN_MEM_EM86XX - MEMORY_BASE_PCI_MEMORY, MEMORY_BASE_PCI_CONFIG + PCI_BASE_ADDRESS_0);            __raw_writel(MEMORY_BASE_RISC, REG_BASE_HOST + PCI_region_base + (1 * 4));            memsize = __raw_readl(REG_BASE_HOST + PCI_devcfg_reg3) & 0x07;            memsize = 1 << memsize;            regsize = (memsize << 20) >> 3; // memory size / 8            g_pcimem_busaddr += regsize * 2;            if (verbose)                uart_printf("PCI: Configured EM86XX as a PCI slave with %dMB PCI memory\n", memsize);            membase = loadaddr_pci_start;            g_pcimem_phyaddr = membase;            for (i = 2; i < 8; ++i) {                __raw_writel(EM86XX_DRAM_C2NC(membase), REG_BASE_HOST + PCI_region_base + (i * 4));                membase += regsize;            }            if (g_pcimem_phyaddr_end > membase)                g_pcimem_phyaddr_end = membase;            if (verbose) {                uart_printf("PCI: Each Region size is %dKB\n", regsize >> 10);                uart_printf("PCI: Reserved memory from 0x%08x to 0x%08x for DMA and mapped to 0x%08x\n",                     g_pcimem_phyaddr, g_pcimem_phyaddr_end, g_pcimem_busaddr);            }        }#endif        // em86xx_request_irq(IRQ_PCILOCALBUSFAULT, pci_em86xx_busfault_irq, NULL);        g_pci_em86xx_inited = 1;    }    return 0;}#if 0static void pci_em86xx_busfault_irq(int irq, void *pdata){    static char *s_fault_reason[] = {        "OK", "Master Abort", "Retry timer expired", "Unknown" };    static int s_faultcount;    unsigned int data;    data = __raw_readb(REG_BASE_HOST + PCI_host_host_reg2 + 3);    uart_printf("PCI: PCI bus fault %d : %s\n",        ++s_faultcount, s_fault_reason[data >> 1]);    // clears PCI bus fault flags    __raw_writeb(0x01, REG_BASE_HOST + PCI_host_host_reg2 + 3);    __raw_writeb(0x00, REG_BASE_HOST + PCI_host_host_reg2 + 3);}#endifint pci_em86xx_info(void){    uart_puts("EM86XX PCI Host Controller : \n");    return 0;}// return 0 if device not found// return vendorid:deviceid if device foundunsigned int pci_em86xx_select(int idsel){#if defined(CONFIG_ARCH_MAMBO)    unsigned int data;#endif    unsigned int  pciid;    g_pci_em86xx_lastidsel = idsel;    #if defined(CONFIG_ARCH_MAMBO)    __raw_writew((idsel << 8), REG_BASE_HOST + PCI_host_host_reg2);    pciid = __raw_readl(MEMORY_BASE_PCI_CONFIG);    data = __raw_readl(REG_BASE_HOST + PCI_host_host_reg2);            if (((data >> 25) & 0x03) == 0) {        return pciid;    } else {        // clears PCI bus fault flags        __raw_writeb(0x01, REG_BASE_HOST + PCI_host_host_reg2 + 3);        __raw_writeb(0x00, REG_BASE_HOST + PCI_host_host_reg2 + 3);    }    return 0;#elif defined(CONFIG_ARCH_TANGO)    return (pci_em86xx_read_config_dword(0, &pciid) == 0) ? pciid : 0;#else#error Unknown architecture#endif}//// Bus address translation//#define is_virt_dmable(x)   (((x) >= g_pcimem_phyaddr && (x) < g_pcimem_phyaddr_end) ? 1 : 0)#define is_bus_dmable(x)    ((((x) - g_pcimem_busaddr) < (g_pcimem_phyaddr_end - g_pcimem_phyaddr)) ? 1 : 0)unsigned int pci_em86xx_virt_to_bus(unsigned int virt){    if (!is_virt_dmable(virt)) {        uart_printf("pci_em86xx_virt_to_bus : Invalid virtual address %08x\n", virt);        return virt;    } else        return (virt - g_pcimem_phyaddr + g_pcimem_busaddr);}unsigned int pci_em86xx_bus_to_virt(unsigned int bus){    if (!is_bus_dmable(bus)) {        uart_printf("pci_em86xx_bus_to_virt : Invalid bus address %08x\n", bus);        return bus;    } else        return (bus + g_pcimem_phyaddr - g_pcimem_busaddr);}//// Basic //unsigned int pci_em86xx_pciio_base(int idsel){    return MEMORY_BASE_PCI_IO + (idsel * 0x00100000);}unsigned int pci_em86xx_pcimemory_base(int idsel){    return MEMORY_BASE_PCI_MEMORY + (idsel * 0x04000000);}//// primitive PCI configuration I/O//#if defined(CONFIG_ARCH_MAMBO)#define PCIEM86XX_READ_CONFIG_X(x, type, name) \    int pci_em86xx_read_config_##name(unsigned int addr, unsigned type *data) \    { \        *data = __raw_read##x(MEMORY_BASE_PCI_CONFIG + addr); \        return 0; \    }#define PCIEM86XX_WRITE_CONFIG_X(x, type, name) \    int pci_em86xx_write_config_##name(unsigned int addr, unsigned int data) \    { \        __raw_write##x(data, MEMORY_BASE_PCI_CONFIG + addr); \        return 0; \    }#elif defined(CONFIG_ARCH_TANGO)#define PCIEM86XX_READ_CONFIG_X(x, type, name) \    int pci_em86xx_read_config_##name(unsigned int addr, unsigned type *data) \    { \        unsigned int reg; \        *data = __raw_read##x(MEMORY_BASE_PCI_CONFIG + addr + (g_pci_em86xx_lastidsel << 11)); \        reg = __raw_readl(REG_BASE_HOST + PCI_host_host_reg2); \        if (((reg >> 25) & 0x03) == 0) { \            return 0; \        } else { \            /* clears PCI bus fault flags */ \            __raw_writeb(0x01, REG_BASE_HOST + PCI_host_host_reg2 + 3); \            __raw_writeb(0x00, REG_BASE_HOST + PCI_host_host_reg2 + 3); \            return 1; \        } \    }#define PCIEM86XX_WRITE_CONFIG_X(x, type, name) \    int pci_em86xx_write_config_##name(unsigned int addr, unsigned int data) \    { \        unsigned int reg; \        __raw_write##x(data, MEMORY_BASE_PCI_CONFIG + addr + (g_pci_em86xx_lastidsel << 11)); \        reg = __raw_readl(REG_BASE_HOST + PCI_host_host_reg2); \        if (((reg >> 25) & 0x03) == 0) { \            return 0; \        } else { \            /* clears PCI bus fault flags */ \            __raw_writeb(0x01, REG_BASE_HOST + PCI_host_host_reg2 + 3); \            __raw_writeb(0x00, REG_BASE_HOST + PCI_host_host_reg2 + 3); \            return 1; \        } \    }#else#error Unknown architecture#endifPCIEM86XX_READ_CONFIG_X(b, char, byte)PCIEM86XX_READ_CONFIG_X(w, short, word)PCIEM86XX_READ_CONFIG_X(l, int, dword)PCIEM86XX_WRITE_CONFIG_X(b, char, byte)PCIEM86XX_WRITE_CONFIG_X(w, short, word)PCIEM86XX_WRITE_CONFIG_X(l, int, dword)//// primitive PCI I/O, Memory access//#define PCIEM86XX_READ_X(x, type, name) \    unsigned type pci_em86xx_read_##name(unsigned int addr) \    { \        return __raw_read##x(addr); \    } #define PCIEM86XX_WRITE_X(x, type, name) \    void pci_em86xx_write_##name(unsigned int data, unsigned int addr) \    { \        __raw_write##x(data, addr); \    } PCIEM86XX_READ_X(b, char, byte)PCIEM86XX_READ_X(w, short, word)PCIEM86XX_READ_X(l, int, dword)PCIEM86XX_WRITE_X(b, char, byte)PCIEM86XX_WRITE_X(w, short, word)PCIEM86XX_WRITE_X(l, int, dword)//// PCI operation//// DMA Transfer#ifdef CONFIG_ENABLE_FULLFUNCTION// Using SBOX_PCI_MASTER <-- MBUS_R1_SBOXvoid pci_em86xx_dma_write(void *buf, int len, unsigned int addr, int verbose){    int port, irq;    unsigned int regbase;    em86xx_clean_cache_data_region((unsigned int) buf, (unsigned int) buf + len);    em86xx_pcimaster_start_write(0);    port = em86xx_mbus_alloc_dma(SBOX_PCIMASTER, 0, &regbase, &irq);    if (verbose) {        uart_puts("Before DMA WRITE transfer...\n");        uart_printf("  SBOX = %08x\n", __raw_readl(REG_BASE_HOST + SBOX_route));        uart_printf("  MBUS regbase = %08x\n", regbase);        uart_printf("  MBUS command = %d\n", __raw_readl(regbase + 0x0c));        uart_printf("  PCI write counter = %d\n", __raw_readl(REG_BASE_HOST + PCI_master_write_counter));    }    if (__raw_readl(regbase + 0x0c) > 0 || __raw_readl(REG_BASE_HOST + PCI_master_write_counter) > 0) {        uart_puts("  Aborting...\n");        __raw_writel(0, regbase + 0x0c);        __raw_writel(0, REG_BASE_HOST + PCI_master_write_counter);        return;    }    if (verbose)        uart_puts("Start transfer...\n");    em86xx_pcimaster_setup_write(addr, len);    em86xx_pcimaster_start_write(1);    em86xx_mbus_setup_dma_linear(regbase, (unsigned int) buf, len);        // em86xx_msleep(10);    while (__raw_readl(REG_BASE_HOST + PCI_master_write_counter) > 0)        ;        em86xx_mbus_free_dma(port);    em86xx_pcimaster_start_write(0);    if (verbose) {        uart_puts("After DMA WRITE transfer...\n");        uart_printf("  MBUS command = %d\n", __raw_readl(regbase + 0x0c));        uart_printf("  PCI write counter = %d\n", __raw_readl(REG_BASE_HOST + PCI_master_write_counter));    }}void pci_em86xx_dma_read(void *buf, int len, unsigned int addr, int verbose){    int port, irq;    unsigned int regbase;    em86xx_clean_cache_data_region((unsigned int) buf, (unsigned int) buf + len);    em86xx_pcimaster_start_read(0);    port = em86xx_mbus_alloc_dma(SBOX_PCIMASTER, 1, &regbase, &irq);    if (verbose) {        uart_puts("Before DMA READ transfer...\n");        uart_printf("  SBOX = %08x\n", __raw_readl(REG_BASE_HOST + SBOX_route));        uart_printf("  MBUS regbase = %08x\n", regbase);        uart_printf("  MBUS command = %d\n", __raw_readl(regbase + 0x0c));        uart_printf("  PCI read counter = %d\n", __raw_readl(REG_BASE_HOST + PCI_master_read_counter));    }    if (__raw_readl(regbase + 0x0c) > 0 || __raw_readl(REG_BASE_HOST + PCI_master_read_counter) > 0) {        uart_puts("  Aborting...\n");        __raw_writel(0, regbase + 0x0c);        __raw_writel(0, REG_BASE_HOST + PCI_master_read_counter);        return;    }    if (verbose)        uart_puts("Start transfer...\n");    em86xx_mbus_setup_dma_linear(regbase, (unsigned int) buf, len);    em86xx_pcimaster_setup_read(addr, len);    em86xx_pcimaster_start_read(1);    // em86xx_msleep(10);    while (__raw_readl(REG_BASE_HOST + PCI_master_read_counter) > 0)        ;    em86xx_mbus_free_dma(port);    em86xx_pcimaster_start_read(0);    em86xx_flush_cache_data_region((unsigned int) buf, (unsigned int) buf + len);    if (verbose) {        uart_puts("After DMA READ transfer...\n");        uart_printf("  MBUS command = %d\n", __raw_readl(regbase + 0x0c));        uart_printf("  PCI read counter = %d\n", __raw_readl(REG_BASE_HOST + PCI_master_read_counter));    }}#endif#ifdef CONFIG_ENABLE_FULLFUNCTIONstatic void pci_em86xx_test_mambo(void) __attribute__ ((unused));static void pci_em86xx_test_mambo(void) {    struct my_pci_dev pcidev, *pdev;    // look for device    pdev = pci_lookup(0x1105, 0, &pcidev);    if (pdev && pdev->idsel == 0)        pdev = pci_lookup(0x1105, 0, &pcidev);    if (pdev == NULL) {        uart_puts("No EM86XX found\n");        return;    }    uart_printf("Found EM86XX PCI device :\n");    uart_printf("  IDSEL = %d, Vendor ID = 0x%04x, Device ID = 0x%04x\n",        pdev->idsel, pdev->vendor_id, pdev->device_id);    // configure the device    pci_configure_device(pdev);    uart_printf("  Assign PCI memory space from 0x%08x, size 0x%08x\n",         pdev->resource[0].start, pdev->resource[0].size);        // enable the device    pci_write_config_word(PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);}int pci_em86xx_test(int argc, char *argv[]){    return 0;}#endif

⌨️ 快捷键说明

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