[Skiboot] [PATCH 17/34] Rename rvwinkle patch to reset patch and install at boot

Benjamin Herrenschmidt benh at kernel.crashing.org
Sun Jul 24 09:27:11 AEST 2016


The patch code itself is unchanged (for now...). Install it during
boot so we will be able to use power management instructions. We
can't just have a proper exception code built at 0x100 as this is
otherwise one of our entry points.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 asm/head.S        | 10 +++++-----
 core/init.c       | 16 ++++++++++++++++
 hw/slw.c          | 16 +++++++---------
 include/skiboot.h |  4 ++++
 4 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/asm/head.S b/asm/head.S
index c3ed3d7..45976a0 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -605,10 +605,10 @@ enter_pm_state:
 	b	.
 
 /* This is a little piece of code that is copied down to
- * 0x100 when doing a "rvwinkle reinit"
+ * 0x100 for handling power management wakeups
  */
-.global rvwinkle_patch_start
-rvwinkle_patch_start:
+.global reset_patch_start
+reset_patch_start:
 	FIXUP_ENDIAN
 	smt_medium
 	LOAD_IMM64(%r30, SKIBOOT_BASE)
@@ -616,8 +616,8 @@ rvwinkle_patch_start:
 	add	%r3,%r30,%r3
 	mtctr	%r3
 	bctr
-.global rvwinkle_patch_end
-rvwinkle_patch_end:
+.global reset_patch_end
+reset_patch_end:
 
 rvwinkle_restore:
 	/* Get PIR */
diff --git a/core/init.c b/core/init.c
index 5c9d84c..bba7d96 100644
--- a/core/init.c
+++ b/core/init.c
@@ -580,6 +580,17 @@ static void setup_branch_null_catcher(void)
        memcpy(0, bn, 16);
 }
 
+void setup_reset_vector(void)
+{
+	uint32_t *src, *dst;
+
+	/* Copy the reset code over the entry point. */
+	src = &reset_patch_start;
+	dst = (uint32_t *)0x100;
+	while(src < &reset_patch_end)
+		*(dst++) = *(src++);
+}
+
 static void copy_exception_vectors(void)
 {
 	/* Backup previous vectors as this could contain a kernel
@@ -749,6 +760,11 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt, u32 master_cpu)
 	/* Call in secondary CPUs */
 	cpu_bringup();
 
+	/* We can now overwrite the 0x100 vector as we are no longer being
+	 * entered there.
+	 */
+	setup_reset_vector();
+
 	/*
 	 * Sycnhronize time bases. Thi resets all the TB values to a small
 	 * value (so they appear to go backward at this point), and synchronize
diff --git a/hw/slw.c b/hw/slw.c
index 9299430..9336679 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -151,17 +151,15 @@ static void slw_do_rvwinkle(void *data)
 
 static void slw_patch_reset(void)
 {
-	extern uint32_t rvwinkle_patch_start;
-	extern uint32_t rvwinkle_patch_end;
 	uint32_t *src, *dst, *sav;
 
-	BUILD_ASSERT((&rvwinkle_patch_end - &rvwinkle_patch_start) <=
+	BUILD_ASSERT((&reset_patch_end - &reset_patch_start) <=
 		     MAX_RESET_PATCH_SIZE);
 
-	src = &rvwinkle_patch_start;
+	src = &reset_patch_start;
 	dst = (uint32_t *)0x100;
 	sav = slw_saved_reset;
-	while(src < &rvwinkle_patch_end) {
+	while(src < &reset_patch_end) {
 		*(sav++) = *(dst);
 		*(dst++) = *(src++);
 	}
@@ -170,14 +168,14 @@ static void slw_patch_reset(void)
 
 static void slw_unpatch_reset(void)
 {
-	extern uint32_t rvwinkle_patch_start;
-	extern uint32_t rvwinkle_patch_end;
+	extern uint32_t reset_patch_start;
+	extern uint32_t reset_patch_end;
 	uint32_t *src, *dst, *sav;
 
-	src = &rvwinkle_patch_start;
+	src = &reset_patch_start;
 	dst = (uint32_t *)0x100;
 	sav = slw_saved_reset;
-	while(src < &rvwinkle_patch_end) {
+	while(src < &reset_patch_end) {
 		*(dst++) = *(sav++);
 		src++;
 	}
diff --git a/include/skiboot.h b/include/skiboot.h
index f475dd6..1dbe38f 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -196,6 +196,7 @@ extern void __noreturn load_and_boot_kernel(bool is_reboot);
 extern void cleanup_tlb(void);
 extern void init_shared_sprs(void);
 extern void init_replicated_sprs(void);
+extern void setup_reset_vector(void);
 
 /* Various probe routines, to replace with an initcall system */
 extern void probe_p7ioc(void);
@@ -271,4 +272,7 @@ extern void fake_rtc_init(void);
 
 /* Assembly in head.S */
 extern void enter_pm_state(bool winkle);
+extern uint32_t reset_patch_start;
+extern uint32_t reset_patch_end;
+
 #endif /* __SKIBOOT_H */
-- 
2.7.4



More information about the Skiboot mailing list