I didn't understand what was going on in tables.c, and it seemed a
little fragile.

These three patches try to help that out.  I would only recommend the
first two, but all three is closer to maintaining the functionality we
had.

When you're reviewing, it will be helpful to note that rom_tables_* ==
LOW_TABLES, high_tables_* == HIGH_TABLES, and low_tables==
coreboot-specific very low tables.

These patches are abuild tested and boot tested on Tyan s2892, qemu, and SimNOW.

tables.diff:
Add comments.
Remove ACPI-specific code.
Align low_table_end after gdt (so it matches high_table_end).
Correct "New low_table_end..." line in coreboot_table.c.

high_low.diff:
Factor out common code for writing tables.

both.diff:
If we need to have the tables written both times we can do something like this.

Signed-off-by: Myles Watson <[email protected]>
Thanks,
Myles
Index: cbv2/src/arch/i386/boot/tables.c
===================================================================
--- cbv2.orig/src/arch/i386/boot/tables.c	2009-05-13 15:30:26.000000000 -0600
+++ cbv2/src/arch/i386/boot/tables.c	2009-05-13 15:39:50.000000000 -0600
@@ -62,13 +62,12 @@
 uint64_t high_tables_size;
 #endif
 
+/* HIGH_TABLES means a table in very low memory + at the end of RAM. */
+/* LOW_TABLES means a table in very low memory + at 0xf0000 (rom_table_*). */
 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
-	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
@@ -114,18 +113,10 @@
 	 */
 #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) {
 		high_table_end = write_acpi_tables(high_table_end);
 		high_table_end = (high_table_end+1023) & ~1023;
 	}
-#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);
@@ -139,42 +130,27 @@
 #if HAVE_MP_TABLE == 1
 
 	/* The smp table must be in 0-1K, 639K-640K, or 960K-1M */
+	/* Put it in the largest spot (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);
-	}
+	mpc_start = rom_table_end;
+	rom_table_end = write_smp_table(rom_table_end);
+	rom_table_end = (rom_table_end+1023) & ~1023;
+	if (mpc_start < 0x100000 && rom_table_end > 0x100000)
+		printk_err("MP table too big to fit below 1M %lx-%lx\n",
+			   mpc_start, rom_table_end);
 #endif /* HAVE_LOW_TABLES */
 
 #if HAVE_HIGH_TABLES == 1
+#if HAVE_LOW_TABLES == 0
+	mpc_start = high_table_end;
+#endif
 	if (high_tables_base) {
 		high_table_end = write_smp_table(high_table_end);
 		high_table_end = (high_table_end+1023) & ~1023;
 	}
 #endif
+	smp_write_floating_table_physaddr(low_table_end, mpc_start);
+	low_table_end += SMP_FLOATING_TABLE_LEN;
 #endif /* HAVE_MP_TABLE */
 
 	if (low_table_end < 0x500) {
@@ -191,6 +167,7 @@
 #endif
 		move_gdt(low_table_end);
 		low_table_end += &gdt_end - &gdt;
+		low_table_end = (low_table_end+1023) & ~1023;
 #if HAVE_HIGH_TABLES == 1
 	}
 #endif
@@ -206,17 +183,17 @@
 #if HAVE_HIGH_TABLES == 1
 	if (high_tables_base) {
 		write_coreboot_table(low_table_start, low_table_end,
-				high_table_start, high_table_end);
+				     high_table_start, high_table_end);
 	} else {
 		printk_err("ERROR: No high_tables_base.\n");
 		write_coreboot_table(low_table_start, low_table_end,
-			      rom_table_start, rom_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
- 
+
 	return get_lb_mem();
 }
Index: cbv2/src/arch/i386/boot/coreboot_table.c
===================================================================
--- cbv2.orig/src/arch/i386/boot/coreboot_table.c	2009-05-13 15:30:26.000000000 -0600
+++ cbv2/src/arch/i386/boot/coreboot_table.c	2009-05-13 15:35:16.000000000 -0600
@@ -429,9 +429,8 @@
 			low_table_end);
 	head = lb_table_init(low_table_end);
 	lb_forward(head, (struct lb_header*)rom_table_end);
