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

📄 sb_pci_machdep.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
{    /* Check for a host bridge seen internally, in which case       we don't want to allocate any address space for its BARs. */        return (tag == SB_PCI_BRIDGE ? 1 : 0);}/* Called for each non-bridge (Type 0) function after assigning the   BAR and InterruptLine resources. */voidpci_device_setup (pcitag_t tag){}/* Called for each bridge (Type 1) function after configuring the   secondary bus, to allow device-specific initialization. */voidpci_bridge_setup (pcitag_t tag, pci_flags_t flags){}/* Machine dependent access primitives and utility functions */voidpci_flush (void){}pcitag_tpci_make_tag (int port, int bus, int device, int function){    return PCI_MAKE_TAG(bus, device, function);}voidpci_break_tag (pcitag_t tag,	       int *portp, int *busp, int *devicep, int *functionp){    if (portp) *portp = 0;    if (busp) *busp = (tag >> 16) & PCI_BUSMAX;    if (devicep) *devicep = (tag >> 11) & PCI_DEVMAX;    if (functionp) *functionp = (tag >> 8) & PCI_FUNCMAX;}/* Read/write access to PCI configuration registers.  Type0 addresses   are used for bus 0, with a unary encoding of IDSEL in which device   n is mapped to bit 16+n (16 possible devices, 0..15). */intpci_canscan (pcitag_t tag){    int bus, device, function;    pci_break_tag(tag, NULL, &bus, &device, &function);     if (bus > PCI_BUSMAX || device > PCI_DEVMAX || function > PCI_FUNCMAX)	return 0;    return (bus != 0 || (device >= 0 && device < 16));}intpci_probe_tag(pcitag_t tag){    pcireg_t data;    jmpbuf_t *jb;    if (!pci_canscan(tag))	return 0;    jb = exc_initialize_block();    if (jb == NULL)	return 0;    if (exc_try(jb) == 0)	data = pci_conf_read(tag, PCI_ID_REG);  /* bus error if no response */    else	data = 0xffffffff;    exc_cleanup_block(jb);    /* if it returned all vendor id bits set, it's not a device */    return (PCI_VENDOR(data) != 0xffff);}/* Note that READCFG/WRITECFG uses below can generate bus errors that   are not caught; guard calls with these functions with pci_probe_tag. */pcireg_tpci_conf_read(pcitag_t tag, int reg){    int bus, device, function;    pcireg_t data;    uint32_t addr;    pci_break_tag(tag, NULL, &bus, &device, &function);    addr = (function << 8) | (reg & 0xFC);  /* common part */    if (bus == 0) {	if (device < 16) {	    /* Generate a Type0 configuration cycle. */	    addr |= (1 << (16 + device));	    WRITECSR(R_SB_TO_PCI_TRANSLATION1,		     (addr & M_SBXLAT_UA) | V_SBXLAT_AT(K_AT_CFG0_RW));	    (void)READCSR(R_SB_TO_PCI_TRANSLATION1);  /* push */	    addr &= ~M_SBXLAT_UA;	    data = READCFG(addr);	    }	else	    data = 0xFFFFFFFF;	}    else {	/* Generate a Type1 configuration cycle. */	addr |= (bus << 16) | (device << 11);	WRITECSR(R_SB_TO_PCI_TRANSLATION1,		 (addr & M_SBXLAT_UA) | V_SBXLAT_AT(K_AT_CFG1_RW));	(void)READCSR(R_SB_TO_PCI_TRANSLATION1);  /* push */	addr &= ~M_SBXLAT_UA;	data = READCFG(addr);	}    return data;}voidpci_conf_write(pcitag_t tag, int reg, pcireg_t data){    int bus, device, function;    uint32_t addr;    pci_break_tag(tag, NULL, &bus, &device, &function);    addr = (function << 8) | (reg & 0xFC);  /* common part */    if (bus == 0) {	if (device < 16) {	    /* Generate a Type0 configuration cycle. */	    addr |= (1 << (16 + device));	    WRITECSR(R_SB_TO_PCI_TRANSLATION1,		     (addr & M_SBXLAT_UA) | V_SBXLAT_AT(K_AT_CFG0_RW));	    (void)READCSR(R_SB_TO_PCI_TRANSLATION1);  /* push */	    addr &= ~M_SBXLAT_UA;	    WRITECFG(addr & ~SB_PCI_CFG_BASE, data);	    }	}    else {	/* Generate a Type1 configuration cycle. */	addr |= (bus << 16) | (device << 11);	WRITECSR(R_SB_TO_PCI_TRANSLATION1,		 (addr & M_SBXLAT_UA) | V_SBXLAT_AT(K_AT_CFG1_RW));	addr &= ~M_SBXLAT_UA;	(void)READCSR(R_SB_TO_PCI_TRANSLATION1);  /* push */	WRITECFG(addr, data);	}}intpci_conf_write_acked(pcitag_t tag, int reg, pcireg_t data){    pci_conf_write(tag, reg, data);    (void) pci_conf_read(tag, reg);    return 1;}intpci_map_io(pcitag_t tag, int reg, pci_endian_t endian, phys_addr_t *pap){    pci_tagprintf(tag, "pci_map_io: i/o regions not supported\n");    return -1;}intpci_map_mem(pcitag_t tag, int reg, pci_endian_t endian, phys_addr_t *pap){    pcireg_t address;    phys_addr_t pa;    if (reg == PCI_MAPREG_ROM) {	/* expansion ROM */	address = pci_conf_read(tag, reg);	if ((address & PCI_MAPREG_ROM_ENABLE) == 0) {	    pci_tagprintf(tag, "pci_map_mem: attempt to map missing rom\n");	    return -1;	    }	pa = address & PCI_MAPREG_ROM_ADDR_MASK;	}    else {	if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {	    if (_pciverbose != 0)		pci_tagprintf(tag, "pci_map_mem: bad request\n");	    return -1;	    }		address = pci_conf_read(tag, reg);		if ((address & PCI_MAPREG_TYPE_IO) != 0) {	    if (_pciverbose != 0)		pci_tagprintf(tag, "pci_map_mem: attempt to memory map an I/O region\n");	    return -1;	    }		pa = address & PCI_MAPREG_MEM_ADDR_MASK;	switch (address & PCI_MAPREG_MEM_TYPE_MASK) {	    case PCI_MAPREG_MEM_TYPE_32BIT:	    case PCI_MAPREG_MEM_TYPE_32BIT_1M:		break;	    case PCI_MAPREG_MEM_TYPE_64BIT:		if (reg + 4 < PCI_MAPREG_END)		    pa |= ((phys_addr_t)pci_conf_read(tag, reg+4) << 32);		else {		    if (_pciverbose != 0)			pci_tagprintf(tag, "pci_map_mem: bad 64-bit reguest\n");		    return -1;		    }		break;	    default:		if (_pciverbose != 0)		    pci_tagprintf(tag, "pci_map_mem: reserved mapping type\n");		return -1;	    }	}    /* XXX Do something about endian.  Byte-swapping in cross-endian       systems cannot really be handled here.  In the BCM47xx cores,       swapping of DRAM accesses (only) is controlled by a bit in the       DRAM address, not in the PCI address as in the BCM1250. */    *pap = pa;    return 0;}/* ISA-style i/o access (not supported) */uint8_tinb (unsigned int port){    xprintf("inb: i/o regions not supported\n");    return 0xFF;}uint16_tinw (unsigned int port){    xprintf("inw: i/o regions not supported\n");    return 0xFFFF;}uint32_tinl (unsigned int port){    xprintf("inl: i/o regions not supported\n");    return 0xFFFFFFFF;}voidoutb (unsigned int port, uint8_t val){    xprintf("outb: i/o regions not supported\n");}voidoutw (unsigned int port, uint16_t val){    xprintf("outw: i/o regions not supported\n");}voidoutl (unsigned int port, uint32_t val){    xprintf("outl: i/o regions not supported\n");}/* Interrupt slot wiring.  Eval boards apparently connect only INTA   and INTB but use INTA<->INTA for all devices and slots.   This should be board specific except that, for all boards, all PCI   interrupts are reduced to a single backplane flag before being   routed to the CPU. *//* Map PCI interrupts A, B, C, D into a value for the IntLine   register.  Return the source number used by the   interrupt mapper, or 0xff if none. */uint8_tpci_int_line(uint8_t pci_int){    uint32_t flag;    flag = READCSR(R_SBTPSFLAG);    return (pci_int == 0) ? 0xFF : G_SBTSF_FN(flag);}

⌨️ 快捷键说明

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