📄 mpc85xx.c
字号:
} } else { pci_windows[0].base_addr = pdev->pci_membase; pci_windows[0].size = MPC85XX_PCI_MEM_SIZE; pci_windows[0].length = MPC85XX_PCI_MEM_LEN; pci_windows[1].base_addr = pdev->pci_iobase; pci_windows[1].size = MPC85XX_PCI_IO_SIZE; pci_windows[1].length = MPC85XX_PCI_IO_LEN; } // allocate pci space memory rreq.align = 0; rreq.flags = RSRCDBMGR_MEMORY | RSRCDBMGR_FLAG_RANGE; rreq.length = pci_windows[0].length; rreq.start = pci_windows[0].base_addr; rreq.end = pci_windows[0].base_addr + pci_windows[0].length - 1; if (rsrcdbmgr_attach(&rreq, 1)) { perror("Unable to allocate PCI memory space: "); return ENOMEM; } pdev->pci_mem = rreq.start; rreq.align = 0; rreq.flags = RSRCDBMGR_MEMORY | RSRCDBMGR_FLAG_RANGE; rreq.length = pci_windows[1].length; rreq.start = pci_windows[1].base_addr; rreq.end = pci_windows[1].base_addr + pci_windows[1].length - 1; if (rsrcdbmgr_attach(&rreq, 1)) { perror("Unable to allocate IO space: "); return ENOMEM; } pdev->pci_io = rreq.start; ralloc.start = pdev->pci_io; ralloc.end = pdev->pci_io + pci_windows[1].length - 1; ralloc.flags = RSRCDBMGR_IO_PORT | RSRCDBMGR_FLAG_RANGE; if( rsrcdbmgr_create( &ralloc, 1 ) == -1 ) { perror( "Unable to create IO space type: " ); return( ENOMEM ); } ralloc.start = pdev->pci_mem; ralloc.end = pdev->pci_mem + pci_windows[0].length -1; ralloc.flags = RSRCDBMGR_PCI_MEMORY | RSRCDBMGR_FLAG_RANGE; if (rsrcdbmgr_create(&ralloc, 1) == -1) { perror("Unable to create PCI memory type: "); return ENOMEM; } temp = pci_windows[0].base_addr >> 12; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_POTAR1) = temp; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_POTEAR1) = 0x00000000; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_POWBAR1) = temp; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_POWAR1) = 0x80044000 | pci_windows[0].size; temp = pci_windows[1].base_addr >> 12; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_POTAR2) = temp; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_POTEAR2) = 0x00000000; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_POWBAR2) = temp; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_POWAR2) = 0x80088000| pci_windows[1].size; mem_cnt = 0; mem_size = pdev->mem_size; while( mem_size - 1 ) { mem_size >>= 1; mem_cnt++; } *(uint32_t *)(pdev->register_base + MPC85XX_PCI_PITAR3) = ( pdev->mem_start & 0xfffff000 ) >> 12; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_PIWBAR3) = ( pdev->mem_start & 0xfffff000 ) >> 12; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_PIWBEAR3) = 0x00000000; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_PIWAR3) = 0xa0f55000 | ( ( mem_cnt - 1) & 0x0000003f) ; *(uint32_t *)(pdev->register_base + MPC85XX_PCI_CFG_ADDR) = 0x80000004; temp = *(uint32_t *)(pdev->register_base + MPC85XX_PCI_CFG_DATA); *(uint32_t *)(pdev->register_base + MPC85XX_PCI_CFG_DATA) = temp | 0x07000000; return EOK;}intmpc85xx_attach(char *options, void **hdl){ mpc85xx_dev_t *pdev; int opt; char *value; int auto_detect = 1; static char *pci_drvr_opts[] = { "auto", "base", "pcibase", "irqbase", "irqrotate", "devbase", "x2b", "x3", NULL }; if ((pdev = calloc(1, sizeof(mpc85xx_dev_t))) == NULL) { return ENOMEM; } pdev->irqbase = -1; pdev->irqrotate = 1; pdev->devbase = -1; while (options && *options != '\0') { if ((opt = getsubopt(&options, pci_drvr_opts, &value)) == -1 ) { continue; } switch (opt) { case 0: auto_detect = strtoul( value, 0, 0 ); continue; case 1: pdev->ccsr_base= strtoul( value, 0, 0 ); continue; case 2: pdev->pci_membase= strtoul( value, 0, 0 ); continue; case 3: pdev->irqbase = strtoul( value,0,0 ); mpc85xx_entry.avail_irq = mpc85xx_avail_irq_gen; continue; case 4: pdev->irqrotate = strtoul( value,0,0 ); mpc85xx_entry.avail_irq = mpc85xx_avail_irq_gen; continue; case 5: pdev->devbase = strtoul( value,0,0 ); mpc85xx_entry.avail_irq = mpc85xx_avail_irq_gen; continue; case 6: pdev->irqbase = PPC85xx_INTR_IRQ0; pdev->irqrotate = 1; pdev->devbase = 18; mpc85xx_entry.avail_irq = mpc85xx_avail_irq_gen; continue; case 7: pdev->irqbase = PPC85xx_INTR_IRQ0; pdev->irqrotate = 0; pdev->devbase = 19; mpc85xx_entry.avail_irq = mpc85xx_avail_irq_gen; continue; default: break; } } if ((pdev->irqbase == -1) || (pdev->devbase == -1)) { if ((pdev->irqbase != -1) || (pdev->devbase != -1)) { /* Error condition. Must specify both irq and dev base for configuration to be valid. */ fprintf(stderr, "Both the interrupt base and device base must be specified" ); free(pdev); return -1; } } if (!pdev->pci_membase) { pdev->pci_membase = MPC85XX_PCI_MEM_BASE; } pdev->pci_iobase = pdev->pci_membase + MPC85XX_PCI_MEM_LEN; if( ( !pdev->ccsr_base ) && ( pdev->ccsr_base = mpc85xx_find_ccsr_info( ) ) == 0) { perror( "Unable to find base address " ); free(pdev); return -1; } if( !mpc85xx_find_mem_info( &(pdev->mem_start), &(pdev->mem_size ) ) ) { perror( "Unable to find memory " ); free( pdev ); return -1; } if( !mpc85xx_config( pdev, auto_detect ) ) { *hdl = pdev; return( EOK ); } free(pdev); return(-1);}intmpc85xx_detach(void *hdl){ mpc85xx_dev_t *pdev; pdev = (mpc85xx_dev_t *)hdl; // free memory munmap_device_memory(pdev->register_base, MPC85XX_PCI_REGISTER_LEN); free(pdev); return EOK;}intmpc85xx_cnfg_bridge(void *hdl, uint32_t bus, uint32_t devfunc, pci_bus_t *pbus){ return EOK;}intmpc85xx_read_cnfg(void *hdl, unsigned bus, unsigned devfunc, unsigned reg, unsigned width, void *buf){ uint_t addr; uint_t dev; uint_t func; void *addrp; mpc85xx_dev_t *pdev = (mpc85xx_dev_t *)hdl; addrp = NULL; dev = (devfunc >> 3) & 0x1F; func = devfunc & 0x07; if( bus > 255 || dev > 31 || func > 7) { return( -1); } addr = (bus << 16) | (dev << 11) | (func << 8) | reg; out32((uintptr_t)(pdev->register_base + MPC85XX_PCI_CFG_ADDR), MPC85XX_PCI_ENABLE_CONFIG | (addr & ~0x3)); addrp = pdev->register_base + MPC85XX_PCI_CFG_DATA ; switch (width) { case 1: *((uint8_t *)buf) = in8((uintptr_t)addrp); break; case 2: *((uint16_t *)buf) = in16((uintptr_t)addrp); break; case 4: *((uint32_t *)buf) = in32((uintptr_t)addrp); break; } return PCI_SUCCESS;}intmpc85xx_write_cnfg(void *hdl, unsigned bus, unsigned devfunc, unsigned reg, unsigned width, const uint32_t data){ uint_t addr; uint_t dev; uint_t func; void *addrp; mpc85xx_dev_t *pdev = (mpc85xx_dev_t *)hdl; addrp = NULL; dev = (devfunc >> 3) & 0x1F; func = devfunc & 0x07; if( bus > 255 || dev > 31 || func > 7) { return( -1); } addr = (bus << 16) | (dev << 11) | (func << 8) | reg; out32((uintptr_t)(pdev->register_base + MPC85XX_PCI_CFG_ADDR), MPC85XX_PCI_ENABLE_CONFIG | (addr & ~0x3)); addrp = pdev->register_base + MPC85XX_PCI_CFG_DATA ; switch( width ) { case 1: out8((uintptr_t)addrp, data); break; case 2: out16((uintptr_t)addrp, data); break; case 4: out32((uintptr_t)addrp, data); break; } return( PCI_SUCCESS );}/* * Map cpu address to pci address/ pci_address to cpu address */intmpc85xx_map_addr(void *hdl, uint64_t iaddr, uint64_t *oaddr, uint32_t type){// mpc85xx_dev_t *pdev = (mpc85xx_dev_t *)hdl; if (type & PCI_MAP_ADDR_PCI) { /* * Map CPU to PCI */ if (type & PCI_IO_SPACE) { *oaddr = iaddr; } if (type & (PCI_MEM_SPACE | PCI_ROM_SPACE)) { *oaddr = iaddr; } if (type & PCI_ISA_SPACE) { *oaddr = iaddr; } if (type & PCI_BMSTR_SPACE) { *oaddr = iaddr; } } if (type & PCI_MAP_ADDR_CPU) { /* * Map PCI to CPU */ if (type & PCI_IO_SPACE) { *oaddr = iaddr; } if (type & (PCI_MEM_SPACE | PCI_ROM_SPACE)) { *oaddr = iaddr; } if (type & PCI_ISA_SPACE) { *oaddr = iaddr; } if (type & PCI_BMSTR_SPACE) { *oaddr = iaddr; } } return EOK; }int mpc85xx_map_irq(void *hdl, uint32_t bus, uint32_t devfunc, uint32_t line, uint32_t pin, uint32_t flags){ return EOK;}intmpc85xx_special_cycle(void *hdl, uint32_t bus, uint32_t data){ hdl = hdl, bus = bus, data = data; return EOK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -