static void cpu_pci_domain_read_resources(struct device *dev) { u16 nbid = pci_read_config16(dev_find_slot(0, 0), PCI_DEVICE_ID); int i440fx = (nbid == 0x1237); int q35 = (nbid == 0x29c0); struct resource *res; unsigned long tomk = 0, high; int idx = 10; int size; pci_domain_read_resources(dev); size = fw_cfg_check_file("etc/e820"); if (size > 0) { /* supported by qemu 1.7+ */ FwCfgE820Entry *list = malloc(size); int i; fw_cfg_load_file("etc/e820", list); for (i = 0; i < size/sizeof(*list); i++) { switch (list[i].type) { case 1: /* RAM */ printk(BIOS_DEBUG, "QEMU: e820/ram: 0x%08llx +0x%08llx\n", list[i].address, list[i].length); if (list[i].address == 0) { tomk = list[i].length / 1024; ram_resource(dev, idx++, 0, 640); ram_resource(dev, idx++, 768, tomk - 768); } else { ram_resource(dev, idx++, list[i].address / 1024, list[i].length / 1024); } break; case 2: /* reserved */ printk(BIOS_DEBUG, "QEMU: e820/res: 0x%08llx +0x%08llx\n", list[i].address, list[i].length); res = new_resource(dev, idx++); res->base = list[i].address; res->size = list[i].length; res->limit = 0xffffffff; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; break; default: /* skip unknown */ break; } } free(list); } if (!tomk) { /* qemu older than 1.7, or reading etc/e820 failed. Fallback to cmos. */ tomk = qemu_get_memory_size(); high = qemu_get_high_memory_size(); printk(BIOS_DEBUG, "QEMU: cmos: %lu MiB RAM below 4G.\n", tomk / 1024); printk(BIOS_DEBUG, "QEMU: cmos: %lu MiB RAM above 4G.\n", high / 1024); /* Report the memory regions. */ ram_resource(dev, idx++, 0, 640); ram_resource(dev, idx++, 768, tomk - 768); if (high) ram_resource(dev, idx++, 4 * 1024 * 1024, high); } /* Reserve I/O ports used by QEMU */ qemu_reserve_ports(dev, idx++, 0x0510, 0x02, "firmware-config"); qemu_reserve_ports(dev, idx++, 0x5658, 0x01, "vmware-port"); if (i440fx) { qemu_reserve_ports(dev, idx++, 0xae00, 0x10, "pci-hotplug"); qemu_reserve_ports(dev, idx++, 0xaf00, 0x20, "cpu-hotplug"); qemu_reserve_ports(dev, idx++, 0xafe0, 0x04, "piix4-gpe0"); } if (inb(CONFIG_CONSOLE_QEMU_DEBUGCON_PORT) == 0xe9) { qemu_reserve_ports(dev, idx++, CONFIG_CONSOLE_QEMU_DEBUGCON_PORT, 1, "debugcon"); } if (q35 && ((tomk * 1024) < 0xb0000000)) { /* * Reserve the region between top-of-ram and the * mmconf xbar (ar 0xb0000000), so coreboot doesn't * place pci bars there. The region isn't declared as * pci io window in the ACPI tables (\_SB.PCI0._CRS). */ res = new_resource(dev, idx++); res->base = tomk * 1024; res->size = 0xb0000000 - tomk * 1024; res->limit = 0xffffffff; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; } if (i440fx) { /* Reserve space for the IOAPIC. This should be in * the southbridge, but I couldn't tell which device * to put it in. */ res = new_resource(dev, 2); res->base = IO_APIC_ADDR; res->size = 0x100000UL; res->limit = 0xffffffffUL; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; } /* Reserve space for the LAPIC. There's one in every processor, but * the space only needs to be reserved once, so we do it here. */ res = new_resource(dev, 3); res->base = LOCAL_APIC_ADDR; res->size = 0x10000UL; res->limit = 0xffffffffUL; res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; }
static void mch_domain_read_resources(device_t dev) { u64 tom, touud; u32 tomk, tolud, uma_sizek = 0; u32 pcie_config_base, pcie_config_size; /* Total Memory 2GB example: * * 00000000 0000MB-2014MB 2014MB RAM (writeback) * 7de00000 2014MB-2016MB 2MB GFX GTT (uncached) * 7e000000 2016MB-2048MB 32MB GFX UMA (uncached) * 80000000 2048MB TOLUD * 80000000 2048MB TOM * * Total Memory 4GB example: * * 00000000 0000MB-3038MB 3038MB RAM (writeback) * bde00000 3038MB-3040MB 2MB GFX GTT (uncached) * be000000 3040MB-3072MB 32MB GFX UMA (uncached) * be000000 3072MB TOLUD * 100000000 4096MB TOM * 100000000 4096MB-5120MB 1024MB RAM (writeback) * 140000000 5120MB TOUUD */ pci_domain_read_resources(dev); /* Top of Upper Usable DRAM, including remap */ touud = pci_read_config16(dev, D0F0_TOUUD); touud <<= 20; /* Top of Lower Usable DRAM */ tolud = pci_read_config16(dev, D0F0_TOLUD) & 0xfff0; tolud <<= 16; /* Top of Memory - does not account for any UMA */ tom = pci_read_config16(dev, D0F0_TOM) & 0x1ff; tom <<= 27; printk(BIOS_DEBUG, "TOUUD 0x%llx TOLUD 0x%08x TOM 0x%llx\n", touud, tolud, tom); tomk = tolud >> 10; /* Graphics memory comes next */ const u16 ggc = pci_read_config16(dev, D0F0_GGC); if (!(ggc & 2)) { printk(BIOS_DEBUG, "IGD decoded, subtracting "); /* Graphics memory */ const u32 gms_sizek = decode_igd_memory_size((ggc >> 4) & 0xf); printk(BIOS_DEBUG, "%uM UMA", gms_sizek >> 10); tomk -= gms_sizek; /* GTT Graphics Stolen Memory Size (GGMS) */ const u32 gsm_sizek = decode_igd_gtt_size((ggc >> 8) & 0xf); printk(BIOS_DEBUG, " and %uM GTT\n", gsm_sizek >> 10); tomk -= gsm_sizek; uma_sizek = gms_sizek + gsm_sizek; }
static void pch_power_options(device_t dev) { u8 reg8; u16 reg16, pmbase; u32 reg32; const char *state; /* Get the chip configuration */ config_t *config = dev->chip_info; int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; int nmi_option; /* Which state do we want to goto after g3 (power restored)? * 0 == S0 Full On * 1 == S5 Soft Off * * If the option is not existent (Laptops), use Kconfig setting. */ get_option(&pwr_on, "power_on_after_fail"); reg16 = pci_read_config16(dev, GEN_PMCON_3); reg16 &= 0xfffe; switch (pwr_on) { case MAINBOARD_POWER_OFF: reg16 |= 1; state = "off"; break; case MAINBOARD_POWER_ON: reg16 &= ~1; state = "on"; break; case MAINBOARD_POWER_KEEP: reg16 &= ~1; state = "state keep"; break; default: state = "undefined"; } reg16 &= ~(3 << 4); /* SLP_S4# Assertion Stretch 4s */ reg16 |= (1 << 3); /* SLP_S4# Assertion Stretch Enable */ reg16 &= ~(1 << 10); reg16 |= (1 << 11); /* SLP_S3# Min Assertion Width 50ms */ reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */ pci_write_config16(dev, GEN_PMCON_3, reg16); printk(BIOS_INFO, "Set power %s after power failure.\n", state); /* Set up NMI on errors. */ reg8 = inb(0x61); reg8 &= 0x0f; /* Higher Nibble must be 0 */ reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */ // reg8 &= ~(1 << 2); /* PCI SERR# Enable */ reg8 |= (1 << 2); /* PCI SERR# Disable for now */ outb(reg8, 0x61); reg8 = inb(0x70); nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { printk(BIOS_INFO, "NMI sources enabled.\n"); reg8 &= ~(1 << 7); /* Set NMI. */ } else { printk(BIOS_INFO, "NMI sources disabled.\n"); reg8 |= ( 1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */ } outb(reg8, 0x70); /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */ reg16 = pci_read_config16(dev, GEN_PMCON_1); reg16 &= ~(3 << 0); // SMI# rate 1 minute reg16 &= ~(1 << 10); // Disable BIOS_PCI_EXP_EN for native PME #if DEBUG_PERIODIC_SMIS /* Set DEBUG_PERIODIC_SMIS in pch.h to debug using * periodic SMIs. */ reg16 |= (3 << 0); // Periodic SMI every 8s #endif pci_write_config16(dev, GEN_PMCON_1, reg16); // Set the board's GPI routing. pch_gpi_routing(dev); pmbase = pci_read_config16(dev, 0x40) & 0xfffe; outl(config->gpe0_en, pmbase + GPE0_EN); outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN); /* Set up power management block and determine sleep mode */ reg32 = inl(pmbase + 0x04); // PM1_CNT reg32 &= ~(7 << 10); // SLP_TYP reg32 |= (1 << 0); // SCI_EN outl(reg32, pmbase + 0x04); /* Clear magic status bits to prevent unexpected wake */ reg32 = RCBA32(0x3310); reg32 |= (1 << 4)|(1 << 5)|(1 << 0); RCBA32(0x3310) = reg32; reg32 = RCBA32(0x3f02); reg32 &= ~0xf; RCBA32(0x3f02) = reg32; }
static void pci_init(struct device *dev) { u32 dword; u16 word; u8 byte; /* RPR 5.1 Enables the PCI-bridge subtractive decode */ /* This setting is strongly recommended since it supports some legacy PCI add-on cards,such as BIOS debug cards */ byte = pci_read_config8(dev, 0x4B); byte |= 1 << 7; pci_write_config8(dev, 0x4B, byte); byte = pci_read_config8(dev, 0x40); byte |= 1 << 5; pci_write_config8(dev, 0x40, byte); /* RPR5.2 PCI-bridge upstream dual address window */ /* this setting is applicable if the system memory is more than 4GB,and the PCI device can support dual address access */ byte = pci_read_config8(dev, 0x50); byte |= 1 << 0; pci_write_config8(dev, 0x50, byte); /* RPR 5.3 PCI bus 64-byte DMA read access */ /* Enhance the PCI bus DMA performance */ byte = pci_read_config8(dev, 0x4B); byte |= 1 << 4; pci_write_config8(dev, 0x4B, byte); /* RPR 5.4 Enables the PCIB writes to be cacheline aligned. */ /* The size of the writes will be set in the Cacheline Register */ byte = pci_read_config8(dev, 0x40); byte |= 1 << 1; pci_write_config8(dev, 0x40, byte); /* RPR 5.5 Enables the PCIB to retain ownership of the bus on the Primary side and on the Secondary side when GNT# is deasserted */ pci_write_config8(dev, 0x0D, 0x40); pci_write_config8(dev, 0x1B, 0x40); /* RPR 5.6 Enable the command matching checking function on "Memory Read" & "Memory Read Line" commands */ byte = pci_read_config8(dev, 0x4B); byte |= 1 << 6; pci_write_config8(dev, 0x4B, byte); /* RPR 5.7 When enabled, the PCI arbiter checks for the Bus Idle before asserting GNT# */ byte = pci_read_config8(dev, 0x4B); byte |= 1 << 0; pci_write_config8(dev, 0x4B, byte); /* RPR 5.8 Adjusts the GNT# de-assertion time */ word = pci_read_config16(dev, 0x64); word |= 1 << 12; pci_write_config16(dev, 0x64, word); /* RPR 5.9 Fast Back to Back transactions support */ byte = pci_read_config8(dev, 0x48); byte |= 1 << 2; /* pci_write_config8(dev, 0x48, byte); */ /* RPR 5.10 Enable Lock Operation */ /* byte = pci_read_config8(dev, 0x48); */ byte |= 1 << 3; pci_write_config8(dev, 0x48, byte); /* RPR 5.11 Enable additional optional PCI clock */ word = pci_read_config16(dev, 0x64); word |= 1 << 8; pci_write_config16(dev, 0x64, word); /* RPR 5.12 Enable One-Prefetch-Channel Mode */ dword = pci_read_config32(dev, 0x64); dword |= 1 << 20; pci_write_config32(dev, 0x64, dword); /* RPR 5.13 Disable PCIB MSI Capability */ byte = pci_read_config8(dev, 0x40); byte &= ~(1 << 3); pci_write_config8(dev, 0x40, byte); /* rpr5.14 Adjusting CLKRUN# */ dword = pci_read_config32(dev, 0x64); dword |= (1 << 15); pci_write_config32(dev, 0x64, dword); }
static void sata_init(struct device *dev) { u8 byte; u16 word; u32 dword; u8 rev_id; void *sata_bar5; u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4; int i, j; struct southbridge_ati_sb800_config *conf; conf = dev->chip_info; struct device *sm_dev; /* SATA SMBus Disable */ sm_dev = pcidev_on_root(0x14, 0); /* get rev_id */ rev_id = pci_read_config8(sm_dev, 0x08) - 0x2F; /* 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); /* Set SATA Operation Mode, Set to IDE mode */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 0); //byte |= (1 << 4); pci_write_config8(dev, 0x40, byte); dword = 0x01018f00; pci_write_config32(dev, 0x8, dword); /* Program the 2C to 0x43801002 */ dword = 0x43801002; pci_write_config32(dev, 0x2c, dword); pci_write_config8(dev, 0x34, 0x70); /* 8.11 SATA MSI and D3 Power State Capability */ dword = read32(sata_bar5 + 0xFC); dword &= ~(1 << 11); /* rpr 8.8. Disabling Aggressive Link Power Management */ dword &= ~(1 << 12); /* rpr 8.9.1 Disabling Port Multiplier support. */ dword &= ~(1 << 10); /* rpr 8.9.2 disabling FIS-based Switching support */ dword &= ~(1 << 19); /* rpr 8.10. Disabling CCC (Command Completion Coalescing) Support */ write32((sata_bar5 + 0xFC), dword); dword = read32(sata_bar5 + 0xF8); dword &= ~(0x3F << 22); /* rpr 8.9.2 disabling FIS-based Switching support */ write32(sata_bar5 + 0xF8, dword); byte = pci_read_config8(dev, 0x40); byte &= ~(1 << 0); pci_write_config8(dev, 0x40, byte); /* rpr 8.3 */ printk(BIOS_SPEW, "rev_id=%x\n", rev_id); dword = pci_read_config32(dev, 0x84); if (rev_id == 0x11) /* A11 */ dword |= 1 << 22; pci_write_config32(dev, 0x84, dword); /* rpr8.12 Program the watchdog counter to 0x20 */ byte = pci_read_config8(dev, 0x44); byte |= 1 << 0; pci_write_config8(dev, 0x44, byte); pci_write_config8(dev, 0x46, 0x20); sb800_setup_sata_phys(dev); /* Enable the I/O, MM, BusMaster access for SATA */ byte = pci_read_config8(dev, 0x4); byte |= 7 << 0; pci_write_config8(dev, 0x4, byte); /* RPR7.7 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 */ /* Use BAR5+0x328,PATA_BAR0/2 for Primary/Secondary master emulation */ /* Use BAR5+0x3A8,PATA_BAR0/2 for Primary/Secondary Slave emulation */ /* TODO: port 4,5, which are PATA emulations. What are PATA_BARs? */ 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); write32((sata_bar5 + 0x330), 0xFFFFFFFF); write32((sata_bar5 + 0x3b0), 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); */ }
void acpi_fill_in_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) { acpi_header_t *header = &(fadt->header); struct device *lpcdev = dev_find_slot(SOC_LPC_DEVFN); u16 pmbase = pci_read_config16(lpcdev, ABASE) & 0xfff0; config_t *config = lpcdev->chip_info; memset((void *) fadt, 0, sizeof(acpi_fadt_t)); /* * Reference section 5.2.9 Fixed ACPI Description Table (FADT) * in the ACPI 3.0b specification. */ /* FADT Header Structure */ memcpy(header->signature, "FACP", 4); header->length = sizeof(acpi_fadt_t); header->revision = ACPI_FADT_REV_ACPI_3_0; memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); memcpy(header->asl_compiler_id, ASLC, 4); header->asl_compiler_revision = 1; /* ACPI Pointers */ fadt->firmware_ctrl = (unsigned long) facs; fadt->dsdt = (unsigned long) dsdt; fadt->model = 0; /* reserved, should be 0 ACPI 3.0 */ fadt->preferred_pm_profile = config->fadt_pm_profile; /* unknown is default */ /* System Management */ fadt->sci_int = 0x09; fadt->smi_cmd = 0x00; /* disable SMM */ fadt->acpi_enable = 0x00; /* unused if SMI_CMD = 0 */ fadt->acpi_disable = 0x00; /* unused if SMI_CMD = 0 */ /* Enable ACPI */ outl(inl(pmbase + PM1_CNT) | SCI_EN, pmbase + PM1_CNT); /* Power Control */ fadt->s4bios_req = 0x00; fadt->pstate_cnt = 0x00; /* Control Registers - Base Address */ fadt->pm1a_evt_blk = pmbase + PM1_STS; fadt->pm1b_evt_blk = 0x00; /* Not Used */ fadt->pm1a_cnt_blk = pmbase + PM1_CNT; fadt->pm1b_cnt_blk = 0x00; /* Not Used */ fadt->pm2_cnt_blk = pmbase + PM2A_CNT_BLK; fadt->pm_tmr_blk = pmbase + PM1_TMR; fadt->gpe0_blk = pmbase + GPE0_STS; fadt->gpe1_blk = 0x00; /* Not Used */ /* Control Registers - Length */ fadt->pm1_evt_len = 4; /* 32 bits */ fadt->pm1_cnt_len = 2; /* 32 bit register, 16 bits used */ fadt->pm2_cnt_len = 1; /* 8 bits */ fadt->pm_tmr_len = 4; /* 32 bits */ fadt->gpe0_blk_len = 8; /* 64 bits */ fadt->gpe1_blk_len = 0; fadt->gpe1_base = 0; fadt->cst_cnt = 0; fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED; fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED; fadt->flush_size = 0; /* set to 0 if WBINVD is 1 in flags */ fadt->flush_stride = 0; /* set to 0 if WBINVD is 1 in flags */ fadt->duty_offset = 1; fadt->duty_width = 0; /* RTC Registers */ fadt->day_alrm = 0x0D; fadt->mon_alrm = 0x00; fadt->century = 0x00; fadt->iapc_boot_arch = config->fadt_boot_arch; /* legacy free default */ fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_RESET_REGISTER | ACPI_FADT_SLEEP_TYPE | ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK; /* Reset Register */ fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO; fadt->reset_reg.bit_width = 8; fadt->reset_reg.bit_offset = 0; fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; fadt->reset_reg.addrl = 0xCF9; fadt->reset_reg.addrh = 0x00; fadt->reset_value = 6; /* Reserved Bits */ fadt->res3 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */ fadt->res4 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */ fadt->res5 = 0x00; /* reserved, MUST be 0 ACPI 3.0 */ /* Extended ACPI Pointers */ fadt->x_firmware_ctl_l = (unsigned long)facs; fadt->x_firmware_ctl_h = 0x00; fadt->x_dsdt_l = (unsigned long)dsdt; fadt->x_dsdt_h = 0x00; /* PM1 Status & PM1 Enable */ fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1a_evt_blk.bit_width = 32; fadt->x_pm1a_evt_blk.bit_offset = 0; fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk; fadt->x_pm1a_evt_blk.addrh = 0x00; fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1b_evt_blk.bit_width = 0; fadt->x_pm1b_evt_blk.bit_offset = 0; fadt->x_pm1b_evt_blk.access_size = 0; fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk; fadt->x_pm1b_evt_blk.addrh = 0x00; /* PM1 Control Registers */ fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1a_cnt_blk.bit_width = 16; fadt->x_pm1a_cnt_blk.bit_offset = 0; fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk; fadt->x_pm1a_cnt_blk.addrh = 0x00; fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1b_cnt_blk.bit_width = 0; fadt->x_pm1b_cnt_blk.bit_offset = 0; fadt->x_pm1b_cnt_blk.access_size = 0; fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk; fadt->x_pm1b_cnt_blk.addrh = 0x00; /* PM2 Control Registers */ fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm2_cnt_blk.bit_width = 8; fadt->x_pm2_cnt_blk.bit_offset = 0; fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk; fadt->x_pm2_cnt_blk.addrh = 0x00; /* PM1 Timer Register */ fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm_tmr_blk.bit_width = 32; fadt->x_pm_tmr_blk.bit_offset = 0; fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk; fadt->x_pm_tmr_blk.addrh = 0x00; /* General-Purpose Event Registers */ fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_gpe0_blk.bit_width = 64; /* EventStatus + EventEnable */ fadt->x_gpe0_blk.bit_offset = 0; fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; fadt->x_gpe0_blk.addrl = fadt->gpe0_blk; fadt->x_gpe0_blk.addrh = 0x00; fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_gpe1_blk.bit_width = 0; fadt->x_gpe1_blk.bit_offset = 0; fadt->x_gpe1_blk.access_size = 0; fadt->x_gpe1_blk.addrl = fadt->gpe1_blk; fadt->x_gpe1_blk.addrh = 0x00; header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t)); }
static void azalia_pch_init(struct device *dev, u8 *base) { u8 reg8; u16 reg16; u32 reg32; if (RCBA32(0x2030) & (1 << 31)) { reg32 = pci_read_config32(dev, 0x120); reg32 &= 0xf8ffff01; reg32 |= (1 << 25); reg32 |= RCBA32(0x2030) & 0xfe; pci_write_config32(dev, 0x120, reg32); if (!pch_is_lp()) { 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 if (pci_read_config32(dev, 0x120) & ((1 << 24) | (1 << 25) | (1 << 26))) { reg32 = pci_read_config32(dev, 0x120); if (pch_is_lp()) reg32 &= ~(1 << 31); else reg32 |= (1 << 31); pci_write_config32(dev, 0x120, reg32); } reg8 = pci_read_config8(dev, 0x43); if (pch_is_lp()) reg8 &= ~(1 << 6); else reg8 |= (1 << 4); pci_write_config8(dev, 0x43, reg8); if (!pch_is_lp()) { reg32 = pci_read_config32(dev, 0xc0); reg32 |= (1 << 17); pci_write_config32(dev, 0xc0, reg32); } /* Additional programming steps */ reg32 = pci_read_config32(dev, 0xc4); if (pch_is_lp()) reg32 |= (1 << 24); else reg32 |= (1 << 14); pci_write_config32(dev, 0xc4, reg32); if (!pch_is_lp()) { reg32 = pci_read_config32(dev, 0xd0); reg32 &= ~(1 << 31); pci_write_config32(dev, 0xd0, reg32); } reg8 = pci_read_config8(dev, 0x40); // Audio Control reg8 |= 1; // Select Azalia mode 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); if (pch_is_lp()) { reg16 = read32(base + 0x0012); reg16 |= (1 << 0); write32(base + 0x0012, reg16); /* disable Auto Voltage Detector */ reg8 = pci_read_config8(dev, 0x42); reg8 |= (1 << 2); pci_write_config8(dev, 0x42, reg8); } }
static void usb_init2(struct device *dev) { u32 dword; void *usb2_bar0; device_t sm_dev; u8 rev; sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); rev = get_sb700_revision(sm_dev); /* dword = pci_read_config32(dev, 0xf8); */ /* dword |= 40; */ /* pci_write_config32(dev, 0xf8, dword); */ usb2_bar0 = (void *)(pci_read_config32(dev, 0x10) & ~0xFF); printk(BIOS_INFO, "usb2_bar0=0x%p\n", usb2_bar0); /* RPR6.4 Enables the USB PHY auto calibration resister to match 45ohm resistance */ dword = 0x00020F00; write32(usb2_bar0 + 0xC0, dword); /* RPR6.9 Sets In/OUT FIFO threshold for best performance */ dword = 0x00400040; write32(usb2_bar0 + 0xA4, dword); /* RPR6.11 Disabling EHCI Advance Asynchronous Enhancement */ dword = pci_read_config32(dev, 0x50); dword |= (1 << 28); pci_write_config32(dev, 0x50, dword); /* RPR 6.12 EHCI Advance PHY Power Savings */ /* RPR says it is just for A12. CIMM sets it when it is above A11. */ /* But it makes the linux crash, so we skip it */ dword = pci_read_config32(dev, 0x50); dword |= 1 << 31; pci_write_config32(dev, 0x50, dword); /* RPR6.13 Enabling Fix for EHCI Controller Driver Yellow Sign Issue */ /* RPR says it is just for A12. CIMx sets it when it is above A11. */ dword = pci_read_config32(dev, 0x50); dword |= (1 << 20); pci_write_config32(dev, 0x50, dword); /* RPR6.15 EHCI Async Park Mode */ dword = pci_read_config32(dev, 0x50); dword |= (1 << 23); pci_write_config32(dev, 0x50, dword); /* Each step below causes the linux crashes. Leave them here * for future debugging. */ u8 byte; u16 word; /* RPR6.16 Disable EHCI MSI support */ byte = pci_read_config8(dev, 0x50); byte |= (1 << 6); pci_write_config8(dev, 0x50, byte); /* RPR6.17 Disable the EHCI Dynamic Power Saving feature */ word = read32(usb2_bar0 + 0xBC); word &= ~(1 << 12); write16(usb2_bar0 + 0xBC, word); /* RPR6.19 USB Controller DMA Read Delay Tolerant. */ if (rev >= REV_SB700_A14) { byte = pci_read_config8(dev, 0x50); byte |= (1 << 7); pci_write_config8(dev, 0x50, byte); } /* SB700_A15, USB-2_EHCI_PID_ERROR_CHECKING */ if (rev == REV_SB700_A15) { word = pci_read_config16(dev, 0x50); word |= (1 << 9); pci_write_config16(dev, 0x50, word); } /* RPR6.20 Async Park Mode. */ /* RPR recommends not to set these bits. */ #if 0 dword = pci_read_config32(dev, 0x50); dword |= 1 << 23; if (rev >= REV_SB700_A14) { dword &= ~(1 << 2); } pci_write_config32(dev, 0x50, dword); #endif /* RPR6.22 Advance Async Enhancement */ /* RPR6.23 USB Periodic Cache Setting */ dword = pci_read_config32(dev, 0x50); if (rev == REV_SB700_A12) { dword |= 1 << 28; /* 6.22 */ dword |= 1 << 27; /* 6.23 */ } else if (rev >= REV_SB700_A14) { dword |= 1 << 3; dword &= ~(1 << 28); /* 6.22 */ dword |= 1 << 8; dword &= ~(1 << 27); /* 6.23 */ } pci_write_config32(dev, 0x50, dword); printk(BIOS_DEBUG, "rpr 6.23, final dword=%x\n", dword); }
/** * @brief Enable resources for children devices * * @param dev the device whose children's resources are to be enabled * */ static void hudson_lpc_enable_childrens_resources(device_t dev) { struct bus *link; u32 reg, reg_x; int var_num = 0; u16 reg_var[3]; u16 reg_size[1] = {512}; u8 wiosize = pci_read_config8(dev, 0x74); /* Be bit relaxed, tolerate that LPC region might be bigger than resource we try to fit, * do it like this for all regions < 16 bytes. If there is a resource > 16 bytes * it must be 512 bytes to be able to allocate the fresh LPC window. * * AGESA likes to enable already one LPC region in wide port base 0x64-0x65, * using DFLT_SIO_PME_BASE_ADDRESS, 512 bytes size * The code tries to check if resource can fit into this region */ reg = pci_read_config32(dev, 0x44); reg_x = pci_read_config32(dev, 0x48); /* check if ranges are free and not use them if entry is just already taken */ if (reg_x & (1 << 2)) var_num = 1; /* just in case check if someone did not manually set other ranges too */ if (reg_x & (1 << 24)) var_num = 2; if (reg_x & (1 << 25)) var_num = 3; /* check AGESA region size */ if (wiosize & (1 << 0)) reg_size[0] = 16; reg_var[2] = pci_read_config16(dev, 0x90); reg_var[1] = pci_read_config16(dev, 0x66); reg_var[0] = pci_read_config16(dev, 0x64); 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 */ u32 rsize, set = 0, set_x = 0; if (!(res->flags & IORESOURCE_IO)) continue; base = res->base; end = resource_end(res); /* find a resource size */ printk(BIOS_DEBUG, "hudson lpc decode:%s, base=0x%08x, end=0x%08x\n", dev_path(child), base, end); switch (base) { case 0x60: /* KB */ case 0x64: /* MS */ set |= (1 << 29); rsize = 1; break; case 0x3f8: /* COM1 */ set |= (1 << 6); rsize = 8; break; case 0x2f8: /* COM2 */ set |= (1 << 7); rsize = 8; break; case 0x378: /* Parallel 1 */ set |= (1 << 0); set |= (1 << 1); /* + 0x778 for ECP */ rsize = 8; break; case 0x3f0: /* FD0 */ set |= (1 << 26); rsize = 8; break; case 0x220: /* 0x220 - 0x227 */ set |= (1 << 8); rsize = 8; break; case 0x228: /* 0x228 - 0x22f */ set |= (1 << 9); rsize = 8; break; case 0x238: /* 0x238 - 0x23f */ set |= (1 << 10); rsize = 8; break; case 0x300: /* 0x300 -0x301 */ set |= (1 << 18); rsize = 2; break; case 0x400: set_x |= (1 << 16); rsize = 0x40; break; case 0x480: set_x |= (1 << 17); rsize = 0x40; break; case 0x500: set_x |= (1 << 18); rsize = 0x40; break; case 0x580: set_x |= (1 << 19); rsize = 0x40; break; case 0x4700: set_x |= (1 << 22); rsize = 0xc; break; case 0xfd60: set_x |= (1 << 23); rsize = 16; break; default: rsize = 0; /* try AGESA allocated region in region 0 */ if ((var_num > 0) && ((base >=reg_var[0]) && ((base + res->size) <= (reg_var[0] + reg_size[0])))) rsize = reg_size[0]; } /* check if region found and matches the enable */ if (res->size <= rsize) { reg |= set; reg_x |= set_x; /* check if we can fit resource in variable range */ } else if ((var_num < 3) && ((res->size <= 16) || (res->size == 512))) { /* use variable ranges if pre-defined do not match */ switch (var_num) { case 0: reg_x |= (1 << 2); if (res->size <= 16) { wiosize |= (1 << 0); } break; case 1: reg_x |= (1 << 24); if (res->size <= 16) wiosize |= (1 << 2); break; case 2: reg_x |= (1 << 25); if (res->size <= 16) wiosize |= (1 << 3); break; } reg_var[var_num++] = base & 0xffff; } else { printk(BIOS_ERR, "cannot fit LPC decode region:%s, base=0x%08x, end=0x%08x\n", dev_path(child), base, end); } } } } } 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 3: pci_write_config16(dev, 0x90, reg_var[2]); /* fall through */ case 2: pci_write_config16(dev, 0x66, reg_var[1]); /* fall through */ case 1: pci_write_config16(dev, 0x64, reg_var[0]); break; } pci_write_config8(dev, 0x74, wiosize); }
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) { acpi_header_t *header = &(fadt->header); u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe; memset((void *) fadt, 0, sizeof(acpi_fadt_t)); memcpy(header->signature, "FACP", 4); header->length = sizeof(acpi_fadt_t); header->revision = 3; memcpy(header->oem_id, "CORE ", 6); memcpy(header->oem_table_id, "COREBOOT", 8); memcpy(header->asl_compiler_id, "CORE", 4); header->asl_compiler_revision = 0; fadt->firmware_ctrl = (unsigned long) facs; fadt->dsdt = (unsigned long) dsdt; fadt->model = 0x00; fadt->preferred_pm_profile = PM_MOBILE; fadt->sci_int = 0x9; fadt->smi_cmd = APM_CNT; fadt->acpi_enable = ACPI_ENABLE; fadt->acpi_disable = ACPI_DISABLE; fadt->s4bios_req = 0x0; fadt->pstate_cnt = PST_CONTROL; fadt->pm1a_evt_blk = pmbase; fadt->pm1b_evt_blk = 0x0; fadt->pm1a_cnt_blk = pmbase + 0x4; fadt->pm1b_cnt_blk = 0x0; fadt->pm2_cnt_blk = pmbase + 0x20; fadt->pm_tmr_blk = pmbase + 0x8; fadt->gpe0_blk = pmbase + 0x28; fadt->gpe1_blk = 0; fadt->pm1_evt_len = 4; fadt->pm1_cnt_len = 2; fadt->pm2_cnt_len = 1; fadt->pm_tmr_len = 4; fadt->gpe0_blk_len = 8; fadt->gpe1_blk_len = 0; fadt->gpe1_base = 0; fadt->cst_cnt = CST_CONTROL; fadt->p_lvl2_lat = 1; fadt->p_lvl3_lat = 0x23; fadt->flush_size = 0; fadt->flush_stride = 0; fadt->duty_offset = 1; fadt->duty_width = 3; fadt->day_alrm = 0xd; fadt->mon_alrm = 0x00; fadt->century = 0x32; fadt->iapc_boot_arch = 0x00; fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_DOCKING_SUPPORTED; fadt->reset_reg.space_id = 0; fadt->reset_reg.bit_width = 0; fadt->reset_reg.bit_offset = 0; fadt->reset_reg.resv = 0; fadt->reset_reg.addrl = 0x0; fadt->reset_reg.addrh = 0x0; fadt->reset_value = 0; fadt->x_firmware_ctl_l = (unsigned long)facs; fadt->x_firmware_ctl_h = 0; fadt->x_dsdt_l = (unsigned long)dsdt; fadt->x_dsdt_h = 0; fadt->x_pm1a_evt_blk.space_id = 1; fadt->x_pm1a_evt_blk.bit_width = 32; fadt->x_pm1a_evt_blk.bit_offset = 0; fadt->x_pm1a_evt_blk.resv = 0; fadt->x_pm1a_evt_blk.addrl = pmbase; fadt->x_pm1a_evt_blk.addrh = 0x0; fadt->x_pm1b_evt_blk.space_id = 0; fadt->x_pm1b_evt_blk.bit_width = 0; fadt->x_pm1b_evt_blk.bit_offset = 0; fadt->x_pm1b_evt_blk.resv = 0; fadt->x_pm1b_evt_blk.addrl = 0x0; fadt->x_pm1b_evt_blk.addrh = 0x0; fadt->x_pm1a_cnt_blk.space_id = 1; fadt->x_pm1a_cnt_blk.bit_width = 16; fadt->x_pm1a_cnt_blk.bit_offset = 0; fadt->x_pm1a_cnt_blk.resv = 0; fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4; fadt->x_pm1a_cnt_blk.addrh = 0x0; fadt->x_pm1b_cnt_blk.space_id = 0; fadt->x_pm1b_cnt_blk.bit_width = 0; fadt->x_pm1b_cnt_blk.bit_offset = 0; fadt->x_pm1b_cnt_blk.resv = 0; fadt->x_pm1b_cnt_blk.addrl = 0x0; fadt->x_pm1b_cnt_blk.addrh = 0x0; fadt->x_pm2_cnt_blk.space_id = 1; fadt->x_pm2_cnt_blk.bit_width = 8; fadt->x_pm2_cnt_blk.bit_offset = 0; fadt->x_pm2_cnt_blk.resv = 0; fadt->x_pm2_cnt_blk.addrl = pmbase + 0x20; fadt->x_pm2_cnt_blk.addrh = 0x0; fadt->x_pm_tmr_blk.space_id = 1; fadt->x_pm_tmr_blk.bit_width = 32; fadt->x_pm_tmr_blk.bit_offset = 0; fadt->x_pm_tmr_blk.resv = 0; fadt->x_pm_tmr_blk.addrl = pmbase + 0x8; fadt->x_pm_tmr_blk.addrh = 0x0; fadt->x_gpe0_blk.space_id = 1; fadt->x_gpe0_blk.bit_width = 64; fadt->x_gpe0_blk.bit_offset = 0; fadt->x_gpe0_blk.resv = 0; fadt->x_gpe0_blk.addrl = pmbase + 0x28; fadt->x_gpe0_blk.addrh = 0x0; fadt->x_gpe1_blk.space_id = 0; fadt->x_gpe1_blk.bit_width = 0; fadt->x_gpe1_blk.bit_offset = 0; fadt->x_gpe1_blk.resv = 0; fadt->x_gpe1_blk.addrl = 0x0; fadt->x_gpe1_blk.addrh = 0x0; header->checksum = acpi_checksum((void *) fadt, header->length); }