static int board_asus_a7v8x_mx(const char *name) { struct pci_dev *dev; uint8_t val; dev = pci_dev_find(0x1106, 0x3177); /* VT8235 ISA bridge */ if (!dev) dev = pci_dev_find(0x1106, 0x3227); /* VT8237 ISA bridge */ if (!dev) { fprintf(stderr, "\nERROR: VT823x ISA bridge not found.\n"); return -1; } /* This bit is marked reserved actually */ val = pci_read_byte(dev, 0x59); val &= 0x7F; pci_write_byte(dev, 0x59, val); /* Raise ROM MEMW# line on Winbond w83697 SuperIO */ w836xx_ext_enter(); if (!(wbsio_read(0x24) & 0x02)) /* flash rom enabled? */ wbsio_mask(0x24, 0x08, 0x08); /* enable MEMW# */ w836xx_ext_leave(); return 0; }
static void exec_op(struct op *op, struct pci_dev *dev) { char *mm[] = { NULL, "%02x", "%04x", NULL, "%08x" }; char *m = mm[op->width]; unsigned int x; int i, addr; if (verbose) printf("%02x:%02x.%x:%02x", dev->bus, dev->dev, dev->func, op->addr); addr = op->addr; if (op->num_values >= 0) for(i=0; i<op->num_values; i++) { if (verbose) { putchar(' '); printf(m, op->values[i]); } if (demo_mode) continue; switch (op->width) { case 1: pci_write_byte(dev, addr, op->values[i]); break; case 2: pci_write_word(dev, addr, op->values[i]); break; default: pci_write_long(dev, addr, op->values[i]); break; } addr += op->width; } else { if (verbose) printf(" = "); if (!demo_mode) { switch (op->width) { case 1: x = pci_read_byte(dev, addr); break; case 2: x = pci_read_word(dev, addr); break; default: x = pci_read_long(dev, addr); break; } printf(m, x); } else putchar('?'); } putchar('\n'); }
static int board_via_epia_m(const char *name) { struct pci_dev *dev; unsigned int base; uint8_t val; dev = pci_dev_find(0x1106, 0x3177); /* VT8235 ISA bridge */ if (!dev) { fprintf(stderr, "\nERROR: VT8235 ISA Bridge not found.\n"); return -1; } /* GPIO12-15 -> output */ val = pci_read_byte(dev, 0xE4); val |= 0x10; pci_write_byte(dev, 0xE4, val); /* Get Power Management IO address. */ base = pci_read_word(dev, 0x88) & 0xFF80; /* enable GPIO15 which is connected to write protect. */ val = inb(base + 0x4D); val |= 0x80; outb(val, base + 0x4D); return 0; }
int undo_pci_write(void *p) { struct undo_pci_write_data *data = p; if (pacc == NULL) { msg_perr("%s: Tried to undo PCI writes without a valid PCI context!\n" "Please report a bug at [email protected]\n", __func__); return 1; } msg_pdbg("Restoring PCI config space for %02x:%02x:%01x reg 0x%02x\n", data->dev.bus, data->dev.dev, data->dev.func, data->reg); switch (data->type) { case pci_write_type_byte: pci_write_byte(&data->dev, data->reg, data->bytedata); break; case pci_write_type_word: pci_write_word(&data->dev, data->reg, data->worddata); break; case pci_write_type_long: pci_write_long(&data->dev, data->reg, data->longdata); break; } /* p was allocated in register_undo_pci_write. */ free(p); return 0; }
static int enable_flash_rdc_r8610(struct pci_dev *dev, const char *name) { uint8_t tmp; /* enable ROMCS for writes */ tmp = pci_read_byte(dev, 0x43); tmp |= 0x80; pci_write_byte(dev, 0x43, tmp); /* read the bootstrapping register */ tmp = pci_read_byte(dev, 0x40) & 0x3; switch (tmp) { case 3: internal_buses_supported = BUS_FWH; break; case 2: internal_buses_supported = BUS_LPC; break; default: internal_buses_supported = BUS_PARALLEL; break; } return 0; }
int try_ich(struct pci_access *pci, uint16_t reg_gpiobase, uint16_t reg_gc, const char *desc, int *fatal) { MSG("Checking for a %s system", desc); struct pci_dev *d31f0 = pci_find_dev(pci, 0, 31, 0); uint32_t gpiobase = pci_read_long(d31f0, reg_gpiobase); uint8_t gc = pci_read_byte(d31f0, reg_gc); MSG("GPIOBASE=%08x, GC=%02x", gpiobase, gc); if(gpiobase == 0xffffffff) { *fatal = 1; ERR("Cannot read GPIOBASE, are you running me as root?"); } else if(gpiobase == 0) { ERR("GPIOBASE not implemented at %04x", reg_gpiobase); } else if(!(gpiobase & 1)) { *fatal = 1; ERR("GPIOBASE is not an I/O BAR"); } if(!(gpiobase & 0xfffc)) { const uint32_t DEFAULT_GPIOBASE = 0x0480; MSG("GPIOBASE is not configured, setting to %08x and hoping this works", DEFAULT_GPIOBASE); pci_write_long(d31f0, reg_gpiobase, DEFAULT_GPIOBASE); gpiobase = pci_read_long(d31f0, reg_gpiobase); if((gpiobase & 0xfffc) != DEFAULT_GPIOBASE) { ERR("Cannot set GPIOBASE"); } } MSG("GPIO decoding is %s", (gc & REG_ICHx_GC_EN) ? "enabled" : "disabled"); MSG("GPIO lockdown is %s", (gc & REG_ICHx_GC_GLE) ? "enabled" : "disabled"); if(!(gc & REG_ICHx_GC_EN)) { MSG("Enabling GPIO decoding"); pci_write_byte(d31f0, reg_gc, gc | REG_ICHx_GC_EN); gc = pci_read_byte(d31f0, reg_gc); if(!(gc & REG_ICHx_GC_EN)) { ERR("Cannot enable GPIO decoding"); } } gpiobase &= 0xfffc; if(ioperm(gpiobase, 128, 1) == -1) { ERR("Cannot access I/O ports %04x:%04x", gpiobase, gpiobase + 128); } for(int n = 1; n < 3; n++) { MSG("USE_SEL%d=%08x", n, inl(gpiobase + ichx_regs[GPIO_USE_SEL][n])); MSG("IO_SEL%d=%08x", n, inl(gpiobase + ichx_regs[GPIO_IO_SEL][n])); MSG("LVL%d=%08x", n, inl(gpiobase + ichx_regs[GPIO_LVL][n])); } return 0; }
static void process_uhci(struct pci_address* addr, pci_device* dev) { uint8_t revision = pci_read_byte(addr, 0x60); if(revision != UHCI_REV_1_0) { // This host controller indicates that it supports a version // of the USB specification that is *not* 1.0. Ignore it KWARN("Detected UHCI with unsupported revision, ignoring..."); return; } // Bit 0 indicates whether it's memory mapped or port I/O bool memory_mapped = (dev->base_addr4 & 0x1) == 1; // Beore we initialize the card, make sure the cards I/O is disabled uint16_t cmd = pci_read_word(addr, PCI_COMMAND_REG_OFFSET); cmd = (cmd & ~0x1); pci_write_word(addr, PCI_COMMAND_REG_OFFSET, cmd); // THe USB book I'm reading is telling me to null out the // capabilities register as well as the two registers marked as "reserved" // Not sure why, TODO: Investigate! :-S pci_write_dword(addr, PCI_CAPS_OFF_REG_OFFSET, 0x00000000); pci_write_dword(addr, 0x38, 0x00000000); // Set the IRQ pci_write_byte(addr, PCI_IRQ_REG_OFFSET, UHCI_IRQ); // Now try to get the size of the address space //uint32_t size = pci_device_get_memory_size(addr, PCI_BASE_ADDR4_REG_OFFSET); // Enable bus mastering and I/O access pci_write_word(addr, 0x04, memory_mapped ? 0x06 : 0x05); // Disable legacy support and clear current status pci_write_word(addr, PCI_LEG_SUP_REG_OFFSET, PCI_LEGACY_PTS | // Clear Sequence ended bit PCI_LEGACY_TBY64W | PCI_LEGACY_TBY64R | PCI_LEGACY_TBY60W | PCI_LEGACY_TBY60R); // Clear status // The device is now ready for the UHCI driver to take over uhci_init(dev->base_addr4, dev, addr, UHCI_IRQ); }
int rpci_write_byte(struct pci_dev *dev, int reg, uint8_t data) { register_undo_pci_write_byte(dev, reg); return pci_write_byte(dev, reg, data); }
static void exec_op(struct op *op, struct pci_dev *dev) { const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x" }; const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x" }; unsigned int i, x, y; int addr = 0; int width = op->width; char slot[16]; sprintf(slot, "%04x:%02x:%02x.%x", dev->domain, dev->bus, dev->dev, dev->func); trace("%s ", slot); if (op->cap_type) { struct pci_cap *cap; cap = pci_find_cap(dev, op->cap_id, op->cap_type); if (cap) addr = cap->addr; else die("%s: %s %04x not found", slot, ((op->cap_type == PCI_CAP_NORMAL) ? "Capability" : "Extended capability"), op->cap_id); trace(((op->cap_type == PCI_CAP_NORMAL) ? "(cap %02x @%02x) " : "(ecap %04x @%03x) "), op->cap_id, addr); } addr += op->addr; trace("@%02x", addr); /* We have already checked it when parsing, but addressing relative to capabilities can change the address. */ if (addr & (width-1)) die("%s: Unaligned access of width %d to register %04x", slot, width, addr); if (addr + width > 0x1000) die("%s: Access of width %d to register %04x out of range", slot, width, addr); if (op->num_values) { for (i=0; i<op->num_values; i++) { if ((op->values[i].mask & max_values[width]) == max_values[width]) { x = op->values[i].value; trace(formats[width], op->values[i].value); } else { switch (width) { case 1: y = pci_read_byte(dev, addr); break; case 2: y = pci_read_word(dev, addr); break; default: y = pci_read_long(dev, addr); break; } x = (y & ~op->values[i].mask) | op->values[i].value; trace(mask_formats[width], y, op->values[i].value, op->values[i].mask, x); } if (!demo_mode) { switch (width) { case 1: pci_write_byte(dev, addr, x); break; case 2: pci_write_word(dev, addr, x); break; default: pci_write_long(dev, addr, x); break; } } addr += width; } trace("\n"); } else { trace(" = "); switch (width) { case 1: x = pci_read_byte(dev, addr); break; case 2: x = pci_read_word(dev, addr); break; default: x = pci_read_long(dev, addr); break; } printf(formats[width]+1, x); putchar('\n'); } }
void pci_config_write_byte(struct pci_device *pdev, uint32_t offset, uint8_t word) { pci_write_byte(pdev->bus, pdev->slot, pdev->func, offset, word); }