forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
4.5 KiB
229 lines
4.5 KiB
/* 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
|
|
|