From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from terminus.zytor.com ([192.83.249.54]:39661 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755150AbXGJDm4 (ORCPT ); Mon, 9 Jul 2007 23:42:56 -0400 From: "H. Peter Anvin" Subject: [x86 setup 25/33] Memory probing support for the new x86 setup code Date: Mon, 9 Jul 2007 19:52:04 -0700 Message-Id: <1184038562864-git-send-email-hpa@zytor.com> In-Reply-To: <1184038457733-git-send-email-hpa@zytor.com> References: <11840359321823-git-send-email-hpa@zytor.com> <11840360383913-git-send-email-hpa@zytor.com> <11840361432207-git-send-email-hpa@zytor.com> <11840362483663-git-send-email-hpa@zytor.com> <11840363531039-git-send-email-hpa@zytor.com> <11840364593068-git-send-email-hpa@zytor.com> <1184036564610-git-send-email-hpa@zytor.com> <11840366692770-git-send-email-hpa@zytor.com> <11840367741994-git-send-email-hpa@zytor.com> <11840368791603-git-send-email-hpa@zytor.com> <11840369841576-git-send-email-hpa@zytor.com> <11840370903975-git-send-email-hpa@zytor.com> <11840371953778-git-send-email-hpa@zytor.com> <11840373002601-git-send-email-hpa@zytor.com> <11840374052662-git-send-email-hpa@zytor.com> <1184037510289-git-send-email-hpa@zytor.com> <11840376162370-git-send-email-hpa@zytor.com> <11840377211519-git-send-email-hpa@zytor.com> <11840378261081-git-send-email-hpa@zytor.com> <11840379311574-git-send-email-hpa@zytor.com> <11840380363720-git-send-email-hpa@zytor.com> <11840381413065-git-send-email-hpa@zytor.com> <11840382473923-git-send-email-hpa@zytor.com> <11840383522914-git-send-email-hpa@zytor.com> <1184038457733-git-send-email-hpa@zytor.com> Message-Id: <75642968817648a7816a4782f76138e4f608f1ab.1184032749.git.hpa@zytor.com> In-Reply-To: <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com> References: <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com> Sender: linux-arch-owner@vger.kernel.org To: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, andi@firstfloor.org, akpm@linux-foundation.org Cc: "H. Peter Anvin" List-ID: From: H. Peter Anvin Probe memory (INT 15h: E820, E801, 88). Signed-off-by: H. Peter Anvin --- arch/i386/boot/memory.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 99 insertions(+), 0 deletions(-) create mode 100644 arch/i386/boot/memory.c diff --git a/arch/i386/boot/memory.c b/arch/i386/boot/memory.c new file mode 100644 index 0000000..1a2e62d --- /dev/null +++ b/arch/i386/boot/memory.c @@ -0,0 +1,99 @@ +/* -*- linux-c -*- ------------------------------------------------------- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007 rPath, Inc. - All Rights Reserved + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * ----------------------------------------------------------------------- */ + +/* + * arch/i386/boot/memory.c + * + * Memory detection code + */ + +#include "boot.h" + +#define SMAP 0x534d4150 /* ASCII "SMAP" */ + +static int detect_memory_e820(void) +{ + u32 next = 0; + u32 size, id; + u8 err; + struct e820entry *desc = boot_params.e820_map; + + do { + size = sizeof(struct e820entry); + id = SMAP; + asm("int $0x15; setc %0" + : "=am" (err), "+b" (next), "+d" (id), "+c" (size), + "=m" (*desc) + : "D" (desc), "a" (0xe820)); + + if (err || id != SMAP) + break; + + boot_params.e820_entries++; + desc++; + } while (next && boot_params.e820_entries < E820MAX); + + return boot_params.e820_entries; +} + +static int detect_memory_e801(void) +{ + u16 ax, bx, cx, dx; + u8 err; + + bx = cx = dx = 0; + ax = 0xe801; + asm("stc; int $0x15; setc %0" + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx)); + + if (err) + return -1; + + /* Do we really need to do this? */ + if (cx || dx) { + ax = cx; + bx = dx; + } + + if (ax > 15*1024) + return -1; /* Bogus! */ + + /* This ignores memory above 16MB if we have a memory hole + there. If someone actually finds a machine with a memory + hole at 16MB and no support for 0E820h they should probably + generate a fake e820 map. */ + boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax; + + return 0; +} + +static int detect_memory_88(void) +{ + u16 ax; + u8 err; + + ax = 0x8800; + asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax)); + + boot_params.screen_info.ext_mem_k = ax; + + return -err; +} + +int detect_memory(void) +{ + if (detect_memory_e820() > 0) + return 0; + + if (!detect_memory_e801()) + return 0; + + return detect_memory_88(); +} -- 1.5.2.2