OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [x86/] [boot/] [memory.c] - Rev 17

Go to most recent revision | Compare with Previous | Blame | View Log

/* -*- 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)
{
	int count = 0;
	u32 next = 0;
	u32 size, id;
	u8 err;
	struct e820entry *desc = boot_params.e820_map;
 
	do {
		size = sizeof(struct e820entry);
 
		/* Important: %edx is clobbered by some BIOSes,
		   so it must be either used for the error output
		   or explicitly marked clobbered. */
		asm("int $0x15; setc %0"
		    : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
		      "=m" (*desc)
		    : "D" (desc), "d" (SMAP), "a" (0xe820));
 
		/* Some BIOSes stop returning SMAP in the middle of
		   the search loop.  We don't know exactly how the BIOS
		   screwed up the map at that point, we might have a
		   partial map, the full map, or complete garbage, so
		   just return failure. */
		if (id != SMAP) {
			count = 0;
			break;
		}
 
		if (err)
			break;
 
		count++;
		desc++;
	} while (next && count < E820MAX);
 
	return boot_params.e820_entries = count;
}
 
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)
{
	int err = -1;
 
	if (detect_memory_e820() > 0)
		err = 0;
 
	if (!detect_memory_e801())
		err = 0;
 
	if (!detect_memory_88())
		err = 0;
 
	return err;
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.