diff options
author | Stefan Reinauer <stepan@coreboot.org> | 2010-12-11 20:33:41 +0000 |
---|---|---|
committer | Stefan Reinauer <stepan@openbios.org> | 2010-12-11 20:33:41 +0000 |
commit | 8677a23d5b053d550f70246de9c7dc8fd4e2fbf9 (patch) | |
tree | d9a7c6042de85d623739e2679ba90c66aad2797f /src/arch/i386/boot | |
parent | 198cb96387c457affa01696405ffaa4531e8e361 (diff) |
After this has been brought up many times before, rename src/arch/i386 to
src/arch/x86.
Signed-off-by: Stefan Reinauer <stepan@coreboot.org>
Acked-by: Patrick Georgi <patrick@georgi-clan.de>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6161 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/arch/i386/boot')
-rw-r--r-- | src/arch/i386/boot/Makefile.inc | 13 | ||||
-rw-r--r-- | src/arch/i386/boot/acpi.c | 604 | ||||
-rw-r--r-- | src/arch/i386/boot/acpigen.c | 517 | ||||
-rw-r--r-- | src/arch/i386/boot/boot.c | 186 | ||||
-rw-r--r-- | src/arch/i386/boot/coreboot_table.c | 600 | ||||
-rw-r--r-- | src/arch/i386/boot/gdt.c | 60 | ||||
-rw-r--r-- | src/arch/i386/boot/mpspec.c | 383 | ||||
-rw-r--r-- | src/arch/i386/boot/multiboot.c | 77 | ||||
-rw-r--r-- | src/arch/i386/boot/pirq_routing.c | 169 | ||||
-rw-r--r-- | src/arch/i386/boot/tables.c | 231 | ||||
-rw-r--r-- | src/arch/i386/boot/wakeup.S | 105 |
11 files changed, 0 insertions, 2945 deletions
diff --git a/src/arch/i386/boot/Makefile.inc b/src/arch/i386/boot/Makefile.inc deleted file mode 100644 index 1ae32e441c..0000000000 --- a/src/arch/i386/boot/Makefile.inc +++ /dev/null @@ -1,13 +0,0 @@ -ramstage-y += boot.c -ramstage-y += coreboot_table.c -ramstage-$(CONFIG_MULTIBOOT) += multiboot.c -ramstage-y += gdt.c -ramstage-y += tables.c -ramstage-$(CONFIG_GENERATE_MP_TABLE) += mpspec.c -ramstage-$(CONFIG_GENERATE_PIRQ_TABLE) += pirq_routing.c -ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c -ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpigen.c -ramstage-$(CONFIG_HAVE_ACPI_RESUME) += wakeup.S - -$(obj)/arch/i386/boot/coreboot_table.ramstage.o : $(OPTION_TABLE_H) - diff --git a/src/arch/i386/boot/acpi.c b/src/arch/i386/boot/acpi.c deleted file mode 100644 index 957ec4559a..0000000000 --- a/src/arch/i386/boot/acpi.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * coreboot ACPI Table support - * written by Stefan Reinauer <stepan@openbios.org> - * - * Copyright (C) 2004 SUSE LINUX AG - * Copyright (C) 2005-2009 coresystems GmbH - * - * ACPI FADT, FACS, and DSDT table support added by - * Nick Barker <nick.barker9@btinternet.com>, and those portions - * Copyright (C) 2004 Nick Barker - * - * Copyright (C) 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved. - * 2005.9 yhlu add SRAT table generation - */ - -/* - * Each system port implementing ACPI has to provide two functions: - * - * write_acpi_tables() - * acpi_dump_apics() - * - * See Kontron 986LCD-M port for a good example of an ACPI implementation - * in coreboot. - */ - -#include <console/console.h> -#include <string.h> -#include <arch/acpi.h> -#include <arch/acpigen.h> -#include <device/pci.h> -#include <cbmem.h> - -u8 acpi_checksum(u8 *table, u32 length) -{ - u8 ret = 0; - while (length--) { - ret += *table; - table++; - } - return -ret; -} - -/** - * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length - * and checksum. - */ -void acpi_add_table(acpi_rsdp_t *rsdp, void *table) -{ - int i, entries_num; - acpi_rsdt_t *rsdt; - acpi_xsdt_t *xsdt = NULL; - - /* The RSDT is mandatory... */ - rsdt = (acpi_rsdt_t *)rsdp->rsdt_address; - - /* ...while the XSDT is not. */ - if (rsdp->xsdt_address) - xsdt = (acpi_xsdt_t *)((u32)rsdp->xsdt_address); - - /* This should always be MAX_ACPI_TABLES. */ - entries_num = ARRAY_SIZE(rsdt->entry); - - for (i = 0; i < entries_num; i++) { - if (rsdt->entry[i] == 0) - break; - } - - if (i >= entries_num) { - printk(BIOS_ERR, "ACPI: Error: Could not add ACPI table, " - "too many tables.\n"); - return; - } - - /* Add table to the RSDT. */ - rsdt->entry[i] = (u32)table; - - /* Fix RSDT length or the kernel will assume invalid entries. */ - rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i + 1)); - - /* Re-calculate checksum. */ - rsdt->header.checksum = 0; /* Hope this won't get optimized away */ - rsdt->header.checksum = acpi_checksum((u8 *)rsdt, rsdt->header.length); - - /* - * And now the same thing for the XSDT. We use the same index as for - * now we want the XSDT and RSDT to always be in sync in coreboot. - */ - if (xsdt) { - /* Add table to the XSDT. */ - xsdt->entry[i] = (u64)(u32)table; - - /* Fix XSDT length. */ - xsdt->header.length = sizeof(acpi_header_t) + - (sizeof(u64) * (i + 1)); - - /* Re-calculate checksum. */ - xsdt->header.checksum = 0; - xsdt->header.checksum = acpi_checksum((u8 *)xsdt, - xsdt->header.length); - } - - printk(BIOS_DEBUG, "ACPI: added table %d/%d, length now %d\n", - i + 1, entries_num, rsdt->header.length); -} - -int acpi_create_mcfg_mmconfig(acpi_mcfg_mmconfig_t *mmconfig, u32 base, - u16 seg_nr, u8 start, u8 end) -{ - mmconfig->base_address = base; - mmconfig->base_reserved = 0; - mmconfig->pci_segment_group_number = seg_nr; - mmconfig->start_bus_number = start; - mmconfig->end_bus_number = end; - - return sizeof(acpi_mcfg_mmconfig_t); -} - -int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic) -{ - lapic->type = 0; /* Local APIC structure */ - lapic->length = sizeof(acpi_madt_lapic_t); - lapic->flags = (1 << 0); /* Processor/LAPIC enabled */ - lapic->processor_id = cpu; - lapic->apic_id = apic; - - return lapic->length; -} - -unsigned long acpi_create_madt_lapics(unsigned long current) -{ - device_t cpu; - int cpu_index = 0; - - for (cpu = all_devices; cpu; cpu = cpu->next) { - if ((cpu->path.type != DEVICE_PATH_APIC) || - (cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER)) { - continue; - } - if (!cpu->enabled) - continue; - current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, - cpu_index, cpu->path.apic.apic_id); - cpu_index++; - } - - return current; -} - -int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr, - u32 gsi_base) -{ - ioapic->type = 1; /* I/O APIC structure */ - ioapic->length = sizeof(acpi_madt_ioapic_t); - ioapic->reserved = 0x00; - ioapic->gsi_base = gsi_base; - ioapic->ioapic_id = id; - ioapic->ioapic_addr = addr; - - return ioapic->length; -} - -int acpi_create_madt_irqoverride(acpi_madt_irqoverride_t *irqoverride, - u8 bus, u8 source, u32 gsirq, u16 flags) -{ - irqoverride->type = 2; /* Interrupt source override */ - irqoverride->length = sizeof(acpi_madt_irqoverride_t); - irqoverride->bus = bus; - irqoverride->source = source; - irqoverride->gsirq = gsirq; - irqoverride->flags = flags; - - return irqoverride->length; -} - -int acpi_create_madt_lapic_nmi(acpi_madt_lapic_nmi_t *lapic_nmi, u8 cpu, - u16 flags, u8 lint) -{ - lapic_nmi->type = 4; /* Local APIC NMI structure */ - lapic_nmi->length = sizeof(acpi_madt_lapic_nmi_t); - lapic_nmi->flags = flags; - lapic_nmi->processor_id = cpu; - lapic_nmi->lint = lint; - - return lapic_nmi->length; -} - -void acpi_create_madt(acpi_madt_t *madt) -{ -#define LOCAL_APIC_ADDR 0xfee00000ULL - - acpi_header_t *header = &(madt->header); - unsigned long current = (unsigned long)madt + sizeof(acpi_madt_t); - - memset((void *)madt, 0, sizeof(acpi_madt_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "APIC", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_madt_t); - header->revision = 1; /* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */ - - madt->lapic_addr = LOCAL_APIC_ADDR; - madt->flags = 0x1; /* PCAT_COMPAT */ - - current = acpi_fill_madt(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)madt; - - header->checksum = acpi_checksum((void *)madt, header->length); -} - -/* MCFG is defined in the PCI Firmware Specification 3.0. */ -void acpi_create_mcfg(acpi_mcfg_t *mcfg) -{ - acpi_header_t *header = &(mcfg->header); - unsigned long current = (unsigned long)mcfg + sizeof(acpi_mcfg_t); - - memset((void *)mcfg, 0, sizeof(acpi_mcfg_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "MCFG", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_mcfg_t); - header->revision = 1; - - current = acpi_fill_mcfg(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)mcfg; - header->checksum = acpi_checksum((void *)mcfg, header->length); -} - -/* - * This can be overriden by platform ACPI setup code, if it calls - * acpi_create_ssdt_generator(). - */ -unsigned long __attribute__((weak)) acpi_fill_ssdt_generator( - unsigned long current, const char *oem_table_id) -{ - return current; -} - -void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id) -{ - unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t); - - memset((void *)ssdt, 0, sizeof(acpi_header_t)); - - memcpy(&ssdt->signature, "SSDT", 4); - ssdt->revision = 2; /* ACPI 1.0/2.0: ?, ACPI 3.0/4.0: 2 */ - memcpy(&ssdt->oem_id, OEM_ID, 6); - memcpy(&ssdt->oem_table_id, oem_table_id, 8); - ssdt->oem_revision = 42; - memcpy(&ssdt->asl_compiler_id, ASLC, 4); - ssdt->asl_compiler_revision = 42; - ssdt->length = sizeof(acpi_header_t); - - acpigen_set_current((char *) current); - current = acpi_fill_ssdt_generator(current, oem_table_id); - - /* (Re)calculate length and checksum. */ - ssdt->length = current - (unsigned long)ssdt; - ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length); -} - -int acpi_create_srat_lapic(acpi_srat_lapic_t *lapic, u8 node, u8 apic) -{ - memset((void *)lapic, 0, sizeof(acpi_srat_lapic_t)); - - lapic->type = 0; /* Processor local APIC/SAPIC affinity structure */ - lapic->length = sizeof(acpi_srat_lapic_t); - lapic->flags = (1 << 0); /* Enabled (the use of this structure). */ - lapic->proximity_domain_7_0 = node; - /* TODO: proximity_domain_31_8, local SAPIC EID, clock domain. */ - lapic->apic_id = apic; - - return lapic->length; -} - -int acpi_create_srat_mem(acpi_srat_mem_t *mem, u8 node, u32 basek, u32 sizek, - u32 flags) -{ - mem->type = 1; /* Memory affinity structure */ - mem->length = sizeof(acpi_srat_mem_t); - mem->base_address_low = (basek << 10); - mem->base_address_high = (basek >> (32 - 10)); - mem->length_low = (sizek << 10); - mem->length_high = (sizek >> (32 - 10)); - mem->proximity_domain = node; - mem->flags = flags; - - return mem->length; -} - -/* http://www.microsoft.com/whdc/system/sysinternals/sratdwn.mspx */ -void acpi_create_srat(acpi_srat_t *srat) -{ - acpi_header_t *header = &(srat->header); - unsigned long current = (unsigned long)srat + sizeof(acpi_srat_t); - - memset((void *)srat, 0, sizeof(acpi_srat_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "SRAT", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_srat_t); - header->revision = 1; /* ACPI 1.0: N/A, 2.0: 1, 3.0: 2, 4.0: 3 */ - - srat->resv = 1; /* Spec: Reserved to 1 for backwards compatibility. */ - - current = acpi_fill_srat(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)srat; - header->checksum = acpi_checksum((void *)srat, header->length); -} - -/* http://h21007.www2.hp.com/portal/download/files/unprot/Itanium/slit.pdf */ -void acpi_create_slit(acpi_slit_t *slit) -{ - acpi_header_t *header = &(slit->header); - unsigned long current = (unsigned long)slit + sizeof(acpi_slit_t); - - memset((void *)slit, 0, sizeof(acpi_slit_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "SLIT", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_slit_t); - header->revision = 1; /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */ - - current = acpi_fill_slit(current); - - /* (Re)calculate length and checksum. */ - header->length = current - (unsigned long)slit; - header->checksum = acpi_checksum((void *)slit, header->length); -} - -/* http://www.intel.com/hardwaredesign/hpetspec_1.pdf */ -void acpi_create_hpet(acpi_hpet_t *hpet) -{ -#define HPET_ADDR 0xfed00000ULL - acpi_header_t *header = &(hpet->header); - acpi_addr_t *addr = &(hpet->addr); - - memset((void *)hpet, 0, sizeof(acpi_hpet_t)); - - /* Fill out header fields. */ - memcpy(header->signature, "HPET", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_hpet_t); - header->revision = 1; /* Currently 1. Table added in ACPI 2.0. */ - - /* Fill out HPET address. */ - addr->space_id = 0; /* Memory */ - addr->bit_width = 64; - addr->bit_offset = 0; - addr->addrl = HPET_ADDR & 0xffffffff; - addr->addrh = HPET_ADDR >> 32; - - hpet->id = 0x102282a0; /* AMD! FIXME */ - hpet->number = 0; - hpet->min_tick = 4096; - - header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t)); -} - -void acpi_create_facs(acpi_facs_t *facs) -{ - memset((void *)facs, 0, sizeof(acpi_facs_t)); - - memcpy(facs->signature, "FACS", 4); - facs->length = sizeof(acpi_facs_t); - facs->hardware_signature = 0; - facs->firmware_waking_vector = 0; - facs->global_lock = 0; - facs->flags = 0; - facs->x_firmware_waking_vector_l = 0; - facs->x_firmware_waking_vector_h = 0; - facs->version = 1; /* ACPI 1.0: 0, ACPI 2.0/3.0: 1, ACPI 4.0: 2 */ -} - -void acpi_write_rsdt(acpi_rsdt_t *rsdt) -{ - acpi_header_t *header = &(rsdt->header); - - /* Fill out header fields. */ - memcpy(header->signature, "RSDT", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_rsdt_t); - header->revision = 1; /* ACPI 1.0/2.0/3.0/4.0: 1 */ - - /* Entries are filled in later, we come with an empty set. */ - - /* Fix checksum. */ - header->checksum = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t)); -} - -void acpi_write_xsdt(acpi_xsdt_t *xsdt) -{ - acpi_header_t *header = &(xsdt->header); - - /* Fill out header fields. */ - memcpy(header->signature, "XSDT", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_xsdt_t); - header->revision = 1; /* ACPI 1.0: N/A, 2.0/3.0/4.0: 1 */ - - /* Entries are filled in later, we come with an empty set. */ - - /* Fix checksum. */ - header->checksum = acpi_checksum((void *)xsdt, sizeof(acpi_xsdt_t)); -} - -void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt, acpi_xsdt_t *xsdt) -{ - memset(rsdp, 0, sizeof(acpi_rsdp_t)); - - memcpy(rsdp->signature, RSDP_SIG, 8); - memcpy(rsdp->oem_id, OEM_ID, 6); - - rsdp->length = sizeof(acpi_rsdp_t); - rsdp->rsdt_address = (u32)rsdt; - - /* - * Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2. - * - * Some OSes expect an XSDT to be present for RSD PTR revisions >= 2. - * If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR - * revision 0). - */ - if (xsdt == NULL) { - rsdp->revision = 0; - } else { - rsdp->xsdt_address = (u64)(u32)xsdt; - rsdp->revision = 2; - } - - /* Calculate checksums. */ - rsdp->checksum = acpi_checksum((void *)rsdp, 20); - rsdp->ext_checksum = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t)); -} - -#if CONFIG_HAVE_ACPI_RESUME == 1 -void suspend_resume(void) -{ - void *wake_vec; - - /* If we happen to be resuming find wakeup vector and jump to OS. */ - wake_vec = acpi_find_wakeup_vector(); - if (wake_vec) - acpi_jump_to_wakeup(wake_vec); -} - -/* This is to be filled by SB code - startup value what was found. */ -u8 acpi_slp_type = 0; - -static int acpi_is_wakeup(void) -{ - return (acpi_slp_type == 3); -} - -static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) -{ - if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) - return NULL; - - printk(BIOS_DEBUG, "Looking on %p for valid checksum\n", rsdp); - - if (acpi_checksum((void *)rsdp, 20) != 0) - return NULL; - printk(BIOS_DEBUG, "Checksum 1 passed\n"); - - if ((rsdp->revision > 1) && (acpi_checksum((void *)rsdp, - rsdp->length) != 0)) - return NULL; - printk(BIOS_DEBUG, "Checksum 2 passed all OK\n"); - - return rsdp; -} - -static acpi_rsdp_t *rsdp; - -void *acpi_get_wakeup_rsdp(void) -{ - return rsdp; -} - -void *acpi_find_wakeup_vector(void) -{ - char *p, *end; - acpi_rsdt_t *rsdt; - acpi_facs_t *facs; - acpi_fadt_t *fadt; - void *wake_vec; - int i; - - rsdp = NULL; - - if (!acpi_is_wakeup()) - return NULL; - - printk(BIOS_DEBUG, "Trying to find the wakeup vector...\n"); - - /* Find RSDP. */ - for (p = (char *)0xe0000; p < (char *)0xfffff; p += 16) { - if ((rsdp = valid_rsdp((acpi_rsdp_t *)p))) - break; - } - - if (rsdp == NULL) - return NULL; - - printk(BIOS_DEBUG, "RSDP found at %p\n", rsdp); - rsdt = (acpi_rsdt_t *) rsdp->rsdt_address; - - end = (char *)rsdt + rsdt->header.length; - printk(BIOS_DEBUG, "RSDT found at %p ends at %p\n", rsdt, end); - - for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) { - fadt = (acpi_fadt_t *)rsdt->entry[i]; - if (strncmp((char *)fadt, "FACP", 4) == 0) - break; - fadt = NULL; - } - - if (fadt == NULL) - return NULL; - - printk(BIOS_DEBUG, "FADT found at %p\n", fadt); - facs = (acpi_facs_t *)fadt->firmware_ctrl; - - if (facs == NULL) { - printk(BIOS_DEBUG, "No FACS found, wake up from S3 not " - "possible.\n"); - return NULL; - } - - printk(BIOS_DEBUG, "FACS found at %p\n", facs); - wake_vec = (void *)facs->firmware_waking_vector; - printk(BIOS_DEBUG, "OS waking vector is %p\n", wake_vec); - - return wake_vec; -} - -extern char *lowmem_backup; -extern char *lowmem_backup_ptr; -extern int lowmem_backup_size; - -#define WAKEUP_BASE 0x600 - -void (*acpi_do_wakeup)(u32 vector, u32 backup_source, u32 backup_target, - u32 backup_size) __attribute__((regparm(0))) = (void *)WAKEUP_BASE; - -extern unsigned char __wakeup, __wakeup_size; - -void acpi_jump_to_wakeup(void *vector) -{ - u32 acpi_backup_memory = (u32)cbmem_find(CBMEM_ID_RESUME); - - if (!acpi_backup_memory) { - printk(BIOS_WARNING, "ACPI: Backup memory missing. " - "No S3 resume.\n"); - return; - } - - // FIXME: This should go into the ACPI backup memory, too. No pork saussages. - /* - * Just restore the SMP trampoline and continue with wakeup on - * assembly level. - */ - memcpy(lowmem_backup_ptr, lowmem_backup, lowmem_backup_size); - - /* Copy wakeup trampoline in place. */ - memcpy((void *)WAKEUP_BASE, &__wakeup, (size_t)&__wakeup_size); - - acpi_do_wakeup((u32)vector, acpi_backup_memory, CONFIG_RAMBASE, - HIGH_MEMORY_SAVE); -} -#endif diff --git a/src/arch/i386/boot/acpigen.c b/src/arch/i386/boot/acpigen.c deleted file mode 100644 index e8cd724e23..0000000000 --- a/src/arch/i386/boot/acpigen.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* how many nesting we support */ -#define ACPIGEN_LENSTACK_SIZE 10 - -/* if you need to change this, change the acpigen_write_f and - acpigen_patch_len */ - -#define ACPIGEN_MAXLEN 0xfff - -#include <string.h> -#include <arch/acpigen.h> -#include <console/console.h> -#include <device/device.h> - -static char *gencurrent; - -char *len_stack[ACPIGEN_LENSTACK_SIZE]; -int ltop = 0; - -static int acpigen_write_len_f(void) -{ - ASSERT(ltop < (ACPIGEN_LENSTACK_SIZE - 1)) - len_stack[ltop++] = gencurrent; - acpigen_emit_byte(0); - acpigen_emit_byte(0); - return 2; -} - -void acpigen_patch_len(int len) -{ - ASSERT(len <= ACPIGEN_MAXLEN) - ASSERT(ltop > 0) - char *p = len_stack[--ltop]; - /* generate store length for 0xfff max */ - p[0] = (0x40 | (len & 0xf)); - p[1] = (len >> 4 & 0xff); - -} - -void acpigen_set_current(char *curr) -{ - gencurrent = curr; -} - -char *acpigen_get_current(void) -{ - return gencurrent; -} - -int acpigen_emit_byte(unsigned char b) -{ - (*gencurrent++) = b; - return 1; -} - -int acpigen_write_package(int nr_el) -{ - int len; - /* package op */ - acpigen_emit_byte(0x12); - len = acpigen_write_len_f(); - acpigen_emit_byte(nr_el); - return len + 2; -} - -int acpigen_write_byte(unsigned int data) -{ - /* byte op */ - acpigen_emit_byte(0xa); - acpigen_emit_byte(data & 0xff); - return 2; -} - -int acpigen_write_dword(unsigned int data) -{ - /* dword op */ - acpigen_emit_byte(0xc); - acpigen_emit_byte(data & 0xff); - acpigen_emit_byte((data >> 8) & 0xff); - acpigen_emit_byte((data >> 16) & 0xff); - acpigen_emit_byte((data >> 24) & 0xff); - return 5; -} - -int acpigen_write_qword(uint64_t data) -{ - /* qword op */ - acpigen_emit_byte(0xe); - acpigen_emit_byte(data & 0xff); - acpigen_emit_byte((data >> 8) & 0xff); - acpigen_emit_byte((data >> 16) & 0xff); - acpigen_emit_byte((data >> 24) & 0xff); - acpigen_emit_byte((data >> 32) & 0xff); - acpigen_emit_byte((data >> 40) & 0xff); - acpigen_emit_byte((data >> 48) & 0xff); - acpigen_emit_byte((data >> 56) & 0xff); - return 9; -} - -int acpigen_write_name_byte(const char *name, uint8_t val) -{ - int len; - len = acpigen_write_name(name); - len += acpigen_write_byte(val); - return len; -} - -int acpigen_write_name_dword(const char *name, uint32_t val) -{ - int len; - len = acpigen_write_name(name); - len += acpigen_write_dword(val); - return len; -} - -int acpigen_write_name_qword(const char *name, uint64_t val) -{ - int len; - len = acpigen_write_name(name); - len += acpigen_write_qword(val); - return len; -} - -int acpigen_emit_stream(const char *data, int size) -{ - int i; - for (i = 0; i < size; i++) { - acpigen_emit_byte(data[i]); - } - return size; -} - -/* The NameString are bit tricky, each element can be 4 chars, if - less its padded with underscore. Check 18.2.2 and 18.4 - and 5.3 of ACPI specs 3.0 for details -*/ - -static int acpigen_emit_simple_namestring(const char *name) { - int i, len = 0; - char ud[] = "____"; - for (i = 0; i < 4; i++) { - if ((name[i] == '\0') || (name[i] == '.')) { - len += acpigen_emit_stream(ud, 4 - i); - break; - } else { - len += acpigen_emit_byte(name[i]); - } - } - return len; -} - -static int acpigen_emit_double_namestring(const char *name, int dotpos) { - int len = 0; - /* mark dual name prefix */ - len += acpigen_emit_byte(0x2e); - len += acpigen_emit_simple_namestring(name); - len += acpigen_emit_simple_namestring(&name[dotpos + 1]); - return len; -} - -static int acpigen_emit_multi_namestring(const char *name) { - int len = 0, count = 0; - unsigned char *pathlen; - /* mark multi name prefix */ - len += acpigen_emit_byte(0x2f); - len += acpigen_emit_byte(0x0); - pathlen = ((unsigned char *) acpigen_get_current()) - 1; - - while (name[0] != '\0') { - len += acpigen_emit_simple_namestring(name); - /* find end or next entity */ - while ((name[0] != '.') && (name[0] != '\0')) - name++; - /* forward to next */ - if (name[0] == '.') - name++; - count++; - } - - pathlen[0] = count; - return len; -} - - -int acpigen_emit_namestring(const char *namepath) { - int dotcount = 0, i; - int dotpos = 0; - int len = 0; - - /* we can start with a \ */ - if (namepath[0] == '\\') { - len += acpigen_emit_byte('\\'); - namepath++; - } - - /* and there can be any number of ^ */ - while (namepath[0] == '^') { - len += acpigen_emit_byte('^'); - namepath++; - } - - ASSERT(namepath[0] != '\0'); - - i = 0; - while (namepath[i] != '\0') { - if (namepath[i] == '.') { - dotcount++; - dotpos = i; - } - i++; - } - - if (dotcount == 0) { - len += acpigen_emit_simple_namestring(namepath); - } else if (dotcount == 1) { - len += acpigen_emit_double_namestring(namepath, dotpos); - } else { - len += acpigen_emit_multi_namestring(namepath); - } - return len; -} - -int acpigen_write_name(const char *name) -{ - int len; - /* name op */ - len = acpigen_emit_byte(0x8); - return len + acpigen_emit_namestring(name); -} - -int acpigen_write_scope(const char *name) -{ - int len; - /* scope op */ - len = acpigen_emit_byte(0x10); - len += acpigen_write_len_f(); - return len + acpigen_emit_namestring(name); -} - -int acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len) -{ -/* - Processor (\_PR.CPUcpuindex, cpuindex, pblock_addr, pblock_len) - { -*/ - char pscope[16]; - int len; - /* processor op */ - acpigen_emit_byte(0x5b); - acpigen_emit_byte(0x83); - len = acpigen_write_len_f(); - - sprintf(pscope, "\\_PR.CPU%x", (unsigned int) cpuindex); - len += acpigen_emit_namestring(pscope); - acpigen_emit_byte(cpuindex); - acpigen_emit_byte(pblock_addr & 0xff); - acpigen_emit_byte((pblock_addr >> 8) & 0xff); - acpigen_emit_byte((pblock_addr >> 16) & 0xff); - acpigen_emit_byte((pblock_addr >> 24) & 0xff); - acpigen_emit_byte(pblock_len); - return 6 + 2 + len; -} - -int acpigen_write_empty_PCT(void) -{ -/* - Name (_PCT, Package (0x02) - { - ResourceTemplate () - { - Register (FFixedHW, - 0x00, // Bit Width - 0x00, // Bit Offset - 0x0000000000000000, // Address - ,) - }, - - ResourceTemplate () - { - Register (FFixedHW, - 0x00, // Bit Width - 0x00, // Bit Offset - 0x0000000000000000, // Address - ,) - } - }) -*/ - static char stream[] = { - 0x08, 0x5F, 0x50, 0x43, 0x54, 0x12, 0x2C, /* 00000030 "0._PCT.," */ - 0x02, 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, /* 00000038 "........" */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00000040 "........" */ - 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x11, 0x14, /* 00000048 "....y..." */ - 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, 0x00, 0x00, /* 00000050 "........" */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00000058 "........" */ - 0x00, 0x79, 0x00 - }; - return acpigen_emit_stream(stream, ARRAY_SIZE(stream)); -} - -/* generates a func with max supported P states */ -int acpigen_write_PPC(u8 nr) -{ -/* - Method (_PPC, 0, NotSerialized) - { - Return (nr) - } -*/ - int len; - /* method op */ - acpigen_emit_byte(0x14); - len = acpigen_write_len_f(); - len += acpigen_emit_namestring("_PPC"); - /* no fnarg */ - acpigen_emit_byte(0x00); - /* return */ - acpigen_emit_byte(0xa4); - /* arg */ - len += acpigen_write_byte(nr); - /* add all single bytes */ - len += 3; - acpigen_patch_len(len - 1); - return len; -} - -int acpigen_write_PSS_package(u32 coreFreq, u32 power, u32 transLat, - u32 busmLat, u32 control, u32 status) -{ - int len; - len = acpigen_write_package(6); - len += acpigen_write_dword(coreFreq); - len += acpigen_write_dword(power); - len += acpigen_write_dword(transLat); - len += acpigen_write_dword(busmLat); - len += acpigen_write_dword(control); - len += acpigen_write_dword(status); - //pkglen without the len opcode - acpigen_patch_len(len - 1); - return len; -} - -int acpigen_write_PSD_package(u32 domain, u32 numprocs, PSD_coord coordtype) -{ - int len, lenh, lenp; - lenh = acpigen_write_name("_PSD"); - lenp = acpigen_write_package(1); - len = acpigen_write_package(5); - len += acpigen_write_byte(5); // 5 values - len += acpigen_write_byte(0); // revision 0 - len += acpigen_write_dword(domain); - len += acpigen_write_dword(coordtype); - len += acpigen_write_dword(numprocs); - acpigen_patch_len(len - 1); - len += lenp; - acpigen_patch_len(len - 1); - return len + lenh; -} - -int acpigen_write_mem32fixed(int readwrite, u32 base, u32 size) -{ - /* - * acpi 4.0 section 6.4.3.4: 32-Bit Fixed Memory Range Descriptor - * Byte 0: - * Bit7 : 1 => big item - * Bit6-0: 0000110 (0x6) => 32-bit fixed memory - */ - acpigen_emit_byte(0x86); - /* Byte 1+2: length (0x0009) */ - acpigen_emit_byte(0x09); - acpigen_emit_byte(0x00); - /* bit1-7 are ignored */ - acpigen_emit_byte(readwrite ? 0x01 : 0x00); - acpigen_emit_byte(base & 0xff); - acpigen_emit_byte((base >> 8) & 0xff); - acpigen_emit_byte((base >> 16) & 0xff); - acpigen_emit_byte((base >> 24) & 0xff); - acpigen_emit_byte(size & 0xff); - acpigen_emit_byte((size >> 8) & 0xff); - acpigen_emit_byte((size >> 16) & 0xff); - acpigen_emit_byte((size >> 24) & 0xff); - return 12; -} - -int acpigen_write_io16(u16 min, u16 max, u8 align, u8 len, u8 decode16) -{ - /* - * acpi 4.0 section 6.4.2.6: I/O Port Descriptor - * Byte 0: - * Bit7 : 0 => small item - * Bit6-3: 1000 (0x8) => I/O port descriptor - * Bit2-0: 111 (0x7) => 7 Bytes long - */ - acpigen_emit_byte(0x47); - /* does the device decode all 16 or just 10 bits? */ - /* bit1-7 are ignored */ - acpigen_emit_byte(decode16 ? 0x01 : 0x00); - /* minimum base address the device may be configured for */ - acpigen_emit_byte(min & 0xff); - acpigen_emit_byte((min >> 8) & 0xff); - /* maximum base address the device may be configured for */ - acpigen_emit_byte(max & 0xff); - acpigen_emit_byte((max >> 8) & 0xff); - /* alignment for min base */ - acpigen_emit_byte(align & 0xff); - acpigen_emit_byte(len & 0xff); - return 8; -} - -int acpigen_write_resourcetemplate_header(void) -{ - int len; - /* - * A ResourceTemplate() is a Buffer() with a - * (Byte|Word|DWord) containing the length, followed by one or more - * resource items, terminated by the end tag - * (small item 0xf, len 1) - */ - len = acpigen_emit_byte(0x11); /* Buffer opcode */ - len += acpigen_write_len_f(); - len += acpigen_emit_byte(0x0b); /* Word opcode */ - len_stack[ltop++] = acpigen_get_current(); - len += acpigen_emit_byte(0x00); - len += acpigen_emit_byte(0x00); - return len; -} - -int acpigen_write_resourcetemplate_footer(int len) -{ - char *p = len_stack[--ltop]; - /* - * end tag (acpi 4.0 Section 6.4.2.8) - * 0x79 <checksum> - * 0x00 is treated as a good checksum according to the spec - * and is what iasl generates. - */ - len += acpigen_emit_byte(0x79); - len += acpigen_emit_byte(0x00); - /* patch len word */ - p[0] = (len-6) & 0xff; - p[1] = ((len-6) >> 8) & 0xff; - /* patch len field */ - acpigen_patch_len(len-1); - return 2; -} - -static void acpigen_add_mainboard_rsvd_mem32(void *gp, struct device *dev, - struct resource *res) -{ - acpigen_write_mem32fixed(0, res->base, res->size); -} - -static void acpigen_add_mainboard_rsvd_io(void *gp, struct device *dev, - struct resource *res) -{ - resource_t base = res->base; - resource_t size = res->size; - while (size > 0) { - resource_t sz = size > 255 ? 255 : size; - acpigen_write_io16(base, base, 0, sz, 1); - size -= sz; - base += sz; - } -} - -int acpigen_write_mainboard_resource_template(void) -{ - int len; - char *start; - char *end; - len = acpigen_write_resourcetemplate_header(); - start = acpigen_get_current(); - - /* Add reserved memory ranges */ - search_global_resources( - IORESOURCE_MEM | IORESOURCE_RESERVE, - IORESOURCE_MEM | IORESOURCE_RESERVE, - acpigen_add_mainboard_rsvd_mem32, 0); - - /* Add reserved io ranges */ - search_global_resources( - IORESOURCE_IO | IORESOURCE_RESERVE, - IORESOURCE_IO | IORESOURCE_RESERVE, - acpigen_add_mainboard_rsvd_io, 0); - - end = acpigen_get_current(); - len += end-start; - len += acpigen_write_resourcetemplate_footer(len); - return len; -} - -int acpigen_write_mainboard_resources(const char *scope, const char *name) -{ - int len; - len = acpigen_write_scope(scope); - len += acpigen_write_name(name); - len += acpigen_write_mainboard_resource_template(); - acpigen_patch_len(len - 1); - return len; -} diff --git a/src/arch/i386/boot/boot.c b/src/arch/i386/boot/boot.c deleted file mode 100644 index d9cb02e776..0000000000 --- a/src/arch/i386/boot/boot.c +++ /dev/null @@ -1,186 +0,0 @@ -#include <console/console.h> -#include <ip_checksum.h> -#include <boot/elf.h> -#include <boot/elf_boot.h> -#include <string.h> -#include <cpu/x86/multiboot.h> - - -#ifndef CMD_LINE -#define CMD_LINE "" -#endif - - - -#define UPSZ(X) ((sizeof(X) + 3) &~3) - -static struct { - Elf_Bhdr hdr; - Elf_Nhdr ft_hdr; - unsigned char ft_desc[UPSZ(FIRMWARE_TYPE)]; - Elf_Nhdr bl_hdr; - unsigned char bl_desc[UPSZ(BOOTLOADER)]; - Elf_Nhdr blv_hdr; - unsigned char blv_desc[UPSZ(BOOTLOADER_VERSION)]; - Elf_Nhdr cmd_hdr; - unsigned char cmd_desc[UPSZ(CMD_LINE)]; -} elf_boot_notes = { - .hdr = { - .b_signature = 0x0E1FB007, - .b_size = sizeof(elf_boot_notes), - .b_checksum = 0, - .b_records = 4, - }, - .ft_hdr = { - .n_namesz = 0, - .n_descsz = sizeof(FIRMWARE_TYPE), - .n_type = EBN_FIRMWARE_TYPE, - }, - .ft_desc = FIRMWARE_TYPE, - .bl_hdr = { - .n_namesz = 0, - .n_descsz = sizeof(BOOTLOADER), - .n_type = EBN_BOOTLOADER_NAME, - }, - .bl_desc = BOOTLOADER, - .blv_hdr = { - .n_namesz = 0, - .n_descsz = sizeof(BOOTLOADER_VERSION), - .n_type = EBN_BOOTLOADER_VERSION, - }, - .blv_desc = BOOTLOADER_VERSION, - .cmd_hdr = { - .n_namesz = 0, - .n_descsz = sizeof(CMD_LINE), - .n_type = EBN_COMMAND_LINE, - }, - .cmd_desc = CMD_LINE, -}; - - -int elf_check_arch(Elf_ehdr *ehdr) -{ - return ( - ((ehdr->e_machine == EM_386) || (ehdr->e_machine == EM_486)) && - (ehdr->e_ident[EI_CLASS] == ELFCLASS32) && - (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) - ); - -} - -void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size) -{ - extern unsigned char _ram_seg, _eram_seg; - unsigned long lb_start, lb_size; - unsigned long adjust, adjusted_boot_notes; - - elf_boot_notes.hdr.b_checksum = - compute_ip_checksum(&elf_boot_notes, sizeof(elf_boot_notes)); - - lb_start = (unsigned long)&_ram_seg; - lb_size = (unsigned long)(&_eram_seg - &_ram_seg); - adjust = buffer + size - lb_start; - - adjusted_boot_notes = (unsigned long)&elf_boot_notes; - adjusted_boot_notes += adjust; - - printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry); - printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start); - printk(BIOS_SPEW, "lb_size = 0x%08lx\n", lb_size); - printk(BIOS_SPEW, "adjust = 0x%08lx\n", adjust); - printk(BIOS_SPEW, "buffer = 0x%08lx\n", buffer); - printk(BIOS_SPEW, " elf_boot_notes = 0x%08lx\n", (unsigned long)&elf_boot_notes); - printk(BIOS_SPEW, "adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes); - - /* Jump to kernel */ - __asm__ __volatile__( - " cld \n\t" - /* Save the callee save registers... */ - " pushl %%esi\n\t" - " pushl %%edi\n\t" - " pushl %%ebx\n\t" - /* Save the parameters I was passed */ - " pushl $0\n\t" /* 20 adjust */ - " pushl %0\n\t" /* 16 lb_start */ - " pushl %1\n\t" /* 12 buffer */ - " pushl %2\n\t" /* 8 lb_size */ - " pushl %3\n\t" /* 4 entry */ - " pushl %4\n\t" /* 0 elf_boot_notes */ - /* Compute the adjustment */ - " xorl %%eax, %%eax\n\t" - " subl 16(%%esp), %%eax\n\t" - " addl 12(%%esp), %%eax\n\t" - " addl 8(%%esp), %%eax\n\t" - " movl %%eax, 20(%%esp)\n\t" - /* Place a copy of coreboot in its new location */ - /* Move ``longs'' the coreboot size is 4 byte aligned */ - " movl 12(%%esp), %%edi\n\t" - " addl 8(%%esp), %%edi\n\t" - " movl 16(%%esp), %%esi\n\t" - " movl 8(%%esp), %%ecx\n\n" - " shrl $2, %%ecx\n\t" - " rep movsl\n\t" - - /* Adjust the stack pointer to point into the new coreboot image */ - " addl 20(%%esp), %%esp\n\t" - /* Adjust the instruction pointer to point into the new coreboot image */ - " movl $1f, %%eax\n\t" - " addl 20(%%esp), %%eax\n\t" - " jmp *%%eax\n\t" - "1: \n\t" - - /* Copy the coreboot bounce buffer over coreboot */ - /* Move ``longs'' the coreboot size is 4 byte aligned */ - " movl 16(%%esp), %%edi\n\t" - " movl 12(%%esp), %%esi\n\t" - " movl 8(%%esp), %%ecx\n\t" - " shrl $2, %%ecx\n\t" - " rep movsl\n\t" - - /* Now jump to the loaded image */ - " movl %5, %%eax\n\t" - " movl 0(%%esp), %%ebx\n\t" - " call *4(%%esp)\n\t" - - /* The loaded image returned? */ - " cli \n\t" - " cld \n\t" - - /* Copy the saved copy of coreboot where coreboot runs */ - /* Move ``longs'' the coreboot size is 4 byte aligned */ - " movl 16(%%esp), %%edi\n\t" - " movl 12(%%esp), %%esi\n\t" - " addl 8(%%esp), %%esi\n\t" - " movl 8(%%esp), %%ecx\n\t" - " shrl $2, %%ecx\n\t" - " rep movsl\n\t" - - /* Adjust the stack pointer to point into the old coreboot image */ - " subl 20(%%esp), %%esp\n\t" - - /* Adjust the instruction pointer to point into the old coreboot image */ - " movl $1f, %%eax\n\t" - " subl 20(%%esp), %%eax\n\t" - " jmp *%%eax\n\t" - "1: \n\t" - - /* Drop the parameters I was passed */ - " addl $24, %%esp\n\t" - - /* Restore the callee save registers */ - " popl %%ebx\n\t" - " popl %%edi\n\t" - " popl %%esi\n\t" - - :: - "ri" (lb_start), "ri" (buffer), "ri" (lb_size), - "ri" (entry), -#if CONFIG_MULTIBOOT - "ri"(mbi), "ri" (MB_MAGIC2) -#else - "ri"(adjusted_boot_notes), "ri" (0x0E1FB007) -#endif - ); -} - - diff --git a/src/arch/i386/boot/coreboot_table.c b/src/arch/i386/boot/coreboot_table.c deleted file mode 100644 index 484340c96a..0000000000 --- a/src/arch/i386/boot/coreboot_table.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2003-2004 Eric Biederman - * Copyright (C) 2005-2010 coresystems GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <console/console.h> -#include <ip_checksum.h> -#include <boot/tables.h> -#include <boot/coreboot_tables.h> -#include <arch/coreboot_tables.h> -#include <string.h> -#include <version.h> -#include <device/device.h> -#include <stdlib.h> -#if (CONFIG_USE_OPTION_TABLE == 1) -#include <option_table.h> -#endif - -static struct lb_header *lb_table_init(unsigned long addr) -{ - struct lb_header *header; - - /* 16 byte align the address */ - addr += 15; - addr &= ~15; - - header = (void *)addr; - header->signature[0] = 'L'; - header->signature[1] = 'B'; - header->signature[2] = 'I'; - header->signature[3] = 'O'; - header->header_bytes = sizeof(*header); - header->header_checksum = 0; - header->table_bytes = 0; - header->table_checksum = 0; - header->table_entries = 0; - return header; -} - -static struct lb_record *lb_first_record(struct lb_header *header) -{ - struct lb_record *rec; - rec = (void *)(((char *)header) + sizeof(*header)); - return rec; -} - -static struct lb_record *lb_last_record(struct lb_header *header) -{ - struct lb_record *rec; - rec = (void *)(((char *)header) + sizeof(*header) + header->table_bytes); - return rec; -} - -#if 0 -static struct lb_record *lb_next_record(struct lb_record *rec) -{ - rec = (void *)(((char *)rec) + rec->size); - return rec; -} -#endif - -static struct lb_record *lb_new_record(struct lb_header *header) -{ - struct lb_record *rec; - rec = lb_last_record(header); - if (header->table_entries) { - header->table_bytes += rec->size; - } - rec = lb_last_record(header); - header->table_entries++; - rec->tag = LB_TAG_UNUSED; - rec->size = sizeof(*rec); - return rec; -} - - -static struct lb_memory *lb_memory(struct lb_header *header) -{ - struct lb_record *rec; - struct lb_memory *mem; - rec = lb_new_record(header); - mem = (struct lb_memory *)rec; - mem->tag = LB_TAG_MEMORY; - mem->size = sizeof(*mem); - return mem; -} - -static struct lb_serial *lb_serial(struct lb_header *header) -{ -#if CONFIG_CONSOLE_SERIAL8250 - struct lb_record *rec; - struct lb_serial *serial; - rec = lb_new_record(header); - serial = (struct lb_serial *)rec; - serial->tag = LB_TAG_SERIAL; - serial->size = sizeof(*serial); - serial->ioport = CONFIG_TTYS0_BASE; - serial->baud = CONFIG_TTYS0_BAUD; - return serial; -#else - return header; -#endif -} - -static void add_console(struct lb_header *header, u16 consoletype) -{ - struct lb_console *console; - - console = (struct lb_console *)lb_new_record(header); - console->tag = LB_TAG_CONSOLE; - console->size = sizeof(*console); - console->type = consoletype; -} - -static void lb_console(struct lb_header *header) -{ -#if CONFIG_CONSOLE_SERIAL8250 - add_console(header, LB_TAG_CONSOLE_SERIAL8250); -#endif -#if CONFIG_CONSOLE_LOGBUF - add_console(header, LB_TAG_CONSOLE_LOGBUF); -#endif -#if CONFIG_USBDEBUG - add_console(header, LB_TAG_CONSOLE_EHCI); -#endif -} - -static void lb_framebuffer(struct lb_header *header) -{ -#if defined(CONFIG_BOOTSPLASH) && CONFIG_BOOTSPLASH && CONFIG_COREBOOT_KEEP_FRAMEBUFFER - void fill_lb_framebuffer(struct lb_framebuffer *framebuffer); - - struct lb_framebuffer *framebuffer; - framebuffer = (struct lb_framebuffer *)lb_new_record(header); - framebuffer->tag = LB_TAG_FRAMEBUFFER; - framebuffer->size = sizeof(*framebuffer); - fill_lb_framebuffer(framebuffer); -#endif -} - -static struct lb_mainboard *lb_mainboard(struct lb_header *header) -{ - struct lb_record *rec; - struct lb_mainboard *mainboard; - rec = lb_new_record(header); - mainboard = (struct lb_mainboard *)rec; - mainboard->tag = LB_TAG_MAINBOARD; - - mainboard->size = (sizeof(*mainboard) + - strlen(mainboard_vendor) + 1 + - strlen(mainboard_part_number) + 1 + - 3) & ~3; - - mainboard->vendor_idx = 0; - mainboard->part_number_idx = strlen(mainboard_vendor) + 1; - - memcpy(mainboard->strings + mainboard->vendor_idx, - mainboard_vendor, strlen(mainboard_vendor) + 1); - memcpy(mainboard->strings + mainboard->part_number_idx, - mainboard_part_number, strlen(mainboard_part_number) + 1); - - return mainboard; -} - -#if (CONFIG_USE_OPTION_TABLE == 1) -static struct cmos_checksum *lb_cmos_checksum(struct lb_header *header) -{ - struct lb_record *rec; - struct cmos_checksum *cmos_checksum; - rec = lb_new_record(header); - cmos_checksum = (struct cmos_checksum *)rec; - cmos_checksum->tag = LB_TAG_OPTION_CHECKSUM; - - cmos_checksum->size = (sizeof(*cmos_checksum)); - - cmos_checksum->range_start = LB_CKS_RANGE_START * 8; - cmos_checksum->range_end = ( LB_CKS_RANGE_END * 8 ) + 7; - cmos_checksum->location = LB_CKS_LOC * 8; - cmos_checksum->type = CHECKSUM_PCBIOS; - - return cmos_checksum; -} -#endif - -static void lb_strings(struct lb_header *header) -{ - static const struct { - uint32_t tag; - const char *string; - } strings[] = { - { LB_TAG_VERSION, coreboot_version, }, - { LB_TAG_EXTRA_VERSION, coreboot_extra_version, }, - { LB_TAG_BUILD, coreboot_build, }, - { LB_TAG_COMPILE_TIME, coreboot_compile_time, }, - { LB_TAG_COMPILE_BY, coreboot_compile_by, }, - { LB_TAG_COMPILE_HOST, coreboot_compile_host, }, - { LB_TAG_COMPILE_DOMAIN, coreboot_compile_domain, }, - { LB_TAG_COMPILER, coreboot_compiler, }, - { LB_TAG_LINKER, coreboot_linker, }, - { LB_TAG_ASSEMBLER, coreboot_assembler, }, - }; - unsigned int i; - for(i = 0; i < ARRAY_SIZE(strings); i++) { - struct lb_string *rec; - size_t len; - rec = (struct lb_string *)lb_new_record(header); - len = strlen(strings[i].string); - rec->tag = strings[i].tag; - rec->size = (sizeof(*rec) + len + 1 + 3) & ~3; - memcpy(rec->string, strings[i].string, len+1); - } - -} - -#if CONFIG_WRITE_HIGH_TABLES == 1 -static struct lb_forward *lb_forward(struct lb_header *header, struct lb_header *next_header) -{ - struct lb_record *rec; - struct lb_forward *forward; - rec = lb_new_record(header); - forward = (struct lb_forward *)rec; - forward->tag = LB_TAG_FORWARD; - forward->size = sizeof(*forward); - forward->forward = (uint64_t)(unsigned long)next_header; - return forward; -} -#endif - -void lb_memory_range(struct lb_memory *mem, - uint32_t type, uint64_t start, uint64_t size) -{ - int entries; - entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); - mem->map[entries].start = pack_lb64(start); - mem->map[entries].size = pack_lb64(size); - mem->map[entries].type = type; - mem->size += sizeof(mem->map[0]); -} - -static void lb_reserve_table_memory(struct lb_header *head) -{ - struct lb_record *last_rec; - struct lb_memory *mem; - uint64_t start; - uint64_t end; - int i, entries; - - last_rec = lb_last_record(head); - mem = get_lb_mem(); - start = (unsigned long)head; - end = (unsigned long)last_rec; - entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); - /* Resize the right two memory areas so this table is in - * a reserved area of memory. Everything has been carefully - * setup so that is all we need to do. - */ - for(i = 0; i < entries; i++ ) { - uint64_t map_start = unpack_lb64(mem->map[i].start); - uint64_t map_end = map_start + unpack_lb64(mem->map[i].size); - /* Does this area need to be expanded? */ - if (map_end == start) { - mem->map[i].size = pack_lb64(end - map_start); - } - /* Does this area need to be contracted? */ - else if (map_start == start) { - mem->map[i].start = pack_lb64(end); - mem->map[i].size = pack_lb64(map_end - end); - } - } -} - -static unsigned long lb_table_fini(struct lb_header *head, int fixup) -{ - struct lb_record *rec, *first_rec; - rec = lb_last_record(head); - if (head->table_entries) { - head->table_bytes += rec->size; - } - - if (fixup) - lb_reserve_table_memory(head); - - first_rec = lb_first_record(head); - head->table_checksum = compute_ip_checksum(first_rec, head->table_bytes); - head->header_checksum = 0; - head->header_checksum = compute_ip_checksum(head, sizeof(*head)); - printk(BIOS_DEBUG, "Wrote coreboot table at: %p - %p checksum %x\n", - head, rec, head->table_checksum); - return (unsigned long)rec; -} - -static void lb_cleanup_memory_ranges(struct lb_memory *mem) -{ - int entries; - int i, j; - entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); - - /* Sort the lb memory ranges */ - for(i = 0; i < entries; i++) { - uint64_t entry_start = unpack_lb64(mem->map[i].start); - for(j = i; j < entries; j++) { - uint64_t temp_start = unpack_lb64(mem->map[j].start); - if (temp_start < entry_start) { - struct lb_memory_range tmp; - tmp = mem->map[i]; - mem->map[i] = mem->map[j]; - mem->map[j] = tmp; - } - } - } - - /* Merge adjacent entries */ - for(i = 0; (i + 1) < entries; i++) { - uint64_t start, end, nstart, nend; - if (mem->map[i].type != mem->map[i + 1].type) { - continue; - } - start = unpack_lb64(mem->map[i].start); - end = start + unpack_lb64(mem->map[i].size); - nstart = unpack_lb64(mem->map[i + 1].start); - nend = nstart + unpack_lb64(mem->map[i + 1].size); - if ((start <= nstart) && (end > nstart)) { - if (start > nstart) { - start = nstart; - } - if (end < nend) { - end = nend; - } - /* Record the new region size */ - mem->map[i].start = pack_lb64(start); - mem->map[i].size = pack_lb64(end - start); - - /* Delete the entry I have merged with */ - memmove(&mem->map[i + 1], &mem->map[i + 2], - ((entries - i - 2) * sizeof(mem->map[0]))); - mem->size -= sizeof(mem->map[0]); - entries -= 1; - /* See if I can merge with the next entry as well */ - i -= 1; - } - } -} - -static void lb_remove_memory_range(struct lb_memory *mem, - uint64_t start, uint64_t size) -{ - uint64_t end; - int entries; - int i; - - end = start + size; - entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); - - /* Remove a reserved area from the memory map */ - for(i = 0; i < entries; i++) { - uint64_t map_start = unpack_lb64(mem->map[i].start); - uint64_t map_end = map_start + unpack_lb64(mem->map[i].size); - if ((start <= map_start) && (end >= map_end)) { - /* Remove the completely covered range */ - memmove(&mem->map[i], &mem->map[i + 1], - ((entries - i - 1) * sizeof(mem->map[0]))); - mem->size -= sizeof(mem->map[0]); - entries -= 1; - /* Since the index will disappear revisit what will appear here */ - i -= 1; - } - else if ((start > map_start) && (end < map_end)) { - /* Split the memory range */ - memmove(&mem->map[i + 1], &mem->map[i], - ((entries - i) * sizeof(mem->map[0]))); - mem->size += sizeof(mem->map[0]); - entries += 1; - /* Update the first map entry */ - mem->map[i].size = pack_lb64(start - map_start); - /* Update the second map entry */ - mem->map[i + 1].start = pack_lb64(end); - mem->map[i + 1].size = pack_lb64(map_end - end); - /* Don't bother with this map entry again */ - i += 1; - } - else if ((start <= map_start) && (end > map_start)) { - /* Shrink the start of the memory range */ - mem->map[i].start = pack_lb64(end); - mem->map[i].size = pack_lb64(map_end - end); - } - else if ((start < map_end) && (start > map_start)) { - /* Shrink the end of the memory range */ - mem->map[i].size = pack_lb64(start - map_start); - } - } -} - -/* This function is used in mainboard specific code, too */ -void lb_add_memory_range(struct lb_memory *mem, - uint32_t type, uint64_t start, uint64_t size) -{ - lb_remove_memory_range(mem, start, size); - lb_memory_range(mem, type, start, size); - lb_cleanup_memory_ranges(mem); -} - -static void lb_dump_memory_ranges(struct lb_memory *mem) -{ - int entries; - int i; - entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); - - printk(BIOS_DEBUG, "coreboot memory table:\n"); - for(i = 0; i < entries; i++) { - uint64_t entry_start = unpack_lb64(mem->map[i].start); - uint64_t entry_size = unpack_lb64(mem->map[i].size); - const char *entry_type; - - switch (mem->map[i].type) { - case LB_MEM_RAM: entry_type="RAM"; break; - case LB_MEM_RESERVED: entry_type="RESERVED"; break; - case LB_MEM_ACPI: entry_type="ACPI"; break; - case LB_MEM_NVS: entry_type="NVS"; break; - case LB_MEM_UNUSABLE: entry_type="UNUSABLE"; break; - case LB_MEM_VENDOR_RSVD: entry_type="VENDOR RESERVED"; break; - case LB_MEM_TABLE: entry_type="CONFIGURATION TABLES"; break; - default: entry_type="UNKNOWN!"; break; - } - - printk(BIOS_DEBUG, "%2d. %016llx-%016llx: %s\n", - i, entry_start, entry_start+entry_size-1, entry_type); - - } -} - - -/* Routines to extract part so the coreboot table or - * information from the coreboot table after we have written it. - * Currently get_lb_mem relies on a global we can change the - * implementaiton. - */ -static struct lb_memory *mem_ranges = 0; -struct lb_memory *get_lb_mem(void) -{ - return mem_ranges; -} - -static void build_lb_mem_range(void *gp, struct device *dev, struct resource *res) -{ - struct lb_memory *mem = gp; - lb_memory_range(mem, LB_MEM_RAM, res->base, res->size); -} - -static struct lb_memory *build_lb_mem(struct lb_header *head) -{ - struct lb_memory *mem; - - /* Record where the lb memory ranges will live */ - mem = lb_memory(head); - mem_ranges = mem; - - /* Build the raw table of memory */ - search_global_resources( - IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE, - build_lb_mem_range, mem); - lb_cleanup_memory_ranges(mem); - return mem; -} - -static void lb_add_rsvd_range(void *gp, struct device *dev, struct resource *res) -{ - struct lb_memory *mem = gp; - lb_add_memory_range(mem, LB_MEM_RESERVED, res->base, res->size); -} - -static void add_lb_reserved(struct lb_memory *mem) -{ - /* Add reserved ranges */ - search_global_resources( - IORESOURCE_MEM | IORESOURCE_RESERVE, IORESOURCE_MEM | IORESOURCE_RESERVE, - lb_add_rsvd_range, mem); -} - -#if CONFIG_WRITE_HIGH_TABLES == 1 -extern uint64_t high_tables_base, high_tables_size; -#endif - -unsigned long write_coreboot_table( - unsigned long low_table_start, unsigned long low_table_end, - unsigned long rom_table_start, unsigned long rom_table_end) -{ - struct lb_header *head; - struct lb_memory *mem; - -#if CONFIG_WRITE_HIGH_TABLES == 1 - printk(BIOS_DEBUG, "Writing high table forward entry at 0x%08lx\n", - low_table_end); - head = lb_table_init(low_table_end); - lb_forward(head, (struct lb_header*)rom_table_end); - - low_table_end = (unsigned long) lb_table_fini(head, 0); - printk(BIOS_DEBUG, "New low_table_end: 0x%08lx\n", low_table_end); - printk(BIOS_DEBUG, "Now going to write high coreboot table at 0x%08lx\n", - rom_table_end); - - head = lb_table_init(rom_table_end); - rom_table_end = (unsigned long)head; - printk(BIOS_DEBUG, "rom_table_end = 0x%08lx\n", rom_table_end); -#else - if(low_table_end > (0x1000 - sizeof(struct lb_header))) { /* after 4K */ - /* We need to put lbtable on to [0xf0000,0x100000) */ - head = lb_table_init(rom_table_end); - rom_table_end = (unsigned long)head; - } else { - head = lb_table_init(low_table_end); - low_table_end = (unsigned long)head; - } -#endif - - printk(BIOS_DEBUG, "Adjust low_table_end from 0x%08lx to ", low_table_end); - low_table_end += 0xfff; // 4K aligned - low_table_end &= ~0xfff; - printk(BIOS_DEBUG, "0x%08lx \n", low_table_end); - - /* The Linux kernel assumes this region is reserved */ - printk(BIOS_DEBUG, "Adjust rom_table_end from 0x%08lx to ", rom_table_end); - rom_table_end += 0xffff; // 64K align - rom_table_end &= ~0xffff; - printk(BIOS_DEBUG, "0x%08lx \n", rom_table_end); - -#if (CONFIG_USE_OPTION_TABLE == 1) - { - struct lb_record *rec_dest = lb_new_record(head); - /* Copy the option config table, it's already a lb_record... */ - memcpy(rec_dest, &option_table, option_table.size); - /* Create cmos checksum entry in coreboot table */ - lb_cmos_checksum(head); - } -#endif - /* Record where RAM is located */ - mem = build_lb_mem(head); - - /* Record the mptable and the the lb_table (This will be adjusted later) */ - lb_add_memory_range(mem, LB_MEM_TABLE, - low_table_start, low_table_end - low_table_start); - - /* Record the pirq table, acpi tables, and maybe the mptable */ - lb_add_memory_range(mem, LB_MEM_TABLE, - rom_table_start, rom_table_end-rom_table_start); - -#if CONFIG_WRITE_HIGH_TABLES == 1 - printk(BIOS_DEBUG, "Adding high table area\n"); - // should this be LB_MEM_ACPI? - lb_add_memory_range(mem, LB_MEM_TABLE, - high_tables_base, high_tables_size); -#endif - - /* Add reserved regions */ - add_lb_reserved(mem); - -#if (CONFIG_HAVE_MAINBOARD_RESOURCES == 1) - add_mainboard_resources(mem); -#endif - - lb_dump_memory_ranges(mem); - - /* Note: - * I assume that there is always memory at immediately after - * the low_table_end. This means that after I setup the coreboot table. - * I can trivially fixup the reserved memory ranges to hold the correct - * size of the coreboot table. - */ - - /* Record our motherboard */ - lb_mainboard(head); - /* Record the serial port, if present */ - lb_serial(head); - /* Record our console setup */ - lb_console(head); - /* Record our various random string information */ - lb_strings(head); - /* Record our framebuffer */ - lb_framebuffer(head); - - /* Remember where my valid memory ranges are */ - return lb_table_fini(head, 1); - -} diff --git a/src/arch/i386/boot/gdt.c b/src/arch/i386/boot/gdt.c deleted file mode 100644 index b425ade59d..0000000000 --- a/src/arch/i386/boot/gdt.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <types.h> -#include <string.h> -#include <cbmem.h> -#include <lib.h> -#include <console/console.h> - -// Global Descriptor Table, defined in c_start.S -extern char gdt; -extern char gdt_end; - -/* i386 lgdt argument */ -struct gdtarg { - u16 limit; - u32 base; -} __attribute__((packed)); - -// Copy GDT to new location and reload it -void move_gdt(void) -{ - void *newgdt; - u16 num_gdt_bytes = &gdt_end - &gdt; - struct gdtarg gdtarg; - - newgdt = cbmem_find(CBMEM_ID_GDT); - if (!newgdt) { - newgdt = cbmem_add(CBMEM_ID_GDT, ALIGN(num_gdt_bytes, 512)); - if (!newgdt) { - printk(BIOS_ERR, "Error: Could not relocate GDT.\n"); - return; - } - printk(BIOS_DEBUG, "Moving GDT to %p...", newgdt); - memcpy((void*)newgdt, &gdt, num_gdt_bytes); - } - - gdtarg.base = (u32)newgdt; - gdtarg.limit = num_gdt_bytes - 1; - - __asm__ __volatile__ ("lgdt %0\n\t" : : "m" (gdtarg)); - printk(BIOS_DEBUG, "ok\n"); -} - diff --git a/src/arch/i386/boot/mpspec.c b/src/arch/i386/boot/mpspec.c deleted file mode 100644 index 70bc5401fd..0000000000 --- a/src/arch/i386/boot/mpspec.c +++ /dev/null @@ -1,383 +0,0 @@ -#include <console/console.h> -#include <device/path.h> -#include <device/pci_ids.h> -#include <cpu/cpu.h> -#include <arch/smp/mpspec.h> -#include <string.h> -#include <arch/cpu.h> -#include <cpu/x86/lapic.h> - -/* Initialize the specified "mc" struct with initial values. */ -void mptable_init(struct mp_config_table *mc, const char *productid, - u32 lapic_addr) -{ - /* Error out if 'product_id' length doesn't match exactly. */ - if (strlen(productid) != 12) - die("ERROR: 'productid' must be 12 bytes long!"); - - memset(mc, 0, sizeof(*mc)); - memcpy(mc->mpc_signature, MPC_SIGNATURE, 4); - mc->mpc_length = sizeof(*mc); /* Initially just the header size. */ - mc->mpc_spec = 0x04; /* MultiProcessor specification 1.4 */ - mc->mpc_checksum = 0; /* Not yet computed. */ - memcpy(mc->mpc_oem, "COREBOOT", 8); - memcpy(mc->mpc_productid, productid, 12); - 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; -} - -unsigned char smp_compute_checksum(void *v, int len) -{ - unsigned char *bytes; - unsigned char checksum; - int i; - bytes = v; - checksum = 0; - for(i = 0; i < len; i++) { - checksum -= bytes[i]; - } - return checksum; -} - -void *smp_write_floating_table(unsigned long addr) -{ - /* 16 byte align the table address */ - addr = (addr + 0xf) & (~0xf); - return smp_write_floating_table_physaddr(addr, addr + SMP_FLOATING_TABLE_LEN); -} - -void *smp_write_floating_table_physaddr(unsigned long addr, unsigned long mpf_physptr) -{ - struct intel_mp_floating *mf; - void *v; - - v = (void *)addr; - mf = v; - mf->mpf_signature[0] = '_'; - mf->mpf_signature[1] = 'M'; - mf->mpf_signature[2] = 'P'; - mf->mpf_signature[3] = '_'; - mf->mpf_physptr = mpf_physptr; - mf->mpf_length = 1; - mf->mpf_specification = 4; - mf->mpf_checksum = 0; - mf->mpf_feature1 = 0; - mf->mpf_feature2 = 0; - mf->mpf_feature3 = 0; - mf->mpf_feature4 = 0; - mf->mpf_feature5 = 0; - mf->mpf_checksum = smp_compute_checksum(mf, mf->mpf_length*16); - return v; -} - -void *smp_next_mpc_entry(struct mp_config_table *mc) -{ - void *v; - v = (void *)(((char *)mc) + mc->mpc_length); - return v; -} -static void smp_add_mpc_entry(struct mp_config_table *mc, unsigned length) -{ - mc->mpc_length += length; - mc->mpc_entry_count++; -} - -void *smp_next_mpe_entry(struct mp_config_table *mc) -{ - void *v; - v = (void *)(((char *)mc) + mc->mpc_length + mc->mpe_length); - return v; -} -static void smp_add_mpe_entry(struct mp_config_table *mc, mpe_t mpe) -{ - mc->mpe_length += mpe->mpe_length; -} - -void smp_write_processor(struct mp_config_table *mc, - unsigned char apicid, unsigned char apicver, - unsigned char cpuflag, unsigned int cpufeature, - unsigned int featureflag) -{ - struct mpc_config_processor *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_PROCESSOR; - mpc->mpc_apicid = apicid; - mpc->mpc_apicver = apicver; - mpc->mpc_cpuflag = cpuflag; - mpc->mpc_cpufeature = cpufeature; - mpc->mpc_featureflag = featureflag; - smp_add_mpc_entry(mc, sizeof(*mpc)); -} - -/* If we assume a symmetric processor configuration we can - * get all of the information we need to write the processor - * entry from the bootstrap processor. - * Plus I don't think linux really even cares. - * Having the proper apicid's in the table so the non-bootstrap - * processors can be woken up should be enough. - */ -void smp_write_processors(struct mp_config_table *mc) -{ - int boot_apic_id; - unsigned apic_version; - unsigned cpu_features; - unsigned cpu_feature_flags; - struct cpuid_result result; - device_t cpu; - - boot_apic_id = lapicid(); - apic_version = lapic_read(LAPIC_LVR) & 0xff; - result = cpuid(1); - cpu_features = result.eax; - cpu_feature_flags = result.edx; - for(cpu = all_devices; cpu; cpu = cpu->next) { - unsigned long cpu_flag; - if ((cpu->path.type != DEVICE_PATH_APIC) || - (cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER)) - { - continue; - } - if (!cpu->enabled) { - continue; - } - cpu_flag = MPC_CPU_ENABLED; - if (boot_apic_id == cpu->path.apic.apic_id) { - cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR; - } - smp_write_processor(mc, - cpu->path.apic.apic_id, apic_version, - cpu_flag, cpu_features, cpu_feature_flags - ); - } -} - -static void smp_write_bus(struct mp_config_table *mc, - unsigned char id, const char *bustype) -{ - struct mpc_config_bus *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_BUS; - mpc->mpc_busid = id; - memcpy(mpc->mpc_bustype, bustype, sizeof(mpc->mpc_bustype)); - smp_add_mpc_entry(mc, sizeof(*mpc)); -} - -void smp_write_ioapic(struct mp_config_table *mc, - unsigned char id, unsigned char ver, - unsigned long apicaddr) -{ - struct mpc_config_ioapic *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_IOAPIC; - mpc->mpc_apicid = id; - mpc->mpc_apicver = ver; - mpc->mpc_flags = MPC_APIC_USABLE; - mpc->mpc_apicaddr = apicaddr; - smp_add_mpc_entry(mc, sizeof(*mpc)); -} - -void smp_write_intsrc(struct mp_config_table *mc, - unsigned char irqtype, unsigned short irqflag, - unsigned char srcbus, unsigned char srcbusirq, - unsigned char dstapic, unsigned char dstirq) -{ - struct mpc_config_intsrc *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_INTSRC; - mpc->mpc_irqtype = irqtype; - mpc->mpc_irqflag = irqflag; - mpc->mpc_srcbus = srcbus; - mpc->mpc_srcbusirq = srcbusirq; - mpc->mpc_dstapic = dstapic; - mpc->mpc_dstirq = dstirq; - smp_add_mpc_entry(mc, sizeof(*mpc)); -#ifdef DEBUG_MPTABLE - printk(BIOS_DEBUG, "add intsrc srcbus 0x%x srcbusirq 0x%x, dstapic 0x%x, dstirq 0x%x\n", - srcbus, srcbusirq, dstapic, dstirq); - hexdump(__func__, mpc, sizeof(*mpc)); -#endif -} - -void smp_write_intsrc_pci_bridge(struct mp_config_table *mc, - unsigned char irqtype, unsigned short irqflag, - struct device *dev, - unsigned char dstapic, unsigned char *dstirq) -{ - struct device *child; - - int i; - int srcbus; - int slot; - - struct bus *link; - unsigned char dstirq_x[4]; - - for (link = dev->link_list; link; link = link->next) { - - child = link->children; - srcbus = link->secondary; - - while (child) { - if (child->path.type != DEVICE_PATH_PCI) - goto next; - - slot = (child->path.pci.devfn >> 3); - /* round pins */ - for (i = 0; i < 4; i++) - dstirq_x[i] = dstirq[(i + slot) % 4]; - - if ((child->class >> 16) != PCI_BASE_CLASS_BRIDGE) { - /* pci device */ - printk(BIOS_DEBUG, "route irq: %s\n", dev_path(child)); - for (i = 0; i < 4; i++) - smp_write_intsrc(mc, irqtype, irqflag, srcbus, (slot<<2)|i, dstapic, dstirq_x[i]); - goto next; - } - - switch (child->class>>8) { - case PCI_CLASS_BRIDGE_PCI: - case PCI_CLASS_BRIDGE_PCMCIA: - case PCI_CLASS_BRIDGE_CARDBUS: - printk(BIOS_DEBUG, "route irq bridge: %s\n", dev_path(child)); - smp_write_intsrc_pci_bridge(mc, irqtype, irqflag, child, dstapic, dstirq_x); - } - - next: - child = child->sibling; - } - - } -} - -void smp_write_lintsrc(struct mp_config_table *mc, - unsigned char irqtype, unsigned short irqflag, - unsigned char srcbusid, unsigned char srcbusirq, - unsigned char destapic, unsigned char destapiclint) -{ - struct mpc_config_lintsrc *mpc; - mpc = smp_next_mpc_entry(mc); - memset(mpc, '\0', sizeof(*mpc)); - mpc->mpc_type = MP_LINTSRC; - mpc->mpc_irqtype = irqtype; - mpc->mpc_irqflag = irqflag; - mpc->mpc_srcbusid = srcbusid; - mpc->mpc_srcbusirq = srcbusirq; - mpc->mpc_destapic = destapic; - mpc->mpc_destapiclint = destapiclint; - smp_add_mpc_entry(mc, sizeof(*mpc)); -} - -void smp_write_address_space(struct mp_config_table *mc, - unsigned char busid, unsigned char address_type, - unsigned int address_base_low, unsigned int address_base_high, - unsigned int address_length_low, unsigned int address_length_high) -{ - struct mp_exten_system_address_space *mpe; - mpe = smp_next_mpe_entry(mc); - memset(mpe, '\0', sizeof(*mpe)); - mpe->mpe_type = MPE_SYSTEM_ADDRESS_SPACE; - mpe->mpe_length = sizeof(*mpe); - mpe->mpe_busid = busid; - mpe->mpe_address_type = address_type; - mpe->mpe_address_base_low = address_base_low; - mpe->mpe_address_base_high = address_base_high; - mpe->mpe_address_length_low = address_length_low; - mpe->mpe_address_length_high = address_length_high; - smp_add_mpe_entry(mc, (mpe_t)mpe); -} - - -void smp_write_bus_hierarchy(struct mp_config_table *mc, - unsigned char busid, unsigned char bus_info, - unsigned char parent_busid) -{ - struct mp_exten_bus_hierarchy *mpe; - mpe = smp_next_mpe_entry(mc); - memset(mpe, '\0', sizeof(*mpe)); - mpe->mpe_type = MPE_BUS_HIERARCHY; - mpe->mpe_length = sizeof(*mpe); - mpe->mpe_busid = busid; - mpe->mpe_bus_info = bus_info; - mpe->mpe_parent_busid = parent_busid; - smp_add_mpe_entry(mc, (mpe_t)mpe); -} - -void smp_write_compatibility_address_space(struct mp_config_table *mc, - unsigned char busid, unsigned char address_modifier, - unsigned int range_list) -{ - struct mp_exten_compatibility_address_space *mpe; - mpe = smp_next_mpe_entry(mc); - memset(mpe, '\0', sizeof(*mpe)); - mpe->mpe_type = MPE_COMPATIBILITY_ADDRESS_SPACE; - mpe->mpe_length = sizeof(*mpe); - mpe->mpe_busid = busid; - mpe->mpe_address_modifier = address_modifier; - mpe->mpe_range_list = range_list; - smp_add_mpe_entry(mc, (mpe_t)mpe); -} - -void mptable_add_isa_interrupts(struct mp_config_table *mc, unsigned long bus_isa, unsigned long apicid, int external_int2) -{ -/*I/O Ints: Type Trigger Polarity Bus ID IRQ APIC ID PIN# */ - smp_write_intsrc(mc, external_int2?mp_INT:mp_ExtINT, - MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid, 0x1); - smp_write_intsrc(mc, external_int2?mp_ExtINT:mp_INT, - MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x9, apicid, 0x9); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xa, apicid, 0xa); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xb, apicid, 0xb); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid, 0xf); -} - -void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus, int *isa_bus) { - int dummy, i, highest; - char buses[256]; - struct device *dev; - - if (!max_pci_bus) max_pci_bus = &dummy; - if (!isa_bus) isa_bus = &dummy; - - *max_pci_bus = 0; - highest = 0; - memset(buses, 0, sizeof(buses)); - - for (dev = all_devices; dev; dev = dev->next) { - struct bus *bus; - for (bus = dev->link_list; bus; bus = bus->next) { - if (bus->secondary > 255) { - printk(BIOS_ERR, "A bus claims to have a bus ID > 255?!? Aborting"); - return; - } - buses[bus->secondary] = 1; - if (highest < bus->secondary) highest = bus->secondary; - } - } - for (i=0; i <= highest; i++) { - if (buses[i]) { - smp_write_bus(mc, i, "PCI "); - *max_pci_bus = i; - } - } - *isa_bus = *max_pci_bus + 1; - smp_write_bus(mc, *isa_bus, "ISA "); -} - diff --git a/src/arch/i386/boot/multiboot.c b/src/arch/i386/boot/multiboot.c deleted file mode 100644 index 4059f2736b..0000000000 --- a/src/arch/i386/boot/multiboot.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * support for Multiboot payloads - * - * Copyright (C) 2008 Robert Millan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include <cpu/x86/multiboot.h> -#include <string.h> -#include <device/resource.h> -#include <console/console.h> -#include <boot/coreboot_tables.h> -#include <arch/coreboot_tables.h> - -struct multiboot_info *mbi = NULL; - -unsigned long write_multiboot_info(unsigned long rom_table_end) -{ - static struct multiboot_mmap_entry *mb_mem; - struct lb_memory* coreboot_table; - int entries; - int i; - - mbi = (struct multiboot_info *)rom_table_end; - - memset(mbi, 0, sizeof(*mbi)); - rom_table_end += sizeof(*mbi); - - mbi->mmap_addr = (u32) rom_table_end; - mb_mem = (struct multiboot_mmap_entry *)rom_table_end; - - /* copy regions from coreboot tables */ - coreboot_table = get_lb_mem(); - entries = (coreboot_table->size - sizeof(*coreboot_table))/sizeof(coreboot_table->map[0]); - - if (coreboot_table == NULL || entries < 1) { - printk(BIOS_INFO, "%s: Cannot find coreboot table.\n", __func__); - return (unsigned long) mb_mem; - } - - for (i = 0; i < entries; i++) { - uint64_t entry_start = unpack_lb64(coreboot_table->map[i].start); - uint64_t entry_size = unpack_lb64(coreboot_table->map[i].size); - mb_mem->addr = entry_start; - mb_mem->len = entry_size; - switch (coreboot_table->map[i].type) { - case LB_MEM_RAM: - mb_mem->type = MULTIBOOT_MEMORY_AVAILABLE; - break; - default: // anything other than usable RAM - mb_mem->type = MULTIBOOT_MEMORY_RESERVED; - break; - } - mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size); - mb_mem++; - } - - mbi->mmap_length = ((u32) mb_mem) - mbi->mmap_addr; - mbi->flags |= MB_INFO_MEM_MAP; - - printk(BIOS_INFO, "Multiboot Information structure has been written.\n"); - - return (unsigned long)mb_mem; -} diff --git a/src/arch/i386/boot/pirq_routing.c b/src/arch/i386/boot/pirq_routing.c deleted file mode 100644 index bb8a7b605a..0000000000 --- a/src/arch/i386/boot/pirq_routing.c +++ /dev/null @@ -1,169 +0,0 @@ -#include <console/console.h> -#include <arch/pirq_routing.h> -#include <string.h> -#include <device/pci.h> - -#if CONFIG_DEBUG_PIRQ -static void check_pirq_routing_table(struct irq_routing_table *rt) -{ - uint8_t *addr = (uint8_t *)rt; - uint8_t sum=0; - int i; - - printk(BIOS_INFO, "Checking Interrupt Routing Table consistency...\n"); - - if (sizeof(struct irq_routing_table) != rt->size) { - printk(BIOS_WARNING, "Inconsistent Interrupt Routing Table size (0x%x/0x%x).\n", - (unsigned int) sizeof(struct irq_routing_table), - rt->size - ); - rt->size=sizeof(struct irq_routing_table); - } - - for (i = 0; i < rt->size; i++) - sum += addr[i]; - - printk(BIOS_DEBUG, "%s(): Interrupt Routing Table located at %p.\n", - __func__, addr); - - - sum = rt->checksum - sum; - - if (sum != rt->checksum) { - printk(BIOS_WARNING, "Interrupt Routing Table checksum is: 0x%02x but should be: 0x%02x.\n", - rt->checksum, sum); - rt->checksum = sum; - } - - if (rt->signature != PIRQ_SIGNATURE || rt->version != PIRQ_VERSION || - rt->size % 16 ) { - printk(BIOS_WARNING, "Interrupt Routing Table not valid.\n"); - return; - } - - sum = 0; - for (i=0; i<rt->size; i++) - sum += addr[i]; - - /* We're manually fixing the checksum above. This warning can probably - * never happen because if the target location is read-only this - * function would have bailed out earlier. - */ - if (sum) { - printk(BIOS_WARNING, "Checksum error in Interrupt Routing Table " - "could not be fixed.\n"); - } - - printk(BIOS_INFO, "done.\n"); -} - -static int verify_copy_pirq_routing_table(unsigned long addr) -{ - int i; - uint8_t *rt_orig, *rt_curr; - - rt_curr = (uint8_t*)addr; - rt_orig = (uint8_t*)&intel_irq_routing_table; - printk(BIOS_INFO, "Verifying copy of Interrupt Routing Table at 0x%08lx... ", addr); - for (i = 0; i < intel_irq_routing_table.size; i++) { - if (*(rt_curr + i) != *(rt_orig + i)) { - printk(BIOS_INFO, "failed\n"); - return -1; - } - } - printk(BIOS_INFO, "done\n"); - - check_pirq_routing_table((struct irq_routing_table *)addr); - - return 0; -} -#endif - -unsigned long copy_pirq_routing_table(unsigned long addr) -{ - /* Align the table to be 16 byte aligned. */ - addr += 15; - addr &= ~15; - - /* This table must be betweeen 0xf0000 & 0x100000 */ - printk(BIOS_INFO, "Copying Interrupt Routing Table to 0x%08lx... ", addr); - memcpy((void *)addr, &intel_irq_routing_table, intel_irq_routing_table.size); - printk(BIOS_INFO, "done.\n"); -#if CONFIG_DEBUG_PIRQ - verify_copy_pirq_routing_table(addr); -#endif - pirq_routing_irqs(addr); - return addr + intel_irq_routing_table.size; -} - -#if CONFIG_PIRQ_ROUTE -void pirq_routing_irqs(unsigned long addr) -{ - int i, j, k, num_entries; - unsigned char irq_slot[4]; - unsigned char pirq[4] = {0, 0, 0, 0}; - struct irq_routing_table *pirq_tbl; - - pirq_tbl = (struct irq_routing_table *)(addr); - num_entries = (pirq_tbl->size - 32) / 16; - - /* Set PCI IRQs. */ - for (i = 0; i < num_entries; i++) { - - printk(BIOS_DEBUG, "PIRQ Entry %d Dev/Fn: %X Slot: %d\n", i, - pirq_tbl->slots[i].devfn >> 3, pirq_tbl->slots[i].slot); - - for (j = 0; j < 4; j++) { - - int link = pirq_tbl->slots[i].irq[j].link; - int bitmap = pirq_tbl->slots[i].irq[j].bitmap; - int irq = 0; - - printk(BIOS_DEBUG, "INT: %c link: %x bitmap: %x ", - 'A' + j, link, bitmap); - - if (!bitmap|| !link || link > 4) { - - printk(BIOS_DEBUG, "not routed\n"); - irq_slot[j] = irq; - continue; - } - - /* yet not routed */ - if (!pirq[link - 1]) { - - for (k = 2; k <= 15; k++) { - - if (!((bitmap >> k) & 1)) - continue; - - irq = k; - - /* yet not routed */ - if (pirq[0] != irq && pirq[1] != irq && pirq[2] != irq && pirq[3] != irq) - break; - } - - if (irq) - pirq[link - 1] = irq; - } - else - irq = pirq[link - 1]; - - printk(BIOS_DEBUG, "IRQ: %d\n", irq); - irq_slot[j] = irq; - } - - /* Bus, device, slots IRQs for {A,B,C,D}. */ - pci_assign_irqs(pirq_tbl->slots[i].bus, - pirq_tbl->slots[i].devfn >> 3, irq_slot); - } - - printk(BIOS_DEBUG, "PIRQ1: %d\n", pirq[0]); - printk(BIOS_DEBUG, "PIRQ2: %d\n", pirq[1]); - printk(BIOS_DEBUG, "PIRQ3: %d\n", pirq[2]); - printk(BIOS_DEBUG, "PIRQ4: %d\n", pirq[3]); - - pirq_assign_irqs(pirq); -} -#endif diff --git a/src/arch/i386/boot/tables.c b/src/arch/i386/boot/tables.c deleted file mode 100644 index d816e76750..0000000000 --- a/src/arch/i386/boot/tables.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2003 Eric Biederman - * Copyright (C) 2005 Steve Magnani - * Copyright (C) 2008-2009 coresystems GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <cpu/cpu.h> -#include <boot/tables.h> -#include <boot/coreboot_tables.h> -#include <arch/coreboot_tables.h> -#include <arch/pirq_routing.h> -#include <arch/smp/mpspec.h> -#include <arch/acpi.h> -#include <string.h> -#include <cpu/x86/multiboot.h> -#include <cbmem.h> -#include <lib.h> - -uint64_t high_tables_base = 0; -uint64_t high_tables_size; - -void cbmem_arch_init(void) -{ - /* defined in gdt.c */ - move_gdt(); -} - -struct lb_memory *write_tables(void) -{ - unsigned long low_table_start, low_table_end; - unsigned long rom_table_start, rom_table_end; - - /* Even if high tables are configured, some tables are copied both to - * the low and the high area, so payloads and OSes don't need to know - * about the high tables. - */ - unsigned long high_table_pointer; - - if (!high_tables_base) { - printk(BIOS_ERR, "ERROR: High Tables Base is not set.\n"); - // Are there any boards without? - // Stepan thinks we should die() here! - } - - printk(BIOS_DEBUG, "High Tables Base is %llx.\n", high_tables_base); - - rom_table_start = 0xf0000; - rom_table_end = 0xf0000; - - /* Start low addr at 0x500, so we don't run into conflicts with the BDA - * in case our data structures grow beyound 0x400. Only multiboot, GDT - * and the coreboot table use low_tables. - */ - low_table_start = 0; - low_table_end = 0x500; - -#if CONFIG_GENERATE_PIRQ_TABLE == 1 -#define MAX_PIRQ_TABLE_SIZE (4 * 1024) - post_code(0x9a); - - /* This table must be between 0x0f0000 and 0x100000 */ - rom_table_end = write_pirq_routing_table(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); - - /* And add a high table version for those payloads that - * want to live in the F segment - */ - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_PIRQ, MAX_PIRQ_TABLE_SIZE); - if (high_table_pointer) { - unsigned long new_high_table_pointer; - new_high_table_pointer = write_pirq_routing_table(high_table_pointer); - // FIXME make pirq table code intelligent enough to know how - // much space it's going to need. - if (new_high_table_pointer > (high_table_pointer + MAX_PIRQ_TABLE_SIZE)) { - printk(BIOS_ERR, "ERROR: Increase PIRQ size.\n"); - } - printk(BIOS_DEBUG, "PIRQ table: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - } - -#endif - -#if CONFIG_GENERATE_MP_TABLE == 1 -#define MAX_MP_TABLE_SIZE (4 * 1024) - post_code(0x9b); - - /* The smp table must be in 0-1K, 639K-640K, or 960K-1M */ - rom_table_end = write_smp_table(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); - - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_MPTABLE, MAX_MP_TABLE_SIZE); - if (high_table_pointer) { - unsigned long new_high_table_pointer; - new_high_table_pointer = write_smp_table(high_table_pointer); - // FIXME make mp table code intelligent enough to know how - // much space it's going to need. - if (new_high_table_pointer > (high_table_pointer + MAX_MP_TABLE_SIZE)) { - printk(BIOS_ERR, "ERROR: Increase MP table size.\n"); - } - - printk(BIOS_DEBUG, "MP table: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - } -#endif /* CONFIG_GENERATE_MP_TABLE */ - -#if CONFIG_GENERATE_ACPI_TABLES == 1 -#define MAX_ACPI_SIZE (47 * 1024) - post_code(0x9c); - - /* Write ACPI tables to F segment and high tables area */ - - /* Ok, this is a bit hacky still, because some day we want to have this - * completely dynamic. But right now we are setting fixed sizes. - * It's probably still better than the old high_table_base code because - * now at least we know when we have an overflow in the area. - * - * We want to use 1MB - 64K for Resume backup. We use 512B for TOC and - * 512 byte for GDT, 4K for PIRQ and 4K for MP table and 8KB for the - * coreboot table. This leaves us with 47KB for all of ACPI. Let's see - * how far we get. - */ - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_ACPI, MAX_ACPI_SIZE); - if (high_table_pointer) { - unsigned long acpi_start = high_table_pointer; - unsigned long new_high_table_pointer; - - rom_table_end = ALIGN(rom_table_end, 16); - new_high_table_pointer = write_acpi_tables(high_table_pointer); - if (new_high_table_pointer > ( high_table_pointer + MAX_ACPI_SIZE)) { - printk(BIOS_ERR, "ERROR: Increase ACPI size\n"); - } - printk(BIOS_DEBUG, "ACPI tables: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - - /* Now we need to create a low table copy of the RSDP. */ - - /* First we look for the high table RSDP */ - while (acpi_start < new_high_table_pointer) { - if (memcmp(((acpi_rsdp_t *)acpi_start)->signature, RSDP_SIG, 8) == 0) { - break; - } - acpi_start++; - } - - /* Now, if we found the RSDP, we take the RSDT and XSDT pointer - * from it in order to write the low RSDP - */ - if (acpi_start < new_high_table_pointer) { - acpi_rsdp_t *low_rsdp = (acpi_rsdp_t *)rom_table_end, - *high_rsdp = (acpi_rsdp_t *)acpi_start; - - acpi_write_rsdp(low_rsdp, - (acpi_rsdt_t *)(high_rsdp->rsdt_address), - (acpi_xsdt_t *)((unsigned long)high_rsdp->xsdt_address)); - } else { - printk(BIOS_ERR, "ERROR: Didn't find RSDP in high table.\n"); - } - rom_table_end = ALIGN(rom_table_end + sizeof(acpi_rsdp_t), 16); - } else { - rom_table_end = write_acpi_tables(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); - } - -#endif - - -#define MAX_COREBOOT_TABLE_SIZE (8 * 1024) - post_code(0x9d); - - high_table_pointer = (unsigned long)cbmem_add(CBMEM_ID_CBTABLE, MAX_COREBOOT_TABLE_SIZE); - - if (high_table_pointer) { - unsigned long new_high_table_pointer; - - /* Also put a forwarder entry into 0-4K */ - new_high_table_pointer = write_coreboot_table(low_table_start, low_table_end, - high_tables_base, high_table_pointer); - - if (new_high_table_pointer > (high_table_pointer + - MAX_COREBOOT_TABLE_SIZE)) - printk(BIOS_ERR, "%s: coreboot table didn't fit (%lx)\n", - __func__, new_high_table_pointer - - high_table_pointer); - - printk(BIOS_DEBUG, "coreboot table: %ld bytes.\n", - new_high_table_pointer - high_table_pointer); - } else { - /* The coreboot table must be in 0-4K or 960K-1M */ - rom_table_end = write_coreboot_table( - low_table_start, low_table_end, - rom_table_start, rom_table_end); - } - - post_code(0x9e); - -#if CONFIG_HAVE_ACPI_RESUME - /* Let's prepare the ACPI S3 Resume area now already, so we can rely on - * it begin there during reboot time. We don't need the pointer, nor - * the result right now. If it fails, ACPI resume will be disabled. - */ - cbmem_add(CBMEM_ID_RESUME, HIGH_MEMORY_SAVE); -#endif - -#if CONFIG_MULTIBOOT - post_code(0x9d); - - /* The Multiboot information structure */ - write_multiboot_info(rom_table_end); -#endif - - // Remove before sending upstream - cbmem_list(); - - return get_lb_mem(); -} diff --git a/src/arch/i386/boot/wakeup.S b/src/arch/i386/boot/wakeup.S deleted file mode 100644 index a1df4d5597..0000000000 --- a/src/arch/i386/boot/wakeup.S +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Rudolf Marek <r.marek@assembler.cz> - * Copyright (C) 2009 coresystems GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define WAKEUP_BASE 0x600 -#define RELOCATED(x) (x - __wakeup + WAKEUP_BASE) - -/* CR0 bits */ -#define PE (1 << 0) - - .code32 - .globl __wakeup -__wakeup: - /* First prepare the jmp to the resume vector */ - mov 0x4(%esp), %eax /* vector */ - /* last 4 bits of linear addr are taken as offset */ - andw $0x0f, %ax - movw %ax, (__wakeup_offset) - mov 0x4(%esp), %eax - /* the rest is taken as segment */ - shr $4, %eax - movw %ax, (__wakeup_segment) - - /* Then overwrite coreboot with our backed up memory */ - movl 8(%esp), %esi - movl 12(%esp), %edi - movl 16(%esp), %ecx - shrl $4, %ecx -1: - movl 0(%esi),%eax - movl 4(%esi),%edx - movl 8(%esi),%ebx - movl 12(%esi),%ebp - addl $16,%esi - subl $1,%ecx - movl %eax,0(%edi) - movl %edx,4(%edi) - movl %ebx,8(%edi) - movl %ebp,12(%edi) - leal 16(%edi),%edi - jne 1b - - /* Activate the right segment descriptor real mode. */ - ljmp $0x28, $RELOCATED(1f) -1: -.code16 - /* 16 bit code from here on... */ - - /* Load the segment registers w/ properly configured - * segment descriptors. They will retain these - * configurations (limits, writability, etc.) once - * protected mode is turned off. - */ - mov $0x30, %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %ax, %ss - - /* Turn off protection */ - movl %cr0, %eax - andl $~PE, %eax - movl %eax, %cr0 - - /* Now really going into real mode */ - ljmp $0, $RELOCATED(1f) -1: - movw $0x0, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss - movw %ax, %fs - movw %ax, %gs - - /* This is a FAR JMP to the OS waking vector. The C code changed - * the address to be correct. - */ - .byte 0xea - -__wakeup_offset = RELOCATED(.) - .word 0x0000 - -__wakeup_segment = RELOCATED(.) - .word 0x0000 - - .globl __wakeup_size -__wakeup_size = ( . - __wakeup) - |