[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