summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2012-11-20 21:03:49 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2012-11-20 21:03:49 +0000
commitb6074390f3ef84676ad2ba8f216cd685b0b92e04 (patch)
tree59c94ec5430e59c6d984135f6ce52912986ed04e
parentf0d5f1d67e7a9c1d47e1afa0a7fa1f474fc17927 (diff)
downloadillumos-joyent-b6074390f3ef84676ad2ba8f216cd685b0b92e04.tar.gz
OS-1693 need workaround for RICHMOND-16
-rw-r--r--usr/src/grub/grub-0.97/stage2/boot.c13
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_startkern.c43
2 files changed, 56 insertions, 0 deletions
diff --git a/usr/src/grub/grub-0.97/stage2/boot.c b/usr/src/grub/grub-0.97/stage2/boot.c
index cfc2336a4c..027de7709b 100644
--- a/usr/src/grub/grub-0.97/stage2/boot.c
+++ b/usr/src/grub/grub-0.97/stage2/boot.c
@@ -25,6 +25,8 @@
#include "imgact_aout.h"
#include "i386-elf.h"
+#define SAFE_LOAD_BASE 0xc800000
+
static int cur_addr;
entry_func entry_addr;
static struct mod_list mll[99];
@@ -773,6 +775,17 @@ load_module (char *module, char *arg)
{
int len;
+ /*
+ * XXX Workaround for RICHMOND-16: on some systems, the region
+ * [c700000, c800000) is corrupted by an unknown external (off-CPU) actor(s)
+ * during boot. To be on the safe side, we will simply ensure that every
+ * module is loaded above this region. Note that this means this particular
+ * boot loader supports only systems with at least 200 MB of DRAM plus the
+ * amount of space used by any modules.
+ */
+ if (cur_addr < SAFE_LOAD_BASE)
+ cur_addr = SAFE_LOAD_BASE;
+
/* if we are supposed to load on 4K boundaries */
cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
diff --git a/usr/src/uts/i86pc/dboot/dboot_startkern.c b/usr/src/uts/i86pc/dboot/dboot_startkern.c
index 8e69766851..56c3857f55 100644
--- a/usr/src/uts/i86pc/dboot/dboot_startkern.c
+++ b/usr/src/uts/i86pc/dboot/dboot_startkern.c
@@ -22,6 +22,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2012 Joyent, Inc. All rights reserved.
*/
@@ -56,6 +58,15 @@ extern int have_cpuid(void);
#include "dboot_elfload.h"
/*
+ * Region of memory that may be corrupted by external actors. This can go away
+ * once the firmware bug RICHMOND-16 is fixed and all systems with the bug are
+ * upgraded.
+ */
+#define CORRUPT_REGION_START 0xc700000
+#define CORRUPT_REGION_SIZE 0x100000
+#define CORRUPT_REGION_END (CORRUPT_REGION_START + CORRUPT_REGION_SIZE)
+
+/*
* This file contains code that runs to transition us from either a multiboot
* compliant loader (32 bit non-paging) or a XPV domain loader to
* regular kernel execution. Its task is to setup the kernel memory image
@@ -874,6 +885,38 @@ init_mem_alloc(void)
case 1:
if (end > max_mem)
max_mem = end;
+
+ /*
+ * Well, this is sad. One some systems, there
+ * is a region of memory that can be corrupted
+ * until some number of seconds after we have
+ * booted. And the BIOS doesn't tell us that
+ * this memory is unsafe to use. And we don't
+ * know how long it's dangerous. So we'll
+ * chop out this range from any memory list
+ * that would otherwise be usable. Note that
+ * any system of this type will give us the
+ * new-style (0x40) memlist, so we need not
+ * fix up the other path below.
+ */
+ if (start < CORRUPT_REGION_START &&
+ end > CORRUPT_REGION_START) {
+ memlists[memlists_used].addr = start;
+ memlists[memlists_used].size =
+ CORRUPT_REGION_START - start;
+ ++memlists_used;
+ if (end > CORRUPT_REGION_END)
+ start = CORRUPT_REGION_END;
+ else
+ continue;
+ }
+ if (start >= CORRUPT_REGION_START &&
+ start < CORRUPT_REGION_END) {
+ if (end <= CORRUPT_REGION_END)
+ continue;
+ start = CORRUPT_REGION_END;
+ }
+
memlists[memlists_used].addr = start;
memlists[memlists_used].size = end - start;
++memlists_used;