Unify memory size detection.
authorKevin O'Connor <kevin@koconnor.net>
Sun, 18 May 2008 02:20:27 +0000 (22:20 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 18 May 2008 02:20:27 +0000 (22:20 -0400)
Figure out memory size once at startup and save in a variable.
Change all run-time locations to use that variable instead of
    re-detecting memory size.

src/biosvar.h
src/post.c
src/rombios32.c
src/system.c

index 8f694e4b4851114fcae4d3c58421b1f438607709..0c68a2e0af3ad1ea598fb06e5babd2db13a494e6 100644 (file)
@@ -257,6 +257,9 @@ struct extended_bios_data_area_s {
     // 0x5d
     u8 other2[0xC4];
 
+    // Physical memory available.
+    u32 ram_size;
+
     // ATA Driver data
     struct ata_s   ata;
 
index 0d8f18e2d5a78bab804a0e36c93d98d6c5784239..da65559bd36375efd4dfbe07b6f761749e0050bc 100644 (file)
@@ -77,6 +77,22 @@ init_ebda()
             , offsetof(struct extended_bios_data_area_s, fdpt[1]));
 }
 
+static void
+ram_probe(void)
+{
+    u32 rs = (inb_cmos(CMOS_MEM_EXTMEM2_LOW)
+              | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 8)) * 65536;
+    if (rs)
+        rs += 16 * 1024 * 1024;
+    else
+        rs = ((inb_cmos(CMOS_MEM_EXTMEM_LOW)
+               | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 8)) * 1024
+              + 1 * 1024 * 1024);
+
+    SET_EBDA(ram_size, rs);
+    BX_INFO("ram_size=0x%08x\n", rs);
+}
+
 static void
 pic_setup()
 {
@@ -190,6 +206,8 @@ post()
     serial_setup();
     pic_setup();
 
+    ram_probe();
+
     rom_scan(0xc0000, 0xc7800);
 
     printf("BIOS - begin\n\n");
index a1e072279e8cd45e7e3f88104ac41c4f55ba058f..4db3465f49a28d1b497914327c6a7314330c2b2f 100644 (file)
@@ -86,7 +86,6 @@ int smp_cpus;
 u32 cpuid_signature;
 u32 cpuid_features;
 u32 cpuid_ext_features;
-unsigned long ram_size;
 u8 bios_uuid[16];
 #if (CONFIG_USE_EBDA_TABLES == 1)
 unsigned long ebda_cur_addr;
@@ -133,23 +132,6 @@ void cpu_probe(void)
     cpuid_ext_features = ecx;
 }
 
-void ram_probe(void)
-{
-    if (inb_cmos(CMOS_MEM_EXTMEM2_LOW) | inb_cmos(CMOS_MEM_EXTMEM2_HIGH))
-        ram_size = (inb_cmos(CMOS_MEM_EXTMEM2_LOW)
-                    | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 8)) * 65536 +
-            16 * 1024 * 1024;
-    else
-        ram_size = ((inb_cmos(CMOS_MEM_EXTMEM_LOW)
-                     | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 8))
-                    * 1024 + 1 * 1024 * 1024);
-    BX_INFO("ram_size=0x%08lx\n", ram_size);
-#if (CONFIG_USE_EBDA_TABLES == 1)
-    ebda_cur_addr = ((*(u16 *)(0x40e)) << 4) + 0x380;
-    BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
-#endif
-}
-
 /****************************************************/
 /* SMP probe */
 
