From 938608cb45cbefa2decc75cd93d919f4df4cf766 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Tue, 31 Mar 2009 21:02:55 +0000 Subject: [PATCH] Probe size of installed memory modules from loader and display it as 'real memory' instead of Maxmem if the value is available. Note amd64 displayed physmem as 'usable memory' since machdep.c r1.640 to unconfuse users. Now it is consistent across amd64 and i386 again. While I am here, clean up smbios.c a bit and update copyright date. Reviewed by: jhb --- sys/amd64/amd64/machdep.c | 16 ++++++++-- sys/boot/i386/libi386/smbios.c | 58 ++++++++++++++++++++++++++++++---- sys/i386/i386/machdep.c | 14 ++++++-- 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index cd3c93867ea2..ad46a62a0835 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -196,6 +196,7 @@ static void cpu_startup(dummy) void *dummy; { + uintmax_t memsize; char *sysenv; /* @@ -226,8 +227,17 @@ cpu_startup(dummy) #ifdef PERFMON perfmon_init(); #endif - printf("usable memory = %ju (%ju MB)\n", ptoa((uintmax_t)physmem), - ptoa((uintmax_t)physmem) / 1048576); + sysenv = getenv("smbios.memory.enabled"); + if (sysenv != NULL) { + memsize = (uintmax_t)strtoul(sysenv, (char **)NULL, 10); + freeenv(sysenv); + } + if (memsize > 0) + printf("real memory = %ju (%ju MB)\n", memsize << 10, + memsize >> 10); + else + printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem), + ptoa((uintmax_t)Maxmem) / 1048576); realmem = Maxmem; /* * Display any holes after the first chunk of extended memory. @@ -250,7 +260,7 @@ cpu_startup(dummy) vm_ksubmap_init(&kmi); - printf("avail memory = %ju (%ju MB)\n", + printf("avail memory = %ju (%ju MB)\n", ptoa((uintmax_t)cnt.v_free_count), ptoa((uintmax_t)cnt.v_free_count) / 1048576); diff --git a/sys/boot/i386/libi386/smbios.c b/sys/boot/i386/libi386/smbios.c index dd39cc284bc5..7c42ab74c9a6 100644 --- a/sys/boot/i386/libi386/smbios.c +++ b/sys/boot/i386/libi386/smbios.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005, 2006 Jung-uk Kim + * Copyright (c) 2005-2009 Jung-uk Kim * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,6 +55,8 @@ __FBSDID("$FreeBSD$"); #define SMBIOS_SIG "_SM_" #define SMBIOS_DMI_SIG "_DMI_" +static uint32_t smbios_enabled_memory = 0; +static uint32_t smbios_old_enabled_memory = 0; static uint8_t smbios_enabled_sockets = 0; static uint8_t smbios_populated_sockets = 0; @@ -89,16 +91,27 @@ smbios_detect(void) for (dmi = addr = PTOV(paddr), i = 0; dmi - addr < length && i < count; i++) dmi = smbios_parse_table(dmi); - sprintf(buf, "%d", smbios_enabled_sockets); - setenv("smbios.socket.enabled", buf, 1); - sprintf(buf, "%d", smbios_populated_sockets); - setenv("smbios.socket.populated", buf, 1); + if (smbios_enabled_memory > 0 || smbios_old_enabled_memory > 0) { + sprintf(buf, "%u", smbios_enabled_memory > 0 ? + smbios_enabled_memory : smbios_old_enabled_memory); + setenv("smbios.memory.enabled", buf, 1); + } + if (smbios_enabled_sockets > 0) { + sprintf(buf, "%u", smbios_enabled_sockets); + setenv("smbios.socket.enabled", buf, 1); + } + if (smbios_populated_sockets > 0) { + sprintf(buf, "%u", smbios_populated_sockets); + setenv("smbios.socket.populated", buf, 1); + } } static uint8_t * smbios_parse_table(const uint8_t *dmi) { uint8_t *dp; + uint16_t size; + uint8_t osize; switch(dmi[0]) { case 0: /* Type 0: BIOS */ @@ -159,10 +172,43 @@ smbios_parse_table(const uint8_t *dmi) smbios_populated_sockets++; break; + case 6: /* Type 6: Memory Module Information (Obsolete) */ + /* + * Offset 0Ah: Enabled Size + * + * Bit 7 Bank connection + * 1 - Double-bank connection + * 0 - Single-bank connection + * Bit 6:0 Size (n), where 2**n is the size in MB + * 7Dh - Not determinable (Installed Size only) + * 7Eh - Module is installed, but no memory + * has been enabled + * 7Fh - Not installed + */ + osize = dmi[0x0a] & 0x7f; + if (osize > 0 && osize < 22) + smbios_old_enabled_memory += (1U << (osize + 10)); + break; + + case 17: /* Type 17: Memory Device */ + /* + * Offset 0Ch: Size + * + * Bit 15 Granularity + * 1 - Value is in kilobytes units + * 0 - Value is in megabytes units + * Bit 14:0 Size + */ + size = *(uint16_t *)(dmi + 0x0c); + if (size != 0 && size != 0xffff) + smbios_enabled_memory += (size & 0x8000) != 0 ? + (size & 0x7fff) : ((uint32_t)size << 10); + break; + default: /* skip other types */ break; } - + /* find structure terminator */ dp = __DECONST(uint8_t *, dmi + dmi[1]); while (dp[0] != 0 || dp[1] != 0) diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 8947be4d23ab..2f0f3b9e5419 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -243,6 +243,7 @@ static void cpu_startup(dummy) void *dummy; { + uintmax_t memsize; char *sysenv; /* @@ -273,8 +274,17 @@ cpu_startup(dummy) #ifdef PERFMON perfmon_init(); #endif - printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem), - ptoa((uintmax_t)Maxmem) / 1048576); + sysenv = getenv("smbios.memory.enabled"); + if (sysenv != NULL) { + memsize = (uintmax_t)strtoul(sysenv, (char **)NULL, 10); + freeenv(sysenv); + } + if (memsize > 0) + printf("real memory = %ju (%ju MB)\n", memsize << 10, + memsize >> 10); + else + printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem), + ptoa((uintmax_t)Maxmem) / 1048576); realmem = Maxmem; /* * Display any holes after the first chunk of extended memory.