summaryrefslogtreecommitdiffstats
path: root/src/bootloader
diff options
context:
space:
mode:
authorMarty Gloff <mgloff@us.ibm.com>2016-12-28 15:11:49 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-01-20 21:39:53 -0500
commit1335057e33390c0ee3d24b537afc9d9c9dbe0a54 (patch)
tree3900f54a42415a7bdce63329a7eb04eb7aec4c0c /src/bootloader
parentcf8fcc043860d45684db89af0f1ccbe4cec99245 (diff)
downloadtalos-hostboot-1335057e33390c0ee3d24b537afc9d9c9dbe0a54.tar.gz
talos-hostboot-1335057e33390c0ee3d24b537afc9d9c9dbe0a54.zip
Bootloader - Error handling - Add exception handling
As a second step for Bootloader error handling add support for various exception vectors and handle these exceptions by calling the terminate function. Change-Id: Ib39818fff377da3fa93d32112f629238a82625ad RTC:135746 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34239 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: Elizabeth K. Liner <eliner@us.ibm.com> Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/bootloader')
-rw-r--r--src/bootloader/bl_start.S203
-rw-r--r--src/bootloader/bl_terminate.C115
2 files changed, 316 insertions, 2 deletions
diff --git a/src/bootloader/bl_start.S b/src/bootloader/bl_start.S
index d1a7d5703..a60c85a7c 100644
--- a/src/bootloader/bl_start.S
+++ b/src/bootloader/bl_start.S
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2016
+# Contributors Listed Below - COPYRIGHT 2015,2017
# [+] International Business Machines Corp.
#
#
@@ -30,8 +30,36 @@
.set SBE_HB_PNORBOOTSIDE, sbe_hb_structures+5 ;// uint8_t
.set SBE_HB_PNORSIZEMB, sbe_hb_structures+6 ;// uint16_t
.set SBE_HB_BLLOADSIZE, sbe_hb_structures+8 ;// uint64_t
+.set HBBL_BASE_ADDRESS, base_load_address
.set HBBL_END_EYECATCHER, 0x4842424C656E6400 ;// 'HBBLend.'
.set HBBL_END_ADDRESS, end_load_address
+.set HBBL_system_reset, 0x100
+.set HBBL_machine_check, 0x200
+.set HBBL_data_storage, 0x300
+.set HBBL_data_segment, 0x380
+.set HBBL_inst_storage, 0x400
+.set HBBL_inst_segment, 0x480
+.set HBBL_external, 0x500
+.set HBBL_alignment, 0x600
+.set HBBL_prog_ex, 0x700
+.set HBBL_fp_unavail, 0x800
+.set HBBL_decrementer, 0x900
+.set HBBL_hype_decrementer, 0x980
+.set HBBL_privileged_doorbell, 0xA00
+.set HBBL_system_call, 0xC00
+.set HBBL_trace, 0xD00
+.set HBBL_hype_data_storage, 0xE00
+.set HBBL_hype_inst_storage, 0xE20
+.set HBBL_hype_emu_assist, 0xE40
+.set HBBL_hype_maint, 0xE60
+.set HBBL_syscall_hype_doorbell, 0xE80
+.set HBBL_perf_monitor, 0xF00
+.set HBBL_vector_unavail, 0xF20
+.set HBBL_vsx_unavail, 0xF40
+.set HBBL_fac_unavail, 0xF60
+.set HBBL_hype_fac_unavail, 0xF80
+.set HBBL_softpatch, 0x1500
+.set HBBL_debug, 0x1600
.section .text.bootloaderasm
@@ -78,6 +106,123 @@ _main:
lis r1, _start@h
addis r1, r1, 1 ;// 64k (1 * 0x10000)
+ ;// Set r5 to base load address where exception vectors are loaded
+ lis r5, HBBL_BASE_ADDRESS@h
+ ori r5, r5, HBBL_BASE_ADDRESS@l
+
+ ;// Set r6 to branch instruction
+ lis r6, 0x4800
+ ori r6, r6, 0
+
+ ;// Create and store system reset handler branch instruction
+ ori r7, r6, intvect_system_reset - HBBL_system_reset
+ st r7, HBBL_system_reset(r5)
+
+ ;// Create and store machine check handler branch instruction
+ ori r7, r6, intvect_machine_check - HBBL_machine_check
+ st r7, HBBL_machine_check(r5)
+
+ ;// Create and store data storage handler branch instruction
+ ori r7, r6, intvect_data_storage - HBBL_data_storage
+ st r7, HBBL_data_storage(r5)
+
+ ;// Create and store data segment handler branch instruction
+ ori r7, r6, intvect_data_segment - HBBL_data_segment
+ st r7, HBBL_data_segment(r5)
+
+ ;// Create and store inst storage handler branch instruction
+ ori r7, r6, intvect_inst_storage - HBBL_inst_storage
+ st r7, HBBL_inst_storage(r5)
+
+ ;// Create and store inst segment handler branch instruction
+ ori r7, r6, intvect_inst_segment - HBBL_inst_segment
+ st r7, HBBL_inst_segment(r5)
+
+ ;// Create and store external handler branch instruction
+ ori r7, r6, intvect_external - HBBL_external
+ st r7, HBBL_external(r5)
+
+ ;// Create and store alignment handler branch instruction
+ ori r7, r6, intvect_alignment - HBBL_alignment
+ st r7, HBBL_alignment(r5)
+
+ ;// Create and store prog ex handler branch instruction
+ ori r7, r6, intvect_prog_ex - HBBL_prog_ex
+ st r7, HBBL_prog_ex(r5)
+
+ ;// Create and store fp unavail handler branch instruction
+ ori r7, r6, intvect_fp_unavail - HBBL_fp_unavail
+ st r7, HBBL_fp_unavail(r5)
+
+ ;// Create and store decrementer handler branch instruction
+ ori r7, r6, intvect_decrementer - HBBL_decrementer
+ st r7, HBBL_decrementer(r5)
+
+ ;// Create and store hype decrementer handler branch instruction
+ ori r7, r6, intvect_hype_decrementer - HBBL_hype_decrementer
+ st r7, HBBL_hype_decrementer(r5)
+
+ ;// Create and store privileged doorbell handler branch instruction
+ ori r7, r6, intvect_privileged_doorbell - HBBL_privileged_doorbell
+ st r7, HBBL_privileged_doorbell(r5)
+
+ ;// Create and store system call handler branch instruction
+ ori r7, r6, intvect_system_call - HBBL_system_call
+ st r7, HBBL_system_call(r5)
+
+ ;// Create and store trace handler branch instruction
+ ori r7, r6, intvect_trace - HBBL_trace
+ st r7, HBBL_trace(r5)
+
+ ;// Create and store hype data storage handler branch instruction
+ ori r7, r6, intvect_hype_data_storage - HBBL_hype_data_storage
+ st r7, HBBL_hype_data_storage(r5)
+
+ ;// Create and store hype inst storage handler branch instruction
+ ori r7, r6, intvect_hype_inst_storage - HBBL_hype_inst_storage
+ st r7, HBBL_hype_inst_storage(r5)
+
+ ;// Create and store hype emu assist handler branch instruction
+ ori r7, r6, intvect_hype_emu_assist - HBBL_hype_emu_assist
+ st r7, HBBL_hype_emu_assist(r5)
+
+ ;// Create and store hype maint handler branch instruction
+ ori r7, r6, intvect_hype_maint - HBBL_hype_maint
+ st r7, HBBL_hype_maint(r5)
+
+ ;// Create and store syscall hype doorbell handler branch instruction
+ ori r7, r6, intvect_syscall_hype_doorbell - HBBL_syscall_hype_doorbell
+ st r7, HBBL_syscall_hype_doorbell(r5)
+
+ ;// Create and store perf monitor handler branch instruction
+ ori r7, r6, intvect_perf_monitor - HBBL_perf_monitor
+ st r7, HBBL_perf_monitor(r5)
+
+ ;// Create and store vector unavail handler branch instruction
+ ori r7, r6, intvect_vector_unavail - HBBL_vector_unavail
+ st r7, HBBL_vector_unavail(r5)
+
+ ;// Create and store vsx unavail handler branch instruction
+ ori r7, r6, intvect_vsx_unavail - HBBL_vsx_unavail
+ st r7, HBBL_vsx_unavail(r5)
+
+ ;// Create and store fac unavail handler branch instruction
+ ori r7, r6, intvect_fac_unavail - HBBL_fac_unavail
+ st r7, HBBL_fac_unavail(r5)
+
+ ;// Create and store hype fac unavail handler branch instruction
+ ori r7, r6, intvect_hype_fac_unavail - HBBL_hype_fac_unavail
+ st r7, HBBL_hype_fac_unavail(r5)
+
+ ;// Create and store softpatch handler branch instruction
+ ori r7, r6, intvect_softpatch - HBBL_softpatch
+ st r7, HBBL_softpatch(r5)
+
+ ;// Create and store debug handler branch instruction
+ ori r7, r6, intvect_debug - HBBL_debug
+ st r7, HBBL_debug(r5)
+
+
;// Do dcbz from end of Bootloader load to end of HBB ECC working space
_dcbz_after_bl:
lis r5, SBE_HB_BLLOADSIZE@h
@@ -116,6 +261,62 @@ _main_loop:
b _main_loop
+;// Interrupt vectors.
+#define STD_INTERRUPT(name, address) \
+ intvect_##name: \
+ or 2,2,2; /* Ensure thread priority is high. */ \
+ mtsprg1 r1; /* Save GPR1 */ \
+ li r1, address; /* Save exception address. */ \
+ mtsprg2 r1; /* Move exception address to SPRG2 */ \
+ mfsprg1 r1; /* Restore GPR1 */ \
+ b kernel_std_exception; /* Process interrupt. */
+
+#define STD_INTERRUPT_WITH(name, address, with) \
+ intvect_##name: \
+ or 2,2,2; /* Ensure thread priority is high. */ \
+ mtsprg1 r1; /* Save GPR1 */ \
+ li r1, address; /* Save exception address. */ \
+ mtsprg2 r1; /* Move exception address to SPRG2 */ \
+ mfsprg1 r1; /* Restore GPR1 */ \
+ b kernel_std_exception_w_##with; /* Process interrupt. */
+
+#define HYPE_INTERRUPT(name, address) \
+ intvect_##name: \
+ or 2,2,2; /* Ensure thread priority is high. */ \
+ mtsprg1 r1; /* Save GPR1 */ \
+ li r1, address; /* Save exception address. */ \
+ mtsprg2 r1; /* Move exception address to SPRG2 */ \
+ mfsprg1 r1; /* Restore GPR1 */ \
+ b kernel_hype_exception; /* Process interrupt. */
+
+STD_INTERRUPT(system_reset, HBBL_system_reset)
+STD_INTERRUPT_WITH(machine_check, HBBL_machine_check, srr1)
+STD_INTERRUPT_WITH(data_storage, HBBL_data_storage, dsisr)
+STD_INTERRUPT(data_segment, HBBL_data_segment)
+STD_INTERRUPT_WITH(inst_storage, HBBL_inst_storage, srr1)
+STD_INTERRUPT(inst_segment, HBBL_inst_segment)
+STD_INTERRUPT(external, HBBL_external)
+STD_INTERRUPT(alignment, HBBL_alignment)
+STD_INTERRUPT_WITH(prog_ex, HBBL_prog_ex, srr1)
+STD_INTERRUPT(fp_unavail, HBBL_fp_unavail)
+STD_INTERRUPT(decrementer, HBBL_decrementer)
+HYPE_INTERRUPT(hype_decrementer, HBBL_hype_decrementer)
+STD_INTERRUPT(privileged_doorbell, HBBL_privileged_doorbell)
+STD_INTERRUPT(system_call, HBBL_system_call)
+STD_INTERRUPT(trace, HBBL_trace)
+HYPE_INTERRUPT(hype_data_storage, HBBL_hype_data_storage)
+HYPE_INTERRUPT(hype_inst_storage, HBBL_hype_inst_storage)
+HYPE_INTERRUPT(hype_emu_assist, HBBL_hype_emu_assist)
+HYPE_INTERRUPT(hype_maint, HBBL_hype_maint)
+HYPE_INTERRUPT(syscall_hype_doorbell, HBBL_syscall_hype_doorbell)
+STD_INTERRUPT(perf_monitor, HBBL_perf_monitor)
+STD_INTERRUPT(vector_unavail, HBBL_vector_unavail)
+STD_INTERRUPT(vsx_unavail, HBBL_vsx_unavail)
+STD_INTERRUPT(fac_unavail, HBBL_fac_unavail)
+HYPE_INTERRUPT(hype_fac_unavail, HBBL_hype_fac_unavail)
+STD_INTERRUPT(softpatch, HBBL_softpatch)
+STD_INTERRUPT(debug, HBBL_debug)
+
;// @fn _other_thread_error:
;// Used for threads other than first to handle this unexpected condition.
_other_thread_error:
diff --git a/src/bootloader/bl_terminate.C b/src/bootloader/bl_terminate.C
index c87c0a207..8c2c1ab1f 100644
--- a/src/bootloader/bl_terminate.C
+++ b/src/bootloader/bl_terminate.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -23,9 +23,122 @@
/* */
/* IBM_PROLOG_END_TAG */
#include <bootloader/bootloader.H>
+#include <bootloader/hbblreasoncodes.H>
+#include <arch/ppc.H>
#define bl_terminate_C
#include <../kernel/terminate.C>
+#define UINT64_HIGH(data) ((data & 0xFFFFFFFF00000000) >> 32)
+#define UINT64_LOW(data) (data & 0x00000000FFFFFFFF)
+#define WORD7_WORD8(data) UINT64_HIGH(data), UINT64_LOW(data)
+
+
+extern "C"
+void kernel_std_exception()
+{
+ uint64_t exception = getSPRG2();
+ uint64_t nip = getSRR0();
+
+ /*@
+ * @errortype
+ * @moduleid MOD_BOOTLOADER_TERMINATE
+ * @reasoncode RC_STD_EXCEPTION
+ * @userdata1[0:15] TI_WITH_SRC
+ * @userdata1[16:31] TI_BOOTLOADER
+ * @userdata1[32:63] Exception vector address
+ * @userdata2 NIP / SRR0
+ * @devdesc Exception occurred during execution of HBBL
+ * @custdesc A problem occurred while running processor
+ * boot code.
+ */
+ bl_terminate(Bootloader::MOD_BOOTLOADER_TERMINATE,
+ Bootloader::RC_STD_EXCEPTION,
+ WORD7_WORD8(nip),
+ true,
+ exception);
+}
+
+extern "C"
+void kernel_std_exception_w_dsisr()
+{
+ uint64_t exception = getSPRG2();
+ uint64_t nip = getSRR0();
+ uint64_t dsisr = getDSISR();
+
+ /*@
+ * @errortype
+ * @moduleid MOD_BOOTLOADER_TERMINATE
+ * @reasoncode RC_STD_EX_W_DSISR
+ * @userdata1[0:15] TI_WITH_SRC
+ * @userdata1[16:31] TI_BOOTLOADER
+ * @userdata1[32:63] Exception vector address
+ * @userdata2 NIP / SRR0
+ * @devdesc Exception occurred during execution of HBBL
+ * @custdesc A problem occurred while running processor
+ * boot code.
+ */
+ kernel_TIDataArea.src.SRCword3 = UINT64_HIGH(dsisr);
+ kernel_TIDataArea.src.SRCword4 = UINT64_LOW(dsisr);
+ bl_terminate(Bootloader::MOD_BOOTLOADER_TERMINATE,
+ Bootloader::RC_STD_EX_W_DSISR,
+ WORD7_WORD8(nip),
+ true,
+ exception);
+}
+
+extern "C"
+void kernel_std_exception_w_srr1()
+{
+ uint64_t exception = getSPRG2();
+ uint64_t nip = getSRR0();
+ uint64_t srr1 = getSRR1();
+
+ /*@
+ * @errortype
+ * @moduleid MOD_BOOTLOADER_TERMINATE
+ * @reasoncode RC_STD_EX_W_SRR1
+ * @userdata1[0:15] TI_WITH_SRC
+ * @userdata1[16:31] TI_BOOTLOADER
+ * @userdata1[32:63] Exception vector address
+ * @userdata2 NIP / SRR0
+ * @devdesc Exception occurred during execution of HBBL
+ * @custdesc A problem occurred while running processor
+ * boot code.
+ */
+ kernel_TIDataArea.src.SRCword3 = UINT64_HIGH(srr1);
+ kernel_TIDataArea.src.SRCword4 = UINT64_LOW(srr1);
+ bl_terminate(Bootloader::MOD_BOOTLOADER_TERMINATE,
+ Bootloader::RC_STD_EX_W_SRR1,
+ WORD7_WORD8(nip),
+ true,
+ exception);
+}
+
+extern "C"
+void kernel_hype_exception()
+{
+ uint64_t exception = getSPRG2();
+ uint64_t nip = getHSRR0();
+
+ /*@
+ * @errortype
+ * @moduleid MOD_BOOTLOADER_TERMINATE
+ * @reasoncode RC_HYPE_EXCEPTION
+ * @userdata1[0:15] TI_WITH_SRC
+ * @userdata1[16:31] TI_BOOTLOADER
+ * @userdata1[32:63] Exception vector address
+ * @userdata2 NIP / HSRR0
+ * @devdesc Exception occurred during execution of HBBL
+ * @custdesc A problem occurred while running processor
+ * boot code.
+ */
+ bl_terminate(Bootloader::MOD_BOOTLOADER_TERMINATE,
+ Bootloader::RC_HYPE_EXCEPTION,
+ WORD7_WORD8(nip),
+ true,
+ exception);
+}
+
#undef bl_terminate_C
OpenPOWER on IntegriCloud