@@ -579,7 +561,7 @@ void pci_bios_init(void)
 {
     pci_bios_io_addr = 0xc000;
     pci_bios_mem_addr = 0xf0000000;
-    pci_bios_bigmem_addr = ram_size;
+    pci_bios_bigmem_addr = GET_EBDA(ram_size);
     if (pci_bios_bigmem_addr < 0x90000000)
         pci_bios_bigmem_addr = 0x90000000;
 
@@ -645,7 +627,8 @@ static void mptable_init(void)
 #endif
 
 #if (CONFIG_USE_EBDA_TABLES == 1)
-    mp_config_table = (u8 *)(ram_size - CONFIG_ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
+    mp_config_table = (u8 *)(GET_EBDA(ram_size) - CONFIG_ACPI_DATA_SIZE
+                             - MPTABLE_MAX_SIZE);
 #else
     bios_table_cur_addr = align(bios_table_cur_addr, 16);
     mp_config_table = (u8 *)bios_table_cur_addr;
@@ -1065,7 +1048,7 @@ void acpi_bios_init(void)
     bios_table_cur_addr += sizeof(*rsdp);
 #endif
 
-    addr = base_addr = ram_size - CONFIG_ACPI_DATA_SIZE;
+    addr = base_addr = GET_EBDA(ram_size) - CONFIG_ACPI_DATA_SIZE;
     rsdt_addr = addr;
     rsdt = (void *)(addr);
     addr += sizeof(*rsdt);
@@ -1634,7 +1617,7 @@ void smbios_init(void)
 {
     unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
     char *start, *p, *q;
-    int memsize = ram_size / (1024 * 1024);
+    int memsize = GET_EBDA(ram_size) / (1024 * 1024);
 
 #if (CONFIG_USE_EBDA_TABLES == 1)
     ebda_cur_addr = align(ebda_cur_addr, 16);
@@ -1687,7 +1670,10 @@ void rombios32_init(void)
 {
     BX_INFO("Starting rombios32\n");
 
-    ram_probe();
+#if (CONFIG_USE_EBDA_TABLES == 1)
+    ebda_cur_addr = ((*(u16 *)(0x40e)) << 4) + 0x380;
+    BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
+#endif
 
     cpu_probe();
 
index 89d68f13a66e8aa9c499a6ff0665d45ccb4be510..68fbf54a0ef696a487fc7e98fc36dcea8824bef9 100644 (file)
@@ -205,12 +205,14 @@ handle_1587(struct bregs *regs)
 static void
 handle_1588(struct bregs *regs)
 {
-    regs->al = inb_cmos(CMOS_MEM_EXTMEM_LOW);
-    regs->ah = inb_cmos(CMOS_MEM_EXTMEM_HIGH);
+    u32 rs = GET_EBDA(ram_size);
+
     // According to Ralf Brown's interrupt the limit should be 15M,
     // but real machines mostly return max. 63M.
-    if (regs->ax > 0xffc0)
-        regs->ax = 0xffc0;
+    if (rs > 64*1024*1024)
+        regs->ax = 63 * 1024;
+    else
+        regs->ax = (rs - 1*1024*1024) / 1024;
     set_success(regs);
 }
 
@@ -259,17 +261,18 @@ handle_15e801(struct bregs *regs)
     // regs.u.r16.ax = 0;
     // regs.u.r16.bx = 0;
 
-    // Get the amount of extended memory (above 1M)
-    regs->cl = inb_cmos(CMOS_MEM_EXTMEM_LOW);
-    regs->ch = inb_cmos(CMOS_MEM_EXTMEM_HIGH);
+    u32 rs = GET_EBDA(ram_size);
 
-    // limit to 15M
-    if (regs->cx > 0x3c00)
-        regs->cx = 0x3c00;
-
-    // Get the amount of extended memory above 16M in 64k blocs
-    regs->dl = inb_cmos(CMOS_MEM_EXTMEM2_LOW);
-    regs->dh = inb_cmos(CMOS_MEM_EXTMEM2_HIGH);
+    // Get the amount of extended memory (above 1M)
+    if (rs > 16*1024*1024) {
+        // limit to 15M
+        regs->cx = 15*1024;
+        // Get the amount of extended memory above 16M in 64k blocks
+        regs->dx = (rs - 16*1024*1024) / (64*1024);
+    } else {
+        regs->cx = (rs - 1*1024*1024) / 1024;
+        regs->dx = 0;
+    }
 
     // Set configured memory equal to extended memory
     regs->ax = regs->cx;
@@ -281,17 +284,9 @@ handle_15e801(struct bregs *regs)
 static void
 set_e820_range(struct bregs *regs, u32 start, u32 end, u16 type, int last)
 {
-    SET_FARVAR(regs->es, *(u16*)(regs->di+0), start);
-    SET_FARVAR(regs->es, *(u16*)(regs->di+2), start >> 16);
-    SET_FARVAR(regs->es, *(u16*)(regs->di+4), 0x00);
-    SET_FARVAR(regs->es, *(u16*)(regs->di+6), 0x00);
-
-    end -= start;
-    SET_FARVAR(regs->es, *(u16*)(regs->di+8), end);
-    SET_FARVAR(regs->es, *(u16*)(regs->di+10), end >> 16);
-    SET_FARVAR(regs->es, *(u16*)(regs->di+12), 0x0000);
-    SET_FARVAR(regs->es, *(u16*)(regs->di+14), 0x0000);
-
+    u32 size = end - start;
+    SET_FARVAR(regs->es, *(u64*)(regs->di+0), start);
+    SET_FARVAR(regs->es, *(u64*)(regs->di+8), size);
     SET_FARVAR(regs->es, *(u16*)(regs->di+16), type);
     SET_FARVAR(regs->es, *(u16*)(regs->di+18), 0x0);
 
@@ -313,24 +308,11 @@ handle_15e820(struct bregs *regs)
         return;
     }
 
-    u32 extended_memory_size = inb_cmos(CMOS_MEM_EXTMEM2_HIGH);
-    extended_memory_size <<= 8;
-    extended_memory_size |= inb_cmos(CMOS_MEM_EXTMEM2_LOW);
-    extended_memory_size *= 64;
+    u32 extended_memory_size = GET_EBDA(ram_size);
     // greater than EFF00000???
-    if (extended_memory_size > 0x3bc000)
+    if (extended_memory_size > 0xf0000000)
         // everything after this is reserved memory until we get to 0x100000000
-        extended_memory_size = 0x3bc000;
-    extended_memory_size *= 1024;
-    extended_memory_size += (16L * 1024 * 1024);
-
-    if (extended_memory_size <= (16L * 1024 * 1024)) {
-        extended_memory_size = inb_cmos(CMOS_MEM_EXTMEM_HIGH);
-        extended_memory_size <<= 8;
-        extended_memory_size |= inb_cmos(CMOS_MEM_EXTMEM_LOW);
-        extended_memory_size *= 1024;
-        extended_memory_size += 1 * 1024 * 1024;
-    }
+        extended_memory_size = 0xf0000000;
 
     switch (regs->bx) {
     case 0: