alarm-tegra-x1 / patches/kernel-boot-markers.patch

raw file 2850 bytes
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 87a822e5c..724bcfd31 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -86,6 +86,21 @@ SYM_CODE_START(primary_entry)
 	bl	record_mmu_state
 	bl	preserve_boot_args
 
+	/*
+	 * ALARM boot marker, stage 1: primary_entry reached.
+	 *
+	 * Writes a word to 0xB0000000, the region hekate reserves and preserves
+	 * across boots as its pstore carveout (bdk/memory_map.h: PSTORE_ADDR).
+	 * The MMU is still off here, so this is a plain physical write. U-Boot
+	 * dumps that region to the SD on the next boot, which is the only way to
+	 * observe how far the kernel gets when it dies before its first printk.
+	 *
+	 * x0-x3 are preserved by preserve_boot_args above; x9/x10 are free.
+	 */
+	movz	x9, #0xB000, lsl #16			// 0xB0000000
+	mov	w10, #0xA1
+	str	w10, [x9]
+
 	adrp	x1, early_init_stack
 	mov	sp, x1
 	mov	x29, xzr
@@ -127,6 +142,12 @@ SYM_CODE_START(primary_entry)
 	 * the TCR will have been set.
 	 */
 	bl	__cpu_setup			// initialise processor
+
+	/* ALARM boot marker, stage 2: page tables built, CPU setup done, MMU off. */
+	movz	x9, #0xB000, lsl #16			// 0xB0000000
+	mov	w10, #0xA2
+	str	w10, [x9, #4]
+
 	b	__primary_switch
 SYM_CODE_END(primary_entry)
 
diff --git a/init/main.c b/init/main.c
index e363232b4..3a5644a71 100644
--- a/init/main.c
+++ b/init/main.c
@@ -40,6 +40,8 @@
 #include <linux/vmalloc.h>
 #include <linux/kernel_stat.h>
 #include <linux/start_kernel.h>
+/* ALARM: __va() for the boot markers written into hekate's pstore region. */
+#include <asm/memory.h>
 #include <linux/security.h>
 #include <linux/smp.h>
 #include <linux/profile.h>
@@ -991,7 +993,23 @@ void start_kernel(void)
 	boot_cpu_init();
 	page_address_init();
 	pr_notice("%s", linux_banner);
+
+	/*
+	 * ALARM boot marker: 0xB0000000 is the region hekate reserves and preserves
+	 * across boots as its pstore carveout (bdk/memory_map.h: PSTORE_ADDR).
+	 * U-Boot dumps it to the SD on the next boot, which is the only way to see
+	 * how far the kernel gets -- the display is tiled and unreadable, there is
+	 * no UART, and the kernel dies before its first printk.
+	 *
+	 * Stages 1 and 2 are written from head.S before the MMU is on (plain
+	 * physical writes). From here the linear mapping exists, hence __va().
+	 */
+#define ALARM_MARK(n) \
+	(*(volatile u32 *)__va(0xB0000000UL + (n) * 4) = 0xA0A00000u | (n))
+
 	setup_arch(&command_line);
+	ALARM_MARK(3);		/* device tree parsed, memory and paging set up */
+
 	mm_core_init_early();
 	/* Static keys and static calls are needed by LSMs */
 	jump_label_init();
@@ -1086,6 +1104,7 @@ void start_kernel(void)
 	vdso_setup_data_pages();
 	timekeeping_init();
 	time_init();
+	ALARM_MARK(4);		/* arch timer initialised */
 
 	/* This must be after timekeeping is initialized */
 	random_init();