static void qemu_nb_init(device_t dev) { /* Map memory at 0xc0000 - 0xfffff */ int i; uint8_t v = pci_read_config8(dev, Q35_PAM0); v |= 0x30; pci_write_config8(dev, Q35_PAM0, v); pci_write_config8(dev, Q35_PAM0 + 1, 0x33); pci_write_config8(dev, Q35_PAM0 + 2, 0x33); pci_write_config8(dev, Q35_PAM0 + 3, 0x33); pci_write_config8(dev, Q35_PAM0 + 4, 0x33); pci_write_config8(dev, Q35_PAM0 + 5, 0x33); pci_write_config8(dev, Q35_PAM0 + 6, 0x33); /* This sneaked in here, because Qemu does not * emulate a SuperIO chip */ pc_keyboard_init(NO_AUX_DEVICE); /* setup IRQ routing for pci slots */ for (i = 0; i < 25; i++) pci_assign_irqs(0, i, qemu_q35_irqs + (i % 4)); /* setup IRQ routing southbridge devices */ for (i = 25; i < 32; i++) pci_assign_irqs(0, i, qemu_q35_irqs); }
static void pci_routing_fixup(struct device *dev) { printk(BIOS_INFO, "%s: dev is %p\n", __func__, dev); /* set up PCI IRQ routing */ pci_write_config8(dev, 0x55, pciIrqs[0] << 4); pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) ); pci_write_config8(dev, 0x57, pciIrqs[3] << 4); // firewire built into southbridge printk(BIOS_INFO, "setting firewire\n"); pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins)); // Standard usb components printk(BIOS_INFO, "setting usb\n"); pci_assign_irqs(0, 0x10, pin_to_irq(usbPins)); // VT8235 + sound hardware printk(BIOS_INFO, "setting vt8235\n"); pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins)); // Ethernet built into southbridge printk(BIOS_INFO, "setting ethernet\n"); pci_assign_irqs(0, 0x12, pin_to_irq(enetPins)); // VGA printk(BIOS_INFO, "setting vga\n"); pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins)); // PCI slot printk(BIOS_INFO, "setting pci slot\n"); pci_assign_irqs(0, 0x14, pin_to_irq(slotPins)); // Cardbus slot printk(BIOS_INFO, "setting cardbus slot\n"); pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins)); // Via 2 slot riser card 2nd slot printk(BIOS_INFO, "setting riser slot\n"); pci_assign_irqs(0, 0x13, pin_to_irq(riserPins)); printk(BIOS_SPEW, "%s: DONE\n", __func__); }
static void pci_routing_fixup(struct device *dev) { printk(BIOS_INFO, "%s: dev is %p\n", __FUNCTION__, dev); /* set up PCI IRQ routing */ pci_write_config8(dev, 0x55, pciIrqs[0] << 4); pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4)); pci_write_config8(dev, 0x57, pciIrqs[3] << 4); /* VGA */ printk(BIOS_INFO, "setting vga\n"); pci_assign_irqs(0, 0x1, pin_to_irq(vgaPins)); /* PCI slot */ printk(BIOS_INFO, "setting pci slot\n"); pci_assign_irqs(0, 0x08, pin_to_irq(slotPins)); /* PCI slot */ printk(BIOS_INFO, "setting USB Device Controller\n"); pci_assign_irqs(0, 0x0b, pin_to_irq(usbdevicePins)); /* PCI slot */ printk(BIOS_INFO, "setting SDIO Controller\n"); pci_assign_irqs(0, 0x0c, pin_to_irq(sdioPins)); /* PCI slot */ printk(BIOS_INFO, "setting SD $ MS Controller\n"); pci_assign_irqs(0, 0x0d, pin_to_irq(sd_ms_ctrl_Pins)); /* PCI slot */ printk(BIOS_INFO, "setting CE-ATA NF Controller(Card Boot)\n"); pci_assign_irqs(0, 0x0e, pin_to_irq(ce_ata_nf_ctrl_Pins)); /* PCI slot */ printk(BIOS_INFO, "setting ide\n"); //pci_assign_irqs(0, 0x0f, pin_to_irq(idePins)); /* Standard usb components */ printk(BIOS_INFO, "setting usb1-2\n"); // pci_assign_irqs(0, 0x10, pin_to_irq(usbPins)); /* sound hardware */ printk(BIOS_INFO, "setting hdac audio\n"); pci_assign_irqs(0, 0x14, pin_to_irq(hdacaudioPins)); printk(BIOS_SPEW, "%s: DONE\n", __FUNCTION__); }
static void qemu_nb_init(device_t dev) { /* Map memory at 0xc0000 - 0xfffff */ int i; uint8_t v = pci_read_config8(dev, 0x59); v |= 0x30; pci_write_config8(dev, 0x59, v); for (i=0; i<6; i++) pci_write_config8(dev, 0x5a + i, 0x33); /* This sneaked in here, because Qemu does not * emulate a SuperIO chip */ pc_keyboard_init(NO_AUX_DEVICE); /* setup IRQ routing */ for (i = 0; i < 32; i++) pci_assign_irqs(0, i, qemu_i440fx_irqs + (i % 4)); }
static void qemu_nb_init(device_t dev) { /* Map memory at 0xc0000 - 0xfffff */ int i; uint8_t v = pci_read_config8(dev, 0x59); v |= 0x30; pci_write_config8(dev, 0x59, v); for (i=0; i<6; i++) pci_write_config8(dev, 0x5a + i, 0x33); /* This sneaked in here, because Qemu does not * emulate a SuperIO chip */ pc_keyboard_init(0); /* The PIRQ table is not working well for interrupt routing purposes. * so we'll just set the IRQ directly. */ printk(BIOS_INFO, "Setting up ethernet...\n"); pci_assign_irqs(0, 3, enetIrqs); }
unsigned long write_pirq_routing_table(unsigned long addr) { struct irq_routing_table *pirq; struct irq_info *pirq_info; unsigned slot_num; uint8_t *v; uint8_t sum=0; int i; struct mb_sysconf_t *m; get_bus_conf(); // it will find out all bus num and apic that share with mptable.c and mptable.c and acpi_tables.c m = sysconf.mb; /* Align the table to be 16 byte aligned. */ addr += 15; addr &= ~15; /* This table must be between 0xf0000 & 0x100000 */ printk(BIOS_INFO, "Writing IRQ routing tables to 0x%lx...", addr); pirq = (void *)(addr); v = (uint8_t *)(addr); pirq->signature = PIRQ_SIGNATURE; pirq->version = PIRQ_VERSION; pirq->rtr_bus = m->bus_8111_0; pirq->rtr_devfn = ((sysconf.sbdn+1)<<3)|0; pirq->exclusive_irqs = 0; pirq->rtr_vendor = 0x1022; pirq->rtr_device = 0x746b; pirq->miniport_data = 0; memset(pirq->rfu, 0, sizeof(pirq->rfu)); pirq_info = (void *) ( &pirq->checksum + 1); slot_num = 0; { device_t dev; dev = dev_find_slot(m->bus_8111_0, PCI_DEVFN(sysconf.sbdn+1,3)); if (dev) { /* initialize PCI interupts - these assignments depend on the PCB routing of PINTA-D PINTA = IRQ3 PINTB = IRQ5 PINTC = IRQ10 PINTD = IRQ11 */ pci_write_config16(dev, 0x56, 0xba53); } } //pci bridge printk(BIOS_DEBUG, "setting Onboard AMD Southbridge\n"); static const unsigned char slotIrqs_1_4[4] = { 3, 5, 10, 11 }; pci_assign_irqs(m->bus_8111_0, sysconf.sbdn+1, slotIrqs_1_4); write_pirq_info(pirq_info, m->bus_8111_0, ((sysconf.sbdn+1)<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0); pirq_info++; slot_num++; printk(BIOS_DEBUG, "setting Onboard AMD USB\n"); static const unsigned char slotIrqs_8111_1_0[4] = { 0, 0, 0, 11}; pci_assign_irqs(m->bus_8111_1, 0, slotIrqs_8111_1_0); write_pirq_info(pirq_info, m->bus_8111_1,0, 0, 0, 0, 0, 0, 0, 0x4, 0xdef8, 0, 0); pirq_info++; slot_num++; //pcix bridge // write_pirq_info(pirq_info, m->bus_8132_0, (sbdn3<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0); // pirq_info++; slot_num++; int j = 0; for(i=1; i< sysconf.hc_possible_num; i++) { if(!(sysconf.pci1234[i] & 0x1) ) continue; unsigned busn = (sysconf.pci1234[i] >> 16) & 0xff; unsigned devn = sysconf.hcdn[i] & 0xff; write_pirq_info(pirq_info, busn, (devn<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0); pirq_info++; slot_num++; j++; } pirq->size = 32 + 16 * slot_num; for (i = 0; i < pirq->size; i++) sum += v[i]; sum = pirq->checksum - sum; if (sum != pirq->checksum) { pirq->checksum = sum; } printk(BIOS_INFO, "done.\n"); return (unsigned long) pirq_info; }
static void pci_routing_fixup(struct device *dev) { pci_assign_irqs(0, 0x8, enetIrqs); pci_assign_irqs(0, 0xa, usbIrqs); }
/** * Create the IRQ routing table. * Values are derived from getpir generated code. */ unsigned long write_pirq_routing_table(unsigned long addr) { struct irq_routing_table *pirq; struct irq_info *pirq_info; unsigned slot_num; uint8_t *v; uint8_t sum = 0; int i; unsigned sbdn; /* get_bus_conf() will find out all bus num and apic that share with * mptable.c and mptable.c */ get_bus_conf(); sbdn = sysconf.sbdn; /* Align the table to be 16 byte aligned. */ addr += 15; addr &= ~15; /* This table must be between 0xf0000 & 0x100000 */ printk(BIOS_INFO, "Writing IRQ routing tables to 0x%lx...", addr); pirq = (void *)(addr); v = (uint8_t *) (addr); pirq->signature = PIRQ_SIGNATURE; pirq->version = PIRQ_VERSION; pirq->rtr_bus = bus_ck804[0]; pirq->rtr_devfn = ((sbdn + 9) << 3) | 0; pirq->exclusive_irqs = 0x828; pirq->rtr_vendor = 0x10de; pirq->rtr_device = 0x005c; pirq->miniport_data = 0; memset(pirq->rfu, 0, sizeof(pirq->rfu)); pirq_info = (void *)(&pirq->checksum + 1); slot_num = 0; //Slot1 PCIE 16x write_pirq_info(pirq_info, bus_ck804[1], (0 << 3) | 0, 0x3, 0xdeb8, 0x4, 0xdeb8, 0x1, 0xdeb8, 0x2, 0xdeb8, 4, 0); pirq_info++; slot_num++; //Slot2 PCIE 1x write_pirq_info(pirq_info, bus_ck804[2], (0 << 3) | 0, 0x4, 0xdeb8, 0x1, 0xdeb8, 0x2, 0xdeb8, 0x3, 0xdeb8, 5, 0); pirq_info++; slot_num++; //Slot3 PCIE 1x write_pirq_info(pirq_info, bus_ck804[3], (0 << 3) | 0, 0x1, 0xdeb8, 0x2, 0xdeb8, 0x3, 0xdeb8, 0x4, 0xdeb8, 6, 0); pirq_info++; slot_num++; //Slot4 PCIE 4x write_pirq_info(pirq_info, bus_ck804[4], (0x4 << 3) | 0, 0x2, 0xdeb8, 0x3, 0xdeb8, 0x4, 0xdeb8, 0x1, 0xdeb8, 7, 0); pirq_info++; slot_num++; //Slot5 - 7 PCI for (i = 0; i < 3; i++) { write_pirq_info(pirq_info, bus_ck804[5], (0 << (6 + i)) | 0, ((i + 0) % 4) + 1, 0xdeb8, ((i + 1) % 4) + 1, 0xdeb8, ((i + 2) % 4) + 1, 0xdeb8, ((i + 3) % 4) + 1, 0xdeb8, i, 0); pirq_info++; slot_num++; } //pci bridge write_pirq_info(pirq_info, bus_ck804[0], ((sbdn + 9) << 3) | 0, 0x1, 0xdeb8, 0x2, 0xdeb8, 0x3, 0xdeb8, 0x4, 0xdeb8, 0, 0); pirq_info++; slot_num++; //smbus write_pirq_info(pirq_info, bus_ck804[0], ((sbdn + 1) << 3) | 0, 0x2, 0xdeb8, 0, 0, 0, 0, 0, 0, 0, 0); pirq_info++; slot_num++; //usb write_pirq_info(pirq_info, bus_ck804[0], ((sbdn + 2) << 3) | 0, 0x1, 0xdeb8, 0x2, 0xdeb8, 0, 0, 0, 0, 0, 0); pirq_info++; slot_num++; //audio write_pirq_info(pirq_info, bus_ck804[0], ((sbdn + 4) << 3) | 0, 0x1, 0xdeb8, 0, 0, 0, 0, 0, 0, 0, 0); pirq_info++; slot_num++; //sata write_pirq_info(pirq_info, bus_ck804[0], ((sbdn + 7) << 3) | 0, 0x1, 0xdeb8, 0, 0, 0, 0, 0, 0, 0, 0); pirq_info++; slot_num++; //sata write_pirq_info(pirq_info, bus_ck804[0], ((sbdn + 8) << 3) | 0, 0x1, 0xdeb8, 0, 0, 0, 0, 0, 0, 0, 0); pirq_info++; slot_num++; //nic write_pirq_info(pirq_info, bus_ck804[0], ((sbdn + 0xa) << 3) | 0, 0x1, 0xdeb8, 0, 0, 0, 0, 0, 0, 0, 0); pirq_info++; slot_num++; pirq->size = 32 + 16 * slot_num; for (i = 0; i < pirq->size; i++) sum += v[i]; sum = pirq->checksum - sum; if (sum != pirq->checksum) { pirq->checksum = sum; } printk(BIOS_INFO, "done.\n"); #if 0 unsigned char irq[4]; irq[0] = 0; irq[1] = 0; irq[2] = 0; irq[3] = 0; /* Bus, device, slots IRQs for {A,B,C,D}. */ irq[0] = 10; /* SMBus *//* test me */ pci_assign_irqs(bus_ck804[0], 1, irq); irq[0] = 10; /* USB */ irq[1] = 10; pci_assign_irqs(bus_ck804[0], 2, irq); irq[0] = 10; /* AC97 */ irq[1] = 0; pci_assign_irqs(bus_ck804[0], 4, irq); irq[0] = 11; /* SATA */ pci_assign_irqs(bus_ck804[0], 7, irq); irq[0] = 5; /* SATA */ pci_assign_irqs(bus_ck804[0], 8, irq); irq[0] = 10; /* Ethernet */ pci_assign_irqs(bus_ck804[0], 10, irq); /* physical slots */ irq[0] = 5; /* PCI E1 - x1 */ pci_assign_irqs(bus_ck804[2], 0, irq); irq[0] = 11; /* PCI E2 - x16 */ pci_assign_irqs(bus_ck804[3], 0, irq); /* AGP-on-PCI "AGR" ignored */ irq[0] = 10; /* PCI1 */ irq[1] = 11; irq[2] = 5; irq[3] = 0; pci_assign_irqs(bus_ck804[1], 7, irq); irq[0] = 11; /* PCI2 */ irq[1] = 10; irq[2] = 5; irq[3] = 0; pci_assign_irqs(bus_ck804[1], 8, irq); irq[0] = 5; /* PCI3 */ irq[1] = 10; irq[2] = 11; irq[3] = 0; pci_assign_irqs(bus_ck804[1], 9, irq); #endif return (unsigned long)pirq_info; }
/* TODO: finish up mmcr struct in sc520.h, and; - set ADDDECTL (now done in raminit.c in cpu/amd/sc520 */ static void mainboard_enable(struct device *dev) { //volatile struct mmcrpic *pic = MMCRPIC; volatile struct mmcr *mmcr = MMCRDEFAULT; /* msm586seg has this register set to a weird value. * follow the board, not the manual! */ /* currently, nothing in the device to use, so ignore it. */ printk(BIOS_ERR, "digital logic msm586 seg ENTER %s\n", __func__); /* from fuctory bios */ /* NOTE: the following interrupt settings made interrupts work * for hard drive, and serial, but not for ethernet */ /* just do what they say and nobody gets hurt. */ mmcr->pic.pcicr = 0 ; // M_GINT_MODE | M_S1_MODE | M_S2_MODE; /* all ints to level */ mmcr->pic.mpicmode = 0; mmcr->pic.sl1picmode = 0; mmcr->pic.sl2picmode = 0x80; mmcr->pic.intpinpol = 0; mmcr->pic.pit0map = 1; mmcr->pic.uart1map = 0xc; mmcr->pic.uart2map = 0xb; mmcr->pic.rtcmap = 3; mmcr->pic.ferrmap = 8; mmcr->pic.gp0imap = 6; mmcr->pic.gp1imap = 2; mmcr->pic.gp2imap = 7; mmcr->pic.gp6imap = 0x15; mmcr->pic.gp7imap = 0x16; mmcr->pic.gp10imap = 0x9; mmcr->pic.gp9imap = 0x4; irqdump(); printk(BIOS_ERR, "uart 1 ctl is 0x%x\n", *(unsigned char *) 0xfffefcc0); printk(BIOS_ERR, "0xc20 ctl is 0x%x\n", *(unsigned short *) 0xfffefc20); printk(BIOS_ERR, "0xc22 0x%x\n", *(unsigned short *) 0xfffefc22); /* The following block has NOT proven sufficient to get * the VGA hardware to talk to us */ /* let's set some mmcr stuff per the BIOS settings */ mmcr->dbctl.dbctl = 0x10; mmcr->sysarb.ctl = 6; mmcr->sysarb.menb = 0xf; mmcr->sysarb.prictl = 0xc0000f0f; /* this is bios setting, depends on sysarb above */ mmcr->hostbridge.ctl = 0x108; printk(BIOS_ERR, "digital logic msm586 seg EXIT %s\n", __func__); /* pio */ mmcr->pio.data31_16 = 0xffbf; /* pci stuff */ mmcr->pic.pciintamap = 0xa; /* END block where vga hardware still will not talk to us */ /* all we get from VGA I/O addresses are ffff etc. */ mmcr->sysmap.adddecctl = 0x10; /* VGA now talks to us, so this adddecctl was the trick. * still no interrupts from enet. * Let's try fixing the piodata stuff, as there may be * some wire there not documented. */ mmcr->pio.data31_16 = 0xffbf; /* also, our sl?picmode needs to match fuctory bios */ mmcr->pic.sl1picmode = 0x80; mmcr->pic.sl2picmode = 0x0; /* and, finally, they do set gp5imap and we don't. */ mmcr->pic.gp5imap = 0xd; /* remaining problem: almost certainly, the irq table is bogus * NO SHOCK as it came from fuctory bios. * but let's try these 4 changes for now and see what shakes. */ /* still not interrupts. */ /* their IRQ table is wrong. Just hardwire it */ { unsigned char pciints[4] = {15, 15, 15, 15}; pci_assign_irqs(0, 12, pciints); } /* the assigned failed but we just noticed -- there is no * dma mapping, and selftest on e100 requires that dma work */ /* follow fuctory here */ mmcr->dmacontrol.extchanmapa = 0x3210; }