From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:58052) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T1bWR-0006Hz-Ne for qemu-devel@nongnu.org; Wed, 15 Aug 2012 07:12:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T1bWQ-0002GO-PV for qemu-devel@nongnu.org; Wed, 15 Aug 2012 07:12:23 -0400 Received: from oxygen.pond.sub.org ([78.46.104.156]:34621) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T1bWQ-0002G6-Iv for qemu-devel@nongnu.org; Wed, 15 Aug 2012 07:12:22 -0400 From: Markus Armbruster Date: Wed, 15 Aug 2012 13:12:20 +0200 Message-Id: <1345029140-12338-3-git-send-email-armbru@redhat.com> In-Reply-To: <1345029140-12338-1-git-send-email-armbru@redhat.com> References: <1345029140-12338-1-git-send-email-armbru@redhat.com> Subject: [Qemu-devel] [PATCH v3 2/2] pc: Fix RTC CMOS info on RAM for ram_size < 1MiB List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: blauwirbel@gmail.com, anthony@codemonkey.ws, avi@redhat.com, gleb@redhat.com pc_cmos_init() always claims 640KiB base memory, and ram_size - 1MiB extended memory. The latter can underflow to "lots of extended memory". Fix both, and clean up some. Note: SeaBIOS currently requires 1MiB of RAM, and doesn't check whether it got enough. Signed-off-by: Markus Armbruster --- hw/pc.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index e8bcfc0..24df1e0 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -337,32 +337,37 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, /* various important CMOS locations needed by PC/Bochs bios */ /* memory size */ - val = 640; /* base memory in K */ + /* base memory (first MiB) */ + val = MIN(ram_size / 1024, 640); rtc_set_memory(s, 0x15, val); rtc_set_memory(s, 0x16, val >> 8); - - val = (ram_size / 1024) - 1024; + /* extended memory (next 64MiB) */ + if (ram_size > 1024 * 1024) { + val = (ram_size - 1024 * 1024) / 1024; + } else { + val = 0; + } if (val > 65535) val = 65535; rtc_set_memory(s, 0x17, val); rtc_set_memory(s, 0x18, val >> 8); rtc_set_memory(s, 0x30, val); rtc_set_memory(s, 0x31, val >> 8); - - if (above_4g_mem_size) { - rtc_set_memory(s, 0x5b, (unsigned int)above_4g_mem_size >> 16); - rtc_set_memory(s, 0x5c, (unsigned int)above_4g_mem_size >> 24); - rtc_set_memory(s, 0x5d, (uint64_t)above_4g_mem_size >> 32); - } - - if (ram_size > (16 * 1024 * 1024)) - val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536); - else + /* memory between 16MiB and 4GiB */ + if (ram_size > 16 * 1024 * 1024) { + val = (ram_size - 16 * 1024 * 1024) / 65536; + } else { val = 0; + } if (val > 65535) val = 65535; rtc_set_memory(s, 0x34, val); rtc_set_memory(s, 0x35, val >> 8); + /* memory above 4GiB */ + val = above_4g_mem_size / 65536; + rtc_set_memory(s, 0x5b, val); + rtc_set_memory(s, 0x5c, val >> 8); + rtc_set_memory(s, 0x5d, val >> 16); /* set the number of CPU */ rtc_set_memory(s, 0x5f, smp_cpus - 1); -- 1.7.11.2