diff options
author | Stefan Reinauer <stepan@openbios.org> | 2006-01-05 00:18:41 +0000 |
---|---|---|
committer | Stefan Reinauer <stepan@openbios.org> | 2006-01-05 00:18:41 +0000 |
commit | f1c0fc7ff27832c52e1a3305ecb720ec9b29ce1b (patch) | |
tree | f4e8ca1abe6a522f2da464eb00e3b857fc2fd367 /src/mainboard/agami/aruma/acpi_tables.c | |
parent | 0571a95262be0d58dc28a3f0fba2c69dc543b018 (diff) |
latest agami/aruma changes. Compiles but won't boot yet
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2154 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/mainboard/agami/aruma/acpi_tables.c')
-rw-r--r-- | src/mainboard/agami/aruma/acpi_tables.c | 437 |
1 files changed, 312 insertions, 125 deletions
diff --git a/src/mainboard/agami/aruma/acpi_tables.c b/src/mainboard/agami/aruma/acpi_tables.c index 004de3d407..823e5e200a 100644 --- a/src/mainboard/agami/aruma/acpi_tables.c +++ b/src/mainboard/agami/aruma/acpi_tables.c @@ -1,7 +1,11 @@ /* * Agami Aruma ACPI support + * + * Copyright 2005 Stefan Reinauer + * Copyright 2005 AMD + * * written by Stefan Reinauer <stepan@openbios.org> - * (C) 2005 Stefan Reinauer + * 2005.9 yhlu modify that to more dynamic for AMD Opteron Based MB */ #include <console/console.h> @@ -9,127 +13,246 @@ #include <arch/acpi.h> #include <device/pci.h> #include <device/pci_ids.h> +#include <cpu/x86/msr.h> +#include <cpu/amd/mtrr.h> +#define DUMP_ACPI_TABLES 0 + +#if DUMP_ACPI_TABLES == 1 +static void dump_mem(unsigned start, unsigned end) +{ + + unsigned i; + print_debug("dump_mem:"); + for (i = start; i < end; i++) { + if ((i & 0xf) == 0) { + printk_debug("\n%08x:", i); + } + printk_debug(" %02x", + (unsigned char) *((unsigned char *) i)); + } + print_debug("\n"); +} +#endif + +#define HC_POSSIBLE_NUM 8 extern unsigned char AmlCode[]; +extern unsigned char AmlCode_ssdt[]; + +#if ACPI_SSDTX_NUM >= 1 +extern unsigned char AmlCode_ssdt2[]; +extern unsigned char AmlCode_ssdt3[]; +extern unsigned char AmlCode_ssdt4[]; +//extern unsigned char AmlCode_ssdt5[]; +//extern unsigned char AmlCode_ssdt6[]; +//extern unsigned char AmlCode_ssdt7[]; +//extern unsigned char AmlCode_ssdt8[]; +#endif #define IO_APIC_ADDR 0xfec00000UL -unsigned long acpi_dump_apics(unsigned long current) +extern unsigned char bus_isa; +extern unsigned char bus_8111_0; +extern unsigned char bus_8111_1; +extern unsigned char bus_8131[7][3]; // another 6 8131 +extern unsigned apicid_8111; +extern unsigned apicid_8131[7][2]; + +extern unsigned pci1234[]; +extern unsigned hc_possible_num; +extern unsigned sblk; +extern unsigned sbdn; +extern unsigned hcdn[]; +extern unsigned sbdnx[7]; // for all 8131 + + +unsigned long acpi_fill_madt(unsigned long current) { - unsigned int gsi_base=0x18, ioapic_nr=2, i; - device_t dev=0; - - /* create all subtables for 4p */ - current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, 0, 16); - current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, 1, 17); - current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, 2, 18); - current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, 3, 19); - + unsigned int gsi_base = 0x18; + + /* create all subtables for processors */ + current = acpi_create_madt_lapics(current); + /* Write 8111 IOAPIC */ - current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, 1, - IO_APIC_ADDR, 0); - - /* Write the two onboard 8131 IOAPICs */ - for(i = 0; i < 2; i++) { - if (dev = dev_find_device(PCI_VENDOR_ID_AMD, 0x7451, dev)){ - ACPI_WRITE_MADT_IOAPIC(dev, ioapic_nr); - ioapic_nr++; + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + apicid_8111, IO_APIC_ADDR, 0); + + /* Write all 8131/8132 IOAPICs */ + { + device_t dev; + struct resource *res; + dev = dev_find_slot(bus_8131[0][0], PCI_DEVFN(sbdnx[0], 1)); + + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + apicid_8131[0][0], res->base, gsi_base); + gsi_base += 4; + + } + } + dev = dev_find_slot(bus_8131[0][0], PCI_DEVFN(sbdnx[0] + 1, 1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + apicid_8131[0][1], res->base, gsi_base); + gsi_base += 4; + } } } - /* The doughter card may contain either 8131 or 8132 */ + int i; + for (i = 1; i < hc_possible_num; i++) + { // 0: is hc sblink + device_t dev; + int j; + struct resource *res; + + if ((pci1234[i] & 1) != 1) + continue; - /* Write the 8132 IOAPICs if they exist */ - for(i = 0; i < 4; i++) { - if (dev = dev_find_device(PCI_VENDOR_ID_AMD, 0x7459, dev)){ - ACPI_WRITE_MADT_IOAPIC(dev, ioapic_nr); - ioapic_nr++; + j = (i - 1) * 2 + 1; + dev = dev_find_slot(bus_8131[j][0], PCI_DEVFN(sbdnx[j], 1)); + + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + apicid_8131[j][0], res->base, gsi_base); + gsi_base += 4; + + } + } + dev = + dev_find_slot(bus_8131[j][0], + PCI_DEVFN(sbdnx[j] + 1, 1)); + if (dev) + { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + apicid_8131[j][1], res->base, gsi_base); + gsi_base += 4; + } } - } - /* In the event there were no 8132s look for the 8131s - * but skip the two onboard 8131 - */ - dev=dev_find_device(PCI_VENDOR_ID_AMD, 0x7451, 0); - dev=dev_find_device(PCI_VENDOR_ID_AMD, 0x7451, dev); - - /* Write all 8131 IOAPICs */ - while((dev = dev_find_device(PCI_VENDOR_ID_AMD, 0x7451, dev))) { - ACPI_WRITE_MADT_IOAPIC(dev, ioapic_nr); - ioapic_nr++; + dev = + dev_find_slot(bus_8131[j + 1][0], + PCI_DEVFN(sbdnx[j + 1], 1)); + + if (dev) + { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + apicid_8131[j + 1][0], res->base, gsi_base); + gsi_base += 4; + + } + } + dev = dev_find_slot(bus_8131[j + 1][0], PCI_DEVFN(sbdnx[j + 1] + 1, 1)); + if (dev) + { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + apicid_8131[j + 1][1], res->base, gsi_base); + gsi_base += 4; + } + } + + } - - current += acpi_create_madt_irqoverride( (acpi_madt_irqoverride_t *) - current, 1, 0, 2, 0 ); - current += acpi_create_madt_irqoverride( (acpi_madt_irqoverride_t *) - current, 1, 0, 2, 0 ); + + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, 0, 2, 5); + /* 0: mean bus 0--->ISA */ + /* 0: PIC 0 */ + /* 2: APIC 2 */ + /* 5 mean: 0101 --> Edige-triggered, Active high */ + + + /* create all subtables for processors */ + current = acpi_create_madt_lapic_nmis(current, 5, 1); + /* 1: LINT1 connect to NMI */ + return current; } +//FIXME: next could be moved to northbridge/amd/amdk8/amdk8_acpi.c or cpu/amd/k8/k8_acpi.c begin +static void int_to_stream(uint32_t val, uint8_t * dest) +{ + int i; + for (i = 0; i < 4; i++) { + *(dest + i) = (val >> (8 * i)) & 0xff; + } +} + +extern void get_bus_conf(void); -/* The next two tables are used by our DSDT and are freely defined - * here. This construct is used because the bus numbers containing - * the 8131 bridges may vary so that we need to pass LinuxBIOS - * knowledge into the DSDT - */ -typedef struct lnxc_busses { - u8 secondary; - u8 subordinate; -} acpi_lnxb_busses_t; - -typedef struct acpi_lnxb { - struct acpi_table_header header; - acpi_lnxb_busses_t busses[5]; -} acpi_lnxb_t; - -/* special linuxbios acpi table */ -void acpi_create_lnxb(acpi_lnxb_t *lnxb) +static void update_ssdt(void *ssdt) { + uint8_t *BUSN; + uint8_t *MMIO; + uint8_t *PCIO; + uint8_t *SBLK; + uint8_t *TOM1; + uint8_t *HCLK; + uint8_t *SBDN; + uint8_t *HCDN; + int i; device_t dev; - int busidx=0; - - acpi_header_t *header=&(lnxb->header); + uint32_t dword; + msr_t msr; - /* fill out header fields */ - memcpy(header->signature, "LNXB", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, "LNXBIOS ", 8); - memcpy(header->asl_compiler_id, ASLC, 4); + BUSN = ssdt + 0x3a; //+5 will be next BUSN + MMIO = ssdt + 0x57; //+5 will be next MMIO + PCIO = ssdt + 0xaf; //+5 will be next PCIO + SBLK = ssdt + 0xdc; // one byte + TOM1 = ssdt + 0xe3; // + HCLK = ssdt + 0xfa; //+5 will be next HCLK + SBDN = ssdt + 0xed; // + HCDN = ssdt + 0x12a; //+5 will be next HCDN - header->length = sizeof(acpi_lnxb_t); - header->revision = 1; + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); - /* - * Write external 8131 bus ranges - */ - /* first skip the onboard 8131 */ - dev=dev_find_device(PCI_VENDOR_ID_AMD, 0x7450, 0); - dev=dev_find_device(PCI_VENDOR_ID_AMD, 0x7450, dev); - - /* now look at the last 8131 in each chain, - * as it contains the valid bus ranges - */ - while((dev = dev_find_device(PCI_VENDOR_ID_AMD, 0x7450, dev)) - && busidx<5 ) { - int subu, fn, slot; - acpi_lnxb_busses_t *busses; - - if(PCI_SLOT(dev->path.u.pci.devfn)!=4) - continue; - - busses=&(lnxb->busses[busidx]); - lnxb->busses[busidx].secondary = dev->bus->secondary; - lnxb->busses[busidx].subordinate = - pci_read_config8(dev, PCI_SUBORDINATE_BUS); - - busidx++; + for (i = 0; i < 4; i++) { + dword = pci_read_config32(dev, 0xe0 + i * 4); + int_to_stream(dword, BUSN + i * 5); } - header->checksum = acpi_checksum((void *)lnxb, sizeof(acpi_lnxb_t)); -} + for (i = 0; i < 0x10; i++) { + dword = pci_read_config32(dev, 0x80 + i * 4); + int_to_stream(dword, MMIO + i * 5); + } + + for (i = 0; i < 0x08; i++) { + dword = pci_read_config32(dev, 0xc0 + i * 4); + int_to_stream(dword, PCIO + i * 5); + } + + *SBLK = (uint8_t) (sblk); + + msr = rdmsr(TOP_MEM); + int_to_stream(msr.lo, TOM1); + + for (i = 0; i < hc_possible_num; i++) { + int_to_stream(pci1234[i], HCLK + i * 5); + int_to_stream(hcdn[i], HCDN + i * 5); + } + for (i = hc_possible_num; i < HC_POSSIBLE_NUM; i++) { // in case we set array size to other than 8 + int_to_stream(0x00000000, HCLK + i * 5); + int_to_stream(hcdn[i], HCDN + i * 5); + } + + int_to_stream(sbdn, SBDN); + +} +//end unsigned long write_acpi_tables(unsigned long start) { @@ -138,15 +261,21 @@ unsigned long write_acpi_tables(unsigned long start) acpi_rsdt_t *rsdt; acpi_hpet_t *hpet; acpi_madt_t *madt; + acpi_srat_t *srat; acpi_fadt_t *fadt; acpi_facs_t *facs; - acpi_lnxb_t *lnxb; acpi_header_t *dsdt; + acpi_header_t *ssdt; + acpi_header_t *ssdtx; + + unsigned char *AmlCode_ssdtx[HC_POSSIBLE_NUM]; + + int i; /* Align ACPI tables to 16byte */ - start = ( start + 0x0f ) & -0x10; + start = (start + 0x0f) & -0x10; current = start; - + printk_info("ACPI: Writing ACPI tables at %lx...\n", start); /* We need at least an RSDP and an RSDT Table */ @@ -156,60 +285,118 @@ unsigned long write_acpi_tables(unsigned long start) current += sizeof(acpi_rsdt_t); /* clear all table memory */ - memset((void *)start, 0, current - start); - + memset((void *) start, 0, current - start); + acpi_write_rsdp(rsdp, rsdt); acpi_write_rsdt(rsdt); - + + get_bus_conf(); // get sblk, pci1234, and sbdn + /* * We explicitly add these tables later on: */ printk_debug("ACPI: * HPET\n"); - hpet = (acpi_hpet_t *) current; current += sizeof(acpi_hpet_t); acpi_create_hpet(hpet); - acpi_add_table(rsdt,hpet); + acpi_add_table(rsdt, hpet); /* If we want to use HPET Timers Linux wants an MADT */ printk_debug("ACPI: * MADT\n"); - madt = (acpi_madt_t *) current; acpi_create_madt(madt); - current+=madt->header.length; - acpi_add_table(rsdt,madt); + current += madt->header.length; + acpi_add_table(rsdt, madt); - printk_debug("ACPI: * LNXB\n"); - lnxb=(acpi_lnxb_t *)current; - current += sizeof(acpi_facs_t); - acpi_create_lnxb(lnxb); - + /* SRAT */ + printk_debug("ACPI: * SRAT\n"); + srat = (acpi_srat_t *) current; + acpi_create_srat(srat); + current += srat->header.length; + acpi_add_table(rsdt, srat); + + /* SSDT */ + printk_debug("ACPI: * SSDT\n"); + ssdt = (acpi_header_t *) current; + current += ((acpi_header_t *) AmlCode_ssdt)->length; + memcpy((void *) ssdt, (void *) AmlCode_ssdt, + ((acpi_header_t *) AmlCode_ssdt)->length); + //Here you need to set value in pci1234, sblk and sbdn in get_bus_conf.c + update_ssdt((void *) ssdt); + /* recalculate checksum */ + ssdt->checksum = 0; + ssdt->checksum = + acpi_checksum((unsigned char *) ssdt, ssdt->length); + acpi_add_table(rsdt, ssdt); + +#if ACPI_SSDTX_NUM >= 1 + // we need to make ssdt2 match to PCI2 in pci2.asl,... pci1234[1] + AmlCode_ssdtx[1] = AmlCode_ssdt2; // if you have different HT IO card for the same ht slot, here need to check vendor id, to set coresponding SSDT + AmlCode_ssdtx[2] = AmlCode_ssdt3; + AmlCode_ssdtx[3] = AmlCode_ssdt4; +// AmlCode_ssdtx[4] = AmlCode_ssdt5; +// AmlCode_ssdtx[5] = AmlCode_ssdt6; +// AmlCode_ssdtx[6] = AmlCode_ssdt7; +// AmlCode_ssdtx[7] = AmlCode_ssdt8; + + //same htio, but different possition? We may have to copy, change HCIN, and recalculate the checknum and add_table + + for (i = 1; i < hc_possible_num; i++) { // 0: is hc sblink + if ((pci1234[i] & 1) != 1) + continue; + printk_debug("ACPI: * SSDT for PCI%d\n", i + 1); //pci0 and pci1 are in dsdt + ssdtx = (acpi_header_t *) current; + current += ((acpi_header_t *) AmlCode_ssdtx[i])->length; + memcpy((void *) ssdtx, (void *) AmlCode_ssdtx[i], + ((acpi_header_t *) AmlCode_ssdtx[i])->length); + acpi_add_table(rsdt, ssdtx); + } +#endif + + + /* FACS */ printk_debug("ACPI: * FACS\n"); facs = (acpi_facs_t *) current; current += sizeof(acpi_facs_t); acpi_create_facs(facs); - dsdt = (acpi_header_t *)current; - current += ((acpi_header_t *)AmlCode)->length; - memcpy((void *)dsdt,(void *)AmlCode, \ - ((acpi_header_t *)AmlCode)->length); + /* DSDT */ + printk_debug("ACPI: * DSDT\n"); + dsdt = (acpi_header_t *) current; + current += ((acpi_header_t *) AmlCode)->length; + memcpy((void *) dsdt, (void *) AmlCode, + ((acpi_header_t *) AmlCode)->length); + printk_debug("ACPI: * DSDT @ %08x Length %x\n", dsdt, + dsdt->length); - /* fix up dsdt */ - ((u32 *)dsdt)[11]=((u32)lnxb)+sizeof(acpi_header_t); - - /* recalculate checksum */ - dsdt->checksum = 0; - dsdt->checksum = acpi_checksum(dsdt,dsdt->length); - printk_debug("ACPI: * DSDT @ %08x Length %x\n",dsdt,dsdt->length); + /* FDAT */ printk_debug("ACPI: * FADT\n"); - fadt = (acpi_fadt_t *) current; current += sizeof(acpi_fadt_t); - acpi_create_fadt(fadt,facs,dsdt); - acpi_add_table(rsdt,fadt); + acpi_create_fadt(fadt, facs, dsdt); + acpi_add_table(rsdt, fadt); + +#if DUMP_ACPI_TABLES == 1 + printk_debug("rsdp\n"); + dump_mem(rsdp, ((void *) rsdp) + sizeof(acpi_rsdp_t)); + + printk_debug("rsdt\n"); + dump_mem(rsdt, ((void *) rsdt) + sizeof(acpi_rsdt_t)); + + printk_debug("madt\n"); + dump_mem(madt, ((void *) madt) + madt->header.length); + + printk_debug("srat\n"); + dump_mem(srat, ((void *) srat) + srat->header.length); + + printk_debug("ssdt\n"); + dump_mem(ssdt, ((void *) ssdt) + ssdt->length); + + printk_debug("fadt\n"); + dump_mem(fadt, ((void *) fadt) + fadt->header.length); +#endif printk_info("ACPI: done.\n"); return current; } - |