[coreboot] [PATCH] v3: Poison RAM
Carl-Daniel Hailfinger
c-d.hailfinger.devel.2006 at gmx.net
Wed Nov 19 19:42:15 CET 2008
Poison RAM and continuously report on status if stack checking is enabled.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
Index: corebootv3-poison/include/arch/x86/cpu.h
===================================================================
--- corebootv3-poison/include/arch/x86/cpu.h (Revision 1046)
+++ corebootv3-poison/include/arch/x86/cpu.h (Arbeitskopie)
@@ -329,5 +329,12 @@
void setup_resource_map(const struct rmap *rm, u32 max);
EXPORT_SYMBOL(setup_resource_map);
+#ifdef CONFIG_CHECK_STACK_USAGE
+/* POISON_BYTE could be a special value like 0x6b. Just make sure the stage0
+ * code fills the complete CAR area with it. And the stack switching needs to
+ * overwrite the unused parts of the stack with POISON_BYTE as well.
+ */
+#define POISON_BYTE 0x6b
+#endif
#endif /* ARCH_X86_CPU_H */
Index: corebootv3-poison/lib/stage2.c
===================================================================
--- corebootv3-poison/lib/stage2.c (Revision 1046)
+++ corebootv3-poison/lib/stage2.c (Arbeitskopie)
@@ -28,6 +28,9 @@
#include <device/device.h>
#include <tables.h>
+/* FIXME: Figure out the proper include file for this function. */
+void find_lowest_unpoisoned_memory(int msg_level);
+
/**
* Main function of the DRAM part of coreboot.
*
@@ -46,6 +49,9 @@
void *mbi;
post_code(POST_STAGE2_BEGIN);
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
dev_init();
/* Phase 1 was console init and making printk work. Both functions are
@@ -54,6 +60,9 @@
post_code(POST_STAGE2_PHASE1_START);
dev_phase1();
show_all_devs(BIOS_DEBUG, "After phase 1.");
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
/* Here is where weird stuff like init_timer handling should be
* done. This is for ANYTHING that might have to happen before
@@ -62,6 +71,9 @@
post_code(POST_STAGE2_PHASE2_START);
dev_phase2();
show_all_devs(BIOS_DEBUG, "After phase 2.");
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
/* Walk physical devices and add any dynamic devices to the
* device tree.
@@ -69,26 +81,41 @@
post_code(POST_STAGE2_PHASE3_START);
dev_root_phase3();
show_all_devs_tree(BIOS_DEBUG, "After phase 3.");
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
/* Compute and assign the bus resources. */
post_code(POST_STAGE2_PHASE4_START);
dev_phase4();
show_all_devs(BIOS_DEBUG, "After phase 4.");
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
/* Now actually enable devices on the bus. */
post_code(POST_STAGE2_PHASE5_START);
dev_root_phase5();
show_all_devs(BIOS_DEBUG, "After phase 5.");
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
/* Initialize devices on the bus. */
post_code(POST_STAGE2_PHASE6_START);
dev_phase6();
show_all_devs(BIOS_DEBUG, "After phase 6.");
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
/* Write tables to pass information to the payloads. */
post_code(POST_STAGE2_WRITE_TABLES);
mbi = write_tables();
show_all_devs(BIOS_DEBUG, "After writing tables.");
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
return mbi;
}
Index: corebootv3-poison/arch/x86/Kconfig
===================================================================
--- corebootv3-poison/arch/x86/Kconfig (Revision 1046)
+++ corebootv3-poison/arch/x86/Kconfig (Arbeitskopie)
@@ -246,5 +246,6 @@
The monitoring code is invoked from printk because printk is
a leaf function and consumes quite a bit of stack for itself.
This slows down booting a LOT.
+ This does not work in CAR stage until the asm is changed.
endmenu
Index: corebootv3-poison/arch/x86/stage1.c
===================================================================
--- corebootv3-poison/arch/x86/stage1.c (Revision 1046)
+++ corebootv3-poison/arch/x86/stage1.c (Arbeitskopie)
@@ -106,11 +106,6 @@
}
#ifdef CONFIG_CHECK_STACK_USAGE
-/* STACKFILL_BYTE could be a special value like 0x6b. Just make sure the stage0
- * code fills the complete CAR area with it. And the stack switching needs to
- * overwrite the unused parts of the stack with STACKFILL_BYTE as well.
- */
-#define STACKFILL_BYTE 0x0
void check_stack()
{
unsigned long stacksize, i;
@@ -121,7 +116,7 @@
stacksize = CAR_STACK_SIZE;
lowestaddr = bottom_of_stack() - stacksize;
for (i = 0; i < stacksize; i++)
- if (lowestaddr[i] != STACKFILL_BYTE)
+ if (lowestaddr[i] != POISON_BYTE)
break;
global_vars()->loweststack = lowestaddr + i;
}
@@ -139,6 +134,22 @@
return;
}
+#ifdef CONFIG_CHECK_STACK_USAGE
+void find_lowest_unpoisoned_memory(int msg_level)
+{
+ char *addr;
+ for (addr = NULL; (unsigned long)addr < 1024*1024; addr++) {
+ if (*addr != POISON_BYTE) {
+ printk(msg_level, "lowest unpoisoned mem is at %p\n",
+ addr);
+ dump_mem_range(msg_level, (unsigned char *)((unsigned long)addr & (~0xf)), 64);
+ break;
+ }
+ }
+ return;
+}
+#endif
+
/** cycles
* provide 64-bit high precision counter
* @returns Time in 64 bits
@@ -290,6 +301,18 @@
*/
void stage1_phase2(void)
{
+#ifdef CONFIG_CHECK_STACK_USAGE
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+ /* We poison the area between 0x00000 and 1 MB, but we exclude
+ * the CAR area. If devices are mapped there, we lose.
+ */
+ memset(NULL, POISON_BYTE, min(CONFIG_CARBASE, 1024 * 1024));
+ if (CONFIG_CARBASE + CONFIG_CARSIZE < 1024 * 1024)
+ memset((void *)CONFIG_CARBASE + CONFIG_CARSIZE, POISON_BYTE,
+ 1024 * 1024 - (CONFIG_CARBASE + CONFIG_CARSIZE));
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
#ifdef CONFIG_CONSOLE_BUFFER
/* Move the printk buffer to PRINTK_BUF_ADDR_RAM */
printk_buffer_move((void *)PRINTK_BUF_ADDR_RAM, PRINTK_BUF_SIZE_RAM);
@@ -332,6 +355,10 @@
/* Provide an easy way to check whether RAM is available. */
global_vars()->ram_available = 1;
+#ifdef CONFIG_CHECK_STACK_USAGE
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
+#endif
+
// location and size of image.
init_archive(&archive);
@@ -354,6 +381,7 @@
#ifdef CONFIG_CHECK_STACK_USAGE
printk(BIOS_DEBUG, "Before handoff to payload, lowest stack is %p\n",
global_vars()->loweststack);
+ find_lowest_unpoisoned_memory(BIOS_DEBUG);
#endif
if (entry != (void*)-1) {
/* Final coreboot call before handing off to the payload. */
--
http://www.hailfinger.org/
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: linuxbios3_poison_ram.diff
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20081119/e3b2ff94/attachment.ksh>
More information about the coreboot
mailing list