-	lb_table_fini(head, 0);
 
-	low_table_end = (unsigned long)head;
+	low_table_end = (unsigned long) lb_table_fini(head, 0);
 	printk_debug("New low_table_end: 0x%08lx\n", low_table_end);
 	printk_debug("Now going to write high coreboot table at 0x%08lx\n",
 			rom_table_end);
Index: cbv2/src/arch/i386/boot/tables.c
===================================================================
--- cbv2.orig/src/arch/i386/boot/tables.c	2009-05-13 15:35:16.000000000 -0600
+++ cbv2/src/arch/i386/boot/tables.c	2009-05-13 15:35:25.000000000 -0600
@@ -57,140 +57,105 @@
 	printk_debug("ok\n");
 }
 
-#if HAVE_HIGH_TABLES == 1
-uint64_t high_tables_base = 0;
-uint64_t high_tables_size;
-#endif
-
-/* HIGH_TABLES means a table in very low memory + at the end of RAM. */
-/* LOW_TABLES means a table in very low memory + at 0xf0000 (rom_table_*). */
-struct lb_memory *write_tables(void)
+void write_table(unsigned long dir_start, unsigned long *dir_end,
+		 unsigned long table_start, unsigned long *table_end)
 {
-	unsigned long low_table_start, low_table_end;
-	unsigned long rom_table_start, rom_table_end;
-
-#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.
-	 */
-	unsigned long high_table_start=0, high_table_end=0;
-
-	if (high_tables_base) {
-		printk_debug("High Tables Base is %llx.\n", high_tables_base);
-		high_table_start = high_tables_base;
-		high_table_end = high_tables_base;
-	} else {
-		printk_debug("High Tables Base is not set.\n");
-	}
-#endif
+	unsigned long dir_table_start = dir_start, dir_table_end = *dir_end;
+	unsigned long rom_table_start = table_start, rom_table_end = *table_end;
 
-	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.
-	 */
-	low_table_start = 0;
-	low_table_end = 16;
-
-	post_code(0x9a);
-
-#if HAVE_LOW_TABLES == 1
 	/* This table must be betweeen 0xf0000 & 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
-	if (high_tables_base) {
-		high_table_end = write_pirq_routing_table(high_table_end);
-		high_table_end = (high_table_end + 1023) & ~1023;
-	}
-#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 
 	 */
 #if HAVE_ACPI_TABLES == 1
-#if HAVE_HIGH_TABLES == 1
-	if (high_tables_base) {
-		high_table_end = write_acpi_tables(high_table_end);
-		high_table_end = (high_table_end+1023) & ~1023;
-	}
-#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
+	rom_table_end = (rom_table_end + 1023) & ~1023;
 #endif
 	/* copy the smp block to address 0 */
 	post_code(0x96);
 
 #if HAVE_MP_TABLE == 1
-
 	/* The smp table must be in 0-1K, 639K-640K, or 960K-1M */
 	/* Put it in the largest spot (960K-1M). */
-#if HAVE_LOW_TABLES == 1
-	mpc_start = rom_table_end;
+	unsigned long mpc_start = rom_table_end;
 	rom_table_end = write_smp_table(rom_table_end);
-	rom_table_end = (rom_table_end+1023) & ~1023;
+	rom_table_end = (rom_table_end + 1023) & ~1023;
 	if (mpc_start < 0x100000 && rom_table_end > 0x100000)
 		printk_err("MP table too big to fit below 1M %lx-%lx\n",
 			   mpc_start, rom_table_end);
-#endif /* HAVE_LOW_TABLES */
+	smp_write_floating_table_physaddr(dir_table_end, mpc_start);
+	dir_table_end += SMP_FLOATING_TABLE_LEN;
+#endif	/* HAVE_MP_TABLE */
 
-#if HAVE_HIGH_TABLES == 1
-#if HAVE_LOW_TABLES == 0
-	mpc_start = high_table_end;
-#endif
-	if (high_tables_base) {
-		high_table_end = write_smp_table(high_table_end);
-		high_table_end = (high_table_end+1023) & ~1023;
+	if (dir_table_end < 0x500) {
+		dir_table_end = 0x500;
 	}
-#endif
-	smp_write_floating_table_physaddr(low_table_end, mpc_start);
-	low_table_end += SMP_FLOATING_TABLE_LEN;
-#endif /* HAVE_MP_TABLE */
 
-	if (low_table_end < 0x500) {
-		low_table_end = 0x500;
-	}
-
-	// 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;
-	} else {
-#endif
-		move_gdt(low_table_end);
-		low_table_end += &gdt_end - &gdt;
-		low_table_end = (low_table_end+1023) & ~1023;
-#if HAVE_HIGH_TABLES == 1
-	}
-#endif
+	/* Relocate the GDT to reserved memory, so it won't get clobbered. */
+	move_gdt(rom_table_end);
+	rom_table_end += &gdt_end - &gdt;
+	rom_table_end = (rom_table_end + 1023) & ~1023;
 
 #if CONFIG_MULTIBOOT
 	/* The Multiboot information structure */
 	mbi = (struct multiboot_info *)rom_table_end;
-	rom_table_end = write_multiboot_info(
-				low_table_start, low_table_end,
-				rom_table_start, rom_table_end);
+	rom_table_end = write_multiboot_info(dir_table_start, dir_table_end,
+					     rom_table_start, rom_table_end);
 #endif
 
+	*dir_end = dir_table_end;
+	*table_end = rom_table_end;
+}
+
 #if HAVE_HIGH_TABLES == 1
