Index: src/arch/i386/boot/linuxbios_table.c
===================================================================
--- src/arch/i386/boot/linuxbios_table.c	(revision 2157)
+++ src/arch/i386/boot/linuxbios_table.c	(working copy)
@@ -349,15 +349,22 @@
 }
 
 unsigned long write_linuxbios_table( 
-	unsigned long low_table_start, unsigned long low_table_end,
-	unsigned long rom_table_startk, unsigned long rom_table_endk)
+	unsigned long low_table_start, unsigned long low_table_end, 
+	unsigned long rom_table_start, unsigned long rom_table_end)
 {
 	unsigned long table_size;
 	struct lb_header *head;
 	struct lb_memory *mem;
 
-	head = lb_table_init(low_table_end);
-	low_table_end = (unsigned long)head;
+	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;
+	}
+
 	if (HAVE_OPTION_TABLE == 1) {
 		struct lb_record *rec_dest, *rec_src;
 		/* Write the option config table... */
@@ -370,16 +377,13 @@
 	/* Record where RAM is located */
 	mem = build_lb_mem(head);
 	
-	/* Find the current mptable size */
-	table_size = (low_table_end - low_table_start);
-
 	/* Record the mptable and the the lb_table (This will be adjusted later) */
 	lb_add_memory_range(mem, LB_MEM_TABLE, 
-		low_table_start, table_size);
+		low_table_start, low_table_end - low_table_start);
 
-	/* Record the pirq table */
+	/* Record the pirq table, acpi tables, and maybe the mptable */
 	lb_add_memory_range(mem, LB_MEM_TABLE, 
-		rom_table_startk << 10, (rom_table_endk - rom_table_startk) << 10);
+		rom_table_start, rom_table_end - rom_table_start);
 
 	/* Note:
 	 * I assume that there is always memory at immediately after
@@ -393,8 +397,7 @@
 	/* Record our various random string information */
 	lb_strings(head);
 
-	low_table_end = lb_table_fini(head);
-
 	/* Remember where my valid memory ranges are */
-	return low_table_end;
+	return lb_table_fini(head);
+	
 }
Index: src/arch/i386/boot/tables.c
===================================================================
--- src/arch/i386/boot/tables.c	(revision 2157)
+++ src/arch/i386/boot/tables.c	(working copy)
@@ -1,3 +1,5 @@
+/*	2006.1 yhlu move mptable to [0xf0000,0x100000)
+
 #include <console/console.h>
 #include <cpu/cpu.h>
 #include <boot/tables.h>
@@ -7,14 +9,15 @@
 #include <arch/acpi.h>
 #include "linuxbios_table.h"
 
+
 // Global Descriptor Table, defined in c_start.S
 extern uint8_t gdt;
 extern uint8_t gdt_end;
 
 /* i386 lgdt argument */
 struct gdtarg {
-    unsigned short limit;
-    unsigned int base;
+	unsigned short limit;
+	unsigned int base;
 } __attribute__((packed));
 
 // Copy GDT to new location and reload it
@@ -23,28 +26,31 @@
 void move_gdt(unsigned long newgdt)
 {
 	uint16_t num_gdt_bytes = &gdt_end - &gdt;
-    struct gdtarg gdtarg;
+	struct gdtarg gdtarg;
 
-    printk_debug("Moving GDT to %#lx...", newgdt);
-    memcpy((void*)newgdt, &gdt, num_gdt_bytes);
-    gdtarg.base = newgdt;
-    gdtarg.limit = num_gdt_bytes - 1;
-    __asm__ __volatile__ ("lgdt %0\n\t" : : "m" (gdtarg));
-    printk_debug("ok\n");
+	printk_debug("Moving GDT to %#lx...", newgdt);
+	memcpy((void*)newgdt, &gdt, num_gdt_bytes);
+	gdtarg.base = newgdt;
+	gdtarg.limit = num_gdt_bytes - 1;
+	__asm__ __volatile__ ("lgdt %0\n\t" : : "m" (gdtarg));
+	printk_debug("ok\n");
 }
 
 struct lb_memory *write_tables(void)
 {
-	unsigned long low_table_start, low_table_end;
+	unsigned long low_table_start, low_table_end, new_low_table_end;
 	unsigned long rom_table_start, rom_table_end;
 
-	rom_table_start = 0xf0000;
+	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.
 	 */
+	/* 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 
+	 */
 	low_table_start = 0;
-	low_table_end = 16;
+	low_table_end = 0x500;
 
 	post_code(0x9a);
 
@@ -55,30 +61,33 @@
 	/* copy the smp block to address 0 */
 	post_code(0x96);
 
-	/* The smp table must be in 0-1K, 639K-640K, or 960K-1M */
-	low_table_end = write_smp_table(low_table_end);
-
 	/* Write ACPI tables */
 	/* write them in the rom area because DSDT can be large (8K on epia-m) which
 	 * pushes linuxbios table out of first 4K if set up in low table area 
          */
-
 	rom_table_end = write_acpi_tables(rom_table_end);
 	rom_table_end = (rom_table_end+1023) & ~1023;
 
-	/* Don't write anything in the traditional x86 BIOS data segment */
-	if (low_table_end < 0x500) {
-		low_table_end = 0x500;
-	}
-
 	// Relocate the GDT to reserved memory, so it won't get clobbered
 	move_gdt(low_table_end);
 	low_table_end += &gdt_end - &gdt;
 
+        /* The smp table must be in 0-1K, 639K-640K, or 960K-1M */
+        new_low_table_end = write_smp_table(low_table_end);
+
+	/* We can not put mptable here, we need to copy them to somewhere else*/
+	unsigned mptable_size = new_low_table_end - low_table_end;
+	if((rom_table_end+mptable_size)<0x100000) {
+		/* We can copy mptable on rom_table, and leave low space for lbtable  */
+		memcpy((unsigned char *)rom_table_end, (unsigned char *)low_table_end, mptable_size);
+		memset((unsigned char *)low_table_end, 0, mptable_size);
+		rom_table_end += mptable_size;
+	} 
+
 	/* The linuxbios table must be in 0-4K or 960K-1M */
 	write_linuxbios_table(
 			      low_table_start, low_table_end,
-			      rom_table_start >> 10, rom_table_end >> 10);
+			      rom_table_start, rom_table_end);
 
 	return get_lb_mem();
 }
