Author: stepan Date: 2009-05-26 16:07:44 +0200 (Tue, 26 May 2009) New Revision: 4306
Modified: trunk/coreboot-v2/src/arch/i386/boot/tables.c Log: Major cleanup of i386 tables.c:
* fix copyright messages * remove all HAVE_HIGH_TABLES and HAVE_LOW_TABLES preprocessor hackery and instead use high_tables_base to find out if high tables should be used. The code path with high tables disabled and high tables not available for another reason should be the same. * put MP-table into Fseg instead of 0x10. This allows us to drop an huge and ugly portion of code. And it will make some ugly Linux warnings go away. * use ALIGN macro instead of hand crafted aligning. * renumber post codes in this piece of code (don't jump ahead and back anymore)
Signed-off-by: Stefan Reinauer stepan@coresystems.de Acked-by: Myles Watson mylesgw@gmail.com
Modified: trunk/coreboot-v2/src/arch/i386/boot/tables.c =================================================================== --- trunk/coreboot-v2/src/arch/i386/boot/tables.c 2009-05-26 14:03:51 UTC (rev 4305) +++ trunk/coreboot-v2/src/arch/i386/boot/tables.c 2009-05-26 14:07:44 UTC (rev 4306) @@ -1,7 +1,8 @@ /* * This file is part of the coreboot project. * - * Copyright (C) .... others + * 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 @@ -42,8 +43,6 @@ } __attribute__((packed));
// Copy GDT to new location and reload it -// 2003-07 by SONE Takeshi -// Ported from Etherboot to coreboot 2005-08 by Steve Magnani void move_gdt(unsigned long newgdt) { uint16_t num_gdt_bytes = &gdt_end - &gdt; @@ -57,24 +56,22 @@ printk_debug("ok\n"); }
-#if HAVE_HIGH_TABLES == 1 uint64_t high_tables_base = 0; uint64_t high_tables_size; -#endif
struct lb_memory *write_tables(void) { unsigned long low_table_start, low_table_end; unsigned long rom_table_start, rom_table_end; -#if HAVE_MP_TABLE == 1 && HAVE_LOW_TABLES == 1 +#if HAVE_MP_TABLE == 1 unsigned long new_low_table_end; #endif
-#if HAVE_HIGH_TABLES == 1 - /* Even if high tables are configured, all tables are copied both to the - * low and the high area, so payloads and OSes don't need to know about - * the high tables. + /* 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_rsdp; unsigned long high_table_start=0, high_table_end=0;
if (high_tables_base) { @@ -82,119 +79,79 @@ high_table_start = high_tables_base; high_table_end = high_tables_base; } else { - printk_debug("High Tables Base is not set.\n"); + printk_err("ERROR: High Tables Base is not set.\n"); } -#endif
rom_table_start = 0xf0000; rom_table_end = 0xf0000; - /* Start low addr at 16 bytes instead of 0 because of a buglet - * in the generic linux unzip code, as it tests for the a20 line. + + /* 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 = 16; + low_table_end = 0x500;
- post_code(0x9a); + post_code(0x99);
-#if HAVE_LOW_TABLES == 1 - /* This table must be betweeen 0xf0000 & 0x100000 */ + /* This table must be between 0x0f0000 and 0x100000 */ rom_table_end = write_pirq_routing_table(rom_table_end); - rom_table_end = (rom_table_end + 1023) & ~1023; -#endif -#if HAVE_HIGH_TABLES == 1 + 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 + */ if (high_tables_base) { high_table_end = write_pirq_routing_table(high_table_end); - high_table_end = (high_table_end + 1023) & ~1023; + high_table_end = ALIGN(high_table_end, 1024); } -#endif
- /* Write ACPI tables */ - /* write them in the rom area because DSDT can be large (8K on epia-m) which - * pushes coreboot table out of first 4K if set up in low table area - */ + post_code(0x9a); + + /* Write ACPI tables to F segment and high tables area */ #if HAVE_ACPI_TABLES == 1 -#if HAVE_HIGH_TABLES == 1 -#if HAVE_LOW_TABLES == 1 - unsigned long high_rsdp=ALIGN(high_table_end, 16); -#endif if (high_tables_base) { + unsigned long rsdt_location; + high_rsdp = ALIGN(high_table_end, 16); high_table_end = write_acpi_tables(high_table_end); - high_table_end = (high_table_end+1023) & ~1023; + high_table_end = ALIGN(high_table_end, 1024); + rsdt_location = (unsigned long)(((acpi_rsdp_t*)high_rsdp)->rsdt_address); + printk_debug("high mem RSDP at %x, RSDT at %x\n", high_rsdp, rsdt_location); + acpi_write_rsdp((acpi_rsdp_t *)rom_table_end, (acpi_rsdt_t *)rsdt_location); + rom_table_end = ALIGN(ALIGN(rom_table_end, 16) + sizeof(acpi_rsdp_t), 16); + } else { + rom_table_end = write_acpi_tables(rom_table_end); + rom_table_end = ALIGN(rom_table_end, 1024); } -#if HAVE_LOW_TABLES == 1 - unsigned long rsdt_location=(unsigned long*)(((acpi_rsdp_t*)high_rsdp)->rsdt_address); - acpi_write_rsdp(rom_table_end, rsdt_location); - rom_table_end = ALIGN(ALIGN(rom_table_end, 16) + sizeof(acpi_rsdp_t), 16); #endif -#else -#if HAVE_LOW_TABLES == 1 - rom_table_end = write_acpi_tables(rom_table_end); - rom_table_end = (rom_table_end+1023) & ~1023; -#endif -#endif -#endif - /* copy the smp block to address 0 */ - post_code(0x96); + post_code(0x9b);
#if HAVE_MP_TABLE == 1 - /* The smp table must be in 0-1K, 639K-640K, or 960K-1M */ -#if HAVE_LOW_TABLES == 1 - new_low_table_end = write_smp_table(low_table_end); // low_table_end is 0x10 at this point - /* Don't write anything in the traditional x86 BIOS data segment, - * for example the linux kernel smp need to use 0x467 to pass reset vector - * or use 0x40e/0x413 for EBDA finding... - */ - if(new_low_table_end>0x400){ - unsigned mptable_size; - unsigned mpc_start; - low_table_end += SMP_FLOATING_TABLE_LEN; /* keep the mpf in 1k low, so kernel can find it */ - mptable_size = new_low_table_end - low_table_end; - /* We can not put mptable low, we need to copy them to somewhere else*/ - if((rom_table_end+mptable_size)<0x100000) { - /* We can copy mptable on rom_table */ - mpc_start = rom_table_end; - rom_table_end += mptable_size; - rom_table_end = (rom_table_end+1023) & ~1023; - } else { - /* We can need to put mptable before rom_table */ - mpc_start = rom_table_start - mptable_size; - mpc_start &= ~1023; - rom_table_start = mpc_start; - } - printk_debug("move mptable from 0x%0lx to 0x%0x, size 0x%0x\n", low_table_end, mpc_start, mptable_size); - memcpy((unsigned char *)mpc_start, (unsigned char *)low_table_end, mptable_size); - smp_write_floating_table_physaddr(low_table_end - SMP_FLOATING_TABLE_LEN, mpc_start); - memset((unsigned char *)low_table_end, '\0', mptable_size); - } -#endif /* HAVE_LOW_TABLES */ + rom_table_end = write_smp_table(rom_table_end); + rom_table_end = ALIGN(rom_table_end, 1024);
-#if HAVE_HIGH_TABLES == 1 + /* ... and a copy in the high tables */ if (high_tables_base) { high_table_end = write_smp_table(high_table_end); - high_table_end = (high_table_end+1023) & ~1023; + high_table_end = ALIGN(high_table_end, 1024); } -#endif #endif /* HAVE_MP_TABLE */
- if (low_table_end < 0x500) { - low_table_end = 0x500; - } + post_code(0x9c);
// Relocate the GDT to reserved memory, so it won't get clobbered -#if HAVE_HIGH_TABLES == 1 if (high_tables_base) { move_gdt(high_table_end); high_table_end += &gdt_end - &gdt; - high_table_end = (high_table_end+1023) & ~1023; + high_table_end = ALIGN(high_table_end, 1024); } else { -#endif move_gdt(low_table_end); low_table_end += &gdt_end - &gdt; -#if HAVE_HIGH_TABLES == 1 } -#endif
+ post_code(0x9d); + #if CONFIG_MULTIBOOT /* The Multiboot information structure */ mbi = (struct multiboot_info *)rom_table_end; @@ -203,20 +160,19 @@ rom_table_start, rom_table_end); #endif
-#if HAVE_HIGH_TABLES == 1 + post_code(0x9e); + if (high_tables_base) { + /* Also put a forwarder entry into 0-4K */ write_coreboot_table(low_table_start, low_table_end, high_table_start, high_table_end); } else { - printk_err("ERROR: No high_tables_base.\n"); + /* The coreboot table must be in 0-4K or 960K-1M */ write_coreboot_table(low_table_start, low_table_end, rom_table_start, rom_table_end); } -#else - /* The coreboot table must be in 0-4K or 960K-1M */ - write_coreboot_table(low_table_start, low_table_end, - rom_table_start, rom_table_end); -#endif
+ post_code(0x9f); + return get_lb_mem(); }