diff options
author | Marty Gloff <mgloff@us.ibm.com> | 2016-12-28 15:11:49 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-01-20 21:39:53 -0500 |
commit | 1335057e33390c0ee3d24b537afc9d9c9dbe0a54 (patch) | |
tree | 3900f54a42415a7bdce63329a7eb04eb7aec4c0c /src/bootloader | |
parent | cf8fcc043860d45684db89af0f1ccbe4cec99245 (diff) | |
download | talos-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.S | 203 | ||||
-rw-r--r-- | src/bootloader/bl_terminate.C | 115 |
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 |