xref: /openbmc/qemu/tests/tcg/ppc64/signal_save_restore_xer.c (revision f1d33f55c47dfdaf8daacd618588ad3ae4c452d1)
1*37b0dba4SPaolo Bonzini #include <assert.h>
2*37b0dba4SPaolo Bonzini #include <stdint.h>
3*37b0dba4SPaolo Bonzini #include <signal.h>
4*37b0dba4SPaolo Bonzini #include <sys/user.h>
5*37b0dba4SPaolo Bonzini 
6*37b0dba4SPaolo Bonzini #define XER_SO   (1 << 31)
7*37b0dba4SPaolo Bonzini #define XER_OV   (1 << 30)
8*37b0dba4SPaolo Bonzini #define XER_CA   (1 << 29)
9*37b0dba4SPaolo Bonzini #define XER_OV32 (1 << 19)
10*37b0dba4SPaolo Bonzini #define XER_CA32 (1 << 18)
11*37b0dba4SPaolo Bonzini 
12*37b0dba4SPaolo Bonzini uint64_t saved;
13*37b0dba4SPaolo Bonzini 
sigtrap_handler(int sig,siginfo_t * si,void * ucontext)14*37b0dba4SPaolo Bonzini void sigtrap_handler(int sig, siginfo_t *si, void *ucontext)
15*37b0dba4SPaolo Bonzini {
16*37b0dba4SPaolo Bonzini     ucontext_t *uc = ucontext;
17*37b0dba4SPaolo Bonzini     uc->uc_mcontext.regs->nip += 4;
18*37b0dba4SPaolo Bonzini     saved = uc->uc_mcontext.regs->xer;
19*37b0dba4SPaolo Bonzini     uc->uc_mcontext.regs->xer |= XER_OV | XER_OV32;
20*37b0dba4SPaolo Bonzini }
21*37b0dba4SPaolo Bonzini 
main(void)22*37b0dba4SPaolo Bonzini int main(void)
23*37b0dba4SPaolo Bonzini {
24*37b0dba4SPaolo Bonzini     uint64_t initial = XER_CA | XER_CA32, restored;
25*37b0dba4SPaolo Bonzini     struct sigaction sa = {
26*37b0dba4SPaolo Bonzini         .sa_sigaction = sigtrap_handler,
27*37b0dba4SPaolo Bonzini         .sa_flags = SA_SIGINFO
28*37b0dba4SPaolo Bonzini     };
29*37b0dba4SPaolo Bonzini 
30*37b0dba4SPaolo Bonzini     sigaction(SIGTRAP, &sa, NULL);
31*37b0dba4SPaolo Bonzini 
32*37b0dba4SPaolo Bonzini     asm("mtspr 1, %1\n\t"
33*37b0dba4SPaolo Bonzini         "trap\n\t"
34*37b0dba4SPaolo Bonzini         "mfspr %0, 1\n\t"
35*37b0dba4SPaolo Bonzini         : "=r" (restored)
36*37b0dba4SPaolo Bonzini         : "r" (initial));
37*37b0dba4SPaolo Bonzini 
38*37b0dba4SPaolo Bonzini     assert(saved == initial);
39*37b0dba4SPaolo Bonzini     assert(restored == (XER_OV | XER_OV32 | XER_CA | XER_CA32));
40*37b0dba4SPaolo Bonzini 
41*37b0dba4SPaolo Bonzini     return 0;
42*37b0dba4SPaolo Bonzini }
43