aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/asm/misc.S
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/asm/misc.S')
-rw-r--r--roms/skiboot/asm/misc.S310
1 files changed, 310 insertions, 0 deletions
diff --git a/roms/skiboot/asm/misc.S b/roms/skiboot/asm/misc.S
new file mode 100644
index 000000000..ea4376322
--- /dev/null
+++ b/roms/skiboot/asm/misc.S
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/*
+ * Misc asm functions
+ *
+ * Copyright 2013-2014 IBM Corp.
+ */
+
+#include <asm-utils.h>
+#include <asm-offsets.h>
+#include <processor.h>
+#include <stack.h>
+#include <opal-api.h>
+
+#define OLD_BINUTILS 1
+
+ .section ".rodata"
+ /* This is the OPAL branch table. It's populated at boot time
+ * with function pointers to the various OPAL functions from
+ * the content of the .opal_table section, indexed by Token.
+ */
+.global opal_branch_table
+opal_branch_table:
+ .space 8 * (OPAL_LAST + 1)
+
+ .section ".text","ax"
+ .balign 0x10
+
+.global enable_machine_check
+enable_machine_check:
+ mflr %r0
+ bcl 20,31,$+4
+0: mflr %r3
+ addi %r3,%r3,(1f - 0b)
+ mtspr SPR_HSRR0,%r3
+ mfmsr %r3
+ ori %r3,%r3,MSR_ME
+ mtspr SPR_HSRR1,%r3
+ hrfid
+1: mtlr %r0
+ blr
+
+.global disable_machine_check
+disable_machine_check:
+ mflr %r0
+ bcl 20,31,$+4
+0: mflr %r3
+ addi %r3,%r3,(1f - 0b)
+ mtspr SPR_HSRR0,%r3
+ mfmsr %r3
+ li %r4,MSR_ME
+ andc %r3,%r3,%r4
+ mtspr SPR_HSRR1,%r3
+ hrfid
+1: mtlr %r0
+ blr
+
+ /* void set_hid0(unsigned long hid0) */
+.global set_hid0
+set_hid0:
+ sync
+ mtspr SPR_HID0,%r3
+ mfspr %r3,SPR_HID0
+ mfspr %r3,SPR_HID0
+ mfspr %r3,SPR_HID0
+ mfspr %r3,SPR_HID0
+ mfspr %r3,SPR_HID0
+ mfspr %r3,SPR_HID0
+ isync
+ blr
+
+.global __trigger_attn
+__trigger_attn:
+ sync
+ isync
+ attn
+ blr
+
+#ifdef STACK_CHECK_ENABLED
+.global _mcount
+_mcount:
+ mr %r3,%r1
+ mflr %r4
+ b __mcount_stack_check
+#endif
+
+ .global cleanup_local_tlb
+cleanup_local_tlb:
+ /* Clean the TLB */
+ li %r3,512
+ mtctr %r3
+ li %r4,0xc00 /* IS field = 0b11 */
+ ptesync
+1: tlbiel %r4
+ addi %r4,%r4,0x1000
+ bdnz 1b
+ ptesync
+ blr
+
+ .global cleanup_global_tlb
+cleanup_global_tlb:
+
+ /* Only supported on P9, P10 for now */
+ mfspr %r3,SPR_PVR
+ srdi %r3,%r3,16
+ cmpwi cr0,%r3,PVR_TYPE_P9
+ beq cr0,1f
+ cmpwi cr0,%r3,PVR_TYPE_P9P
+ beq cr0,1f
+ cmpwi cr0,%r3,PVR_TYPE_P10
+ beq cr0,1f
+ blr
+
+ /* Sync out previous updates */
+1: ptesync
+
+#ifndef OLD_BINUTILS
+ .machine "power9"
+#endif
+ /* Lead RB with IS=11 */
+ li %r3,3
+ sldi %r3,%r3,10
+ li %r0,0
+
+ /* Blow up radix partition scoped translations */
+#ifdef OLD_BINUTILS
+ .long 0x7c0b1a64
+#else
+ tlbie %r3, %r0 /* rs */, 2 /* ric */, 1 /* prs */, 1 /* r */
+#endif
+ eieio
+ tlbsync
+ ptesync
+#ifdef OLD_BINUTILS
+ .long 0x7c091a64
+#else
+ tlbie %r3, %r0 /* rs */, 2 /* ric */, 0 /* prs */, 1 /* r */
+#endif
+ eieio
+ tlbsync
+ ptesync
+
+ /* Blow up hash partition scoped translations */
+#ifdef OLD_BINUTILS
+ .long 0x7c0a1a64
+#else
+ tlbie %r3, %r0 /* rs */, 2 /* ric */, 1 /* prs */, 0 /* r */
+#endif
+ eieio
+ tlbsync
+ ptesync
+#ifdef OLD_BINUTILS
+ .long 0x7c081a64
+#else
+ tlbie %r3, %r0 /* rs */, 2 /* ric */, 0 /* prs */, 0 /* r */
+#endif
+ eieio
+ tlbsync
+ ptesync
+
+ blr
+
+
+/* Power management instructions */
+#define PPC_INST_NAP .long 0x4c000364
+#define PPC_INST_SLEEP .long 0x4c0003a4
+#define PPC_INST_RVWINKLE .long 0x4c0003e4
+
+#define PPC_INST_STOP .long 0x4c0002e4
+#define PPC_INST_URFID .long 0x4c000264
+
+#define SAVE_GPR(reg,sp) std %r##reg,STACK_GPR##reg(sp)
+#define REST_GPR(reg,sp) ld %r##reg,STACK_GPR##reg(sp)
+
+pm_save_regs:
+ SAVE_GPR(2,%r1)
+ SAVE_GPR(14,%r1)
+ SAVE_GPR(15,%r1)
+ SAVE_GPR(16,%r1)
+ SAVE_GPR(17,%r1)
+ SAVE_GPR(18,%r1)
+ SAVE_GPR(19,%r1)
+ SAVE_GPR(20,%r1)
+ SAVE_GPR(21,%r1)
+ SAVE_GPR(22,%r1)
+ SAVE_GPR(23,%r1)
+ SAVE_GPR(24,%r1)
+ SAVE_GPR(25,%r1)
+ SAVE_GPR(26,%r1)
+ SAVE_GPR(27,%r1)
+ SAVE_GPR(28,%r1)
+ SAVE_GPR(29,%r1)
+ SAVE_GPR(30,%r1)
+ SAVE_GPR(31,%r1)
+ mfcr %r4
+ mfxer %r5
+ mfspr %r6,SPR_HSPRG0
+ mfspr %r7,SPR_HSPRG1
+ stw %r4,STACK_CR(%r1)
+ stw %r5,STACK_XER(%r1)
+ std %r6,STACK_GPR0(%r1)
+ std %r7,STACK_GPR1(%r1)
+ blr
+
+.global enter_p8_pm_state
+enter_p8_pm_state:
+ /* Before entering map or rvwinkle, we create a stack frame
+ * and save our non-volatile registers.
+ *
+ * We also save these SPRs:
+ *
+ * - HSPRG0 in GPR0 slot
+ * - HSPRG1 in GPR1 slot
+ *
+ * - xxx TODO: HIDs
+ * - TODO: Mask MSR:ME during the process
+ *
+ * On entry, r3 indicates:
+ *
+ * 0 = nap
+ * 1 = rvwinkle
+ */
+ mflr %r0
+ std %r0,16(%r1)
+ stdu %r1,-STACK_FRAMESIZE(%r1)
+
+ bl pm_save_regs
+
+ /* Save stack pointer in struct cpu_thread */
+ std %r1,CPUTHREAD_SAVE_R1(%r16)
+
+ /* Winkle or nap ? */
+ cmpli %cr0,0,%r3,0
+ bne 1f
+
+ /* nap sequence */
+ ptesync
+0: ld %r0,CPUTHREAD_SAVE_R1(%r16)
+ cmpd cr0,%r0,%r0
+ bne 0b
+ PPC_INST_NAP
+ b .
+
+ /* rvwinkle sequence */
+1: ptesync
+0: ld %r0,CPUTHREAD_SAVE_R1(%r16)
+ cmpd cr0,%r0,%r0
+ bne 0b
+ PPC_INST_RVWINKLE
+ b .
+
+.global enter_p9_pm_lite_state
+enter_p9_pm_lite_state:
+ mtspr SPR_PSSCR,%r3
+ PPC_INST_STOP
+ blr
+
+.global enter_p9_pm_state
+enter_p9_pm_state:
+ mflr %r0
+ std %r0,16(%r1)
+ stdu %r1,-STACK_FRAMESIZE(%r1)
+
+ bl pm_save_regs
+
+ /* Save stack pointer in struct cpu_thread */
+ std %r1,CPUTHREAD_SAVE_R1(%r16)
+
+ mtspr SPR_PSSCR,%r3
+ PPC_INST_STOP
+ b .
+
+/*
+ * Exit UV mode and disable Protected Execution Facility.
+ *
+ * For each core, this should be run on all secondary threads first to bring
+ * them out of UV mode. Then, it is called by the primary thread to disable
+ * PEF and bring it out of UV mode. All threads will then be running in HV
+ * mode and the only way to re-enable UV mode is with a reboot.
+ *
+ * r3 = 1 if primary thread
+ * 0 if secondary thread
+ */
+.global exit_uv_mode
+exit_uv_mode:
+ mfmsr %r4
+ LOAD_IMM64(%r5, ~MSR_S)
+ and %r4,%r4,%r5
+ mtspr SPR_USRR1,%r4
+
+ mfspr %r4,SPR_HSRR1
+ and %r4,%r4,%r5
+ mtspr SPR_HSRR1,%r3
+
+ mfspr %r4,SPR_SRR1
+ and %r4,%r4,%r5
+ mtspr SPR_SRR1,%r4
+
+ cmpdi %r3,1
+ bne 1f
+ mfspr %r4, SPR_SMFCTRL
+ LOAD_IMM64(%r5, ~PPC_BIT(0))
+ and %r4,%r4,%r5
+ mtspr SPR_SMFCTRL,%r4
+1:
+ isync
+
+ mflr %r4
+ mtspr SPR_USRR0,%r4
+
+ PPC_INST_URFID