[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