| /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | |
| /* | |
| * Register definitions for the Hexagon architecture | |
| */ | |
| #ifndef _ASM_REGISTERS_H | |
| #define _ASM_REGISTERS_H | |
| #ifndef __ASSEMBLY__ | |
| /* See kernel/entry.S for further documentation. */ | |
| /* | |
| * Entry code copies the event record out of guest registers into | |
| * this structure (which is on the stack). | |
| */ | |
| struct hvm_event_record { | |
| unsigned long vmel; /* Event Linkage (return address) */ | |
| unsigned long vmest; /* Event context - pre-event SSR values */ | |
| unsigned long vmpsp; /* Previous stack pointer */ | |
| unsigned long vmbadva; /* Bad virtual address for addressing events */ | |
| }; | |
| struct pt_regs { | |
| long restart_r0; /* R0 checkpoint for syscall restart */ | |
| long syscall_nr; /* Only used in system calls */ | |
| union { | |
| struct { | |
| unsigned long usr; | |
| unsigned long preds; | |
| }; | |
| long long int predsusr; | |
| }; | |
| union { | |
| struct { | |
| unsigned long m0; | |
| unsigned long m1; | |
| }; | |
| long long int m1m0; | |
| }; | |
| union { | |
| struct { | |
| unsigned long sa1; | |
| unsigned long lc1; | |
| }; | |
| long long int lc1sa1; | |
| }; | |
| union { | |
| struct { | |
| unsigned long sa0; | |
| unsigned long lc0; | |
| }; | |
| long long int lc0sa0; | |
| }; | |
| union { | |
| struct { | |
| unsigned long ugp; | |
| unsigned long gp; | |
| }; | |
| long long int gpugp; | |
| }; | |
| union { | |
| struct { | |
| unsigned long cs0; | |
| unsigned long cs1; | |
| }; | |
| long long int cs1cs0; | |
| }; | |
| /* | |
| * Be extremely careful with rearranging these, if at all. Some code | |
| * assumes the 32 registers exist exactly like this in memory; | |
| * e.g. kernel/ptrace.c | |
| * e.g. kernel/signal.c (restore_sigcontext) | |
| */ | |
| union { | |
| struct { | |
| unsigned long r00; | |
| unsigned long r01; | |
| }; | |
| long long int r0100; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r02; | |
| unsigned long r03; | |
| }; | |
| long long int r0302; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r04; | |
| unsigned long r05; | |
| }; | |
| long long int r0504; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r06; | |
| unsigned long r07; | |
| }; | |
| long long int r0706; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r08; | |
| unsigned long r09; | |
| }; | |
| long long int r0908; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r10; | |
| unsigned long r11; | |
| }; | |
| long long int r1110; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r12; | |
| unsigned long r13; | |
| }; | |
| long long int r1312; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r14; | |
| unsigned long r15; | |
| }; | |
| long long int r1514; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r16; | |
| unsigned long r17; | |
| }; | |
| long long int r1716; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r18; | |
| unsigned long r19; | |
| }; | |
| long long int r1918; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r20; | |
| unsigned long r21; | |
| }; | |
| long long int r2120; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r22; | |
| unsigned long r23; | |
| }; | |
| long long int r2322; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r24; | |
| unsigned long r25; | |
| }; | |
| long long int r2524; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r26; | |
| unsigned long r27; | |
| }; | |
| long long int r2726; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r28; | |
| unsigned long r29; | |
| }; | |
| long long int r2928; | |
| }; | |
| union { | |
| struct { | |
| unsigned long r30; | |
| unsigned long r31; | |
| }; | |
| long long int r3130; | |
| }; | |
| /* VM dispatch pushes event record onto stack - we can build on it */ | |
| struct hvm_event_record hvmer; | |
| }; | |
| /* Defines to conveniently access the values */ | |
| /* | |
| * As of the VM spec 0.5, these registers are now set/retrieved via a | |
| * VM call. On the in-bound side, we just fetch the values | |
| * at the entry points and stuff them into the old record in pt_regs. | |
| * However, on the outbound side, probably at VM rte, we set the | |
| * registers back. | |
| */ | |
| #define pt_elr(regs) ((regs)->hvmer.vmel) | |
| #define pt_set_elr(regs, val) ((regs)->hvmer.vmel = (val)) | |
| #define pt_cause(regs) ((regs)->hvmer.vmest & (HVM_VMEST_CAUSE_MSK)) | |
| #define user_mode(regs) \ | |
| (((regs)->hvmer.vmest & (HVM_VMEST_UM_MSK << HVM_VMEST_UM_SFT)) != 0) | |
| #define ints_enabled(regs) \ | |
| (((regs)->hvmer.vmest & (HVM_VMEST_IE_MSK << HVM_VMEST_IE_SFT)) != 0) | |
| #define pt_psp(regs) ((regs)->hvmer.vmpsp) | |
| #define pt_badva(regs) ((regs)->hvmer.vmbadva) | |
| #define pt_set_singlestep(regs) ((regs)->hvmer.vmest |= (1<<HVM_VMEST_SS_SFT)) | |
| #define pt_clr_singlestep(regs) ((regs)->hvmer.vmest &= ~(1<<HVM_VMEST_SS_SFT)) | |
| #define pt_set_rte_sp(regs, sp) do {\ | |
| pt_psp(regs) = (regs)->r29 = (sp);\ | |
| } while (0) | |
| #define pt_set_kmode(regs) \ | |
| (regs)->hvmer.vmest = (HVM_VMEST_IE_MSK << HVM_VMEST_IE_SFT) | |
| #define pt_set_usermode(regs) \ | |
| (regs)->hvmer.vmest = (HVM_VMEST_UM_MSK << HVM_VMEST_UM_SFT) \ | |
| | (HVM_VMEST_IE_MSK << HVM_VMEST_IE_SFT) | |
| #endif /* ifndef __ASSEMBLY */ | |
| #endif |