/*===========================================================================* * root_pci * *===========================================================================*/ static void root_pci(void) { /* Print information about PCI devices present in the system. */ u16_t vid, did; u8_t bcr, scr, pifr; char *slot_name, *dev_name; int r, devind; static int first = TRUE; /* This should be taken care of behind the scenes by the PCI lib. */ if (first) { pci_init(); first = FALSE; } /* Iterate over all devices, printing info for each of them. */ r = pci_first_dev(&devind, &vid, &did); while (r == 1) { slot_name = pci_slot_name(devind); dev_name = pci_dev_name(vid, did); bcr = pci_attr_r8(devind, PCI_BCR); scr = pci_attr_r8(devind, PCI_SCR); pifr = pci_attr_r8(devind, PCI_PIFR); buf_printf("%s %x/%x/%x %04X:%04X %s\n", slot_name ? slot_name : "-", bcr, scr, pifr, vid, did, dev_name ? dev_name : ""); r = pci_next_dev(&devind, &vid, &did); } }
static int de_probe(dpeth_t *dep, int skip) { int i, r, devind; u16_t vid, did, temp16; DEBUG(printf("PROBING...")); r= pci_first_dev(&devind, &vid, &did); if (r == 0) return FALSE; while (skip--) { r= pci_next_dev(&devind, &vid, &did); if (!r) return FALSE; } pci_reserve(devind); dep->de_base_port = pci_attr_r32(devind, PCI_BAR) & 0xffffffe0; dep->de_irq = pci_attr_r8(devind, PCI_ILR); if (dep->de_base_port < DE_MIN_BASE_ADDR) panic("de_probe: base address invalid: %d", dep->de_base_port); DEBUG(printf("%s: using I/O address 0x%lx, IRQ %d\n", dep->de_name, (unsigned long)dep->de_base_port, dep->de_irq)); dep->de_type = pci_attr_r8(devind, PCI_REV); /* device validation. We support only the DEC21140A */ if(dep->de_type != DEC_21140A){ dep->de_type = DE_TYPE_UNKNOWN; printf("%s: unsupported device\n", str_DevName); return FALSE; } de_reset(dep); DEBUG(printf("Reading SROM...\n")); for(i=0;i<(1<<SROM_BITWIDTH)-1;i++){ temp16 = de_read_rom(dep, i, SROM_BITWIDTH); dep->srom[i*2] = temp16 & 0xFF; dep->srom[i*2+1] = temp16 >> 8; } /* TODO: validate SROM content */ /* acquire MAC addr */ DEBUG(printf("Using MAC addr= ")); for(i=0;i<6;i++){ dep->de_address.ea_addr[i] = dep->srom[i+DE_SROM_EA_OFFSET]; DEBUG(printf("%02X%c",dep->de_address.ea_addr[i],i!=5?'-':'\n')); } DEBUG(printf("probe success\n")); return TRUE; }
static int init_device(int devind, struct virtio_device *dev) { u32_t base, size; int iof, r; pci_reserve(devind); if ((r = pci_get_bar(devind, PCI_BAR, &base, &size, &iof)) != OK) { printf("%s: Could not get BAR (%d)", dev->name, r); return r; } if (!iof) { printf("%s: PCI not IO space?", dev->name); return EINVAL; } if (base & 0xFFFF0000) { printf("%s: IO port weird (%08x)", dev->name, base); return EINVAL; } /* store the I/O port */ dev->port = base; /* Reset the device */ virtio_write8(dev, VIRTIO_DEV_STATUS_OFF, 0); /* Read IRQ line */ dev->irq = pci_attr_r8(devind, PCI_ILR); return OK; }
/*===========================================================================* * vbox_init * *===========================================================================*/ static int vbox_init(int UNUSED(type), sef_init_info_t *UNUSED(info)) { /* Initialize the device. */ int devind; u16_t vid, did; struct VMMDevReportGuestInfo *req; int r; interval = DEFAULT_INTERVAL; drift = DEFAULT_DRIFT; if (env_argc > 1) optset_parse(optset_table, env_argv[1]); pci_init(); r = pci_first_dev(&devind, &vid, &did); for (;;) { if (r != 1) panic("backdoor device not found"); if (vid == VMMDEV_PCI_VID && did == VMMDEV_PCI_DID) break; r = pci_next_dev(&devind, &vid, &did); } pci_reserve(devind); port = pci_attr_r32(devind, PCI_BAR) & PCI_BAR_IO_MASK; irq = pci_attr_r8(devind, PCI_ILR); hook_id = 0; if ((r = sys_irqsetpolicy(irq, 0 /* IRQ_REENABLE */, &hook_id)) != OK) panic("unable to register IRQ: %d", r); if ((r = sys_irqenable(&hook_id)) != OK) panic("unable to enable IRQ: %d", r); if ((vir_ptr = alloc_contig(VMMDEV_BUF_SIZE, 0, &phys_ptr)) == NULL) panic("unable to allocate memory"); req = (struct VMMDevReportGuestInfo *) vir_ptr; req->add_version = VMMDEV_GUEST_VERSION; req->os_type = VMMDEV_GUEST_OS_OTHER; if ((r = vbox_request(&req->header, phys_ptr, VMMDEV_REQ_REPORTGUESTINFO, sizeof(*req))) != VMMDEV_ERR_OK) panic("backdoor device not functioning"); ticks = sys_hz() * interval; sys_setalarm(ticks, 0); return OK; }
static int detect_hw(void) { u32_t device; int devind; u16_t v_id, d_id; /* detect_hw tries to find device and get IRQ and base address with a little (much) help from the PCI library. This code is quite device independent and you can copy it. (just make sure to get the bugs out first)*/ pci_init(); /* get first device and then search through the list */ device = pci_first_dev(&devind, &v_id, &d_id); while( device > 0 ) { /* if we have a match...break */ if (v_id == VENDOR_ID && d_id == DEVICE_ID) break; device = pci_next_dev(&devind, &v_id, &d_id); } /* did we find anything? */ if (v_id != VENDOR_ID || d_id != DEVICE_ID) { return EIO; } pci_reserve(devind); dev.name = pci_dev_name(v_id, d_id); /* get base address of our device, ignore least signif. bit this last bit thing could be device dependent, i don't know */ dev.base = pci_attr_r32(devind, PCI_BAR) & 0xfffffffe; /* get IRQ */ dev.irq = pci_attr_r8(devind, PCI_ILR); dev.revision = pci_attr_r8(devind, PCI_REV); dev.d_id = d_id; dev.v_id = v_id; dev.devind = devind; /* pci device identifier */ return OK; }
int ddekit_pci_readb (int bus, int slot, int func, int pos, ddekit_uint8_t *val) { struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func); if (func!=0) { *val=0; return 0; } if (dev) { *val = pci_attr_r8 (dev->devind, pos); DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x", bus, slot, func, pos, *val); return 0; } return -1; }
/*===========================================================================* * atl2_init * *===========================================================================*/ static void atl2_init(int devind) { /* Initialize the device. */ u32_t bar; int r, flag; /* Initialize global state. */ state.devind = devind; state.mode = DL_NOMODE; state.flags = 0; state.recv_count = 0; memset(&state.stat, 0, sizeof(state.stat)); if ((r = pci_get_bar(devind, PCI_BAR, &bar, &state.size, &flag)) != OK) panic("unable to retrieve bar: %d", r); if (state.size < ATL2_MIN_MMAP_SIZE || flag) panic("invalid register bar"); state.base = vm_map_phys(SELF, (void *) bar, state.size); if (state.base == MAP_FAILED) panic("unable to map in registers"); if ((r = atl2_alloc_dma()) != OK) panic("unable to allocate DMA buffers: %d", r); state.irq = pci_attr_r8(devind, PCI_ILR); if ((r = sys_irqsetpolicy(state.irq, 0, &state.hook_id)) != OK) panic("unable to register IRQ: %d", r); if (!atl2_reset()) panic("unable to reset hardware"); if ((r = sys_irqenable(&state.hook_id)) != OK) panic("unable to enable IRQ: %d", r); atl2_get_hwaddr(); atl2_setup(); }
/*===========================================================================* * e1000_probe * *===========================================================================*/ PRIVATE int e1000_probe(e1000_t *e, int skip) { int i, r, devind; u16_t vid, did; u32_t status[2]; u32_t gfpreg, sector_base_addr; char *dname; E1000_DEBUG(3, ("%s: probe()\n", e->name)); /* * Attempt to iterate the PCI bus. Start at the beginning. */ if ((r = pci_first_dev(&devind, &vid, &did)) == 0) { return FALSE; } /* Loop devices on the PCI bus. */ for(;;) { for (i = 0; pcitab_e1000[i] != 0; i++) { if (vid != 0x8086) continue; if (did != pcitab_e1000[i]) continue; else break; } if (pcitab_e1000[i] != 0) { if (!skip) break; skip--; } if (!(r = pci_next_dev(&devind, &vid, &did))) { return FALSE; } } /* * Successfully detected an Intel Pro/1000 on the PCI bus. */ e->status |= E1000_DETECTED; e->eeprom_read = eeprom_eerd; /* * Set card specific properties. */ switch (did) { case E1000_DEV_ID_ICH10_R_BM_LF: e->eeprom_read = eeprom_ich; break; case E1000_DEV_ID_82574L: case E1000_DEV_ID_82541GI_LF: e->eeprom_done_bit = (1 << 1); e->eeprom_addr_off = 2; break; default: e->eeprom_done_bit = (1 << 4); e->eeprom_addr_off = 8; break; } /* Inform the user about the new card. */ if (!(dname = pci_dev_name(vid, did))) { dname = "Intel Pro/1000 Gigabit Ethernet Card"; } E1000_DEBUG(1, ("%s: %s (%04x/%04x/%02x) at %s\n", e->name, dname, vid, did, e->revision, pci_slot_name(devind))); /* Reserve PCI resources found. */ if ((r = pci_reserve_ok(devind)) != OK) { panic("failed to reserve PCI device: %d", r); } /* Read PCI configuration. */ e->irq = pci_attr_r8(devind, PCI_ILR); e->regs = vm_map_phys(SELF, (void *) pci_attr_r32(devind, PCI_BAR), 0x20000); /* Verify mapped registers. */ if (e->regs == (u8_t *) -1) { panic("failed to map hardware registers from PCI"); } /* Optionally map flash memory. */ if (did != E1000_DEV_ID_82540EM && did != E1000_DEV_ID_82540EP && pci_attr_r32(devind, PCI_BAR_2)) { if((e->flash = vm_map_phys(SELF, (void *) pci_attr_r32(devind, PCI_BAR_2), 0x10000)) == MAP_FAILED) { if((e->flash = vm_map_phys(SELF, (void *) pci_attr_r32(devind, PCI_BAR_2), 0x1000)) == MAP_FAILED) { panic("e1000: couldn't map in flash."); } } gfpreg = E1000_READ_FLASH_REG(e, ICH_FLASH_GFPREG); /* * sector_base_addr is a "sector"-aligned address (4096 bytes) */ sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK; /* flash_base_addr is byte-aligned */ e->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT; } /* * Output debug information. */ status[0] = e1000_reg_read(e, E1000_REG_STATUS); E1000_DEBUG(3, ("%s: MEM at %p, IRQ %d\n", e->name, e->regs, e->irq)); E1000_DEBUG(3, ("%s: link %s, %s duplex\n", e->name, status[0] & 3 ? "up" : "down", status[0] & 1 ? "full" : "half")); return TRUE; }
/* * Find a matching device. Return TRUE on success. */ static int e1000_probe(e1000_t * e, int skip) { int r, devind, ioflag; u16_t vid, did, cr; u32_t status; u32_t base, size; char *dname; E1000_DEBUG(3, ("%s: probe()\n", e->name)); /* Initialize communication to the PCI driver. */ pci_init(); /* Attempt to iterate the PCI bus. Start at the beginning. */ if ((r = pci_first_dev(&devind, &vid, &did)) == 0) return FALSE; /* Loop devices on the PCI bus. */ while (skip--) { E1000_DEBUG(3, ("%s: probe() devind %d vid 0x%x did 0x%x\n", e->name, devind, vid, did)); if (!(r = pci_next_dev(&devind, &vid, &did))) return FALSE; } /* We found a matching card. Set card-specific properties. */ e->eeprom_read = eeprom_eerd; switch (did) { case E1000_DEV_ID_ICH10_D_BM_LM: case E1000_DEV_ID_ICH10_R_BM_LF: e->eeprom_read = eeprom_ich; break; case E1000_DEV_ID_82540EM: case E1000_DEV_ID_82545EM: case E1000_DEV_ID_82540EP_LP: e->eeprom_done_bit = (1 << 4); e->eeprom_addr_off = 8; break; default: e->eeprom_done_bit = (1 << 1); e->eeprom_addr_off = 2; break; } /* Inform the user about the new card. */ if (!(dname = pci_dev_name(vid, did))) dname = "Intel Pro/1000 Gigabit Ethernet Card"; E1000_DEBUG(1, ("%s: %s (%04x/%04x) at %s\n", e->name, dname, vid, did, pci_slot_name(devind))); /* Reserve PCI resources found. */ pci_reserve(devind); /* Read PCI configuration. */ e->irq = pci_attr_r8(devind, PCI_ILR); if ((r = pci_get_bar(devind, PCI_BAR, &base, &size, &ioflag)) != OK) panic("failed to get PCI BAR: %d", r); if (ioflag) panic("PCI BAR is not for memory"); if ((e->regs = vm_map_phys(SELF, (void *)base, size)) == MAP_FAILED) panic("failed to map hardware registers from PCI"); /* Enable DMA bus mastering if necessary. */ cr = pci_attr_r16(devind, PCI_CR); if (!(cr & PCI_CR_MAST_EN)) pci_attr_w16(devind, PCI_CR, cr | PCI_CR_MAST_EN); /* Optionally map flash memory. */ e1000_map_flash(e, devind, did); /* Output debug information. */ status = e1000_reg_read(e, E1000_REG_STATUS); E1000_DEBUG(3, ("%s: MEM at %p, IRQ %d\n", e->name, e->regs, e->irq)); E1000_DEBUG(3, ("%s: link %s, %s duplex\n", e->name, status & 3 ? "up" : "down", status & 1 ? "full" : "half")); return TRUE; }
/*===========================================================================* * do_int * *===========================================================================*/ static void do_int(struct port *pp) { int devind, vcc_5v, vcc_3v, vcc_Xv, vcc_Yv, socket_5v, socket_3v, socket_Xv, socket_Yv; spin_t spin; u32_t csr_event, csr_present, csr_control; u8_t v8; u16_t v16; #if USE_INTS int r; #endif devind= pp->p_devind; v8= pci_attr_r8(devind, TI_CARD_CTRL); if (v8 & TI_CCR_IFG) { printf("ti1225: got functional interrupt\n"); pci_attr_w8(devind, TI_CARD_CTRL, v8); } if (debug) { printf("Socket event: 0x%x\n", pp->csr_ptr->csr_event); printf("Socket mask: 0x%x\n", pp->csr_ptr->csr_mask); } csr_present= pp->csr_ptr->csr_present; csr_control= pp->csr_ptr->csr_control; if ((csr_present & (CP_CDETECT1|CP_CDETECT2)) != 0) { if (debug) printf("do_int: no card present\n"); return; } if (csr_present & CP_BADVCCREQ) { printf("do_int: Bad Vcc request\n"); /* return; */ } if (csr_present & CP_DATALOST) { /* Do we care? */ if (debug) printf("do_int: Data lost\n"); /* return; */ } if (csr_present & CP_NOTACARD) { printf("do_int: Not a card\n"); return; } if (debug) { if (csr_present & CP_CBCARD) printf("do_int: Cardbus card detected\n"); if (csr_present & CP_16BITCARD) printf("do_int: 16-bit card detected\n"); } if (csr_present & CP_PWRCYCLE) { if (debug) printf("do_int: powered up\n"); return; } vcc_5v= !!(csr_present & CP_5VCARD); vcc_3v= !!(csr_present & CP_3VCARD); vcc_Xv= !!(csr_present & CP_XVCARD); vcc_Yv= !!(csr_present & CP_YVCARD); if (debug) { printf("do_int: card supports:%s%s%s%s\n", vcc_5v ? " 5V" : "", vcc_3v ? " 3V" : "", vcc_Xv ? " X.X V" : "", vcc_Yv ? " Y.Y V" : ""); } socket_5v= !!(csr_present & CP_5VSOCKET); socket_3v= !!(csr_present & CP_3VSOCKET); socket_Xv= !!(csr_present & CP_XVSOCKET); socket_Yv= !!(csr_present & CP_YVSOCKET); if (debug) { printf("do_int: socket supports:%s%s%s%s\n", socket_5v ? " 5V" : "", socket_3v ? " 3V" : "", socket_Xv ? " X.X V" : "", socket_Yv ? " Y.Y V" : ""); } if (vcc_5v && socket_5v) { csr_control= (csr_control & ~CC_VCCCTRL) | CC_VCC_5V; pp->csr_ptr->csr_control= csr_control; if (debug) printf("do_int: applying 5V\n"); } else if (vcc_3v && socket_3v) { csr_control= (csr_control & ~CC_VCCCTRL) | CC_VCC_3V; pp->csr_ptr->csr_control= csr_control; if (debug) printf("do_int: applying 3V\n"); } else if (vcc_Xv && socket_Xv) { csr_control= (csr_control & ~CC_VCCCTRL) | CC_VCC_XV; pp->csr_ptr->csr_control= csr_control; printf("do_int: applying X.X V\n"); } else if (vcc_Yv && socket_Yv) { csr_control= (csr_control & ~CC_VCCCTRL) | CC_VCC_YV; pp->csr_ptr->csr_control= csr_control; printf("do_int: applying Y.Y V\n"); } else { printf("do_int: socket and card are not compatible\n"); return; } csr_event= pp->csr_ptr->csr_event; if (csr_event) { if (debug) printf("clearing socket event\n"); pp->csr_ptr->csr_event= csr_event; if (debug) { printf("Socket event (cleared): 0x%x\n", pp->csr_ptr->csr_event); } } devind= pp->p_devind; v8= pci_attr_r8(devind, TI_CARD_CTRL); if (v8 & TI_CCR_IFG) { printf("ti1225: got functional interrupt\n"); pci_attr_w8(devind, TI_CARD_CTRL, v8); } if (debug) { v8= pci_attr_r8(devind, TI_CARD_CTRL); printf("TI_CARD_CTRL: 0x%02x\n", v8); } spin_init(&spin, 100000); do { csr_present= pp->csr_ptr->csr_present; if (csr_present & CP_PWRCYCLE) break; } while (spin_check(&spin)); if (!(csr_present & CP_PWRCYCLE)) { printf("do_int: not powered up?\n"); return; } /* Reset device */ v16= pci_attr_r16(devind, CBB_BRIDGECTRL); v16 |= CBB_BC_CRST; pci_attr_w16(devind, CBB_BRIDGECTRL, v16); /* Wait one microsecond. Is this correct? What are the specs? */ micro_delay(1); /* Clear CBB_BC_CRST */ v16= pci_attr_r16(devind, CBB_BRIDGECTRL); v16 &= ~CBB_BC_CRST; pci_attr_w16(devind, CBB_BRIDGECTRL, v16); /* Wait one microsecond after clearing the reset line. Is this * correct? What are the specs? */ micro_delay(1); pci_rescan_bus(pp->p_cb_busnr); #if USE_INTS r= sys_irqenable(&pp->p_hook); if (r != OK) panic("unable enable interrupts: %d", r); #endif }
/*===========================================================================* * hw_init * *===========================================================================*/ static void hw_init(struct port *pp, int devind) { u8_t v8; u16_t v16; u32_t v32; #if USE_INTS int r, irq; #endif pp->p_devind= devind; if (debug) printf("hw_init: devind = %d\n", devind); if (debug) { v16= pci_attr_r16(devind, PCI_CR); printf("ti1225: command register 0x%x\n", v16); } v32= pci_attr_r32(devind, TI_CB_BASEADDR); if (debug) printf("ti1225: Cardbus/ExCA base address 0x%x\n", v32); v32 &= PCI_BAR_MEM_MASK; /* Clear low order bits in base */ pp->csr_ptr= (struct csr *) vm_map_phys(SELF, (void *) v32, I386_PAGE_SIZE); if (pp->csr_ptr == MAP_FAILED) panic("hw_init: vm_map_phys failed"); if (debug) { v8= pci_attr_r8(devind, TI_PCI_BUS_NR); printf("ti1225: PCI bus number %d\n", v8); } v8= pci_attr_r8(devind, TI_CB_BUS_NR); pp->p_cb_busnr= v8; if (debug) { printf("ti1225: CardBus bus number %d\n", v8); v8= pci_attr_r8(devind, TI_SO_BUS_NR); printf("ti1225: Subordinate bus number %d\n", v8); } #if USE_INTS irq= pci_attr_r8(devind, PCI_ILR); pp->p_irq= irq; printf("ti1225 using IRQ %d\n", irq); #endif v32= pci_attr_r32(devind, TI_LEGACY_BA); v32 &= ~1; if (debug) { printf("ti1225: PC Card 16-bit legacy-mode base address 0x%x\n", v32); } if (v32 == 0) panic("bad legacy-mode base address: %d", v32); pp->p_exca_port= v32; if (debug) { v32= pci_attr_r32(devind, TI_MF_ROUTE); printf("ti1225: Multifunction routing 0x%08x\n", v32); } #if USE_INTS pp->p_hook = pp->p_irq; r= sys_irqsetpolicy(pp->p_irq, 0, &pp->p_hook); if (r != OK) panic("sys_irqsetpolicy failed: %d", r); #endif /* Clear CBB_BC_INTEXCA */ v16= pci_attr_r16(devind, CBB_BRIDGECTRL); if (debug) printf("ti1225: Bridge control 0x%04x\n", v16); v16 &= ~CBB_BC_INTEXCA; pci_attr_w16(devind, CBB_BRIDGECTRL, v16); if (debug) { v32= pci_attr_r32(devind, TI_SYSCTRL); printf("ti1225: System Control Register 0x%08x\n", v32); v8= pci_attr_r8(devind, TI_CARD_CTRL); printf("ti1225: Card Control 0x%02x\n", v8); v8= pci_attr_r8(devind, TI_DEV_CTRL); printf("ti1225: Device Control 0x%02x\n", v8); } /* Enable socket interrupts */ pp->csr_ptr->csr_mask |= CM_PWRMASK | CM_CDMASK | CM_CSTSMASK; do_int(pp); #if USE_INTS r= sys_irqenable(&pp->p_hook); if (r != OK) panic("unable enable interrupts: %d", r); #endif }