Author: stepan
Date: Mon May  3 18:21:52 2010
New Revision: 5521
URL: https://tracker.coreboot.org/trac/coreboot/changeset/5521

Log:
Qemu, despite "emulating" an intel chipset, uses the CMOS to 
tell the BIOS how much RAM the virtual machine has available.
This patch fixes the detection.

Signed-off-by: Valdimir Serbinenko <[email protected]>
Acked-by: Stefan Reinauer <[email protected]>

Modified:
   trunk/src/mainboard/emulation/qemu-x86/northbridge.c

Modified: trunk/src/mainboard/emulation/qemu-x86/northbridge.c
==============================================================================
--- trunk/src/mainboard/emulation/qemu-x86/northbridge.c        Fri Apr 30 
22:44:30 2010        (r5520)
+++ trunk/src/mainboard/emulation/qemu-x86/northbridge.c        Mon May  3 
18:21:52 2010        (r5521)
@@ -53,60 +53,44 @@
 extern uint64_t high_tables_base, high_tables_size;
 #endif
 
+#define CMOS_ADDR_PORT 0x70
+#define CMOS_DATA_PORT 0x71
+#define HIGH_RAM_ADDR 0x35
+#define LOW_RAM_ADDR 0x34
+
 static void cpu_pci_domain_set_resources(device_t dev)
 {
-       static const uint8_t ramregs[] = {
-               0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x56, 0x57
-       };
-       device_t mc_dev;
-       uint32_t pci_tolm;
-
-       pci_tolm = find_pci_tolm(&dev->link[0]);
-       mc_dev = dev->link[0].children;
-       if (mc_dev) {
-               unsigned long tomk, tolmk;
-               unsigned char rambits;
-               int i, idx;
-
-               for(rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
-                       unsigned char reg;
-                       reg = pci_read_config8(mc_dev, ramregs[i]);
-                       /* these are ENDING addresses, not sizes.
-                        * if there is memory in this slot, then reg will be > 
rambits.
-                        * So we just take the max, that gives us total.
-                        * We take the highest one to cover for once and future 
coreboot
-                        * bugs. We warn about bugs.
-                        */
-                       if (reg > rambits)
-                               rambits = reg;
-                       if (reg < rambits)
-                               printk(BIOS_ERR, "ERROR! register 0x%x is not 
set!\n",
-                                       ramregs[i]);
-               }
-               if (rambits == 0) {
-                       printk(BIOS_ERR, "RAM size config registers are empty; 
defaulting to 64 MBytes\n");
-                       rambits = 8;
-               }
-               printk(BIOS_DEBUG, "I would set ram size to 0x%x Kbytes\n", 
(rambits)*8*1024);
-               tomk = rambits*8*1024;
-               /* Compute the top of Low memory */
-               tolmk = pci_tolm >> 10;
-               if (tolmk >= tomk) {
-                       /* The PCI hole does not overlap the memory. */
-                       tolmk = tomk;
-               }
-
-               /* Report the memory regions. */
-               idx = 10;
-               ram_resource(dev, idx++, 0, 640);
-               ram_resource(dev, idx++, 768, tolmk - 768);
+       u32 pci_tolm = find_pci_tolm(&dev->link[0]);
+       unsigned long tomk = 0, tolmk;
+       int idx;
+
+       outb (HIGH_RAM_ADDR, CMOS_ADDR_PORT);
+       tomk = ((unsigned long) inb(CMOS_DATA_PORT)) << 14;
+       outb (LOW_RAM_ADDR, CMOS_ADDR_PORT);
+       tomk |= ((unsigned long) inb(CMOS_DATA_PORT)) << 6;
+       tomk += 16 * 1024;
+
+       printk(BIOS_DEBUG, "Detected %lu Kbytes (%lu MiB) RAM.\n",
+              tomk, tomk / 1024);
+
+       /* Compute the top of Low memory */
+       tolmk = pci_tolm >> 10;
+       if (tolmk >= tomk) {
+               /* The PCI hole does not overlap the memory. */
+               tolmk = tomk;
+       }
+
+       /* Report the memory regions. */
+       idx = 10;
+       ram_resource(dev, idx++, 0, 640);
+       ram_resource(dev, idx++, 768, tolmk - 768);
 
 #if CONFIG_WRITE_HIGH_TABLES==1
-               /* Leave some space for ACPI, PIRQ and MP tables */
-               high_tables_base = (tomk - HIGH_TABLES_SIZE) * 1024;
-               high_tables_size = HIGH_TABLES_SIZE * 1024;
+       /* Leave some space for ACPI, PIRQ and MP tables */
+       high_tables_base = (tomk - HIGH_TABLES_SIZE) * 1024;
+       high_tables_size = HIGH_TABLES_SIZE * 1024;
 #endif
-       }
+
        assign_resources(&dev->link[0]);
 }
 

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to