Poison RAM and continuously report on status if stack checking is enabled.

Signed-off-by: Carl-Daniel Hailfinger <[EMAIL PROTECTED]>

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/

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. */
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to