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 <phcoder@gmail.com> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5521 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
80d9804ff7
commit
7339f36961
|
@ -53,60 +53,44 @@ static uint32_t find_pci_tolm(struct bus *bus)
|
||||||
extern uint64_t high_tables_base, high_tables_size;
|
extern uint64_t high_tables_base, high_tables_size;
|
||||||
#endif
|
#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 void cpu_pci_domain_set_resources(device_t dev)
|
||||||
{
|
{
|
||||||
static const uint8_t ramregs[] = {
|
u32 pci_tolm = find_pci_tolm(&dev->link[0]);
|
||||||
0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x56, 0x57
|
unsigned long tomk = 0, tolmk;
|
||||||
};
|
int idx;
|
||||||
device_t mc_dev;
|
|
||||||
uint32_t pci_tolm;
|
|
||||||
|
|
||||||
pci_tolm = find_pci_tolm(&dev->link[0]);
|
outb (HIGH_RAM_ADDR, CMOS_ADDR_PORT);
|
||||||
mc_dev = dev->link[0].children;
|
tomk = ((unsigned long) inb(CMOS_DATA_PORT)) << 14;
|
||||||
if (mc_dev) {
|
outb (LOW_RAM_ADDR, CMOS_ADDR_PORT);
|
||||||
unsigned long tomk, tolmk;
|
tomk |= ((unsigned long) inb(CMOS_DATA_PORT)) << 6;
|
||||||
unsigned char rambits;
|
tomk += 16 * 1024;
|
||||||
int i, idx;
|
|
||||||
|
|
||||||
for(rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
|
printk(BIOS_DEBUG, "Detected %lu Kbytes (%lu MiB) RAM.\n",
|
||||||
unsigned char reg;
|
tomk, tomk / 1024);
|
||||||
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. */
|
/* Compute the top of Low memory */
|
||||||
idx = 10;
|
tolmk = pci_tolm >> 10;
|
||||||
ram_resource(dev, idx++, 0, 640);
|
if (tolmk >= tomk) {
|
||||||
ram_resource(dev, idx++, 768, tolmk - 768);
|
/* 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
|
#if CONFIG_WRITE_HIGH_TABLES==1
|
||||||
/* Leave some space for ACPI, PIRQ and MP tables */
|
/* Leave some space for ACPI, PIRQ and MP tables */
|
||||||
high_tables_base = (tomk - HIGH_TABLES_SIZE) * 1024;
|
high_tables_base = (tomk - HIGH_TABLES_SIZE) * 1024;
|
||||||
high_tables_size = HIGH_TABLES_SIZE * 1024;
|
high_tables_size = HIGH_TABLES_SIZE * 1024;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
assign_resources(&dev->link[0]);
|
assign_resources(&dev->link[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue