169de9b31SRicardo Koller #include <libcflat.h> 27cefda52SNico Boehr #include <migrate.h> 369de9b31SRicardo Koller #include <errata.h> 469de9b31SRicardo Koller #include <asm/setup.h> 569de9b31SRicardo Koller #include <asm/processor.h> 669de9b31SRicardo Koller #include <asm/delay.h> 769de9b31SRicardo Koller #include <asm/smp.h> 869de9b31SRicardo Koller #include <asm/barrier.h> 969de9b31SRicardo Koller #include <asm/io.h> 1069de9b31SRicardo Koller 1169de9b31SRicardo Koller #define MDSCR_KDE (1 << 13) 1269de9b31SRicardo Koller #define MDSCR_MDE (1 << 15) 13843fa9e2SRicardo Koller #define MDSCR_SS (1 << 0) 1469de9b31SRicardo Koller 1569de9b31SRicardo Koller #define DBGBCR_LEN8 (0xff << 5) 1669de9b31SRicardo Koller #define DBGBCR_EXEC (0x0 << 3) 1769de9b31SRicardo Koller #define DBGBCR_EL1 (0x1 << 1) 1869de9b31SRicardo Koller #define DBGBCR_E (0x1 << 0) 1969de9b31SRicardo Koller 20843fa9e2SRicardo Koller #define DBGWCR_LEN8 (0xff << 5) 21843fa9e2SRicardo Koller #define DBGWCR_RD (0x1 << 3) 22843fa9e2SRicardo Koller #define DBGWCR_WR (0x2 << 3) 23843fa9e2SRicardo Koller #define DBGWCR_EL1 (0x1 << 1) 24843fa9e2SRicardo Koller #define DBGWCR_E (0x1 << 0) 25843fa9e2SRicardo Koller 2669de9b31SRicardo Koller #define SPSR_D (1 << 9) 27ac97ac81SRicardo Koller #define SPSR_SS (1 << 21) 2869de9b31SRicardo Koller 2969de9b31SRicardo Koller #define ESR_EC_HW_BP_CURRENT 0x31 30ac97ac81SRicardo Koller #define ESR_EC_SSTEP_CURRENT 0x33 31843fa9e2SRicardo Koller #define ESR_EC_WP_CURRENT 0x35 3269de9b31SRicardo Koller 3369de9b31SRicardo Koller #define ID_AA64DFR0_BRPS_SHIFT 12 3469de9b31SRicardo Koller #define ID_AA64DFR0_BRPS_MASK 0xf 35843fa9e2SRicardo Koller #define ID_AA64DFR0_WRPS_SHIFT 20 36843fa9e2SRicardo Koller #define ID_AA64DFR0_WRPS_MASK 0xf 3769de9b31SRicardo Koller 3869de9b31SRicardo Koller static volatile uint64_t hw_bp_idx, hw_bp_addr[16]; 39843fa9e2SRicardo Koller static volatile uint64_t wp_idx, wp_data_addr[16]; 40ac97ac81SRicardo Koller static volatile uint64_t ss_addr[4], ss_idx; 4169de9b31SRicardo Koller 4269de9b31SRicardo Koller static void hw_bp_handler(struct pt_regs *regs, unsigned int esr) 4369de9b31SRicardo Koller { 4469de9b31SRicardo Koller hw_bp_addr[hw_bp_idx++] = regs->pc; 4569de9b31SRicardo Koller regs->pstate |= SPSR_D; 4669de9b31SRicardo Koller } 4769de9b31SRicardo Koller 48843fa9e2SRicardo Koller static void wp_handler(struct pt_regs *regs, unsigned int esr) 49843fa9e2SRicardo Koller { 50843fa9e2SRicardo Koller wp_data_addr[wp_idx++] = read_sysreg(far_el1); 51843fa9e2SRicardo Koller regs->pstate |= SPSR_D; 52843fa9e2SRicardo Koller } 53843fa9e2SRicardo Koller 54ac97ac81SRicardo Koller static void ss_handler(struct pt_regs *regs, unsigned int esr) 55ac97ac81SRicardo Koller { 56ac97ac81SRicardo Koller ss_addr[ss_idx++] = regs->pc; 57ac97ac81SRicardo Koller regs->pstate |= SPSR_SS; 58ac97ac81SRicardo Koller } 59ac97ac81SRicardo Koller 6069de9b31SRicardo Koller static int get_num_hw_bp(void) 6169de9b31SRicardo Koller { 6269de9b31SRicardo Koller uint64_t reg = read_sysreg(id_aa64dfr0_el1); 6369de9b31SRicardo Koller /* Number of breakpoints, minus 1 */ 6469de9b31SRicardo Koller uint8_t brps = (reg >> ID_AA64DFR0_BRPS_SHIFT) & ID_AA64DFR0_BRPS_MASK; 6569de9b31SRicardo Koller 6669de9b31SRicardo Koller return brps + 1; 6769de9b31SRicardo Koller } 6869de9b31SRicardo Koller 69843fa9e2SRicardo Koller static int get_num_wp(void) 70843fa9e2SRicardo Koller { 71843fa9e2SRicardo Koller uint64_t reg = read_sysreg(id_aa64dfr0_el1); 72843fa9e2SRicardo Koller /* Number of watchpoints, minus 1 */ 73843fa9e2SRicardo Koller uint8_t wrps = (reg >> ID_AA64DFR0_WRPS_SHIFT) & ID_AA64DFR0_WRPS_MASK; 74843fa9e2SRicardo Koller 75843fa9e2SRicardo Koller return wrps + 1; 76843fa9e2SRicardo Koller } 77843fa9e2SRicardo Koller 7869de9b31SRicardo Koller static void write_dbgbcr(int n, uint32_t bcr) 7969de9b31SRicardo Koller { 8069de9b31SRicardo Koller switch (n) { 8169de9b31SRicardo Koller case 0: 8269de9b31SRicardo Koller write_sysreg(bcr, dbgbcr0_el1); break; 8369de9b31SRicardo Koller case 1: 8469de9b31SRicardo Koller write_sysreg(bcr, dbgbcr1_el1); break; 8569de9b31SRicardo Koller case 2: 8669de9b31SRicardo Koller write_sysreg(bcr, dbgbcr2_el1); break; 8769de9b31SRicardo Koller case 3: 8869de9b31SRicardo Koller write_sysreg(bcr, dbgbcr3_el1); break; 8969de9b31SRicardo Koller case 4: 9069de9b31SRicardo Koller write_sysreg(bcr, dbgbcr4_el1); break; 9169de9b31SRicardo Koller case 5: 9269de9b31SRicardo Koller write_sysreg(bcr, dbgbcr5_el1); break; 9369de9b31SRicardo Koller case 6: 9469de9b31SRicardo Koller write_sysreg(bcr, dbgbcr6_el1); break; 9569de9b31SRicardo Koller case 7: 9669de9b31SRicardo Koller write_sysreg(bcr, dbgbcr7_el1); break; 9769de9b31SRicardo Koller case 8: 9869de9b31SRicardo Koller write_sysreg(bcr, dbgbcr8_el1); break; 9969de9b31SRicardo Koller case 9: 10069de9b31SRicardo Koller write_sysreg(bcr, dbgbcr9_el1); break; 10169de9b31SRicardo Koller case 10: 10269de9b31SRicardo Koller write_sysreg(bcr, dbgbcr10_el1); break; 10369de9b31SRicardo Koller case 11: 10469de9b31SRicardo Koller write_sysreg(bcr, dbgbcr11_el1); break; 10569de9b31SRicardo Koller case 12: 10669de9b31SRicardo Koller write_sysreg(bcr, dbgbcr12_el1); break; 10769de9b31SRicardo Koller case 13: 10869de9b31SRicardo Koller write_sysreg(bcr, dbgbcr13_el1); break; 10969de9b31SRicardo Koller case 14: 11069de9b31SRicardo Koller write_sysreg(bcr, dbgbcr14_el1); break; 11169de9b31SRicardo Koller case 15: 11269de9b31SRicardo Koller write_sysreg(bcr, dbgbcr15_el1); break; 11369de9b31SRicardo Koller default: 11469de9b31SRicardo Koller report_abort("Invalid bcr"); 11569de9b31SRicardo Koller } 11669de9b31SRicardo Koller } 11769de9b31SRicardo Koller 11869de9b31SRicardo Koller static void write_dbgbvr(int n, uint64_t bvr) 11969de9b31SRicardo Koller { 12069de9b31SRicardo Koller switch (n) { 12169de9b31SRicardo Koller case 0: 12269de9b31SRicardo Koller write_sysreg(bvr, dbgbvr0_el1); break; 12369de9b31SRicardo Koller case 1: 12469de9b31SRicardo Koller write_sysreg(bvr, dbgbvr1_el1); break; 12569de9b31SRicardo Koller case 2: 12669de9b31SRicardo Koller write_sysreg(bvr, dbgbvr2_el1); break; 12769de9b31SRicardo Koller case 3: 12869de9b31SRicardo Koller write_sysreg(bvr, dbgbvr3_el1); break; 12969de9b31SRicardo Koller case 4: 13069de9b31SRicardo Koller write_sysreg(bvr, dbgbvr4_el1); break; 13169de9b31SRicardo Koller case 5: 13269de9b31SRicardo Koller write_sysreg(bvr, dbgbvr5_el1); break; 13369de9b31SRicardo Koller case 6: 13469de9b31SRicardo Koller write_sysreg(bvr, dbgbvr6_el1); break; 13569de9b31SRicardo Koller case 7: 13669de9b31SRicardo Koller write_sysreg(bvr, dbgbvr7_el1); break; 13769de9b31SRicardo Koller case 8: 13869de9b31SRicardo Koller write_sysreg(bvr, dbgbvr8_el1); break; 13969de9b31SRicardo Koller case 9: 14069de9b31SRicardo Koller write_sysreg(bvr, dbgbvr9_el1); break; 14169de9b31SRicardo Koller case 10: 14269de9b31SRicardo Koller write_sysreg(bvr, dbgbvr10_el1); break; 14369de9b31SRicardo Koller case 11: 14469de9b31SRicardo Koller write_sysreg(bvr, dbgbvr11_el1); break; 14569de9b31SRicardo Koller case 12: 14669de9b31SRicardo Koller write_sysreg(bvr, dbgbvr12_el1); break; 14769de9b31SRicardo Koller case 13: 14869de9b31SRicardo Koller write_sysreg(bvr, dbgbvr13_el1); break; 14969de9b31SRicardo Koller case 14: 15069de9b31SRicardo Koller write_sysreg(bvr, dbgbvr14_el1); break; 15169de9b31SRicardo Koller case 15: 15269de9b31SRicardo Koller write_sysreg(bvr, dbgbvr15_el1); break; 15369de9b31SRicardo Koller default: 15469de9b31SRicardo Koller report_abort("invalid bvr"); 15569de9b31SRicardo Koller } 15669de9b31SRicardo Koller } 15769de9b31SRicardo Koller 158843fa9e2SRicardo Koller static void write_dbgwcr(int n, uint32_t wcr) 159843fa9e2SRicardo Koller { 160843fa9e2SRicardo Koller switch (n) { 161843fa9e2SRicardo Koller case 0: 162843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr0_el1); break; 163843fa9e2SRicardo Koller case 1: 164843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr1_el1); break; 165843fa9e2SRicardo Koller case 2: 166843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr2_el1); break; 167843fa9e2SRicardo Koller case 3: 168843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr3_el1); break; 169843fa9e2SRicardo Koller case 4: 170843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr4_el1); break; 171843fa9e2SRicardo Koller case 5: 172843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr5_el1); break; 173843fa9e2SRicardo Koller case 6: 174843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr6_el1); break; 175843fa9e2SRicardo Koller case 7: 176843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr7_el1); break; 177843fa9e2SRicardo Koller case 8: 178843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr8_el1); break; 179843fa9e2SRicardo Koller case 9: 180843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr9_el1); break; 181843fa9e2SRicardo Koller case 10: 182843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr10_el1); break; 183843fa9e2SRicardo Koller case 11: 184843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr11_el1); break; 185843fa9e2SRicardo Koller case 12: 186843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr12_el1); break; 187843fa9e2SRicardo Koller case 13: 188843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr13_el1); break; 189843fa9e2SRicardo Koller case 14: 190843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr14_el1); break; 191843fa9e2SRicardo Koller case 15: 192843fa9e2SRicardo Koller write_sysreg(wcr, dbgwcr15_el1); break; 193843fa9e2SRicardo Koller default: 194843fa9e2SRicardo Koller report_abort("Invalid wcr"); 195843fa9e2SRicardo Koller } 196843fa9e2SRicardo Koller } 197843fa9e2SRicardo Koller 198843fa9e2SRicardo Koller static void write_dbgwvr(int n, uint64_t wvr) 199843fa9e2SRicardo Koller { 200843fa9e2SRicardo Koller switch (n) { 201843fa9e2SRicardo Koller case 0: 202843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr0_el1); break; 203843fa9e2SRicardo Koller case 1: 204843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr1_el1); break; 205843fa9e2SRicardo Koller case 2: 206843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr2_el1); break; 207843fa9e2SRicardo Koller case 3: 208843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr3_el1); break; 209843fa9e2SRicardo Koller case 4: 210843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr4_el1); break; 211843fa9e2SRicardo Koller case 5: 212843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr5_el1); break; 213843fa9e2SRicardo Koller case 6: 214843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr6_el1); break; 215843fa9e2SRicardo Koller case 7: 216843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr7_el1); break; 217843fa9e2SRicardo Koller case 8: 218843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr8_el1); break; 219843fa9e2SRicardo Koller case 9: 220843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr9_el1); break; 221843fa9e2SRicardo Koller case 10: 222843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr10_el1); break; 223843fa9e2SRicardo Koller case 11: 224843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr11_el1); break; 225843fa9e2SRicardo Koller case 12: 226843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr12_el1); break; 227843fa9e2SRicardo Koller case 13: 228843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr13_el1); break; 229843fa9e2SRicardo Koller case 14: 230843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr14_el1); break; 231843fa9e2SRicardo Koller case 15: 232843fa9e2SRicardo Koller write_sysreg(wvr, dbgwvr15_el1); break; 233843fa9e2SRicardo Koller default: 234843fa9e2SRicardo Koller report_abort("invalid wvr"); 235843fa9e2SRicardo Koller } 236843fa9e2SRicardo Koller } 237843fa9e2SRicardo Koller 23869de9b31SRicardo Koller static void reset_debug_state(void) 23969de9b31SRicardo Koller { 24069de9b31SRicardo Koller int i, num_bp = get_num_hw_bp(); 241843fa9e2SRicardo Koller int num_wp = get_num_wp(); 24269de9b31SRicardo Koller 24369de9b31SRicardo Koller asm volatile("msr daifset, #8"); 24469de9b31SRicardo Koller 24569de9b31SRicardo Koller write_sysreg(0, osdlr_el1); 24669de9b31SRicardo Koller write_sysreg(0, oslar_el1); 24769de9b31SRicardo Koller isb(); 24869de9b31SRicardo Koller 24969de9b31SRicardo Koller write_sysreg(0, mdscr_el1); 25069de9b31SRicardo Koller for (i = 0; i < num_bp; i++) { 25169de9b31SRicardo Koller write_dbgbvr(i, 0); 25269de9b31SRicardo Koller write_dbgbcr(i, 0); 25369de9b31SRicardo Koller } 254843fa9e2SRicardo Koller for (i = 0; i < num_wp; i++) { 255843fa9e2SRicardo Koller write_dbgwvr(i, 0); 256843fa9e2SRicardo Koller write_dbgwcr(i, 0); 257843fa9e2SRicardo Koller } 25869de9b31SRicardo Koller isb(); 25969de9b31SRicardo Koller } 26069de9b31SRicardo Koller 26130333fbcSRicardo Koller static noinline void test_hw_bp(bool migrate) 26269de9b31SRicardo Koller { 26369de9b31SRicardo Koller extern unsigned char hw_bp0; 26469de9b31SRicardo Koller uint32_t bcr; 26569de9b31SRicardo Koller uint32_t mdscr; 26669de9b31SRicardo Koller uint64_t addr; 26769de9b31SRicardo Koller int num_bp = get_num_hw_bp(); 26869de9b31SRicardo Koller int i; 26969de9b31SRicardo Koller 27069de9b31SRicardo Koller install_exception_handler(EL1H_SYNC, ESR_EC_HW_BP_CURRENT, hw_bp_handler); 27169de9b31SRicardo Koller 27269de9b31SRicardo Koller reset_debug_state(); 27369de9b31SRicardo Koller 27469de9b31SRicardo Koller bcr = DBGBCR_LEN8 | DBGBCR_EXEC | DBGBCR_EL1 | DBGBCR_E; 27569de9b31SRicardo Koller for (i = 0, addr = (uint64_t)&hw_bp0; i < num_bp; i++, addr += 4) { 27669de9b31SRicardo Koller write_dbgbcr(i, bcr); 27769de9b31SRicardo Koller write_dbgbvr(i, addr); 27869de9b31SRicardo Koller } 27969de9b31SRicardo Koller isb(); 28069de9b31SRicardo Koller 28169de9b31SRicardo Koller asm volatile("msr daifclr, #8"); 28269de9b31SRicardo Koller 28369de9b31SRicardo Koller mdscr = read_sysreg(mdscr_el1) | MDSCR_KDE | MDSCR_MDE; 28469de9b31SRicardo Koller write_sysreg(mdscr, mdscr_el1); 28569de9b31SRicardo Koller isb(); 28669de9b31SRicardo Koller 28769de9b31SRicardo Koller if (migrate) { 2887cefda52SNico Boehr migrate_once(); 28969de9b31SRicardo Koller report(num_bp == get_num_hw_bp(), "brps match after migrate"); 29069de9b31SRicardo Koller } 29169de9b31SRicardo Koller 29269de9b31SRicardo Koller hw_bp_idx = 0; 29369de9b31SRicardo Koller 29469de9b31SRicardo Koller /* Trap on up to 16 debug exception unmask instructions. */ 295*79521ee7SNikos Nikoleris asm volatile( 296*79521ee7SNikos Nikoleris ".globl hw_bp0\n" 297*79521ee7SNikos Nikoleris "hw_bp0:\n" 29869de9b31SRicardo Koller "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr daifclr, #8\n" 29969de9b31SRicardo Koller "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr daifclr, #8\n" 30069de9b31SRicardo Koller "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr daifclr, #8\n" 301*79521ee7SNikos Nikoleris "msr daifclr, #8; msr daifclr, #8; msr daifclr, #8; msr daifclr, #8\n" 302*79521ee7SNikos Nikoleris ); 30369de9b31SRicardo Koller 30469de9b31SRicardo Koller for (i = 0, addr = (uint64_t)&hw_bp0; i < num_bp; i++, addr += 4) 30569de9b31SRicardo Koller report(hw_bp_addr[i] == addr, "hw breakpoint: %d", i); 30669de9b31SRicardo Koller } 30769de9b31SRicardo Koller 308843fa9e2SRicardo Koller static volatile char write_data[16]; 309843fa9e2SRicardo Koller 31030333fbcSRicardo Koller static noinline void test_wp(bool migrate) 311843fa9e2SRicardo Koller { 312843fa9e2SRicardo Koller uint32_t wcr; 313843fa9e2SRicardo Koller uint32_t mdscr; 314843fa9e2SRicardo Koller int num_wp = get_num_wp(); 315843fa9e2SRicardo Koller int i; 316843fa9e2SRicardo Koller 317843fa9e2SRicardo Koller install_exception_handler(EL1H_SYNC, ESR_EC_WP_CURRENT, wp_handler); 318843fa9e2SRicardo Koller 319843fa9e2SRicardo Koller reset_debug_state(); 320843fa9e2SRicardo Koller 321843fa9e2SRicardo Koller wcr = DBGWCR_LEN8 | DBGWCR_RD | DBGWCR_WR | DBGWCR_EL1 | DBGWCR_E; 322843fa9e2SRicardo Koller for (i = 0; i < num_wp; i++) { 323843fa9e2SRicardo Koller write_dbgwcr(i, wcr); 324843fa9e2SRicardo Koller write_dbgwvr(i, (uint64_t)&write_data[i]); 325843fa9e2SRicardo Koller } 326843fa9e2SRicardo Koller isb(); 327843fa9e2SRicardo Koller 328843fa9e2SRicardo Koller asm volatile("msr daifclr, #8"); 329843fa9e2SRicardo Koller 330843fa9e2SRicardo Koller mdscr = read_sysreg(mdscr_el1) | MDSCR_KDE | MDSCR_MDE; 331843fa9e2SRicardo Koller write_sysreg(mdscr, mdscr_el1); 332843fa9e2SRicardo Koller isb(); 333843fa9e2SRicardo Koller 334843fa9e2SRicardo Koller if (migrate) { 3357cefda52SNico Boehr migrate_once(); 336843fa9e2SRicardo Koller report(num_wp == get_num_wp(), "wrps match after migrate"); 337843fa9e2SRicardo Koller } 338843fa9e2SRicardo Koller 339843fa9e2SRicardo Koller wp_idx = 0; 340843fa9e2SRicardo Koller 341843fa9e2SRicardo Koller for (i = 0; i < num_wp; i++) { 342843fa9e2SRicardo Koller write_data[i] = i; 343843fa9e2SRicardo Koller asm volatile("msr daifclr, #8"); 344843fa9e2SRicardo Koller } 345843fa9e2SRicardo Koller 346843fa9e2SRicardo Koller for (i = 0; i < num_wp; i++) { 347843fa9e2SRicardo Koller report(wp_data_addr[i] == (uint64_t)&write_data[i], 348843fa9e2SRicardo Koller "watchpoint received: %d", i); 349843fa9e2SRicardo Koller report(write_data[i] == i, "watchpoint data: %d", i); 350843fa9e2SRicardo Koller } 351843fa9e2SRicardo Koller } 352843fa9e2SRicardo Koller 35330333fbcSRicardo Koller static noinline void test_ss(bool migrate) 354ac97ac81SRicardo Koller { 355ac97ac81SRicardo Koller extern unsigned char ss_start; 356ac97ac81SRicardo Koller uint32_t mdscr; 357ac97ac81SRicardo Koller 358ac97ac81SRicardo Koller install_exception_handler(EL1H_SYNC, ESR_EC_SSTEP_CURRENT, ss_handler); 359ac97ac81SRicardo Koller 360ac97ac81SRicardo Koller reset_debug_state(); 361ac97ac81SRicardo Koller 362ac97ac81SRicardo Koller ss_idx = 0; 363ac97ac81SRicardo Koller 364ac97ac81SRicardo Koller mdscr = read_sysreg(mdscr_el1) | MDSCR_KDE | MDSCR_SS; 365ac97ac81SRicardo Koller write_sysreg(mdscr, mdscr_el1); 366ac97ac81SRicardo Koller isb(); 367ac97ac81SRicardo Koller 3687cefda52SNico Boehr if (migrate) 3697cefda52SNico Boehr migrate_once(); 370ac97ac81SRicardo Koller 371ac97ac81SRicardo Koller asm volatile("msr daifclr, #8"); 372ac97ac81SRicardo Koller 373*79521ee7SNikos Nikoleris asm volatile( 374*79521ee7SNikos Nikoleris ".globl ss_start\n" 375*79521ee7SNikos Nikoleris "ss_start:\n" 376ac97ac81SRicardo Koller "mrs x0, esr_el1\n" 377ac97ac81SRicardo Koller "add x0, x0, #1\n" 378ac97ac81SRicardo Koller "msr daifset, #8\n" 379*79521ee7SNikos Nikoleris : : : "x0" 380*79521ee7SNikos Nikoleris ); 381ac97ac81SRicardo Koller 382ac97ac81SRicardo Koller report(ss_addr[0] == (uint64_t)&ss_start, "single step"); 383ac97ac81SRicardo Koller } 384ac97ac81SRicardo Koller 38569de9b31SRicardo Koller int main(int argc, char **argv) 38669de9b31SRicardo Koller { 38769de9b31SRicardo Koller if (argc < 2) 38869de9b31SRicardo Koller report_abort("no test specified"); 38969de9b31SRicardo Koller 39069de9b31SRicardo Koller if (strcmp(argv[1], "bp") == 0) { 39169de9b31SRicardo Koller report_prefix_push(argv[1]); 39269de9b31SRicardo Koller test_hw_bp(false); 39369de9b31SRicardo Koller report_prefix_pop(); 39469de9b31SRicardo Koller } else if (strcmp(argv[1], "bp-migration") == 0) { 39569de9b31SRicardo Koller report_prefix_push(argv[1]); 39669de9b31SRicardo Koller test_hw_bp(true); 39769de9b31SRicardo Koller report_prefix_pop(); 398843fa9e2SRicardo Koller } else if (strcmp(argv[1], "wp") == 0) { 399843fa9e2SRicardo Koller report_prefix_push(argv[1]); 400843fa9e2SRicardo Koller test_wp(false); 401843fa9e2SRicardo Koller report_prefix_pop(); 402843fa9e2SRicardo Koller } else if (strcmp(argv[1], "wp-migration") == 0) { 403843fa9e2SRicardo Koller report_prefix_push(argv[1]); 404843fa9e2SRicardo Koller test_wp(true); 405843fa9e2SRicardo Koller report_prefix_pop(); 406ac97ac81SRicardo Koller } else if (strcmp(argv[1], "ss") == 0) { 407ac97ac81SRicardo Koller report_prefix_push(argv[1]); 408ac97ac81SRicardo Koller test_ss(false); 409ac97ac81SRicardo Koller report_prefix_pop(); 410ac97ac81SRicardo Koller } else if (strcmp(argv[1], "ss-migration") == 0) { 411ac97ac81SRicardo Koller report_prefix_push(argv[1]); 412ac97ac81SRicardo Koller test_ss(true); 413ac97ac81SRicardo Koller report_prefix_pop(); 41469de9b31SRicardo Koller } else { 41569de9b31SRicardo Koller report_abort("Unknown subtest '%s'", argv[1]); 41669de9b31SRicardo Koller } 41769de9b31SRicardo Koller 41869de9b31SRicardo Koller return report_summary(); 41969de9b31SRicardo Koller } 420