| /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| /* |
| * Ptrace interface test helper functions |
| * |
| * Copyright (C) 2015 Anshuman Khandual, IBM Corporation. |
| */ |
| |
| #define __SANE_USERSPACE_TYPES__ |
| |
| #include <inttypes.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <malloc.h> |
| #include <errno.h> |
| #include <time.h> |
| #include <sys/ptrace.h> |
| #include <sys/ioctl.h> |
| #include <sys/uio.h> |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #include <sys/signal.h> |
| #include <sys/ipc.h> |
| #include <sys/shm.h> |
| #include <sys/user.h> |
| #include <sys/syscall.h> |
| #include <linux/elf.h> |
| #include <linux/types.h> |
| #include <linux/auxvec.h> |
| #include "reg.h" |
| #include "utils.h" |
| |
| #define TEST_PASS 0 |
| #define TEST_FAIL 1 |
| |
| struct fpr_regs { |
| __u64 fpr[32]; |
| __u64 fpscr; |
| }; |
| |
| struct tm_spr_regs { |
| unsigned long tm_tfhar; |
| unsigned long tm_texasr; |
| unsigned long tm_tfiar; |
| }; |
| |
| #ifndef NT_PPC_TAR |
| #define NT_PPC_TAR 0x103 |
| #define NT_PPC_PPR 0x104 |
| #define NT_PPC_DSCR 0x105 |
| #define NT_PPC_EBB 0x106 |
| #define NT_PPC_PMU 0x107 |
| #define NT_PPC_TM_CGPR 0x108 |
| #define NT_PPC_TM_CFPR 0x109 |
| #define NT_PPC_TM_CVMX 0x10a |
| #define NT_PPC_TM_CVSX 0x10b |
| #define NT_PPC_TM_SPR 0x10c |
| #define NT_PPC_TM_CTAR 0x10d |
| #define NT_PPC_TM_CPPR 0x10e |
| #define NT_PPC_TM_CDSCR 0x10f |
| #endif |
| |
| /* Basic ptrace operations */ |
| int start_trace(pid_t child) |
| { |
| int ret; |
| |
| ret = ptrace(PTRACE_ATTACH, child, NULL, NULL); |
| if (ret) { |
| perror("ptrace(PTRACE_ATTACH) failed"); |
| return TEST_FAIL; |
| } |
| ret = waitpid(child, NULL, 0); |
| if (ret != child) { |
| perror("waitpid() failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int stop_trace(pid_t child) |
| { |
| int ret; |
| |
| ret = ptrace(PTRACE_DETACH, child, NULL, NULL); |
| if (ret) { |
| perror("ptrace(PTRACE_DETACH) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int cont_trace(pid_t child) |
| { |
| int ret; |
| |
| ret = ptrace(PTRACE_CONT, child, NULL, NULL); |
| if (ret) { |
| perror("ptrace(PTRACE_CONT) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[], |
| int n) |
| { |
| struct iovec iov; |
| long ret; |
| |
| FAIL_IF(start_trace(child)); |
| |
| iov.iov_base = regs; |
| iov.iov_len = n * sizeof(unsigned long); |
| |
| ret = ptrace(PTRACE_GETREGSET, child, type, &iov); |
| if (ret) |
| return ret; |
| |
| FAIL_IF(stop_trace(child)); |
| |
| return TEST_PASS; |
| } |
| |
| long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[], |
| int n) |
| { |
| struct iovec iov; |
| long ret; |
| |
| FAIL_IF(start_trace(child)); |
| |
| iov.iov_base = regs; |
| iov.iov_len = n * sizeof(unsigned long); |
| |
| ret = ptrace(PTRACE_SETREGSET, child, type, &iov); |
| |
| FAIL_IF(stop_trace(child)); |
| |
| return ret; |
| } |
| |
| /* TAR, PPR, DSCR */ |
| int show_tar_registers(pid_t child, unsigned long *out) |
| { |
| struct iovec iov; |
| unsigned long *reg; |
| int ret; |
| |
| reg = malloc(sizeof(unsigned long)); |
| if (!reg) { |
| perror("malloc() failed"); |
| return TEST_FAIL; |
| } |
| iov.iov_base = (u64 *) reg; |
| iov.iov_len = sizeof(unsigned long); |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| if (out) |
| out[0] = *reg; |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| if (out) |
| out[1] = *reg; |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| if (out) |
| out[2] = *reg; |
| |
| free(reg); |
| return TEST_PASS; |
| fail: |
| free(reg); |
| return TEST_FAIL; |
| } |
| |
| int write_tar_registers(pid_t child, unsigned long tar, |
| unsigned long ppr, unsigned long dscr) |
| { |
| struct iovec iov; |
| unsigned long *reg; |
| int ret; |
| |
| reg = malloc(sizeof(unsigned long)); |
| if (!reg) { |
| perror("malloc() failed"); |
| return TEST_FAIL; |
| } |
| |
| iov.iov_base = (u64 *) reg; |
| iov.iov_len = sizeof(unsigned long); |
| |
| *reg = tar; |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_SETREGSET) failed"); |
| goto fail; |
| } |
| |
| *reg = ppr; |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_SETREGSET) failed"); |
| goto fail; |
| } |
| |
| *reg = dscr; |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_SETREGSET) failed"); |
| goto fail; |
| } |
| |
| free(reg); |
| return TEST_PASS; |
| fail: |
| free(reg); |
| return TEST_FAIL; |
| } |
| |
| int show_tm_checkpointed_state(pid_t child, unsigned long *out) |
| { |
| struct iovec iov; |
| unsigned long *reg; |
| int ret; |
| |
| reg = malloc(sizeof(unsigned long)); |
| if (!reg) { |
| perror("malloc() failed"); |
| return TEST_FAIL; |
| } |
| |
| iov.iov_base = (u64 *) reg; |
| iov.iov_len = sizeof(unsigned long); |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| if (out) |
| out[0] = *reg; |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| if (out) |
| out[1] = *reg; |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| if (out) |
| out[2] = *reg; |
| |
| free(reg); |
| return TEST_PASS; |
| |
| fail: |
| free(reg); |
| return TEST_FAIL; |
| } |
| |
| int write_ckpt_tar_registers(pid_t child, unsigned long tar, |
| unsigned long ppr, unsigned long dscr) |
| { |
| struct iovec iov; |
| unsigned long *reg; |
| int ret; |
| |
| reg = malloc(sizeof(unsigned long)); |
| if (!reg) { |
| perror("malloc() failed"); |
| return TEST_FAIL; |
| } |
| |
| iov.iov_base = (u64 *) reg; |
| iov.iov_len = sizeof(unsigned long); |
| |
| *reg = tar; |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| |
| *reg = ppr; |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| |
| *reg = dscr; |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| goto fail; |
| } |
| |
| free(reg); |
| return TEST_PASS; |
| fail: |
| free(reg); |
| return TEST_FAIL; |
| } |
| |
| /* FPR */ |
| int show_fpr(pid_t child, __u64 *fpr) |
| { |
| struct fpr_regs *regs; |
| int ret, i; |
| |
| regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs)); |
| ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| if (fpr) { |
| for (i = 0; i < 32; i++) |
| fpr[i] = regs->fpr[i]; |
| } |
| return TEST_PASS; |
| } |
| |
| int write_fpr(pid_t child, __u64 val) |
| { |
| struct fpr_regs *regs; |
| int ret, i; |
| |
| regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs)); |
| ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| for (i = 0; i < 32; i++) |
| regs->fpr[i] = val; |
| |
| ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int show_ckpt_fpr(pid_t child, __u64 *fpr) |
| { |
| struct fpr_regs *regs; |
| struct iovec iov; |
| int ret, i; |
| |
| regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs)); |
| iov.iov_base = regs; |
| iov.iov_len = sizeof(struct fpr_regs); |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| if (fpr) { |
| for (i = 0; i < 32; i++) |
| fpr[i] = regs->fpr[i]; |
| } |
| |
| return TEST_PASS; |
| } |
| |
| int write_ckpt_fpr(pid_t child, unsigned long val) |
| { |
| struct fpr_regs *regs; |
| struct iovec iov; |
| int ret, i; |
| |
| regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs)); |
| iov.iov_base = regs; |
| iov.iov_len = sizeof(struct fpr_regs); |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| for (i = 0; i < 32; i++) |
| regs->fpr[i] = val; |
| |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| /* GPR */ |
| int show_gpr(pid_t child, unsigned long *gpr) |
| { |
| struct pt_regs *regs; |
| int ret, i; |
| |
| regs = (struct pt_regs *) malloc(sizeof(struct pt_regs)); |
| if (!regs) { |
| perror("malloc() failed"); |
| return TEST_FAIL; |
| } |
| |
| ret = ptrace(PTRACE_GETREGS, child, NULL, regs); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| if (gpr) { |
| for (i = 14; i < 32; i++) |
| gpr[i-14] = regs->gpr[i]; |
| } |
| |
| return TEST_PASS; |
| } |
| |
| long sys_ptrace(enum __ptrace_request request, pid_t pid, unsigned long addr, unsigned long data) |
| { |
| return syscall(__NR_ptrace, request, pid, (void *)addr, data); |
| } |
| |
| // 33 because of FPSCR |
| #define PT_NUM_FPRS (33 * (sizeof(__u64) / sizeof(unsigned long))) |
| |
| __u64 *peek_fprs(pid_t child) |
| { |
| unsigned long *fprs, *p, addr; |
| long ret; |
| int i; |
| |
| fprs = malloc(sizeof(unsigned long) * PT_NUM_FPRS); |
| if (!fprs) { |
| perror("malloc() failed"); |
| return NULL; |
| } |
| |
| for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) { |
| addr = sizeof(unsigned long) * (PT_FPR0 + i); |
| ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)p); |
| if (ret) { |
| perror("ptrace(PTRACE_PEEKUSR) failed"); |
| return NULL; |
| } |
| } |
| |
| addr = sizeof(unsigned long) * (PT_FPR0 + i); |
| ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)&addr); |
| if (!ret) { |
| printf("ptrace(PTRACE_PEEKUSR) succeeded unexpectedly!\n"); |
| return NULL; |
| } |
| |
| return (__u64 *)fprs; |
| } |
| |
| int poke_fprs(pid_t child, unsigned long *fprs) |
| { |
| unsigned long *p, addr; |
| long ret; |
| int i; |
| |
| for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) { |
| addr = sizeof(unsigned long) * (PT_FPR0 + i); |
| ret = sys_ptrace(PTRACE_POKEUSER, child, addr, *p); |
| if (ret) { |
| perror("ptrace(PTRACE_POKEUSR) failed"); |
| return -1; |
| } |
| } |
| |
| addr = sizeof(unsigned long) * (PT_FPR0 + i); |
| ret = sys_ptrace(PTRACE_POKEUSER, child, addr, addr); |
| if (!ret) { |
| printf("ptrace(PTRACE_POKEUSR) succeeded unexpectedly!\n"); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int write_gpr(pid_t child, unsigned long val) |
| { |
| struct pt_regs *regs; |
| int i, ret; |
| |
| regs = (struct pt_regs *) malloc(sizeof(struct pt_regs)); |
| if (!regs) { |
| perror("malloc() failed"); |
| return TEST_FAIL; |
| } |
| |
| ret = ptrace(PTRACE_GETREGS, child, NULL, regs); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| for (i = 14; i < 32; i++) |
| regs->gpr[i] = val; |
| |
| ret = ptrace(PTRACE_SETREGS, child, NULL, regs); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int show_ckpt_gpr(pid_t child, unsigned long *gpr) |
| { |
| struct pt_regs *regs; |
| struct iovec iov; |
| int ret, i; |
| |
| regs = (struct pt_regs *) malloc(sizeof(struct pt_regs)); |
| if (!regs) { |
| perror("malloc() failed"); |
| return TEST_FAIL; |
| } |
| |
| iov.iov_base = (u64 *) regs; |
| iov.iov_len = sizeof(struct pt_regs); |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| if (gpr) { |
| for (i = 14; i < 32; i++) |
| gpr[i-14] = regs->gpr[i]; |
| } |
| |
| return TEST_PASS; |
| } |
| |
| int write_ckpt_gpr(pid_t child, unsigned long val) |
| { |
| struct pt_regs *regs; |
| struct iovec iov; |
| int ret, i; |
| |
| regs = (struct pt_regs *) malloc(sizeof(struct pt_regs)); |
| if (!regs) { |
| perror("malloc() failed\n"); |
| return TEST_FAIL; |
| } |
| iov.iov_base = (u64 *) regs; |
| iov.iov_len = sizeof(struct pt_regs); |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| for (i = 14; i < 32; i++) |
| regs->gpr[i] = val; |
| |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| /* VMX */ |
| int show_vmx(pid_t child, unsigned long vmx[][2]) |
| { |
| int ret; |
| |
| ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx); |
| if (ret) { |
| perror("ptrace(PTRACE_GETVRREGS) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int show_vmx_ckpt(pid_t child, unsigned long vmx[][2]) |
| { |
| unsigned long regs[34][2]; |
| struct iovec iov; |
| int ret; |
| |
| iov.iov_base = (u64 *) regs; |
| iov.iov_len = sizeof(regs); |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed"); |
| return TEST_FAIL; |
| } |
| memcpy(vmx, regs, sizeof(regs)); |
| return TEST_PASS; |
| } |
| |
| |
| int write_vmx(pid_t child, unsigned long vmx[][2]) |
| { |
| int ret; |
| |
| ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx); |
| if (ret) { |
| perror("ptrace(PTRACE_SETVRREGS) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int write_vmx_ckpt(pid_t child, unsigned long vmx[][2]) |
| { |
| unsigned long regs[34][2]; |
| struct iovec iov; |
| int ret; |
| |
| memcpy(regs, vmx, sizeof(regs)); |
| iov.iov_base = (u64 *) regs; |
| iov.iov_len = sizeof(regs); |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| /* VSX */ |
| int show_vsx(pid_t child, unsigned long *vsx) |
| { |
| int ret; |
| |
| ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx); |
| if (ret) { |
| perror("ptrace(PTRACE_GETVSRREGS) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int show_vsx_ckpt(pid_t child, unsigned long *vsx) |
| { |
| unsigned long regs[32]; |
| struct iovec iov; |
| int ret; |
| |
| iov.iov_base = (u64 *) regs; |
| iov.iov_len = sizeof(regs); |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed"); |
| return TEST_FAIL; |
| } |
| memcpy(vsx, regs, sizeof(regs)); |
| return TEST_PASS; |
| } |
| |
| int write_vsx(pid_t child, unsigned long *vsx) |
| { |
| int ret; |
| |
| ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx); |
| if (ret) { |
| perror("ptrace(PTRACE_SETVSRREGS) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| int write_vsx_ckpt(pid_t child, unsigned long *vsx) |
| { |
| unsigned long regs[32]; |
| struct iovec iov; |
| int ret; |
| |
| memcpy(regs, vsx, sizeof(regs)); |
| iov.iov_base = (u64 *) regs; |
| iov.iov_len = sizeof(regs); |
| ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed"); |
| return TEST_FAIL; |
| } |
| return TEST_PASS; |
| } |
| |
| /* TM SPR */ |
| int show_tm_spr(pid_t child, struct tm_spr_regs *out) |
| { |
| struct tm_spr_regs *regs; |
| struct iovec iov; |
| int ret; |
| |
| regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs)); |
| if (!regs) { |
| perror("malloc() failed"); |
| return TEST_FAIL; |
| } |
| |
| iov.iov_base = (u64 *) regs; |
| iov.iov_len = sizeof(struct tm_spr_regs); |
| |
| ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov); |
| if (ret) { |
| perror("ptrace(PTRACE_GETREGSET) failed"); |
| return TEST_FAIL; |
| } |
| |
| if (out) |
| memcpy(out, regs, sizeof(struct tm_spr_regs)); |
| |
| return TEST_PASS; |
| } |
| |
| |
| |
| /* Analyse TEXASR after TM failure */ |
| inline unsigned long get_tfiar(void) |
| { |
| return mfspr(SPRN_TFIAR); |
| } |
| |
| void analyse_texasr(unsigned long texasr) |
| { |
| printf("TEXASR: %16lx\t", texasr); |
| |
| if (texasr & TEXASR_FP) |
| printf("TEXASR_FP "); |
| |
| if (texasr & TEXASR_DA) |
| printf("TEXASR_DA "); |
| |
| if (texasr & TEXASR_NO) |
| printf("TEXASR_NO "); |
| |
| if (texasr & TEXASR_FO) |
| printf("TEXASR_FO "); |
| |
| if (texasr & TEXASR_SIC) |
| printf("TEXASR_SIC "); |
| |
| if (texasr & TEXASR_NTC) |
| printf("TEXASR_NTC "); |
| |
| if (texasr & TEXASR_TC) |
| printf("TEXASR_TC "); |
| |
| if (texasr & TEXASR_TIC) |
| printf("TEXASR_TIC "); |
| |
| if (texasr & TEXASR_IC) |
| printf("TEXASR_IC "); |
| |
| if (texasr & TEXASR_IFC) |
| printf("TEXASR_IFC "); |
| |
| if (texasr & TEXASR_ABT) |
| printf("TEXASR_ABT "); |
| |
| if (texasr & TEXASR_SPD) |
| printf("TEXASR_SPD "); |
| |
| if (texasr & TEXASR_HV) |
| printf("TEXASR_HV "); |
| |
| if (texasr & TEXASR_PR) |
| printf("TEXASR_PR "); |
| |
| if (texasr & TEXASR_FS) |
| printf("TEXASR_FS "); |
| |
| if (texasr & TEXASR_TE) |
| printf("TEXASR_TE "); |
| |
| if (texasr & TEXASR_ROT) |
| printf("TEXASR_ROT "); |
| |
| printf("TFIAR :%lx\n", get_tfiar()); |
| } |
| |
| void store_gpr(unsigned long *addr); |