diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2016-07-24 09:27:11 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-08-22 15:26:51 +1000 |
commit | ad0eb2ca2ca7cab621f990a694746198cbc94ed1 (patch) | |
tree | 6e54f3b96625ebdd95fe8e6188c6fbbd51082490 | |
parent | 3476b2ad3a5a53c92ec5e358dd9c28f5ef09c96d (diff) | |
download | skiboot-ad0eb2ca2ca7cab621f990a694746198cbc94ed1.zip skiboot-ad0eb2ca2ca7cab621f990a694746198cbc94ed1.tar.gz skiboot-ad0eb2ca2ca7cab621f990a694746198cbc94ed1.tar.bz2 |
Rename rvwinkle patch to reset patch and install at boot
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@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | asm/head.S | 10 | ||||
-rw-r--r-- | core/init.c | 16 | ||||
-rw-r--r-- | hw/slw.c | 16 | ||||
-rw-r--r-- | include/skiboot.h | 4 |
4 files changed, 32 insertions, 14 deletions
@@ -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 cb49d68..cc29a3c 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 @@ -755,6 +766,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 @@ -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 */ |