/* Initialize IGD OpRegion, called from ACPI code */ int init_igd_opregion(igd_opregion_t *opregion) { device_t igd; u16 reg16; memset((void *)opregion, 0, sizeof(igd_opregion_t)); // FIXME if IGD is disabled, we should exit here. memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE, sizeof(IGD_OPREGION_SIGNATURE)); /* 8kb */ opregion->header.size = sizeof(igd_opregion_t) / 1024; opregion->header.version = IGD_OPREGION_VERSION; // FIXME We just assume we're mobile for now opregion->header.mailboxes = MAILBOXES_MOBILE; // TODO Initialize Mailbox 1 // TODO Initialize Mailbox 3 opregion->mailbox3.bclp = IGD_BACKLIGHT_BRIGHTNESS; opregion->mailbox3.pfit = IGD_FIELD_VALID | IGD_PFIT_STRETCH; opregion->mailbox3.pcft = 0; // should be (IMON << 1) & 0x3e opregion->mailbox3.cblv = IGD_FIELD_VALID | IGD_INITIAL_BRIGHTNESS; opregion->mailbox3.bclm[0] = IGD_WORD_FIELD_VALID + 0x0000; opregion->mailbox3.bclm[1] = IGD_WORD_FIELD_VALID + 0x0a19; opregion->mailbox3.bclm[2] = IGD_WORD_FIELD_VALID + 0x1433; opregion->mailbox3.bclm[3] = IGD_WORD_FIELD_VALID + 0x1e4c; opregion->mailbox3.bclm[4] = IGD_WORD_FIELD_VALID + 0x2866; opregion->mailbox3.bclm[5] = IGD_WORD_FIELD_VALID + 0x327f; opregion->mailbox3.bclm[6] = IGD_WORD_FIELD_VALID + 0x3c99; opregion->mailbox3.bclm[7] = IGD_WORD_FIELD_VALID + 0x46b2; opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc; opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5; opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff; init_opregion_vbt(opregion); /* TODO This needs to happen in S3 resume, too. * Maybe it should move to the finalize handler */ igd = dev_find_slot(0, PCI_DEVFN(0x2, 0)); pci_write_config32(igd, ASLS, (u32)opregion); reg16 = pci_read_config16(igd, SWSCI); reg16 &= ~(1 << 0); reg16 |= (1 << 15); pci_write_config16(igd, SWSCI, reg16); /* clear dmisci status */ reg16 = inw(DEFAULT_PMBASE + TCO1_STS); reg16 |= DMISCI_STS; // reference code does an &= outw(DEFAULT_PMBASE + TCO1_STS, reg16); /* clear acpi tco status */ outl(DEFAULT_PMBASE + GPE0_STS, TCOSCI_STS); /* enable acpi tco scis */ reg16 = inw(DEFAULT_PMBASE + GPE0_EN); reg16 |= TCOSCI_EN; outw(DEFAULT_PMBASE + GPE0_EN, reg16); return 0; }
static void sata_init(struct device *dev) { config_t *config = dev->chip_info; u32 reg32; u16 reg16; u8 reg8; printk(BIOS_DEBUG, "SATA: Initializing...\n"); if (config == NULL) { printk(BIOS_ERR, "SATA: ERROR: Device not in devicetree.cb!\n"); return; } if (!config->sata_ahci) { /* Set legacy or native decoding mode */ if (config->ide_legacy_combined) { reg8 = pci_read_config8(dev, 0x09); reg8 &= ~0x5; pci_write_config8(dev, 0x09, reg8); } else { reg8 = pci_read_config8(dev, 0x09); reg8 |= 0x5; pci_write_config8(dev, 0x09, reg8); } /* Set capabilities pointer */ pci_write_config8(dev, 0x34, 0x70); reg16 = pci_read_config16(dev, 0x70); reg16 &= ~0xFF00; pci_write_config16(dev, 0x70, reg16); } /* Primary timing - decode enable */ reg16 = pci_read_config16(dev, 0x40); reg16 |= 1 << 15; pci_write_config16(dev, 0x40, reg16); /* Secondary timing - decode enable */ reg16 = pci_read_config16(dev, 0x42); reg16 |= 1 << 15; pci_write_config16(dev, 0x42, reg16); /* Port mapping enables */ reg16 = pci_read_config16(dev, 0x90); reg16 |= (config->sata_port_map ^ 0x3) << 8; pci_write_config16(dev, 0x90, reg16); /* Port control enables */ reg16 = pci_read_config16(dev, 0x92); reg16 &= ~0x003f; reg16 |= config->sata_port_map; pci_write_config16(dev, 0x92, reg16); if (config->sata_ahci) { u8 *abar = (u8 *)pci_read_config32(dev, PCI_BASE_ADDRESS_5); /* Enable CR memory space decoding */ reg16 = pci_read_config16(dev, 0x04); reg16 |= 0x2; pci_write_config16(dev, 0x04, reg16); /* Set capability register */ reg32 = read32(abar + 0x00); reg32 |= 0x0c046000; // set PSC+SSC+SALP+SSS+SAM reg32 &= ~0x00f20060; // clear SXS+EMS+PMS+gen bits reg32 |= (0x3 << 20); // Gen3 SATA write32(abar + 0x00, reg32); /* Ports enabled */ reg32 = read32(abar + 0x0c); reg32 &= (u32)(~0x3f); reg32 |= config->sata_port_map; write32(abar + 0xc, reg32); /* Two extra reads to latch */ read32(abar + 0x0c); read32(abar + 0x0c); /* Set cap2 - Support devslp */ reg32 = (1 << 5) | (1 << 4) | (1 << 3); write32(abar + 0x24, reg32); /* Set PxCMD registers */ reg32 = read32(abar + 0x118); reg32 &= ~((1 << 27) | (1 << 26) | (1 << 22) | (1 << 21) | (1 << 19) | (1 << 18) | (1 << 1)); reg32 |= 2; write32(abar + 0x118, reg32); reg32 = read32(abar + 0x198); reg32 &= ~((1 << 27) | (1 << 26) | (1 << 22) | (1 << 21) | (1 << 19) | (1 << 18) | (1 << 1)); reg32 |= 2; write32(abar + 0x198, reg32); /* Clear reset features */ write32(abar + 0xc8, 0); /* Enable interrupts */ reg8 = read8(abar + 0x04); reg8 |= 0x02; write8(abar + 0x04, reg8); } else { /* TODO(shawnn): Configure IDE SATA speed regs */ } /* 1.4 us delay after configuring port / enable bits */ udelay(2); /* Enable clock for ports */ reg32 = pci_read_config32(dev, 0x94); reg32 |= 0x3f << 24; pci_write_config32(dev, 0x94, reg32); reg32 &= (config->sata_port_map ^ 0x3) << 24; pci_write_config32(dev, 0x94, reg32); /* Lock SataGc register */ reg32 = (0x1 << 31) | (0x7 << 12); pci_write_config32(dev, 0x98, reg32); }
static void sata_init(struct device *dev) { u32 dword; struct southbridge_nvidia_ck804_config *conf; conf = dev->chip_info; dword = pci_read_config32(dev, 0x50); /* Ensure prefetch is disabled. */ dword &= ~((1 << 15) | (1 << 13)); if (conf->sata1_enable) { /* Enable secondary SATA interface. */ dword |= (1 << 0); printk(BIOS_DEBUG, "SATA S\t"); } if (conf->sata0_enable) { /* Enable primary SATA interface. */ dword |= (1 << 1); printk(BIOS_DEBUG, "SATA P\n"); } #if 0 /* Write back */ dword |= (1 << 12); dword |= (1 << 14); #endif #if 0 /* ADMA */ dword |= (1 << 16); dword |= (1 << 17); #endif #if 1 /* DO NOT relay OK and PAGE_FRNDLY_DTXFR_CNT. */ dword &= ~(0x1f << 24); dword |= (0x15 << 24); #endif pci_write_config32(dev, 0x50, dword); #if 0 /* SLUMBER_DURING_D3 */ dword = pci_read_config32(dev, 0x7c); dword &= ~(1 << 4); pci_write_config32(dev, 0x7c, dword); dword = pci_read_config32(dev, 0xd0); dword &= ~(0xff << 24); dword |= (0x68 << 24); pci_write_config32(dev, 0xd0, dword); dword = pci_read_config32(dev, 0xe0); dword &= ~(0xff << 24); dword |= (0x68 << 24); pci_write_config32(dev, 0xe0, dword); #endif dword = pci_read_config32(dev, 0xf8); dword |= 2; pci_write_config32(dev, 0xf8, dword); #if CK804_SATA_RESET_FOR_ATAPI dword = pci_read_config32(dev, 0xac); dword &= ~((1 << 13) | (1 << 14)); dword |= (1 << 13) | (0 << 14); pci_write_config32(dev, 0xac, dword); sata_com_reset(dev, 1); /* For discover some s-atapi device. */ #endif }
static void sata_init(struct device *dev) { u8 byte; u16 word; u32 dword; void *sata_bar5; u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4; int i, j; struct southbridge_ati_sb600_config *conf; conf = dev->chip_info; device_t sm_dev; /* SATA SMBus Disable */ /* sm_dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); /* Disable SATA SMBUS */ byte = pci_read_config8(sm_dev, 0xad); byte |= (1 << 1); /* Enable SATA and power saving */ byte = pci_read_config8(sm_dev, 0xad); byte |= (1 << 0); byte |= (1 << 5); pci_write_config8(sm_dev, 0xad, byte); /* Set the interrupt Mapping to INTG# */ byte = pci_read_config8(sm_dev, 0xaf); byte = 0x6 << 2; pci_write_config8(sm_dev, 0xaf, byte); /* get base address */ sata_bar5 = (void *)(pci_read_config32(dev, 0x24) & ~0x3FF); sata_bar0 = pci_read_config16(dev, 0x10) & ~0x7; sata_bar1 = pci_read_config16(dev, 0x14) & ~0x3; sata_bar2 = pci_read_config16(dev, 0x18) & ~0x7; sata_bar3 = pci_read_config16(dev, 0x1C) & ~0x3; sata_bar4 = pci_read_config16(dev, 0x20) & ~0xf; printk(BIOS_SPEW, "sata_bar0=%x\n", sata_bar0); /* 3030 */ printk(BIOS_SPEW, "sata_bar1=%x\n", sata_bar1); /* 3070 */ printk(BIOS_SPEW, "sata_bar2=%x\n", sata_bar2); /* 3040 */ printk(BIOS_SPEW, "sata_bar3=%x\n", sata_bar3); /* 3080 */ printk(BIOS_SPEW, "sata_bar4=%x\n", sata_bar4); /* 3000 */ printk(BIOS_SPEW, "sata_bar5=%p\n", sata_bar5); /* e0309000 */ /* SERR-Enable */ word = pci_read_config16(dev, 0x04); word |= (1 << 8); pci_write_config16(dev, 0x04, word); /* Dynamic power saving */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 2); pci_write_config8(dev, 0x40, byte); /* Set SATA Operation Mode */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 0); byte |= (1 << 4); pci_write_config8(dev, 0x40, byte); // 1 means IDE, 0 means AHCI i = CONFIG_SATA_MODE; get_option(&i, "sata_mode"); printk(BIOS_INFO, "%s: setting sata mode = %s\n", __func__, (i == SATA_MODE_IDE)?"ide":"ahci" ); dword = pci_read_config32(dev, 0x8); dword &= 0xff0000ff; if (i == SATA_MODE_IDE) dword |= 0x00018f00; // IDE mode else dword |= 0x00060100; // AHCI mode pci_write_config32(dev, 0x8, dword); byte = pci_read_config8(dev, 0x40); byte &= ~(1 << 0); pci_write_config8(dev, 0x40, byte); /* Enable the SATA watchdog counter */ byte = pci_read_config8(dev, 0x44); byte |= (1 << 0); pci_write_config8(dev, 0x44, byte); /* Program the watchdog counter to 0x10 */ byte = 0x10; pci_write_config8(dev, 0x46, byte); /* RPR6.5 Program the PHY Global Control to 0x2C00 for A13 */ word = 0x2c00; pci_write_config16(dev, 0x86, word); /* RPR6.5 Program the Phy Tuning4Ports */ dword = 0x00B401D6; pci_write_config32(dev, 0x88, dword); pci_write_config32(dev, 0x8c, dword); pci_write_config32(dev, 0x90, dword); pci_write_config32(dev, 0x94, dword); byte = 0xB8; pci_write_config8(dev, 0xA5, byte); pci_write_config8(dev, 0xAD, byte); pci_write_config8(dev, 0xB5, byte); pci_write_config8(dev, 0xBD, byte); /* RPR 6.8 */ word = pci_read_config16(dev, 0x42); word |= 1 << 7; pci_write_config16(dev, 0x42, word); /* RPR 6.9 */ dword = pci_read_config32(dev, 0x40); dword |= 1 << 25; pci_write_config32(dev, 0x40, dword); /* Enable the I/O, MM, BusMaster access for SATA */ byte = pci_read_config8(dev, 0x4); byte |= 7 << 0; pci_write_config8(dev, 0x4, byte); /* RPR6.6 SATA drive detection. */ /* Use BAR5+0x128,BAR0 for Primary Slave */ /* Use BAR5+0x1A8,BAR0 for Primary Slave */ /* Use BAR5+0x228,BAR2 for Secondary Master */ /* Use BAR5+0x2A8,BAR2 for Secondary Slave */ for (i = 0; i < 4; i++) { byte = read8(sata_bar5 + 0x128 + 0x80 * i); printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte); byte &= 0xF; if( byte == 0x1 ) { /* If the drive status is 0x1 then we see it but we aren't talking to it. */ /* Try to do something about it. */ printk(BIOS_SPEW, "SATA device detected but not talking. Trying lower speed.\n"); /* Read in Port-N Serial ATA Control Register */ byte = read8(sata_bar5 + 0x12C + 0x80 * i); /* Set Reset Bit and 1.5g bit */ byte |= 0x11; write8((sata_bar5 + 0x12C + 0x80 * i), byte); /* Wait 1ms */ mdelay(1); /* Clear Reset Bit */ byte &= ~0x01; write8((sata_bar5 + 0x12C + 0x80 * i), byte); /* Wait 1ms */ mdelay(1); /* Reread status */ byte = read8(sata_bar5 + 0x128 + 0x80 * i); printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte); byte &= 0xF; } if (byte == 0x3) { for (j = 0; j < 10; j++) { if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2)) break; } printk(BIOS_DEBUG, "%s %s device is %sready after %i tries\n", (i / 2) ? "Secondary" : "Primary", (i % 2 ) ? "Slave" : "Master", (j == 10) ? "not " : "", (j == 10) ? j : j + 1); } else { printk(BIOS_DEBUG, "No %s %s SATA drive on Slot%i\n", (i / 2) ? "Secondary" : "Primary", (i % 2 ) ? "Slave" : "Master", i); } } /* Below is CIM InitSataLateFar */ /* Enable interrupts from the HBA */ byte = read8(sata_bar5 + 0x4); byte |= 1 << 1; write8((sata_bar5 + 0x4), byte); /* Clear error status */ write32((sata_bar5 + 0x130), 0xFFFFFFFF); write32((sata_bar5 + 0x1b0), 0xFFFFFFFF); write32((sata_bar5 + 0x230), 0xFFFFFFFF); write32((sata_bar5 + 0x2b0), 0xFFFFFFFF); /* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */ /* ????? why CIM does not set the AcpiGpe0BlkAddr , but use it??? */ /* word = 0x0000; */ /* word = pm_ioread(0x28); */ /* byte = pm_ioread(0x29); */ /* word |= byte<<8; */ /* printk(BIOS_DEBUG, "AcpiGpe0Blk addr = %x\n", word); */ /* write32(word, 0x80000000); */ }
/** * @brief Enable resources for children devices * * @param dev the device whos children's resources are to be enabled * */ void lpc_enable_childrens_resources(device_t dev) { struct bus *link; u32 reg, reg_x; int var_num = 0; u16 reg_var[3]; printk(BIOS_DEBUG, "SB800 - Lpc.c - lpc_enable_childrens_resources - Start.\n"); reg = pci_read_config32(dev, 0x44); reg_x = pci_read_config32(dev, 0x48); for (link = dev->link_list; link; link = link->next) { device_t child; for (child = link->children; child; child = child->sibling) { if (child->enabled && (child->path.type == DEVICE_PATH_PNP)) { struct resource *res; for (res = child->resource_list; res; res = res->next) { u32 base, end; /* don't need long long */ if (!(res->flags & IORESOURCE_IO)) continue; base = res->base; end = resource_end(res); /* printk(BIOS_DEBUG, "sb800 lpc decode:%s, base=0x%08x, end=0x%08x\n", dev_path(child), base, end); */ switch (base) { case 0x60: /* KB */ case 0x64: /* MS */ reg |= (1 << 29); break; case 0x3f8: /* COM1 */ reg |= (1 << 6); break; case 0x2f8: /* COM2 */ reg |= (1 << 7); break; case 0x378: /* Parallal 1 */ reg |= (1 << 0); break; case 0x3f0: /* FD0 */ reg |= (1 << 26); break; case 0x220: /* Aduio 0 */ reg |= (1 << 8); break; case 0x300: /* Midi 0 */ reg |= (1 << 18); break; case 0x400: reg_x |= (1 << 16); break; case 0x480: reg_x |= (1 << 17); break; case 0x500: reg_x |= (1 << 18); break; case 0x580: reg_x |= (1 << 19); break; case 0x4700: reg_x |= (1 << 22); break; case 0xfd60: reg_x |= (1 << 23); break; default: if (var_num >= 3) continue; /* only 3 var ; compact them ? */ switch (var_num) { case 0: reg_x |= (1 << 2); break; case 1: reg_x |= (1 << 24); break; case 2: reg_x |= (1 << 25); break; } reg_var[var_num++] = base & 0xffff; } } } } } pci_write_config32(dev, 0x44, reg); pci_write_config32(dev, 0x48, reg_x); /* Set WideIO for as many IOs found (fall through is on purpose) */ switch (var_num) { case 2: pci_write_config16(dev, 0x90, reg_var[2]); case 1: pci_write_config16(dev, 0x66, reg_var[1]); case 0: //pci_write_config16(dev, 0x64, reg_var[0]); //cause filo can not find sata break; } printk(BIOS_DEBUG, "SB800 - Lpc.c - lpc_enable_childrens_resources - End.\n"); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; struct mb_sysconf_t *m; unsigned sbdn; int i, j, bus_isa; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); sbdn = sysconf.sbdn; m = sysconf.mb; mptable_write_buses(mc, NULL, &bus_isa); /*I/O APICs: APIC ID Version State Address*/ { struct device *dev; struct resource *res; uint32_t dword; dev = dev_find_slot(m->bus_mcp55[0], PCI_DEVFN(sbdn+ 0x1,0)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_1); if (res) { smp_write_ioapic(mc, m->apicid_mcp55, 0x11, res2mmio(res, 0, 0)); } dword = 0x00000ab5; pci_write_config32(dev, 0x7c, dword); dword = 0x5ab0a500; pci_write_config32(dev, 0x80, dword); dword = 0xa000000b; pci_write_config32(dev, 0x84, dword); } } mptable_add_isa_interrupts(mc, bus_isa, m->apicid_mcp55, 0); /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[0], sbdn + 1, 1, m->apicid_mcp55, 0x5); /* 5 SMBus, OK */ smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[0], sbdn + 2, 0, m->apicid_mcp55, 0xb); /* 11 USB, OK */ smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[0], sbdn + 2, 1, m->apicid_mcp55, 0xa); /* 10 USB, OK */ smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[0], sbdn + 5, 0, m->apicid_mcp55, 0x5); /* 5 IDE, OK*/ smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[0], sbdn + 5, 1, m->apicid_mcp55, 0xa); /* 10 IDE, OK*/ smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[0], sbdn + 5, 2, m->apicid_mcp55, 0xa); /* 10 IDE, OK*/ smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[0], sbdn + 6, 1, m->apicid_mcp55, 0xa); /* 10 VGA, OK*/ smp_write_pci_intsrc(mc, mp_INT, m->bus_8132_2, 3, 0, m->apicid_mcp55, 0x5); /* 5 eth0, OK*/ smp_write_pci_intsrc(mc, mp_INT, m->bus_8132_2, 3, 1, m->apicid_mcp55, 0xb); /* 11 eth1, OK*/ for(j = 7;j >= 2; j--) { if(!m->bus_mcp55[j]) continue; for(i = 0; i < 4; i++) { smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[j], 0x00, i, m->apicid_mcp55, 0x10 + (2+j+i+4-sbdn%4)%4); } } for(j = 0; j < 1; j++) for(i = 0; i < 4; i++) { smp_write_pci_intsrc(mc, mp_INT, m->bus_mcp55[1], 0x04+j, i, m->apicid_mcp55, 0x10 + (2+i+j)%4); } /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ mptable_lintsrc(mc, bus_isa); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; unsigned sbdn; get_bus_conf(); sbdn = sysconf.sbdn; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LAPIC_ADDR); smp_write_processors(mc); mptable_write_buses(mc, NULL, &bus_isa); /* I/O APICs: APIC ID Version State Address*/ { device_t dev; struct resource *res; u32 dword; dev = dev_find_slot(bus_ck804[0], PCI_DEVFN(sbdn + 0x1, 0)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_1); if (res) { smp_write_ioapic(mc, apicid_ck804, 0x11, res->base); } /* Initialize interrupt mapping */ /* copied from stock bios */ /*0x01800500,0x1800d509,0x00520d08*/ dword = 0x08d0d218; pci_write_config32(dev, 0x7c, dword); dword = 0x8d001509; pci_write_config32(dev, 0x80, dword); dword = 0x00010271; pci_write_config32(dev, 0x84, dword); } } /* Now, assemble the table. */ mptable_add_isa_interrupts(mc, bus_isa, apicid_ck804, 0); #define PCI_INT(bus, dev, fn, pin) \ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, \ bus_ck804[bus], (((dev)<<2)|(fn)), apicid_ck804, (pin)) #if 0 // Onboard ck804 smbus PCI_INT(0, sbdn+1, 1, 10); /* (this seems odd, how to test?) */ #endif // Onboard ck804 USB PCI_INT(0, sbdn+2, 0, 23); PCI_INT(0, sbdn+2, 1, 23); // Onboard ck804 AC-97 PCI_INT(0, sbdn+4, 0, 23); // Onboard ck804 SATA 0 PCI_INT(0, sbdn+7, 0, 20); // Onboard ck804 SATA 1 PCI_INT(0, sbdn+8, 0, 21); // Onboard ck804 NIC PCI_INT(0, sbdn+10, 0, 22); /* "AGR" slot */ PCI_INT(1, 0, 0, 16); PCI_INT(1, 0, 1, 17); /* legacy PCI */ PCI_INT(1, 7, 0, 17); PCI_INT(1, 7, 1, 18); PCI_INT(1, 7, 2, 19); PCI_INT(1, 7, 3, 16); PCI_INT(1, 8, 0, 18); PCI_INT(1, 8, 1, 19); PCI_INT(1, 8, 2, 16); PCI_INT(1, 8, 3, 17); PCI_INT(1, 9, 0, 19); PCI_INT(1, 9, 1, 16); PCI_INT(1, 9, 2, 17); PCI_INT(1, 9, 3, 18); /* PCI-E x1 port */ PCI_INT(2, 0, 0, 19); /* XXX guesses */ PCI_INT(2, 0, 1, 16); PCI_INT(2, 0, 2, 17); PCI_INT(2, 0, 3, 18); /* PCI-E x16 port */ /* XXX fix me ? */ PCI_INT(3, 0, 0, 18); /* XXX guesses */ PCI_INT(3, 0, 1, 19); PCI_INT(3, 0, 2, 16); PCI_INT(3, 0, 3, 17); /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ mptable_lintsrc(mc, bus_ck804[0]); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
static void serialio_init(struct device *dev) { struct southbridge_intel_lynxpoint_config *config = dev->chip_info; struct resource *bar0, *bar1; int sio_index = -1; u32 reg32; printk(BIOS_DEBUG, "Initializing Serial IO device\n"); /* Ensure memory and bus master are enabled */ reg32 = pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; pci_write_config32(dev, PCI_COMMAND, reg32); /* Find BAR0 and BAR1 */ bar0 = find_resource(dev, PCI_BASE_ADDRESS_0); if (!bar0) return; bar1 = find_resource(dev, PCI_BASE_ADDRESS_1); if (!bar1) return; if (!config->sio_acpi_mode) serialio_enable_clock(bar0); switch (dev->path.pci.devfn) { case PCI_DEVFN(21, 0): /* SDMA */ sio_index = SIO_ID_SDMA; serialio_init_once(config->sio_acpi_mode); serialio_d21_mode(sio_index, SIO_PIN_INTB, config->sio_acpi_mode); break; case PCI_DEVFN(21, 1): /* I2C0 */ sio_index = SIO_ID_I2C0; serialio_d21_ltr(bar0); serialio_i2c_voltage_sel(bar0, config->sio_i2c0_voltage); serialio_d21_mode(sio_index, SIO_PIN_INTC, config->sio_acpi_mode); break; case PCI_DEVFN(21, 2): /* I2C1 */ sio_index = SIO_ID_I2C1; serialio_d21_ltr(bar0); serialio_i2c_voltage_sel(bar0, config->sio_i2c1_voltage); serialio_d21_mode(sio_index, SIO_PIN_INTC, config->sio_acpi_mode); break; case PCI_DEVFN(21, 3): /* SPI0 */ sio_index = SIO_ID_SPI0; serialio_d21_ltr(bar0); serialio_d21_mode(sio_index, SIO_PIN_INTC, config->sio_acpi_mode); break; case PCI_DEVFN(21, 4): /* SPI1 */ sio_index = SIO_ID_SPI1; serialio_d21_ltr(bar0); serialio_d21_mode(sio_index, SIO_PIN_INTC, config->sio_acpi_mode); break; case PCI_DEVFN(21, 5): /* UART0 */ sio_index = SIO_ID_UART0; serialio_d21_ltr(bar0); serialio_d21_mode(sio_index, SIO_PIN_INTD, config->sio_acpi_mode); break; case PCI_DEVFN(21, 6): /* UART1 */ sio_index = SIO_ID_UART1; serialio_d21_ltr(bar0); serialio_d21_mode(sio_index, SIO_PIN_INTD, config->sio_acpi_mode); break; case PCI_DEVFN(23, 0): /* SDIO */ sio_index = SIO_ID_SDIO; serialio_d23_ltr(bar0); serialio_d23_mode(config->sio_acpi_mode); break; default: return; } if (config->sio_acpi_mode) { global_nvs_t *gnvs; /* Find ACPI NVS to update BARs */ gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS); if (!gnvs) { printk(BIOS_ERR, "Unable to locate Global NVS\n"); return; } /* Save BAR0 and BAR1 to ACPI NVS */ gnvs->s0b[sio_index] = (u32)bar0->base; gnvs->s1b[sio_index] = (u32)bar1->base; } }
static void usb_xhci_init(device_t dev) { u32 reg32; u16 reg16; u32 mem_base = usb_xhci_mem_base(dev); config_t *config = dev->chip_info; /* D20:F0:74h[1:0] = 00b (set D0 state) */ reg16 = pci_read_config16(dev, XHCI_PWR_CTL_STS); reg16 &= ~PWR_CTL_SET_MASK; reg16 |= PWR_CTL_SET_D0; pci_write_config16(dev, XHCI_PWR_CTL_STS, reg16); /* Enable clock gating first */ usb_xhci_clock_gating(dev); reg32 = read32(mem_base + 0x8144); if (pch_is_lp()) { /* XHCIBAR + 8144h[8,7,6] = 111b */ reg32 |= (1 << 8) | (1 << 7) | (1 << 6); } else { /* XHCIBAR + 8144h[8,7,6] = 100b */ reg32 &= ~((1 << 7) | (1 << 6)); reg32 |= (1 << 8); } write32(mem_base + 0x8144, reg32); if (pch_is_lp()) { /* XHCIBAR + 816Ch[19:0] = 000e0038h */ reg32 = read32(mem_base + 0x816c); reg32 &= ~0x000fffff; reg32 |= 0x000e0038; write32(mem_base + 0x816c, reg32); /* D20:F0:B0h[17,14,13] = 100b */ reg32 = pci_read_config32(dev, 0xb0); reg32 &= ~((1 << 14) | (1 << 13)); reg32 |= (1 << 17); pci_write_config32(dev, 0xb0, reg32); } reg32 = pci_read_config32(dev, 0x50); if (pch_is_lp()) { /* D20:F0:50h[28:0] = 0FCE2E5Fh */ reg32 &= ~0x1fffffff; reg32 |= 0x0fce2e5f; } else { /* D20:F0:50h[26:0] = 07886E9Fh */ reg32 &= ~0x07ffffff; reg32 |= 0x07886e9f; } pci_write_config32(dev, 0x50, reg32); /* D20:F0:44h[31] = 1 (Access Control Bit) */ reg32 = pci_read_config32(dev, 0x44); reg32 |= (1 << 31); pci_write_config32(dev, 0x44, reg32); /* D20:F0:40h[31,23] = 10b (OC Configuration Done) */ reg32 = pci_read_config32(dev, 0x40); reg32 &= ~(1 << 23); /* unsupported request */ reg32 |= (1 << 31); pci_write_config32(dev, 0x40, reg32); #if CONFIG_HAVE_ACPI_RESUME if (acpi_slp_type == 3) { /* Reset ports that are disabled or * polling before returning to the OS. */ usb_xhci_reset_usb3(dev, 0); } else #endif /* Route all ports to XHCI */ if (config->xhci_default) outb(0xca, 0xb2); }
static void pci_init(struct device *dev) { u16 reg16; u32 reg32; printk(BIOS_DEBUG, "Initializing ICH9 PCIe root port.\n"); /* Enable Bus Master */ reg32 = pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER; pci_write_config32(dev, PCI_COMMAND, reg32); /* Set Cache Line Size to 0x10 */ // This has no effect but the OS might expect it pci_write_config8(dev, 0x0c, 0x10); reg16 = pci_read_config16(dev, 0x3e); reg16 &= ~(1 << 0); /* disable parity error response */ reg16 |= (1 << 2); /* ISA enable */ pci_write_config16(dev, 0x3e, reg16); /* Enable IO xAPIC on this PCIe port */ reg32 = pci_read_config32(dev, 0xd8); reg32 |= (1 << 7); pci_write_config32(dev, 0xd8, reg32); /* Enable Backbone Clock Gating */ reg32 = pci_read_config32(dev, 0xe1); reg32 |= (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); pci_write_config32(dev, 0xe1, reg32); /* Set VC0 transaction class */ reg32 = pci_read_config32(dev, 0x114); reg32 &= 0xffffff00; reg32 |= 1; pci_write_config32(dev, 0x114, reg32); /* Mask completion timeouts */ reg32 = pci_read_config32(dev, 0x148); reg32 |= (1 << 14); pci_write_config32(dev, 0x148, reg32); /* Lock R/WO Correctable Error Mask. */ pci_write_config32(dev, 0x154, pci_read_config32(dev, 0x154)); /* Clear errors in status registers */ reg16 = pci_read_config16(dev, 0x06); pci_write_config16(dev, 0x06, reg16); reg16 = pci_read_config16(dev, 0x1e); pci_write_config16(dev, 0x1e, reg16); /* Get configured ASPM state */ const enum aspm_type apmc = pci_read_config32(dev, 0x50) & 3; /* If both L0s and L1 enabled then set root port 0xE8[1]=1 */ if (apmc == PCIE_ASPM_BOTH) { reg32 = pci_read_config32(dev, 0xe8); reg32 |= (1 << 1); pci_write_config32(dev, 0xe8, reg32); } }
static void gpio_init(device_t dev) { pci_write_config32(dev, GPIO_BASE, (GPIO_BASE_ADDR | 1)); pci_write_config8(dev, GPIO_CNTL, GPIO_EN); }
static void pch_pcie_pm_early(struct device *dev) { u16 link_width_p0, link_width_p4; u8 slot_power_limit = 10; /* 10W for x1 */ u32 reg32; u8 reg8; reg32 = RCBA32(RPC); /* Port 0-3 link aggregation from PCIEPCS1[1:0] soft strap */ switch (reg32 & 3) { case 3: link_width_p0 = 4; break; case 1: case 2: link_width_p0 = 2; break; case 0: default: link_width_p0 = 1; } /* Port 4-7 link aggregation from PCIEPCS2[1:0] soft strap */ switch ((reg32 >> 2) & 3) { case 3: link_width_p4 = 4; break; case 1: case 2: link_width_p4 = 2; break; case 0: default: link_width_p4 = 1; } /* Enable dynamic clock gating where needed */ reg8 = pci_read_config8(dev, 0xe1); switch (PCI_FUNC(dev->path.pci.devfn)) { case 0: /* Port 0 */ if (link_width_p0 == 4) slot_power_limit = 40; /* 40W for x4 */ else if (link_width_p0 == 2) slot_power_limit = 20; /* 20W for x2 */ reg8 |= 0x3f; break; case 4: /* Port 4 */ if (link_width_p4 == 4) slot_power_limit = 40; /* 40W for x4 */ else if (link_width_p4 == 2) slot_power_limit = 20; /* 20W for x2 */ reg8 |= 0x3f; break; case 1: /* Port 1 only if Port 0 is x1 */ if (link_width_p0 == 1) reg8 |= 0x3; break; case 2: /* Port 2 only if Port 0 is x1 or x2 */ case 3: /* Port 3 only if Port 0 is x1 or x2 */ if (link_width_p0 <= 2) reg8 |= 0x3; break; case 5: /* Port 5 only if Port 4 is x1 */ if (link_width_p4 == 1) reg8 |= 0x3; break; case 6: /* Port 7 only if Port 4 is x1 or x2 */ case 7: /* Port 7 only if Port 4 is x1 or x2 */ if (link_width_p4 <= 2) reg8 |= 0x3; break; } pci_write_config8(dev, 0xe1, reg8); /* Set 0xE8[0] = 1 */ reg32 = pci_read_config32(dev, 0xe8); reg32 |= 1; pci_write_config32(dev, 0xe8, reg32); /* Adjust Common Clock exit latency */ reg32 = pci_read_config32(dev, 0xd8); reg32 &= ~(1 << 17); reg32 |= (1 << 16) | (1 << 15); reg32 &= ~(1 << 31); /* Disable PME# SCI for native PME handling */ pci_write_config32(dev, 0xd8, reg32); /* Adjust ASPM L1 exit latency */ reg32 = pci_read_config32(dev, 0x4c); reg32 &= ~((1 << 17) | (1 << 16) | (1 << 15)); if (RCBA32(0x2320) & (1 << 16)) { /* If RCBA+2320[15]=1 set ASPM L1 to 8-16us */ reg32 |= (1 << 17); } else { /* Else set ASPM L1 to 2-4us */ reg32 |= (1 << 16); } pci_write_config32(dev, 0x4c, reg32); /* Set slot power limit as configured above */ reg32 = pci_read_config32(dev, 0x54); reg32 &= ~((1 << 15) | (1 << 16)); /* 16:15 = Slot power scale */ reg32 &= ~(0xff << 7); /* 14:7 = Slot power limit */ reg32 |= (slot_power_limit << 7); pci_write_config32(dev, 0x54, reg32); }
static void pch_pcie_pm_late(struct device *dev) { struct southbridge_intel_bd82x6x_config *config = dev->chip_info; enum aspm_type apmc = 0; u32 reg32; /* Set 0x314 = 0x743a361b */ pci_write_config32(dev, 0x314, 0x743a361b); /* Set 0x318[31:16] = 0x1414 */ reg32 = pci_read_config32(dev, 0x318); reg32 &= 0x0000ffff; reg32 |= 0x14140000; pci_write_config32(dev, 0x318, reg32); /* Set 0x324[5] = 1 */ reg32 = pci_read_config32(dev, 0x324); reg32 |= (1 << 5); pci_write_config32(dev, 0x324, reg32); /* Set 0x330[7:0] = 0x40 */ reg32 = pci_read_config32(dev, 0x330); reg32 &= ~(0xff); reg32 |= 0x40; pci_write_config32(dev, 0x330, reg32); /* Set 0x33C[24:0] = 0x854c74 */ reg32 = pci_read_config32(dev, 0x33c); reg32 &= 0xff000000; reg32 |= 0x00854c74; pci_write_config32(dev, 0x33c, reg32); /* No IO-APIC, Disable EOI forwarding */ reg32 = pci_read_config32(dev, 0xd4); reg32 |= (1 << 1); pci_write_config32(dev, 0xd4, reg32); /* Check for a rootport ASPM override */ switch (PCI_FUNC(dev->path.pci.devfn)) { case 0: apmc = config->pcie_aspm_f0; break; case 1: apmc = config->pcie_aspm_f1; break; case 2: apmc = config->pcie_aspm_f2; break; case 3: apmc = config->pcie_aspm_f3; break; case 4: apmc = config->pcie_aspm_f4; break; case 5: apmc = config->pcie_aspm_f5; break; case 6: apmc = config->pcie_aspm_f6; break; case 7: apmc = config->pcie_aspm_f7; break; } /* Setup the override or get the real ASPM setting */ if (apmc) { reg32 = pci_read_config32(dev, 0xd4); reg32 |= (apmc << 2) | (1 << 4); pci_write_config32(dev, 0xd4, reg32); } else { apmc = pci_read_config32(dev, 0x50) & 3; } /* If both L0s and L1 enabled then set root port 0xE8[1]=1 */ if (apmc == PCIE_ASPM_BOTH) { reg32 = pci_read_config32(dev, 0xe8); reg32 |= (1 << 1); pci_write_config32(dev, 0xe8, reg32); } }
static void pci_init(struct device *dev) { u16 reg16; u32 reg32; printk(BIOS_DEBUG, "Initializing ICH7 PCIe bridge.\n"); /* Enable Bus Master */ reg32 = pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER; pci_write_config32(dev, PCI_COMMAND, reg32); /* Set Cache Line Size to 0x10 */ // This has no effect but the OS might expect it pci_write_config8(dev, 0x0c, 0x10); reg16 = pci_read_config16(dev, 0x3e); reg16 &= ~(1 << 0); /* disable parity error response */ // reg16 &= ~(1 << 1); /* disable SERR */ reg16 |= (1 << 2); /* ISA enable */ pci_write_config16(dev, 0x3e, reg16); /* Enable IO xAPIC on this PCIe port */ reg32 = pci_read_config32(dev, 0xd8); reg32 |= (1 << 7); pci_write_config32(dev, 0xd8, reg32); /* Enable Backbone Clock Gating */ reg32 = pci_read_config32(dev, 0xe1); reg32 |= (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); pci_write_config32(dev, 0xe1, reg32); #if CONFIG_MMCONF_SUPPORT /* Set VC0 transaction class */ reg32 = pci_mmio_read_config32(dev, 0x114); reg32 &= 0xffffff00; reg32 |= 1; pci_mmio_write_config32(dev, 0x114, reg32); /* Mask completion timeouts */ reg32 = pci_mmio_read_config32(dev, 0x148); reg32 |= (1 << 14); pci_mmio_write_config32(dev, 0x148, reg32); #else #error "MMIO needed for ICH7 PCIe" #endif /* Enable common clock configuration */ // Are there cases when we don't want that? reg16 = pci_read_config16(dev, 0x50); reg16 |= (1 << 6); pci_write_config16(dev, 0x50, reg16); #ifdef EVEN_MORE_DEBUG reg32 = pci_read_config32(dev, 0x20); printk(BIOS_SPEW, " MBL = 0x%08x\n", reg32); reg32 = pci_read_config32(dev, 0x24); printk(BIOS_SPEW, " PMBL = 0x%08x\n", reg32); reg32 = pci_read_config32(dev, 0x28); printk(BIOS_SPEW, " PMBU32 = 0x%08x\n", reg32); reg32 = pci_read_config32(dev, 0x2c); printk(BIOS_SPEW, " PMLU32 = 0x%08x\n", reg32); #endif /* Clear errors in status registers */ reg16 = pci_read_config16(dev, 0x06); //reg16 |= 0xf900; pci_write_config16(dev, 0x06, reg16); reg16 = pci_read_config16(dev, 0x1e); //reg16 |= 0xf900; pci_write_config16(dev, 0x1e, reg16); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; u32 apicid_sp5100; u32 apicid_sr5650; device_t dev; u32 dword; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); get_bus_conf(); mptable_write_buses(mc, NULL, &bus_isa); /* * AGESA v5 Apply apic enumeration rules * For systems with >= 16 APICs, put the IO-APICs at 0..n and * put the local-APICs at m..z * For systems with < 16 APICs, put the Local-APICs at 0..n and * put the IO-APICs at (n + 1)..z */ #if CONFIG_MAX_CPUS >= 16 apicid_sp5100 = 0x0; #else apicid_sp5100 = CONFIG_MAX_CPUS + 1 #endif apicid_sr5650 = apicid_sp5100 + 1; dev = dev_find_slot(0, PCI_DEVFN(sbdn_sp5100 + 0x14, 0)); if (dev) { /* Set SP5100 IOAPIC ID */ dword = pci_read_config32(dev, 0x74) & 0xfffffff0; smp_write_ioapic(mc, apicid_sp5100, 0x20, dword); #ifdef UNUSED_CODE u8 byte; /* Initialize interrupt mapping */ /* aza */ byte = pci_read_config8(dev, 0x63); byte &= 0xf8; byte |= 0; /* 0: INTA, ...., 7: INTH */ pci_write_config8(dev, 0x63, byte); /* SATA */ dword = pci_read_config32(dev, 0xAC); dword &= ~(7 << 26); dword |= 6 << 26; /* 0: INTA, ...., 7: INTH */ /* dword |= 1<<22; PIC and APIC co exists */ pci_write_config32(dev, 0xAC, dword); #endif /* * 00:12.0: PROG SATA : INT F * 00:13.0: INTA USB_0 * 00:13.1: INTB USB_1 * 00:13.2: INTC USB_2 * 00:13.3: INTD USB_3 * 00:13.4: INTC USB_4 * 00:13.5: INTD USB2 * 00:14.1: INTA IDE * 00:14.2: Prog HDA : INT E * 00:14.5: INTB ACI * 00:14.6: INTB MCI */ /* Set RS5650 IOAPIC ID */ dev = dev_find_slot(0, PCI_DEVFN(0, 0)); if (dev) { pci_write_config32(dev, 0xF8, 0x1); dword = pci_read_config32(dev, 0xFC) & 0xfffffff0; smp_write_ioapic(mc, apicid_sr5650, 0x20, dword); } } /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ #define IO_LOCAL_INT(type, intr, apicid, pin) \ smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); mptable_add_isa_interrupts(mc, bus_isa, apicid_sp5100, 0); /* PCI interrupts are level triggered, and are * associated with a specific bus/device/function tuple. */ #define PCI_INT(bus, dev, int_sign, pin) \ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(int_sign)), apicid_sp5100, (pin)) /* SMBUS */ //PCI_INT(0x0, 0x14, 0x0, 0x10); //not generate interrupt, 3Ch hardcoded to 0 /* HD Audio */ PCI_INT(0x0, 0x14, 0x2, 0x10); /* USB */ /* OHCI0, OHCI1 hard-wired to 01h, corresponding to using INTA# */ /* EHCI hard-wired to 02h, corresponding to using INTB# */ /* USB1 */ PCI_INT(0x0, 0x12, 0x0, 0x10); /* OHCI0 Port 0~2 */ PCI_INT(0x0, 0x12, 0x1, 0x10); /* OHCI1 Port 3~5 */ PCI_INT(0x0, 0x12, 0x2, 0x11); /* EHCI Port 0~5 */ /* USB2 */ PCI_INT(0x0, 0x13, 0x0, 0x10); /* OHCI0 Port 6~8 */ PCI_INT(0x0, 0x13, 0x1, 0x10); /* OHCI1 Port 9~11 */ PCI_INT(0x0, 0x13, 0x2, 0x11); /* EHCI Port 6~11 */ /* USB3 EHCI hard-wired to 03h, corresponding to using INTC# */ PCI_INT(0x0, 0x14, 0x5, 0x12); /* OHCI0 Port 12~13 */ /* SATA */ PCI_INT(0x0, 0x11, 0x0, 0x16); //6, INTG /* on board NIC & Slot PCIE. */ /* configuration B doesnt need dev 5,6,7 */ /* * PCI_INT(bus_sr5650[0x5], 0x0, 0x0, 0x11); * PCI_INT(bus_sr5650[0x6], 0x0, 0x0, 0x12); * PCI_INT(bus_sr5650[0x7], 0x0, 0x0, 0x13); */ //smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0, (((13)<<2)|(0)), apicid_sr5650, 28); /* dev d */ //smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sr5650[13], (((0)<<2)|(1)), apicid_sr5650, 0); /* card behind dev13 */ /* PCI slots */ /* PCI_SLOT 0. */ PCI_INT(bus_sp5100[1], 0x5, 0x0, 0x14); PCI_INT(bus_sp5100[1], 0x5, 0x1, 0x15); PCI_INT(bus_sp5100[1], 0x5, 0x2, 0x16); PCI_INT(bus_sp5100[1], 0x5, 0x3, 0x17); /* PCI_SLOT 1. */ PCI_INT(bus_sp5100[1], 0x6, 0x0, 0x15); PCI_INT(bus_sp5100[1], 0x6, 0x1, 0x16); PCI_INT(bus_sp5100[1], 0x6, 0x2, 0x17); PCI_INT(bus_sp5100[1], 0x6, 0x3, 0x14); /* PCI_SLOT 2. */ PCI_INT(bus_sp5100[1], 0x7, 0x0, 0x16); PCI_INT(bus_sp5100[1], 0x7, 0x1, 0x17); PCI_INT(bus_sp5100[1], 0x7, 0x2, 0x14); PCI_INT(bus_sp5100[1], 0x7, 0x3, 0x15); /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ IO_LOCAL_INT(mp_ExtINT, 0, MP_APIC_ALL, 0x0); IO_LOCAL_INT(mp_NMI, 0, MP_APIC_ALL, 0x1); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
void main(unsigned long bist) { int s3resume = 0; int dock_err; const u8 spd_addrmap[2 * DIMM_SOCKETS] = { 0x50, 0x52, 0x51, 0x53 }; timestamp_init(get_initial_timestamp()); timestamp_add_now(TS_START_ROMSTAGE); if (bist == 0) enable_lapic(); /* Force PCIRST# */ pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, SBR); udelay(200 * 1000); pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, 0); ich7_enable_lpc(); /* We want early GPIO setup, to be able to detect legacy I/O module */ pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIOBASE, DEFAULT_GPIOBASE | 1); /* Enable GPIOs */ pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x4c /* GC */ , 0x10); setup_ich7_gpios(); dock_err = dlpc_init(); /* We prefer Legacy I/O module over docking */ if (legacy_io_present()) { legacy_io_init(); early_superio_config(); } else if (!dock_err && dock_present()) { dock_connect(); early_superio_config(); } /* Setup the console */ console_init(); /* Halt if there was a built in self test failure */ report_bist_failure(bist); if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); outb(0x6, 0xcf9); halt(); } /* Perform some early chipset initialization required * before RAM initialization can work */ i945_early_initialization(); s3resume = southbridge_detect_s3_resume(); /* Enable SPD ROMs and DDR-II DRAM */ enable_smbus(); #if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8 dump_spd_registers(); #endif timestamp_add_now(TS_BEFORE_INITRAM); sdram_initialize(s3resume ? 2 : 0, spd_addrmap); timestamp_add_now(TS_AFTER_INITRAM); /* Perform some initialization that must run before stage2 */ early_ich7_init(); /* This should probably go away. Until now it is required * and mainboard specific */ rcba_config(); /* Chipset Errata! */ fixup_i945_errata(); /* Initialize the internal PCIe links before we go into stage2 */ i945_late_initialization(s3resume); timestamp_add_now(TS_END_ROMSTAGE); }
static void map_rcba(void) { pci_write_config32(PCH_DEV_LPC, RCBA, RCBA_BASE_ADDRESS | 1); }
static void azalia_init(struct device *dev) { u32 base; struct resource *res; u32 codec_mask; u8 reg8; u16 reg16; u32 reg32; /* Find base address */ res = find_resource(dev, PCI_BASE_ADDRESS_0); if (!res) return; // NOTE this will break as soon as the Azalia get's a bar above // 4G. Is there anything we can do about it? base = (u32)res->base; printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base); if (RCBA32(0x2030) & (1 << 31)) { reg32 = pci_read_config32(dev, 0x120); reg32 &= 0xf8ffff01; reg32 |= (1 << 24); // 2 << 24 for server reg32 |= RCBA32(0x2030) & 0xfe; pci_write_config32(dev, 0x120, reg32); reg16 = pci_read_config16(dev, 0x78); reg16 |= (1 << 11); pci_write_config16(dev, 0x78, reg16); } else printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n"); reg32 = pci_read_config32(dev, 0x114); reg32 &= ~0xfe; pci_write_config32(dev, 0x114, reg32); // Set VCi enable bit reg32 = pci_read_config32(dev, 0x120); reg32 |= (1 << 31); pci_write_config32(dev, 0x120, reg32); // Enable HDMI codec: reg32 = pci_read_config32(dev, 0xc4); reg32 |= (1 << 1); pci_write_config32(dev, 0xc4, reg32); reg8 = pci_read_config8(dev, 0x43); reg8 |= (1 << 6); pci_write_config8(dev, 0x43, reg8); /* Additional programming steps */ reg32 = pci_read_config32(dev, 0xc4); reg32 |= (1 << 13); pci_write_config32(dev, 0xc4, reg32); reg32 = pci_read_config32(dev, 0xc4); reg32 |= (1 << 10); pci_write_config32(dev, 0xc4, reg32); reg32 = pci_read_config32(dev, 0xd0); reg32 &= ~(1 << 31); pci_write_config32(dev, 0xd0, reg32); if (dev->device == 0x1e20) { /* Additional step on Panther Point */ reg32 = pci_read_config32(dev, 0xc4); reg32 |= (1 << 17); pci_write_config32(dev, 0xc4, reg32); } /* Set Bus Master */ reg32 = pci_read_config32(dev, PCI_COMMAND); pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER); pci_write_config8(dev, 0x3c, 0x0a); // unused? /* Codec Initialization Programming Sequence */ /* Take controller out of reset */ reg32 = read32(base + 0x08); reg32 |= (1 << 0); write32(base + 0x08, reg32); /* Wait 1ms */ udelay(1000); // reg8 = pci_read_config8(dev, 0x40); // Audio Control reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb pci_write_config8(dev, 0x40, reg8); reg8 = pci_read_config8(dev, 0x4d); // Docking Status reg8 &= ~(1 << 7); // Docking not supported pci_write_config8(dev, 0x4d, reg8); codec_mask = codec_detect(base); if (codec_mask) { printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask); codecs_init(dev, base, codec_mask); } /* Enable dynamic clock gating */ reg8 = pci_read_config8(dev, 0x43); reg8 &= ~0x7; reg8 |= (1 << 2) | (1 << 0); pci_write_config8(dev, 0x43, reg8); }
void main(unsigned long bist) { int s3resume = 0; spd_raw_data spd[4]; if (MCHBAR16(SSKPD) == 0xCAFE) { outb(0x6, 0xcf9); halt (); } timestamp_init(get_initial_timestamp()); timestamp_add_now(TS_START_ROMSTAGE); if (bist == 0) enable_lapic(); pch_enable_lpc(); /* Enable GPIOs */ pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE|1); pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10); setup_pch_gpios(&mainboard_gpio_map); early_usb_init(mainboard_usb_ports); /* Initialize console device(s) */ console_init(); /* Halt if there was a built in self test failure */ report_bist_failure(bist); /* Perform some early chipset initialization required * before RAM initialization can work */ sandybridge_early_initialization(SANDYBRIDGE_MOBILE); printk(BIOS_DEBUG, "Back from sandybridge_early_initialization()\n"); s3resume = southbridge_detect_s3_resume(); post_code(0x38); /* Enable SPD ROMs and DDR-III DRAM */ enable_smbus(); post_code(0x39); post_code(0x3a); memset (spd, 0, sizeof (spd)); mainboard_get_spd(spd); timestamp_add_now(TS_BEFORE_INITRAM); init_dram_ddr3(spd, 1, get_mem_min_tck(), s3resume); timestamp_add_now(TS_AFTER_INITRAM); post_code(0x3c); southbridge_configure_default_intmap(); rcba_config(); post_code(0x3d); northbridge_romstage_finalize(s3resume); #if CONFIG_LPC_TPM init_tpm(s3resume); #endif post_code(0x3f); }
void mdr_write(uint32_t value) { pci_write_config32(MC_BDF, QNC_ACCESS_PORT_MDR, value); }
void main(unsigned long bist) { int boot_mode = 0; int cbmem_was_initted; struct pei_data pei_data = { .pei_version = PEI_VERSION, .mchbar = (uintptr_t)DEFAULT_MCHBAR, .dmibar = (uintptr_t)DEFAULT_DMIBAR, .epbar = DEFAULT_EPBAR, .pciexbar = CONFIG_MMCONF_BASE_ADDRESS, .smbusbar = SMBUS_IO_BASE, .wdbbar = 0x4000000, .wdbsize = 0x1000, .hpet_address = CONFIG_HPET_ADDRESS, .rcba = (uintptr_t)DEFAULT_RCBABASE, .pmbase = DEFAULT_PMBASE, .gpiobase = DEFAULT_GPIOBASE, .thermalbase = 0xfed08000, .system_type = 0, // 0 Mobile, 1 Desktop/Server .tseg_size = CONFIG_SMM_TSEG_SIZE, .spd_addresses = { 0xa0, 0x00, 0xa4, 0x00 }, .ts_addresses = { 0x00, 0x00, 0x00, 0x00 }, .ec_present = 0, // 0 = leave channel enabled // 1 = disable dimm 0 on channel // 2 = disable dimm 1 on channel // 3 = disable dimm 0+1 on channel .dimm_channel0_disabled = 2, .dimm_channel1_disabled = 2, .max_ddr3_freq = 1600, .usb_port_config = { { 1, 0, 0x0040 }, /* P0: Front port (OC0) */ { 1, 1, 0x0040 }, /* P1: Back port (OC1) */ { 1, 0, 0x0040 }, /* P2: MINIPCIE1 (no OC) */ { 1, 0, 0x0040 }, /* P3: MMC (no OC) */ { 1, 2, 0x0040 }, /* P4: Front port (OC2) */ { 0, 0, 0x0000 }, /* P5: Empty */ { 0, 0, 0x0000 }, /* P6: Empty */ { 0, 0, 0x0000 }, /* P7: Empty */ { 1, 4, 0x0040 }, /* P8: Back port (OC4) */ { 1, 4, 0x0040 }, /* P9: MINIPCIE3 (no OC) */ { 1, 4, 0x0040 }, /* P10: BLUETOOTH (no OC) */ { 0, 4, 0x0000 }, /* P11: Empty */ { 1, 6, 0x0040 }, /* P12: Back port (OC6) */ { 1, 5, 0x0040 }, /* P13: Back port (OC5) */ }, }; timestamp_init(get_initial_timestamp()); timestamp_add_now(TS_START_ROMSTAGE); if (bist == 0) enable_lapic(); pch_enable_lpc(); /* Enable GPIOs */ pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE|1); pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10); setup_pch_gpios(&emeraldlake2_gpio_map); setup_sio_gpios(); /* Early SuperIO setup */ console_init(); /* Halt if there was a built in self test failure */ report_bist_failure(bist); if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "soft reset detected\n"); boot_mode = 1; /* System is not happy after keyboard reset... */ printk(BIOS_DEBUG, "Issuing CF9 warm reset\n"); outb(0x6, 0xcf9); halt(); } /* Perform some early chipset initialization required * before RAM initialization can work */ sandybridge_early_initialization(SANDYBRIDGE_MOBILE); printk(BIOS_DEBUG, "Back from sandybridge_early_initialization()\n"); boot_mode = southbridge_detect_s3_resume() ? 2 : 0; post_code(0x38); /* Enable SPD ROMs and DDR-III DRAM */ enable_smbus(); /* Prepare USB controller early in S3 resume */ if (boot_mode == 2) enable_usb_bar(); post_code(0x3a); pei_data.boot_mode = boot_mode; timestamp_add_now(TS_BEFORE_INITRAM); sdram_initialize(&pei_data); timestamp_add_now(TS_AFTER_INITRAM); post_code(0x3b); /* Perform some initialization that must run before stage2 */ early_pch_init(); post_code(0x3c); /* This should probably go away. Until now it is required * and mainboard specific */ rcba_config(); post_code(0x3d); quick_ram_check(); post_code(0x3e); cbmem_was_initted = !cbmem_recovery(boot_mode==2); if (boot_mode!=2) save_mrc_data(&pei_data); if (boot_mode==2 && !cbmem_was_initted) { /* Failed S3 resume, reset to come up cleanly */ outb(0x6, 0xcf9); halt(); } northbridge_romstage_finalize(boot_mode==2); post_code(0x3f); if (CONFIG_LPC_TPM) { init_tpm(boot_mode == 2); } }
void mea_write(uint32_t reg_address) { pci_write_config32(MC_BDF, QNC_ACCESS_PORT_MEA, reg_address & QNC_MEA_MASK); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; unsigned sbdn; int i, bus_isa; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LAPIC_ADDR); smp_write_processors(mc); get_bus_conf(); sbdn = sysconf.sbdn; mptable_write_buses(mc, NULL, &bus_isa); /*I/O APICs: APIC ID Version State Address*/ { device_t dev; struct resource *res; uint32_t dword; dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(sbdn+ 0x1,0)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_1); if (res) { smp_write_ioapic(mc, apicid_ck804, 0x11, res->base); } /* Initialize interrupt mapping*/ dword = 0x0120d218; pci_write_config32(dev, 0x7c, dword); dword = 0x12008a00; pci_write_config32(dev, 0x80, dword); dword = 0x0000007d; pci_write_config32(dev, 0x84, dword); } dev = dev_find_slot(bus_8131_0, PCI_DEVFN(sbdn3,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } dev = dev_find_slot(bus_8131_0, PCI_DEVFN(sbdn3+1,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base); } } } mptable_add_isa_interrupts(mc, bus_isa, apicid_ck804, 1); // Onboard ck804 smbus smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn+1)<<2)|1, apicid_ck804, 0xa); // 10 // Onboard ck804 USB 1.1 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn+2)<<2)|0, apicid_ck804, 0x15); // 21 // Onboard ck804 USB 2 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn+2)<<2)|1, apicid_ck804, 0x14); // 20 // Onboard ck804 SATA 0 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn +7)<<2)|0, apicid_ck804, 0x17); // 23 // Onboard ck804 SATA 1 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn +8)<<2)|0, apicid_ck804, 0x16); // 22 //Slot PCIE x16 for(i=0;i<4;i++) { smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|i, apicid_ck804, 0x10 + (2+i+4-sbdn%4)%4); } //Slot PCIE x4 for(i=0;i<4;i++) { smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|i, apicid_ck804, 0x10 + (1+i+4-sbdn%4)%4); } //Onboard ati smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (7<<2)|0, apicid_ck804, 0x13); // 19 //Channel B of 8131 //Onboard Broadcom NIC for(i=0;i<2;i++) { smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|i, apicid_8131_2, (0+i)%4); //28 } //Channel A of 8131 //Slot 4 PCIX 133/100/66 for(i=0;i<4;i++) { smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|i, apicid_8131_1, (0+i)%4); //24 } //Slot 3 PCIX 133/100/66 SoDIMM PCI for(i=0;i<4;i++) { smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|i, apicid_8131_1, (2+i)%4); //26 } /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1); /* There is no extension information... */ /* Compute the checksums */ mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc)); return smp_next_mpe_entry(mc); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; unsigned sbdn; int i, j, bus_isa; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); get_bus_conf(); sbdn = sysconf.sbdn; mptable_write_buses(mc, NULL, &bus_isa); /*I/O APICs: APIC ID Version State Address*/ { device_t dev; struct resource *res; uint32_t dword; dev = dev_find_slot(bus_sis966[0], PCI_DEVFN(sbdn+ 0x1,0)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_1); if (res) { smp_write_ioapic(mc, apicid_sis966, 0x11, res2mmio(res, 0, 0)); } dword = 0x43c6c643; pci_write_config32(dev, 0x7c, dword); dword = 0x81001a00; pci_write_config32(dev, 0x80, dword); dword = 0xd0001202; pci_write_config32(dev, 0x84, dword); } } mptable_add_isa_interrupts(mc, bus_isa, apicid_sis966, 0); /* PCI interrupts are level triggered, and are * associated with a specific bus/device/function tuple. */ #define PCI_INT(bus, dev, fn, pin) \ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[bus], (((dev)<<2)|(fn)), apicid_sis966, (pin)) PCI_INT(0, sbdn+1, 1, 0xa); PCI_INT(0, sbdn+2, 0, 0x16); // 22 PCI_INT(0, sbdn+2, 1, 0x17); // 23 PCI_INT(0, sbdn+6, 1, 0x17); // 23 PCI_INT(0, sbdn+5, 0, 0x14); // 20 PCI_INT(0, sbdn+5, 1, 0x17); // 23 PCI_INT(0, sbdn+5, 2, 0x15); // 21 PCI_INT(0, sbdn+8, 0, 0x16); // 22 for(j=7; j>=2; j--) { if(!bus_sis966[j]) continue; for(i=0; i<4; i++) { PCI_INT(j, 0x00, i, 0x10 + (2+j+i+4-sbdn%4)%4); } } for(j=0; j<2; j++) for(i=0; i<4; i++) { PCI_INT(1, 0x06+j, i, 0x10 + (2+i+j)%4); } /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ mptable_lintsrc(mc, bus_isa); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }
static inline void sir_write(struct device *dev, int idx, u32 value) { pci_write_config32(dev, SATA_SIRI, idx); pci_write_config32(dev, SATA_SIRD, value); }
static void map_rcba(void) { pci_devfn_t dev = PCI_DEV(0, 0x1f, 0); pci_write_config32(dev, RCBA, (uintptr_t)DEFAULT_RCBA | 1); }
static void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; static const char oem[8] = "COREBOOT"; static const char productid[12] = "TREX "; struct mp_config_table *mc; struct mb_sysconf_t *m; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); memset(mc, 0, sizeof(*mc)); memcpy(mc->mpc_signature, sig, sizeof(sig)); mc->mpc_length = sizeof(*mc); /* initially just the header */ mc->mpc_spec = 0x04; mc->mpc_checksum = 0; /* not yet computed */ memcpy(mc->mpc_oem, oem, sizeof(oem)); memcpy(mc->mpc_productid, productid, sizeof(productid)); mc->mpc_oemptr = 0; mc->mpc_oemsize = 0; mc->mpc_entry_count = 0; /* No entries yet... */ mc->mpc_lapic = LAPIC_ADDR; mc->mpe_length = 0; mc->mpe_checksum = 0; mc->reserved = 0; smp_write_processors(mc); get_bus_conf(); m = sysconf.mb; /*Bus: Bus ID Type*/ /* define bus and isa numbers */ #if 0 unsigned char bus_num; for(bus_num = 0; bus_num < m->bus_isa; bus_num++) { smp_write_bus(mc, bus_num, "PCI "); printk(BIOS_DEBUG, "writing bus %d as PCI...\n",bus_num); } #endif smp_write_bus(mc, 0, "PCI "); smp_write_bus(mc, 1, "PCI "); smp_write_bus(mc, 7, "PCI "); smp_write_bus(mc, 8, "PCI "); smp_write_bus(mc,m->bus_isa, "ISA "); printk(BIOS_DEBUG, "writing %d as ISA...\n",m->bus_isa); /*I/O APICs: APIC ID Version State Address*/ { device_t dev = 0; int i; struct resource *res; for(i=0; i<3; i++) { dev = dev_find_device(0x1166, 0x0235, dev); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { printk(BIOS_DEBUG, "APIC %d base address: %llx\n",m->apicid_bcm5785[i], res->base); smp_write_ioapic(mc, m->apicid_bcm5785[i], 0x11, res->base); } } } } /* IRQ routing as factory BIOS */ outb(0x01, 0xc00); outb(0x0A, 0xc01); outb(0x17, 0xc00); outb(0x05, 0xc01); /* outb(0x2E, 0xc00); outb(0x0B, 0xc01); */ /* outb(0x07, 0xc00); outb(0x07, 0xc01); */ outb(0x07, 0xc00); outb(0x0b, 0xc01); outb(0x24, 0xc00); outb(0x05, 0xc01); //outb(0x00, 0xc00); outb(0x09, 0xc01); outb(0x02, 0xc00); outb(0x0E, 0xc01); // 8259 registers... outb(0xa0, 0x4d0); outb(0x0e, 0x4d1); { device_t dev; dev = dev_find_device(0x1166, 0x0205, 0); if(dev) { uint32_t dword; dword = pci_read_config32(dev, 0x64); dword |= (1<<30); // GEVENT14-21 used as PCI IRQ0-7 pci_write_config32(dev, 0x64, dword); } // set GEVENT pins to NO OP outb(0x33, 0xcd6); outb(0x00, 0xcd7); outb(0x34, 0xcd6); outb(0x00, 0xcd7); outb(0x35, 0xcd6); outb(0x00, 0xcd7); } // hide XIOAPIC PCI configuration space { device_t dev; dev = dev_find_device(0x1166, 0x205, 0); if (dev) { uint32_t dword; dword = pci_read_config32(dev, 0x64); dword |= (1<<26); pci_write_config32(dev, 0x64, dword); } } mptable_add_isa_interrupts(mc, m->bus_isa, m->apicid_bcm5785[0], 0); //SATA /* printk(BIOS_DEBUG, "MPTABLE_SATA: bus_id:%d irq:%d apic_id:%d pin:%d\n",m->bus_bcm5785_1, (0x0e<<2)|0, m->apicid_bcm5785[0], 0x7); */ /* smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_1, (0x0e<<2)|0, m->apicid_bcm5785[0], 0x7); */ printk(BIOS_DEBUG, "MPTABLE_SATA: bus_id:%d irq:%d apic_id:%d pin:%d\n",m->bus_bcm5785_1, (0x0e<<2)|0, m->apicid_bcm5785[0], 0xb); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_1, (0x0e<<2)|0, m->apicid_bcm5785[0], 0xb); //USB printk(BIOS_DEBUG, "sysconf.sbdn: %d on bus: %x \n",sysconf.sbdn, m->bus_bcm5785_0); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (0x03<<2)|0, m->apicid_bcm5785[0], 0xa); //VGA smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (0x4<<2)|0, m->apicid_bcm5785[1], 0x7); //PCIE smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (0x6<<2)|0, m->apicid_bcm5785[2], 0xe); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (0x7<<2)|0, m->apicid_bcm5785[2], 0xe); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (0x8<<2)|0, m->apicid_bcm5785[2], 0xe); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (0x9<<2)|0, m->apicid_bcm5785[2], 0xe); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (0xa<<2)|0, m->apicid_bcm5785[2], 0xe); //IDE // outb(0x02, 0xc00); outb(0x0e, 0xc01); // printk(BIOS_DEBUG, "MPTABLE_IDE: bus_id:%d irq:%d apic_id:%d pin:%d\n",m->bus_bcm5785_0, ((1+sysconf.sbdn)<<2)|1, m->apicid_bcm5785[0], 0xe); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_bcm5785_0, (0x02<<2)|1, m->apicid_bcm5785[0], 0xe); //onboard Broadcom GbE smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,8, (4<<2)|0, m->apicid_bcm5785[2], 0x4); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,8, (4<<2)|1, m->apicid_bcm5785[2], 0x4); /* enable int */ /* why here? must get the BAR and PCI command bit 1 set before enable it ....*/ { device_t dev; dev = dev_find_device(0x1166, 0x0205, 0); if(dev) { uint32_t dword; dword = pci_read_config32(dev, 0x6c); dword |= (1<<4); // enable interrupts printk(BIOS_DEBUG, "6ch: %x\n",dword); pci_write_config32(dev, 0x6c, dword); } } /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ printk(BIOS_DEBUG, "m->bus_isa is: %x\n",m->bus_isa); smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x0); smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa , 0x0, MP_APIC_ALL, 0x1); //extended table entries smp_write_address_space(mc,0 , ADDRESS_TYPE_IO, 0x0, 0x0, 0x0, 0x0001); smp_write_address_space(mc,0 , ADDRESS_TYPE_MEM, 0x0, 0x7f80, 0x0, 0x5e80); smp_write_address_space(mc,0 , ADDRESS_TYPE_PREFETCH, 0x0, 0xde00, 0x0, 0x0100); smp_write_address_space(mc,0 , ADDRESS_TYPE_MEM, 0x0, 0xdf00, 0x0, 0x1fe0); smp_write_address_space(mc,0 , ADDRESS_TYPE_MEM, 0x1000, 0xfee0, 0xf000, 0x011f); smp_write_address_space(mc,0 , ADDRESS_TYPE_MEM, 0x0, 0x000a, 0x0, 0x0006); smp_write_bus_hierarchy(mc, 9, 0x01, 0); smp_write_compatibility_address_space(mc, 0, ADDRESS_RANGE_ADD, 0); smp_write_compatibility_address_space(mc, 0, ADDRESS_RANGE_ADD, 1); /* Compute the checksums */ mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc)); return smp_next_mpe_entry(mc); }
unsigned long acpi_fill_madt(unsigned long current) { device_t dev; u32 dword; u32 gsi_base = 0; u32 apicid_sp5100; u32 apicid_sr5650; /* * AGESA v5 Apply apic enumeration rules * For systems with >= 16 APICs, put the IO-APICs at 0..n and * put the local-APICs at m..z * For systems with < 16 APICs, put the Local-APICs at 0..n and * put the IO-APICs at (n + 1)..z */ if (CONFIG_MAX_CPUS >= 16) apicid_sp5100 = 0x0; else apicid_sp5100 = CONFIG_MAX_CPUS + 1; apicid_sr5650 = apicid_sp5100 + 1; /* create all subtables for processors */ current = acpi_create_madt_lapics(current); /* Write sp5100 IOAPIC, only one */ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, apicid_sp5100, IO_APIC_ADDR, 0 ); /* IOAPIC on rs5690 */ gsi_base += IO_APIC_INTERRUPTS; /* SP5100 has 24 IOAPIC entries. */ dev = dev_find_slot(0, PCI_DEVFN(0, 0)); if (dev) { pci_write_config32(dev, 0xF8, 0x1); dword = pci_read_config32(dev, 0xFC) & 0xfffffff0; current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, apicid_sr5650, dword, gsi_base ); } current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, //BUS 0, //SOURCE 2, //gsirq 0 //flags ); /* 0: mean bus 0--->ISA */ /* 0: PIC 0 */ /* 2: APIC 2 */ /* 5 mean: 0101 --> Edge-triggered, Active high */ /* create all subtables for processors */ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 0, 5, 1); current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 1, 5, 1); /* 1: LINT1 connect to NMI */ return current; }
static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) { pci_write_config32(dev, 0x40, ((device & 0xffff) << 16) | (vendor & 0xffff)); }
static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); mptable_init(mc, LOCAL_APIC_ADDR); smp_write_processors(mc); mptable_write_buses(mc, NULL, &bus_isa); /* I/O APICs: APIC ID Version State Address */ { struct device *dev; u32 dword; u8 byte; dev = dev_find_slot(pirq_router_bus, PCI_DEVFN(0x14, 0)); if (dev) { dword = pci_read_config32(dev, 0x74) & 0xfffffff0; smp_write_ioapic(mc, apicid_sb700, 0x11,(void *) dword); /* Initialize interrupt mapping */ /* aza */ byte = pci_read_config8(dev, 0x63); byte &= 0xf8; byte |= 0; /* 0: INTA, ...., 7: INTH */ pci_write_config8(dev, 0x63, byte); /* SATA */ dword = pci_read_config32(dev, 0xac); dword &= ~(7 << 26); dword |= 6 << 26; /* 0: INTA, ...., 7: INTH */ /* dword |= 1 << 22; PIC and APIC co exists */ pci_write_config32(dev, 0xac, dword); /* * 00:12.0: PROG SATA : INT F * 00:13.0: INTA USB_0 * 00:13.1: INTB USB_1 * 00:13.2: INTC USB_2 * 00:13.3: INTD USB_3 * 00:13.4: INTC USB_4 * 00:13.5: INTD USB2 * 00:14.1: INTA IDE * 00:14.2: Prog HDA : INT E * 00:14.5: INTB ACI * 00:14.6: INTB MCI */ } } /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ #define IO_LOCAL_INT(type, intr, apicid, pin) \ smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); mptable_add_isa_interrupts(mc, bus_isa, apicid_sb700, 0); /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ IO_LOCAL_INT(mp_ExtINT, 0x0, MP_APIC_ALL, 0x0); IO_LOCAL_INT(mp_NMI, 0x0, MP_APIC_ALL, 0x1); /* There is no extension information... */ /* Compute the checksums */ return mptable_finalize(mc); }