+uint64_t high_tables_base = 0;
+uint64_t high_tables_size;
+#endif
+
+/* HIGH_TABLES means a table in very low memory + at the end of RAM. */
+/* LOW_TABLES means a table in very low memory + at 0xf0000 (rom_table_*). */
+struct lb_memory *write_tables(void)
+{
+	unsigned long low_table_start, low_table_end;
+	unsigned long rom_table_start, rom_table_end;
+
+	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.
+	 */
+	low_table_start = 0;
+	low_table_end = 16;
+
+	post_code(0x9a);
+
+#if HAVE_HIGH_TABLES == 1
+	unsigned long high_table_start=0, high_table_end=0;
+
 	if (high_tables_base) {
+		printk_debug("High Tables Base is %llx.\n", high_tables_base);
+		high_table_start = high_tables_base;
+		high_table_end = high_tables_base;
+		write_table(low_table_start, &low_table_end,
+			    high_table_start, &high_table_end);
 		write_coreboot_table(low_table_start, low_table_end,
 				     high_table_start, high_table_end);
 	} else {
 		printk_err("ERROR: No high_tables_base.\n");
+		write_table(low_table_start, &low_table_end,
+			    rom_table_start, &rom_table_end);
 		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_table(low_table_start, &low_table_end,
+		    rom_table_start, &rom_table_end);
 	write_coreboot_table(low_table_start, low_table_end,
 			      rom_table_start, rom_table_end);
 #endif
Index: cbv2/src/arch/i386/boot/tables.c
===================================================================
--- cbv2.orig/src/arch/i386/boot/tables.c	2009-05-13 15:21:31.000000000 -0600
+++ cbv2/src/arch/i386/boot/tables.c	2009-05-13 15:22:41.000000000 -0600
@@ -134,6 +134,9 @@
 
 	post_code(0x9a);
 
+	write_table(low_table_start, &low_table_end,
+		    rom_table_start, &rom_table_end);
+
 #if HAVE_HIGH_TABLES == 1
 	unsigned long high_table_start=0, high_table_end=0;
 
@@ -147,15 +150,11 @@
 				     high_table_start, high_table_end);
 	} else {
 		printk_err("ERROR: No high_tables_base.\n");
-		write_table(low_table_start, &low_table_end,
-			    rom_table_start, &rom_table_end);
 		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_table(low_table_start, &low_table_end,
-		    rom_table_start, &rom_table_end);
 	write_coreboot_table(low_table_start, low_table_end,
 			      rom_table_start, rom_table_end);
 #endif
-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to