new general reg changes and headers

This commit is contained in:
quackerd 2024-11-03 14:33:30 -05:00
parent ae5541ce16
commit b5ac633a9e
11 changed files with 456 additions and 336 deletions

View File

@ -6,53 +6,53 @@
#define MCODE ALIGNED(16) __attribute__((section("mcode"))) #define MCODE ALIGNED(16) __attribute__((section("mcode")))
#define MDATA __attribute__((section("mdata"))) #define MDATA __attribute__((section("mdata")))
#define METAL_REG_MSTK (METAL_REG_MG8) #if defined(DECL_MRT)
#undef DECL_MRT
#if defined(DECL_MROUTINE) #define DECL_MRT(name) void MCODE name(void)
#undef DECL_MROUTINE
#define DECL_MROUTINE(name) void MCODE name(void)
#endif #endif
#if defined(IMPL_MROUTINE) #define MGREG_MSTK (MCREG_MG16)
#undef IMPL_MROUTINE
#define IMPL_MROUTINE(name) int MCODE _ ## name ## _impl(void); \ #if defined(IMPL_MRT)
#undef IMPL_MRT
#define IMPL_MRT(name) int MCODE _ ## name ## _impl(void); \
__asm__ ( \ __asm__ ( \
".section \"mcode\";" \ ".section \"mcode\";" \
".globl " _METAL_STR(name) ";" \ ".globl " METAL_STR(name) ";" \
".balign 16;" \ ".balign 16;" \
_METAL_STR(name) ":;" \ METAL_STR(name) ":;" \
METAL_RMR_GAS(METAL_REG_MSTK, AARCH_REG_X0) \ METAL_STR(RMR_GAS(MGREG_MSTK, REG_X0)) ";" \
"mov x1, sp;" \ "mov x1, sp;" \
"str x1, [x0, #-16]!;" \ "str x1, [x0, #-16]!;" \
"mov sp, x0;" \ "mov sp, x0;" \
"mov x0, xzr;" \ "mov x0, xzr;" \
"ldr x0,=_" _METAL_STR(name) "_impl;" \ "ldr x0,=_" METAL_STR(name) "_impl;" \
"blr x0;" \ "blr x0;" \
"ldr x1, [sp], #16;" \ "ldr x1, [sp], #16;" \
"mov sp, x1;" \ "mov sp, x1;" \
METAL_WMR_GAS(METAL_REG_MR0, AARCH_REG_X0) \ METAL_STR(WMR_GAS(MREG_MR0, REG_X0)) ";" \
METAL_MEXIT_GAS(METAL_REG_MR0) \ METAL_STR(MEXIT_GAS(MREG_MR0)) ";" \
); \ ); \
int MCODE _ ## name ## _impl(void) int MCODE _ ## name ## _impl(void)
#endif #endif
#define IMPL_SHORT_MROUTINE(name) int MCODE _ ## name ## _impl(void); \ #define IMPL_SHORT_MRT(name) int MCODE _ ## name ## _impl(void); \
__asm__ ( \ __asm__ ( \
".section \"mcode\";" \ ".section \"mcode\";" \
".globl " _METAL_STR(name) ";" \ ".globl " METAL_STR(name) ";" \
".balign 16;" \ ".balign 16;" \
_METAL_STR(name) ":;" \ METAL_STR(name) ":;" \
"mov x0, xzr;" \ "mov x0, xzr;" \
"ldr x0,=_" _METAL_STR(name) "_impl;" \ "ldr x0,=_" METAL_STR(name) "_impl;" \
"blr x0;" \ "blr x0;" \
METAL_WMR_GAS(METAL_REG_MR0, AARCH_REG_X0) \ METAL_STR(WMR_GAS(MREG_MR0, REG_X0)) ";" \
METAL_MEXIT_GAS(METAL_REG_MR0) \ METAL_STR(MEXIT_GAS(MREG_MR0)) ";" \
); \ ); \
int MCODE _ ## name ## _impl(void) int MCODE _ ## name ## _impl(void)
#define DECL_MVAR(type, name) type MDATA name #define DECL_MVAR(type, name) type MDATA name
#define DECL_MVAR_ALIGNED(type, name, align) type ALIGNED(align) MDATA name #define DECL_MVAR_ALIGNED(type, name, align) type ALIGNED(align) MDATA name
#define METAL_REG_MPTB_DMAP (METAL_REG_MG6) #define MGREG_MPTB_DMAP (MCREG_MG19)
#define METAL_REG_MPTB_XMEM (METAL_REG_MG7) #define MGREG_MPTB_XMEM (MCREG_MG18)
#define METAL_REG_MPTB_USER (METAL_REG_MG5) #define MGREG_MPTB_USER (MCREG_MG17)

View File

@ -1,102 +1,149 @@
#pragma once #pragma once
#define AARCH_REG_X0 (0)
#define AARCH_REG_X1 (1)
#define AARCH_REG_X2 (2)
#define AARCH_REG_X3 (3)
#define AARCH_REG_X4 (4)
#define AARCH_REG_X5 (5)
#define AARCH_REG_X6 (6)
#define AARCH_REG_X7 (7)
#define AARCH_REG_X8 (8)
#define AARCH_REG_X9 (9)
#define AARCH_REG_X10 (10)
#define AARCH_REG_X11 (11)
#define AARCH_REG_X12 (12)
#define AARCH_REG_X13 (13)
#define AARCH_REG_X14 (14)
#define AARCH_REG_X15 (15)
#define AARCH_REG_X16 (16)
#define AARCH_REG_X17 (17)
#define AARCH_REG_X18 (18)
#define AARCH_REG_X19 (19)
#define AARCH_REG_X20 (20)
#define AARCH_REG_X21 (21)
#define AARCH_REG_X22 (22)
#define AARCH_REG_X23 (23)
#define AARCH_REG_X24 (24)
#define AARCH_REG_X25 (25)
#define AARCH_REG_X26 (26)
#define AARCH_REG_X27 (27)
#define AARCH_REG_X28 (28)
#define AARCH_REG_X29 (29)
#define AARCH_REG_X30 (30)
#define AARCH_REG_X31 (31)
#define METAL_REG_MO0 (0) // aarch64 regs
#define METAL_REG_MO1 (1) #define REG_X0 (0)
#define METAL_REG_MO2 (2) #define REG_X1 (1)
#define METAL_REG_MO3 (3) #define REG_X2 (2)
#define METAL_REG_MO4 (4) #define REG_X3 (3)
#define METAL_REG_MO5 (5) #define REG_X4 (4)
#define METAL_REG_MR0 (6) #define REG_X5 (5)
#define METAL_REG_MR1 (7) #define REG_X6 (6)
#define METAL_REG_MR2 (8) #define REG_X7 (7)
#define METAL_REG_MR3 (9) #define REG_X8 (8)
#define METAL_REG_MI0 (10) #define REG_X9 (9)
#define METAL_REG_MI1 (11) #define REG_X10 (10)
#define METAL_REG_MI2 (12) #define REG_X11 (11)
#define METAL_REG_MI3 (13) #define REG_X12 (12)
#define METAL_REG_MI4 (14) #define REG_X13 (13)
#define METAL_REG_MI5 (15) #define REG_X14 (14)
#define METAL_REG_MLR (METAL_REG_MI5) #define REG_X15 (15)
#define METAL_REG_MIR0 (METAL_REG_MI0) #define REG_X16 (16)
#define METAL_REG_MIR1 (METAL_REG_MI1) #define REG_X17 (17)
#define METAL_REG_MIR2 (METAL_REG_MI2) #define REG_X18 (18)
#define METAL_REG_MER0 (METAL_REG_MI0) #define REG_X19 (19)
#define METAL_REG_MER1 (METAL_REG_MI1) #define REG_X20 (20)
#define METAL_REG_MER2 (METAL_REG_MI2) #define REG_X21 (21)
#define METAL_REG_MSPSR (METAL_REG_MI3) #define REG_X22 (22)
#define METAL_REG_MSR (16) #define REG_X23 (23)
#define METAL_REG_MBR (17) #define REG_X24 (24)
#define METAL_REG_MIB (18) #define REG_X25 (25)
#define METAL_REG_MEB (19) #define REG_X26 (26)
#define METAL_REG_MTP (20) #define REG_X27 (27)
#define METAL_REG_MG5 (21) #define REG_X28 (28)
#define METAL_REG_MG6 (22) #define REG_X29 (29)
#define METAL_REG_MG7 (23) #define REG_X30 (30)
#define METAL_REG_MG8 (24) #define REG_X31 (31)
#define METAL_REG_MG9 (25)
#define METAL_REG_MG10 (26) // Metal general regs
#define METAL_REG_MG11 (27) #define MREG_MO0 (0)
#define METAL_REG_MG12 (28) #define MREG_MO1 (1)
#define METAL_REG_MG13 (29) #define MREG_MO2 (2)
#define METAL_REG_MG14 (30) #define MREG_MO3 (3)
#define METAL_REG_MG15 (31) #define MREG_MO4 (4)
#define MREG_MO5 (5)
#define MREG_MO6 (6)
#define MREG_MO7 (7)
#define MREG_MO8 (8)
#define MREG_MO9 (9)
#define MREG_MR0 (10)
#define MREG_MR1 (11)
#define MREG_MR2 (12)
#define MREG_MR3 (13)
#define MREG_MR4 (14)
#define MREG_MR5 (15)
#define MREG_MR6 (16)
#define MREG_MR7 (17)
#define MREG_MR8 (18)
#define MREG_MR9 (19)
#define MREG_MR10 (20)
#define MREG_MR11 (21)
#define MREG_MI0 (22)
#define MREG_MI1 (23)
#define MREG_MI2 (24)
#define MREG_MI3 (25)
#define MREG_MI4 (26)
#define MREG_MI5 (27)
#define MREG_MI6 (28)
#define MREG_MI7 (29)
#define MREG_MI8 (30)
#define MREG_MI9 (31)
// aliases
#define MREG_MLR (MREG_MI9)
#define MREG_MIR0 (MREG_MI0)
#define MREG_MIR1 (MREG_MI1)
#define MREG_MIR2 (MREG_MI2)
#define MREG_MER0 (MREG_MI0)
#define MREG_MER1 (MREG_MI1)
#define MREG_MER2 (MREG_MI2)
#define MREG_MSPSR (MREG_MI3)
// metal control regs
#define MCREG_MG0 (0)
#define MCREG_MG1 (1)
#define MCREG_MG2 (2)
#define MCREG_MG3 (3)
#define MCREG_MG4 (4)
#define MCREG_MG5 (5)
#define MCREG_MG6 (6)
#define MCREG_MG7 (7)
#define MCREG_MG8 (8)
#define MCREG_MG9 (9)
#define MCREG_MG10 (10)
#define MCREG_MG11 (11)
#define MCREG_MG12 (12)
#define MCREG_MG13 (13)
#define MCREG_MG14 (14)
#define MCREG_MG15 (15)
#define MCREG_MG16 (16)
#define MCREG_MG17 (17)
#define MCREG_MG18 (18)
#define MCREG_MG19 (19)
#define MCREG_MG20 (20)
#define MCREG_MG21 (21)
#define MCREG_MG22 (22)
#define MCREG_MG23 (23)
#define MCREG_MG24 (24)
#define MCREG_MG25 (25)
#define MCREG_MG26 (26)
#define MCREG_MG27 (27)
#define MCREG_MG28 (28)
#define MCREG_MG29 (29)
#define MCREG_MG30 (30)
#define MCREG_MG31 (31)
// aliases
#define MCREG_MSR (MCREG_MG0)
#define MCREG_MBR (MCREG_MG1)
#define MCREG_MIB (MCREG_MG2)
#define MCREG_MEB (MCREG_MG3)
#define MCREG_MTP (MCREG_MG4)
#define MCREG_MAR (MCREG_MG5)
#define _METAL_STR(x) #x #define _METAL_STR(x) #x
#define METAL_STR(x) _METAL_STR(x) #define METAL_STR(x) _METAL_STR(x)
#define _METAL_GAS_ENCODE(x) ".word " METAL_STR(x) ";" #define _METAL_GAS_ENCODE(x) .word x
#define METAL_GAS_ENCODE(x) _METAL_GAS_ENCODE(x) #define METAL_GAS_ENCODE(x) _METAL_GAS_ENCODE(x)
// metal insts defs // metal insts defs
#define METAL_WMR_ENCODING(mreg, greg) (0xd61f2C00 | ((mreg) << 5) | ((greg) << 0)) #define WMR_ENCODING(mreg, greg) (0xd61f2C00 | ((mreg) << 5) | ((greg) << 0))
#define METAL_WMR_GAS(mreg, greg) METAL_GAS_ENCODE(METAL_WMR_ENCODING(mreg, greg)) #define WMR_GAS(mreg, greg) METAL_GAS_ENCODE(WMR_ENCODING(mreg, greg))
#define MASM_WMR(mreg, greg) .word METAL_WMR_ENCODING(mreg, greg) #define WMR(reg, var) do { __asm__ volatile (\
#define METAL_WMR(reg, var) do { __asm__ volatile (\
"mov x0, %x0;" \ "mov x0, %x0;" \
METAL_WMR_GAS(reg, AARCH_REG_X0)\ METAL_STR(WMR_GAS(reg, REG_X0)) ";" \
: \ : \
: "r" (var)\ : "r" (var)\
: "x0" \ : "x0" \
); } while(0) ); } while(0)
#define METAL_RMR_ENCODING(mreg, greg) (0xd61f2800 | ((mreg) << 5) | ((greg) << 0))
#define METAL_RMR_GAS(mreg, greg) METAL_GAS_ENCODE(METAL_RMR_ENCODING(mreg,greg)) #define RMR_ENCODING(mreg, greg) (0xd61f2800 | ((mreg) << 5) | ((greg) << 0))
#define MASM_RMR(mreg, greg) .word METAL_RMR_ENCODING(mreg, greg) #define RMR_GAS(mreg, greg) METAL_GAS_ENCODE(RMR_ENCODING(mreg, greg))
#define METAL_RMR(reg, var) do { \ #define RMR(reg, var) do { __asm__ volatile ( \
__asm__ volatile ( \ METAL_STR(RMR_GAS(reg, REG_X0)) ";" \
METAL_RMR_GAS(reg, AARCH_REG_X0) \ "mov %x0, x0;" \
"mov %x0, x0;"\
: "+r" (var) \ : "+r" (var) \
: \ : \
: "x0" \ : "x0" \
@ -111,22 +158,22 @@
// //
// we do this using the mroutine stub function to wrap mroutine calls // we do this using the mroutine stub function to wrap mroutine calls
// //
#define METAL_MENTER_ENCODING(mroutine) (0xd61f2000 | ((mroutine) << 0)) #define MENTER_ENCODING(mroutine) (0xd61f2000 | ((mroutine) << 0))
#define METAL_MENTER_GAS(mroutine) METAL_GAS_ENCODE(METAL_MENTER_ENCODING(mroutine)) #define MENTER_GAS(mroutine) METAL_GAS_ENCODE(MENTER_ENCODING(mroutine))
#define METAL_MENTER(mroutine) do { \ #define MENTER(mroutine) do { \
__asm__ volatile ( \ __asm__ volatile ( \
METAL_MENTER_GAS(mroutine) \ METAL_STR(MENTER_GAS(mroutine)) \
: \ : \
: \ : \
: \ : \
); \ ); \
} while(0) } while(0)
#define METAL_MEXIT_ENCODING(mreg) (0xd61f2400 | ((mreg) << 0)) #define MEXIT_ENCODING(mreg) (0xd61f2400 | ((mreg) << 0))
#define METAL_MEXIT_GAS(mreg) METAL_GAS_ENCODE(METAL_MEXIT_ENCODING(mreg)) #define MEXIT_GAS(mreg) METAL_GAS_ENCODE(MEXIT_ENCODING(mreg))
#define METAL_MEXIT(mreg) do { \ #define MEXIT(mreg) do { \
__asm__ volatile ( \ __asm__ volatile ( \
METAL_MEXIT_GAS(mreg) \ METAL_STR(MEXIT_GAS(mreg)) \
: \ : \
: \ : \
: \ : \
@ -139,85 +186,79 @@
// do not provide C version of RAR/WAR for the current bank // do not provide C version of RAR/WAR for the current bank
// can't decide which GP register to use as temp // can't decide which GP register to use as temp
#define METAL_RAR_ENCODING(idxmreg, dstmreg) (0xd61f3000 | ((idxmreg) << 5) | ((dstmreg) << 0)) #define RAR_ENCODING(idxmreg, dstmreg) (0xd61f3000 | ((idxmreg) << 5) | ((dstmreg) << 0))
#define METAL_RAR_GAS(idxmreg, dstmreg) METAL_GAS_ENCODE(METAL_RAR_ENCODING(idxmreg, dstmreg)) #define RAR_GAS(idxmreg, dstmreg) METAL_GAS_ENCODE(RAR_ENCODING(idxmreg, dstmreg))
#define METAL_WAR_ENCODING(idxmreg, srcmreg) (0xd61f3400 | ((idxmreg) << 5) | ((srcmreg) << 0)) #define WAR_ENCODING(idxmreg, srcmreg) (0xd61f3400 | ((idxmreg) << 5) | ((srcmreg) << 0))
#define METAL_WAR_GAS(idxmreg, dstmreg) METAL_GAS_ENCODE(METAL_WAR_ENCODING(idxmreg, dstmreg)) #define WAR_GAS(idxmreg, dstmreg) METAL_GAS_ENCODE(WAR_ENCODING(idxmreg, dstmreg))
#define METAL_RPR_ENCODING(idxmreg, dstmreg) (0xd61f4000 | ((idxmreg) << 5) | ((dstmreg) << 0)) #define RPR_ENCODING(idxmreg, dstmreg) (0xd61f4000 | ((idxmreg) << 5) | ((dstmreg) << 0))
#define METAL_RPR_GAS(idxmreg, dstmreg) METAL_GAS_ENCODE(METAL_RPR_ENCODING(idxmreg, dstmreg)) #define RPR_GAS(idxmreg, dstmreg) METAL_GAS_ENCODE(RPR_ENCODING(idxmreg, dstmreg))
#define METAL_RPR(idxvar, var) do { __asm__ volatile (\ #define RPR(idxvar, var) do { __asm__ volatile (\
METAL_RMR_GAS(METAL_REG_MR0, AARCH_REG_X1) \ METAL_STR(RMR_GAS(MREG_MR0, REG_X1)) ";" \
METAL_RMR_GAS(METAL_REG_MR1, AARCH_REG_X2) \ METAL_STR(RMR_GAS(MREG_MR1, REG_X2)) ";" \
\
"mov x0, %x1;" \ "mov x0, %x1;" \
METAL_WMR_GAS(METAL_REG_MR0, AARCH_REG_X0) \ METAL_STR(WMR_GAS(MREG_MR0, REG_X0)) ";" \
METAL_RPR_GAS(METAL_REG_MR0, METAL_REG_MR1) \ METAL_STR(RPR_GAS(MREG_MR0, MREG_MR1)) ";" \
METAL_RMR_GAS(METAL_REG_MR1, AARCH_REG_X0) \ METAL_STR(RMR_GAS(MREG_MR1, REG_X0)) ";" \
"mov %x0, x0;" \ "mov %x0, x0;" \
\ METAL_STR(WMR_GAS(MREG_MR0, REG_X1)) ";" \
METAL_WMR_GAS(METAL_REG_MR0, AARCH_REG_X1) \ METAL_STR(WMR_GAS(MREG_MR1, REG_X2)) ";" \
METAL_WMR_GAS(METAL_REG_MR1, AARCH_REG_X2) \
: "+r" (var) \ : "+r" (var) \
: "r" (idxvar)\ : "r" (idxvar)\
: "x0", "x1", "x2" \ : "x0", "x1", "x2" \
); } while(0) ); } while(0)
#define METAL_WPR_ENCODING(idxmreg, srcmreg) (0xd61f4400 | ((idxmreg) << 5) | ((srcmreg) << 0)) #define WPR_ENCODING(idxmreg, srcmreg) (0xd61f4400 | ((idxmreg) << 5) | ((srcmreg) << 0))
#define METAL_WPR_GAS(idxmreg, srcmreg) METAL_GAS_ENCODE(METAL_WPR_ENCODING(idxmreg, srcmreg)) #define WPR_GAS(idxmreg, srcmreg) METAL_GAS_ENCODE(WPR_ENCODING(idxmreg, srcmreg))
#define METAL_WPR(idxvar, var) do { __asm__ volatile (\ #define WPR(idxvar, var) do { __asm__ volatile (\
METAL_RMR_GAS(METAL_REG_MR0, AARCH_REG_X1) \ METAL_STR(RMR_GAS(MREG_MR0, REG_X1)) ";" \
METAL_RMR_GAS(METAL_REG_MR1, AARCH_REG_X2) \ METAL_STR(RMR_GAS(MREG_MR1, REG_X2)) ";" \
\ \
"mov x0, %x0;" \ "mov x0, %x0;" \
METAL_WMR_GAS(METAL_REG_MR0, AARCH_REG_X0) \ METAL_STR(WMR_GAS(MREG_MR0, REG_X0)) ";" \
"mov x0, %x1;" \ "mov x0, %x1;" \
METAL_WMR_GAS(METAL_REG_MR1, AARCH_REG_X0) \ METAL_STR(WMR_GAS(MREG_MR1, REG_X0)) ";" \
\ \
METAL_WPR_GAS(METAL_REG_MR0, METAL_REG_MR1) \ METAL_STR(WPR_GAS(MREG_MR0, MREG_MR1)) ";" \
\ \
METAL_WMR_GAS(METAL_REG_MR0, AARCH_REG_X1) \ METAL_STR(WMR_GAS(MREG_MR0, REG_X1)) ";" \
METAL_WMR_GAS(METAL_REG_MR1, AARCH_REG_X2) \ METAL_STR(WMR_GAS(MREG_MR1, REG_X2)) ";" \
: \ : \
: "r" (idxvar), "r" (var) \ : "r" (idxvar), "r" (var) \
: "x0", "x1", "x2" \ : "x0", "x1", "x2" \
); } while(0) ); } while(0)
#define METAL_MCLI_ENCODING (0xd61f3800) #define RMCR_ENCODING(mreg, greg) (0xd61f3800 | ((mreg) << 5) | ((greg) << 0))
#define METAL_MCLI_GAS METAL_GAS_ENCODE(METAL_MCLI_ENCODING) #define RMCR_GAS(mreg, greg) METAL_GAS_ENCODE(RMCR_ENCODING(mreg, greg))
#define METAL_MCLI do { \ #define RMCR(reg, var) do { __asm__ volatile ( \
__asm__ volatile ( \ METAL_STR(RMCR_GAS(reg, REG_X0)) ";" \
METAL_MCLI_GAS \ "mov %x0, x0;" \
: \ : "+r" (var) \
: \
: \ : \
: "x0" \
); } while(0) ); } while(0)
#define METAL_MSTI_ENCODING (0xd61f3C00) #define WMCR_ENCODING(mreg, greg) (0xd61f3C00 | ((mreg) << 5) | ((greg) << 0))
#define METAL_MSTI_GAS METAL_GAS_ENCODE(METAL_MSTI_ENCODING) #define WMCR_GAS(mreg, greg) METAL_GAS_ENCODE(WMCR_ENCODING(mreg, greg))
#define METAL_MSTI do { \ #define WMCR(reg, var) do { __asm__ volatile (\
__asm__ volatile ( \ "mov x0, %x0;" \
METAL_MSTI_GAS \ METAL_STR(WMCR_GAS(reg, REG_X0)) ";" \
: \
: \
: \ : \
: "r" (var)\
: "x0" \
); } while(0) ); } while(0)
#define _METAL_WTLB_SHIFT_RM (0) #define WTLB_ENCODING(rl, rn, rm) (0xd63f8000 | (rl << 10) | (rn << 5) | (rm << 0))
#define _METAL_WTLB_SHIFT_RN (5) #define WTLB_GAS(rl, rn, rm) METAL_GAS_ENCODE(WTLB_ENCODING(rl, rn, rm))
#define _METAL_WTLB_SHIFT_RL (10) #define WTLB(descreg, inforeg, vaddrreg) do { __asm__ volatile (\
#define _METAL_WTLB_ENCODING(rl, rn, rm) ".word " METAL_STR(0xd63f8000 | (rl << _METAL_WTLB_SHIFT_RL) | (rn << _METAL_WTLB_SHIFT_RN) | (rm << _METAL_WTLB_SHIFT_RM)) METAL_STR(WTLB_GAS(descreg, vaddrreg, inforeg))); \
#define METAL_WTLB(descreg, inforeg, vaddrreg) do { __asm__ volatile (\
_METAL_WTLB_ENCODING(descreg, vaddrreg, inforeg)); \
} while (0) } while (0)
#define _METAL_RTLB_SHIFT_RM (0) #define RTLB_ENCODING(rl, rn, rm) (0xd61f8000 | (rl << 10) | (rn << 5) | (rm << 0))
#define _METAL_RTLB_SHIFT_RN (5) #define RTLB_GAS(rl, rn, rm) METAL_GAS_ENCODE(RTLB_ENCODING(rl, rn, rm))
#define _METAL_RTLB_SHIFT_RL (10) #define RTLB(descreg, inforeg, vaddrreg) do { __asm__ volatile (\
#define _METAL_RTLB_ENCODING(rl, rn, rm) ".word " METAL_STR(0xd61f8000 | (rl << _METAL_RTLB_SHIFT_RL) | (rn << _METAL_RTLB_SHIFT_RN) | (rm << _METAL_RTLB_SHIFT_RM)) METAL_STR(RTLB_GAS(descreg, vaddrreg, inforeg))); \
#define METAL_RTLB(descreg, inforeg, vaddrreg) do { __asm__ volatile (\
_METAL_RTLB_ENCODING(descreg, vaddrreg, inforeg)); \
} while (0) } while (0)
@ -226,55 +267,55 @@
#define METAL_PMEMOP_MODE_POST (2) #define METAL_PMEMOP_MODE_POST (2)
// PSTR // PSTR
#define _METAL_PSTR_TEMPLATE(var, paddr, cmd) do { __asm__ volatile (\ #define _PSTR_TEMPLATE(var, paddr, cmd) do { __asm__ volatile (\
"mov x0, %x0;" \ "mov x0, %x0;" \
"mov x1, %x1;" \ "mov x1, %x1;" \
"mov x2, #0;" \ "mov x2, #0;" \
cmd \ METAL_STR(cmd) ";" \
: \ : \
: "r" (var), "r" (paddr) \ : "r" (var), "r" (paddr) \
: "x0", "x1", "x2" \ : "x0", "x1", "x2" \
); } while (0) ); } while (0)
#define METAL_PSTRR8_ENCODING(dReg, bReg, oReg) (0x8c400000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10)) #define PSTRR8_ENCODING(dReg, bReg, oReg) (0x8c400000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10))
#define METAL_PSTRR8_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(METAL_PSTRR8_ENCODING(dReg, bReg, oReg)) #define PSTRR8_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(PSTRR8_ENCODING(dReg, bReg, oReg))
#define METAL_PSTR8(var, paddr) _METAL_PSTR_TEMPLATE(var, paddr, METAL_PSTRR8_GAS(AARCH_REG_X0, AARCH_REG_X1, AARCH_REG_X2)) #define PSTR8(var, paddr) _PSTR_TEMPLATE(var, paddr, PSTRR8_GAS(REG_X0, REG_X1, REG_X2))
#define METAL_PSTRR16_ENCODING(dReg, bReg, oReg) (0x8cc00000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10)) #define PSTRR16_ENCODING(dReg, bReg, oReg) (0x8cc00000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10))
#define METAL_PSTRR16_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(METAL_PSTRR16_ENCODING(dReg, bReg, oReg)) #define PSTRR16_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(PSTRR16_ENCODING(dReg, bReg, oReg))
#define METAL_PSTR16(var, paddr) _METAL_PSTR_TEMPLATE(var, paddr, METAL_PSTRR16_GAS(AARCH_REG_X0, AARCH_REG_X1, AARCH_REG_X2)) #define PSTR16(var, paddr) _PSTR_TEMPLATE(var, paddr, PSTRR16_GAS(REG_X0, REG_X1, REG_X2))
#define METAL_PSTRR32_ENCODING(dReg, bReg, oReg) (0x8d400000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10)) #define PSTRR32_ENCODING(dReg, bReg, oReg) (0x8d400000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10))
#define METAL_PSTRR32_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(METAL_PSTRR32_ENCODING(dReg, bReg, oReg)) #define PSTRR32_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(PSTRR32_ENCODING(dReg, bReg, oReg))
#define METAL_PSTR32(var, paddr) _METAL_PSTR_TEMPLATE(var, paddr, METAL_PSTRR32_GAS(AARCH_REG_X0, AARCH_REG_X1, AARCH_REG_X2)) #define PSTR32(var, paddr) _PSTR_TEMPLATE(var, paddr, PSTRR32_GAS(REG_X0, REG_X1, REG_X2))
#define METAL_PSTRR64_ENCODING(dReg, bReg, oReg) (0x8dc00000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10)) #define PSTRR64_ENCODING(dReg, bReg, oReg) (0x8dc00000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10))
#define METAL_PSTRR64_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(METAL_PSTRR64_ENCODING(dReg, bReg, oReg)) #define PSTRR64_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(PSTRR64_ENCODING(dReg, bReg, oReg))
#define METAL_PSTR64(var, paddr) _METAL_PSTR_TEMPLATE(var, paddr, METAL_PSTRR64_GAS(AARCH_REG_X0, AARCH_REG_X1, AARCH_REG_X2)) #define PSTR64(var, paddr) _PSTR_TEMPLATE(var, paddr, PSTRR64_GAS(REG_X0, REG_X1, REG_X2))
// PLDR // PLDR
#define _METAL_PLDR_TEMPLATE(var, paddr, cmd) do { __asm__ volatile (\ #define _PLDR_TEMPLATE(var, paddr, cmd) do { __asm__ volatile (\
"mov x1, %x1;" \ "mov x1, %x1;" \
"mov x2, #0;" \ "mov x2, #0;" \
cmd \ METAL_STR(cmd) ";" \
"mov %x0, x0;" \ "mov %x0, x0;" \
: "+r" (var) \ : "+r" (var) \
: "r" (paddr) \ : "r" (paddr) \
: "x0", "x1", "x2" \ : "x0", "x1", "x2" \
); } while (0) ); } while (0)
#define METAL_PLDRR8_ENCODING(dReg, bReg, oReg) (0x8c000000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10)) #define PLDRR8_ENCODING(dReg, bReg, oReg) (0x8c000000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10))
#define METAL_PLDRR8_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(METAL_PLDRR8_ENCODING(dReg, bReg, oReg)) #define PLDRR8_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(PLDRR8_ENCODING(dReg, bReg, oReg))
#define METAL_PLDR8(var, paddr) _METAL_PLDR_TEMPLATE(var, paddr, METAL_PLDRR8_GAS(AARCH_REG_X0, AARCH_REG_X1, AARCH_REG_X2)) #define PLDR8(var, paddr) _PLDR_TEMPLATE(var, paddr, PLDRR8_GAS(REG_X0, REG_X1, REG_X2))
#define METAL_PLDRR16_ENCODING(dReg, bReg, oReg) (0x8c800000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10)) #define PLDRR16_ENCODING(dReg, bReg, oReg) (0x8c800000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10))
#define METAL_PLDRR16_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(METAL_PLDRR16_ENCODING(dReg, bReg, oReg)) #define PLDRR16_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(PLDRR16_ENCODING(dReg, bReg, oReg))
#define METAL_PLDR16(var, paddr) _METAL_PLDR_TEMPLATE(var, paddr, METAL_PLDRR16_GAS(AARCH_REG_X0, AARCH_REG_X1, AARCH_REG_X2)) #define PLDR16(var, paddr) _PLDR_TEMPLATE(var, paddr, PLDRR16_GAS(REG_X0, REG_X1, REG_X2))
#define METAL_PLDRR32_ENCODING(dReg, bReg, oReg) (0x8d000000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10)) #define PLDRR32_ENCODING(dReg, bReg, oReg) (0x8d000000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10))
#define METAL_PLDRR32_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(METAL_PLDRR32_ENCODING(dReg, bReg, oReg)) #define PLDRR32_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(PLDRR32_ENCODING(dReg, bReg, oReg))
#define METAL_PLDR32(var, paddr) _METAL_PLDR_TEMPLATE(var, paddr, METAL_PLDRR32_GAS(AARCH_REG_X0, AARCH_REG_X1, AARCH_REG_X2)) #define PLDR32(var, paddr) _PLDR_TEMPLATE(var, paddr, PLDRR32_GAS(REG_X0, REG_X1, REG_X2))
#define METAL_PLDRR64_ENCODING(dReg, bReg, oReg) (0x8d800000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10)) #define PLDRR64_ENCODING(dReg, bReg, oReg) (0x8d800000 | ((dReg) << 0) | ((bReg) << 5) | ((oReg) << 10))
#define METAL_PLDRR64_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(METAL_PLDRR64_ENCODING(dReg, bReg, oReg)) #define PLDRR64_GAS(dReg, bReg, oReg) METAL_GAS_ENCODE(PLDRR64_ENCODING(dReg, bReg, oReg))
#define METAL_PLDR64(var, paddr) _METAL_PLDR_TEMPLATE(var, paddr, METAL_PLDRR64_GAS(AARCH_REG_X0, AARCH_REG_X1, AARCH_REG_X2)) #define PLDR64(var, paddr) _PLDR_TEMPLATE(var, paddr, PLDRR64_GAS(REG_X0, REG_X1, REG_X2))

View File

@ -6,58 +6,55 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <machine/metalasm.h> #include "metalasm.h"
// Mroutine helpers // Mroutine helpers
// can get MI0-MI4, MI5 is link reg // can get MI0-MI8, MI9 is link reg
// MR23 = link register #define MRT_GETARG(idx, var) do { \
#define METAL_MROUTINE_GETARG(idx, var) do { \ _Static_assert(idx < (MREG_MI8 - MREG_MI0)); \
_Static_assert(idx < (METAL_REG_MI4 - METAL_REG_MI0)); \ RMR(MREG_MI0 + idx, var); \
METAL_RMR(METAL_REG_MI0 + idx, var); \
} while(0) } while(0)
// can set MO0-MO4, MO5 is Link Reg // can set MO0-MO8, MO9 is link reg (callee's MI9)
// MR7 is link register #define MRT_SETARG(idx, var) do { \
#define METAL_MROUTINE_SETARG(idx, var) do { \ _Static_assert(idx < (MREG_MO8 - MREG_MO0)); \
_Static_assert(idx < (METAL_REG_MO4 - METAL_REG_MO0)); \ WMR(MREG_MO0 + idx, var); \
METAL_WMR(METAL_REG_MO0 + idx, var); \
} while(0) } while(0)
// mroutine defs #define MRT_SETRET(idx, var) do { \
#define METAL_MROUTINE_SETRET(idx, var) do { \ _Static_assert(idx < (MREG_MI8 - MREG_MI0)); \
_Static_assert(idx < (METAL_REG_MI4 - METAL_REG_MI0)); \ WMR(MREG_MI0 + idx, var); \
METAL_WMR(METAL_REG_MI0 + idx, var); \
} while(0) } while(0)
#define METAL_MROUTINE_GETRET(idx, var) do { \ #define MRT_GETRET(idx, var) do { \
_Static_assert(idx < (METAL_REG_MO4 - METAL_REG_MO0)); \ _Static_assert(idx < (MREG_MO8 - MREG_MO0)); \
METAL_RMR(METAL_REG_MO0 + idx, var); \ RMR(MREG_MO0 + idx, var); \
} while(0) } while(0)
#define DECL_MROUTINE(name) int __attribute__((aligned(16))) name(void) #define DECL_MRT(name) int __attribute__((aligned(16))) name(void)
#define IMPL_MROUTINE(name) int _ ## name ## _impl(void); \ #define IMPL_MRT(name) int _ ## name ## _impl(void); \
__asm__ ( \ __asm__ ( \
".globl " _METAL_STR(name) ";" \ ".globl " _METAL_STR(name) ";" \
".balign 16;" \ ".balign 16;" \
_METAL_STR(name) ":;" \ _METAL_STR(name) ":;" \
"bl _" _METAL_STR(name) "_impl;" \ "bl _" _METAL_STR(name) "_impl;" \
METAL_WMR_GAS(METAL_REG_MR0, AARCH_REG_X0) \ METAL_STR(WMR_GAS(MREG_MR0, REG_X0)) ";" \
METAL_MEXIT_GAS(METAL_REG_MR0) \ METAL_STR(MEXIT_GAS(MREG_MR0)) ";" \
); \ ); \
int _ ## name ## _impl(void) int _ ## name ## _impl(void)
// mroutine table defs // mroutine table defs
#define _MROUTINE_ENTRY_CTRL_MASK_VALID (1ul) #define _MRT_ENTRY_CTRL_MASK_VALID (1ul)
#define _MROUTINE_ENTRY_CTRL_MASK_ADDR (~((1ul << 4) - 1)) #define _MRT_ENTRY_CTRL_MASK_ADDR (~((1ul << 4) - 1))
#define MROUTINE_ENTRY_MAKE(addr, valid) (((uintptr_t)addr & _MROUTINE_ENTRY_CTRL_MASK_ADDR) | (valid & _MROUTINE_ENTRY_CTRL_MASK_VALID)) #define MRT_ENTRY_MAKE(addr, valid) (((uintptr_t)addr & _MRT_ENTRY_CTRL_MASK_ADDR) | (valid & _MRT_ENTRY_CTRL_MASK_VALID))
typedef uint64_t mroutine_entry; typedef uint64_t mroutine_entry;
#define MROUTINE_TABLE_MAX_ENTRY_NUM (256) #define MRT_TABLE_MAX_ENTRY_NUM (256)
struct mroutine_table { struct mroutine_table {
mroutine_entry entries[MROUTINE_TABLE_MAX_ENTRY_NUM]; mroutine_entry entries[MRT_TABLE_MAX_ENTRY_NUM];
}; };
// inst intercept defs // inst intercept defs
@ -98,14 +95,14 @@ struct exc_intercept_table {
typedef uint64_t regval_t; typedef uint64_t regval_t;
typedef regval_t msr_t; typedef regval_t msr_t;
#define METAL_MSR_MASK_INIT (1ull << 63) #define MSR_MASK_INIT (1ull << 63)
#define METAL_MSR_MASK_II (1ull << 62) #define MSR_MASK_II (1ull << 62)
#define METAL_MSR_MASK_IM (1ull << 61) #define MSR_MASK_IM (1ull << 61)
#define METAL_MSR_MASK_EI (1ull << 60) #define MSR_MASK_EI (1ull << 60)
#define METAL_MSR_MASK_EM (1ull << 59) #define MSR_MASK_EM (1ull << 59)
#define METAL_MSR_MASK_PD (1ull << 58) #define MSR_MASK_PD (1ull << 58)
#define METAL_MSR_MASK_ID (1ull << 57) #define MSR_MASK_ID (1ull << 57)
#define METAL_MSR_MASK_LV (0xffull) #define MSR_MASK_LV (0xffull)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -3,21 +3,21 @@
#include "machine/metalp.h" #include "machine/metalp.h"
#include <machine/metal.h> #include <machine/metal.h>
DECL_MROUTINE(mrt_init); DECL_MRT(mrt_init);
#define MRT_INIT_IDX (1) #define MRT_INIT_IDX (1)
DECL_MROUTINE(mrt_pf_itlb_handler); DECL_MRT(mrt_pf_itlb_handler);
#define MRT_PF_ITLB_HANDLER_IDX (2) #define MRT_PF_ITLB_HANDLER_IDX (2)
DECL_MROUTINE(mrt_pf_dtlb_handler); DECL_MRT(mrt_pf_dtlb_handler);
#define MRT_PF_DTLB_HANDLER_IDX (3) #define MRT_PF_DTLB_HANDLER_IDX (3)
DECL_MROUTINE(mrt_dummy); DECL_MRT(mrt_dummy);
// //
// int mrt_set_mptb(int ptbidx, regval_t val); // int mrt_set_mptb(int ptbidx, regval_t val);
// //
DECL_MROUTINE(mrt_set_mptb); DECL_MRT(mrt_set_mptb);
#define MRT_SET_MPTB_IDX (4) #define MRT_SET_MPTB_IDX (4)
#define MRT_SET_MPTB_USER (0) #define MRT_SET_MPTB_USER (0)
#define MRT_SET_MPTB_DMAP (1) #define MRT_SET_MPTB_DMAP (1)
@ -30,12 +30,12 @@ DECL_MROUTINE(mrt_set_mptb);
// //
// void mrt_set_mtp(regval_t mtp); // void mrt_set_mtp(regval_t mtp);
// //
DECL_MROUTINE(mrt_set_mtp); DECL_MRT(mrt_set_mtp);
#define MRT_SET_MTP_IDX (5) #define MRT_SET_MTP_IDX (5)
#define MRT_SET_MTP_ARG_MTP (0) #define MRT_SET_MTP_ARG_MTP (0)
DECL_MROUTINE(mrt_wfi); DECL_MRT(mrt_wfi);
#define MRT_WFI_IDX (6) #define MRT_WFI_IDX (6)
extern DECL_MVAR(struct mroutine_table, mtl_mrt_tbl); extern DECL_MVAR(struct mroutine_table, mtl_mrt_tbl);

View File

@ -53,16 +53,34 @@ typedef struct TrapFrame
uint64_t mi3; uint64_t mi3;
uint64_t mi4; uint64_t mi4;
uint64_t mi5; uint64_t mi5;
uint64_t mi6;
uint64_t mi7;
uint64_t mi8;
uint64_t mi9;
uint64_t mr0; uint64_t mr0;
uint64_t mr1; uint64_t mr1;
uint64_t mr2; uint64_t mr2;
uint64_t mr3; uint64_t mr3;
uint64_t mr4;
uint64_t mr5;
uint64_t mr6;
uint64_t mr7;
uint64_t mr8;
uint64_t mr9;
uint64_t mr10;
uint64_t mr11;
uint64_t mo0; uint64_t mo0;
uint64_t mo1; uint64_t mo1;
uint64_t mo2; uint64_t mo2;
uint64_t mo3; uint64_t mo3;
uint64_t mo4; uint64_t mo4;
uint64_t mo5; uint64_t mo5;
uint64_t mo6;
uint64_t mo7;
uint64_t mo8;
uint64_t mo9;
uint64_t r0; uint64_t r0;
uint64_t r1; uint64_t r1;

View File

@ -8,14 +8,14 @@ void mtl_init(void)
// initialize metal mode // initialize metal mode
memset(&mtl_mrt_tbl, 0, sizeof(mtl_mrt_tbl)); memset(&mtl_mrt_tbl, 0, sizeof(mtl_mrt_tbl));
mtl_mrt_tbl.entries[MRT_INIT_IDX] = MROUTINE_ENTRY_MAKE(mrt_init, 1); mtl_mrt_tbl.entries[MRT_INIT_IDX] = MRT_ENTRY_MAKE(mrt_init, 1);
// load mroutine table // load mroutine table
METAL_WMR(METAL_REG_MBR, &mtl_mrt_tbl); WMCR(MCREG_MBR, &mtl_mrt_tbl);
// toggle metal mode // toggle metal mode
METAL_MENTER(MRT_INIT_IDX); MENTER(MRT_INIT_IDX);
// call dummy mroutine to cache the entries // call dummy mroutine to cache the entries
METAL_MENTER(0); MENTER(0);
} }

View File

@ -9,15 +9,15 @@ DECL_MVAR(struct inst_intercept_table, mtl_inst_tbl);
#define METAL_BOOTSTACK_SZ (4096) #define METAL_BOOTSTACK_SZ (4096)
DECL_MVAR_ALIGNED(static char, mtl_bootstack[METAL_BOOTSTACK_SZ], METAL_BOOTSTACK_SZ); DECL_MVAR_ALIGNED(static char, mtl_bootstack[METAL_BOOTSTACK_SZ], METAL_BOOTSTACK_SZ);
IMPL_SHORT_MROUTINE(mrt_dummy) IMPL_SHORT_MRT(mrt_dummy)
{ {
return 0; return 0;
} }
IMPL_SHORT_MROUTINE(mrt_wfi) IMPL_SHORT_MRT(mrt_wfi)
{ {
unsigned int times; unsigned int times;
METAL_MROUTINE_GETARG(0, times); MRT_GETARG(0, times);
while (times > 0) { while (times > 0) {
__asm__ volatile ( __asm__ volatile (
"wfi;" "wfi;"
@ -30,20 +30,20 @@ IMPL_SHORT_MROUTINE(mrt_wfi)
return 0; return 0;
} }
IMPL_SHORT_MROUTINE(mrt_init) IMPL_SHORT_MRT(mrt_init)
{ {
memset(&mtl_mrt_tbl, 0, sizeof(mtl_mrt_tbl)); memset(&mtl_mrt_tbl, 0, sizeof(mtl_mrt_tbl));
memset(&mtl_exc_tbl, 0, sizeof(mtl_exc_tbl)); memset(&mtl_exc_tbl, 0, sizeof(mtl_exc_tbl));
memset(&mtl_inst_tbl, 0, sizeof(mtl_inst_tbl)); memset(&mtl_inst_tbl, 0, sizeof(mtl_inst_tbl));
// mroutine 0 - 8 // mroutine 0 - 8
mtl_mrt_tbl.entries[0] = MROUTINE_ENTRY_MAKE(mrt_dummy, 1); mtl_mrt_tbl.entries[0] = MRT_ENTRY_MAKE(mrt_dummy, 1);
mtl_mrt_tbl.entries[MRT_INIT_IDX] = MROUTINE_ENTRY_MAKE(mrt_init, 1); mtl_mrt_tbl.entries[MRT_INIT_IDX] = MRT_ENTRY_MAKE(mrt_init, 1);
mtl_mrt_tbl.entries[MRT_PF_DTLB_HANDLER_IDX] = MROUTINE_ENTRY_MAKE(mrt_pf_dtlb_handler, 1); mtl_mrt_tbl.entries[MRT_PF_DTLB_HANDLER_IDX] = MRT_ENTRY_MAKE(mrt_pf_dtlb_handler, 1);
mtl_mrt_tbl.entries[MRT_PF_ITLB_HANDLER_IDX] = MROUTINE_ENTRY_MAKE(mrt_pf_itlb_handler, 1); mtl_mrt_tbl.entries[MRT_PF_ITLB_HANDLER_IDX] = MRT_ENTRY_MAKE(mrt_pf_itlb_handler, 1);
mtl_mrt_tbl.entries[MRT_SET_MPTB_IDX] = MROUTINE_ENTRY_MAKE(mrt_set_mptb, 1); mtl_mrt_tbl.entries[MRT_SET_MPTB_IDX] = MRT_ENTRY_MAKE(mrt_set_mptb, 1);
mtl_mrt_tbl.entries[MRT_SET_MTP_IDX] = MROUTINE_ENTRY_MAKE(mrt_set_mtp, 1); mtl_mrt_tbl.entries[MRT_SET_MTP_IDX] = MRT_ENTRY_MAKE(mrt_set_mtp, 1);
mtl_mrt_tbl.entries[MRT_WFI_IDX] = MROUTINE_ENTRY_MAKE(mrt_wfi, 1); mtl_mrt_tbl.entries[MRT_WFI_IDX] = MRT_ENTRY_MAKE(mrt_wfi, 1);
mtl_exc_tbl.entries[0].esrbits = (0b100100 << 26) | (0b00100); // data abort, lv0 translation mtl_exc_tbl.entries[0].esrbits = (0b100100 << 26) | (0b00100); // data abort, lv0 translation
mtl_exc_tbl.entries[0].esrmask = (0b111111 << 26) | (0b11111); mtl_exc_tbl.entries[0].esrmask = (0b111111 << 26) | (0b11111);
@ -95,25 +95,25 @@ IMPL_SHORT_MROUTINE(mrt_init)
// load mroutine table // load mroutine table
void* tbl_addr = &mtl_mrt_tbl; void* tbl_addr = &mtl_mrt_tbl;
METAL_WMR(METAL_REG_MBR, tbl_addr); WMCR(MCREG_MBR, tbl_addr);
// reset inst intercept table // reset inst intercept table
tbl_addr = &mtl_inst_tbl; tbl_addr = &mtl_inst_tbl;
METAL_WMR(METAL_REG_MIB, tbl_addr); WMCR(MCREG_MIB, tbl_addr);
// load exc intercept table // load exc intercept table
tbl_addr = &mtl_exc_tbl; tbl_addr = &mtl_exc_tbl;
METAL_WMR(METAL_REG_MEB, tbl_addr); WMCR(MCREG_MEB, tbl_addr);
// enable exc intercept // enable exc intercept
regval_t msr; regval_t msr;
METAL_RMR(METAL_REG_MSR, msr); RMCR(MCREG_MSR, msr);
msr |= (1ull << 60); msr |= (1ull << 60);
METAL_WMR(METAL_REG_MSR, msr); WMCR(MCREG_MSR, msr);
// temporary metal stack // temporary metal stack
regval_t mstk = (regval_t)&mtl_bootstack[METAL_BOOTSTACK_SZ]; regval_t mstk = (regval_t)&mtl_bootstack[METAL_BOOTSTACK_SZ];
METAL_WMR(METAL_REG_MSTK, mstk); WMCR(MGREG_MSTK, mstk);
return 0; return 0;
} }

View File

@ -19,13 +19,13 @@ vmm_get_ptb(vaddr_t uva, paddr_t * paddr, unsigned int * pgshift)
{ {
paddr_t addr = 0; paddr_t addr = 0;
if (uva >= MEM_USERSPACE_BASE && uva < MEM_USERSPACE_TOP) { if (uva >= MEM_USERSPACE_BASE && uva < MEM_USERSPACE_TOP) {
METAL_RMR(METAL_REG_MPTB_USER, addr); RMCR(MGREG_MPTB_USER, addr);
*pgshift = PGSHIFT; *pgshift = PGSHIFT;
} else if (uva >= MEM_DIRECTMAP_BASE && uva < MEM_DIRECTMAP_TOP) { } else if (uva >= MEM_DIRECTMAP_BASE && uva < MEM_DIRECTMAP_TOP) {
METAL_RMR(METAL_REG_MPTB_DMAP, addr); RMCR(MGREG_MPTB_DMAP, addr);
*pgshift = LARGE_PGSHIFT; *pgshift = LARGE_PGSHIFT;
} else if (uva >= MEM_XMAP_BASE && uva < MEM_XMAP_TOP) { } else if (uva >= MEM_XMAP_BASE && uva < MEM_XMAP_TOP) {
METAL_RMR(METAL_REG_MPTB_XMEM, addr); RMCR(MGREG_MPTB_XMEM, addr);
*pgshift = PGSHIFT; *pgshift = PGSHIFT;
} else { } else {
return EINVAL; return EINVAL;
@ -67,20 +67,20 @@ vmm_get_pd(paddr_t ptb, unsigned int pgshift, vaddr_t uva, paddr_t * out)
const paddr_t pte = ptb + vahash * sizeof(struct vmpte); const paddr_t pte = ptb + vahash * sizeof(struct vmpte);
paddr_t cur; paddr_t cur;
METAL_PLDR64(cur, pte + offsetof(struct vmpte, first)); PLDR64(cur, pte + offsetof(struct vmpte, first));
vaddr_t curvaddr; vaddr_t curvaddr;
uint64_t attr; uint64_t attr;
while (cur != (paddr_t)NULL) { while (cur != (paddr_t)NULL) {
METAL_PLDR64(curvaddr, cur + offsetof(struct vmpd, vaddr)); PLDR64(curvaddr, cur + offsetof(struct vmpd, vaddr));
if (vm_get_pfn(curvaddr, pgshift) == pfn) { if (vm_get_pfn(curvaddr, pgshift) == pfn) {
METAL_PLDR64(attr, cur + offsetof(struct vmpd, attr)); PLDR64(attr, cur + offsetof(struct vmpd, attr));
if (attr & VMPD_ATTR_P) { if (attr & VMPD_ATTR_P) {
*out = cur; *out = cur;
return 0; return 0;
} }
} }
METAL_PLDR64(cur, cur + offsetof(struct vmpd, next)); PLDR64(cur, cur + offsetof(struct vmpd, next));
} }
return ENOENT; return ENOENT;
@ -113,8 +113,8 @@ vmm_map_page(vaddr_t uva, int itlb)
} }
struct vmpd vmpd; struct vmpd vmpd;
METAL_PLDR64(vmpd.attr, pd + offsetof(struct vmpd, attr)); PLDR64(vmpd.attr, pd + offsetof(struct vmpd, attr));
METAL_PLDR64(vmpd.paddr, pd + offsetof(struct vmpd, paddr)); PLDR64(vmpd.paddr, pd + offsetof(struct vmpd, paddr));
// access override bits // access override bits
//AO REG for Kernel: //AO REG for Kernel:
@ -163,20 +163,20 @@ vmm_map_page(vaddr_t uva, int itlb)
(1ull << 51) | // ns = 0 (1ull << 51) | // ns = 0
(1ull << 52); // nstid = 1 (1ull << 52); // nstid = 1
METAL_WMR(METAL_REG_MR0, desc); WMR(MREG_MR0, desc);
METAL_WMR(METAL_REG_MR1, extAttrs); WMR(MREG_MR1, extAttrs);
METAL_WMR(METAL_REG_MR2, pgvaddr); WMR(MREG_MR2, pgvaddr);
METAL_WTLB(METAL_REG_MR0, METAL_REG_MR1, METAL_REG_MR2); WTLB(MREG_MR0, MREG_MR1, MREG_MR2);
return 0; return 0;
} }
// flag: skip exception intercept on the next instruction upon mreturn // flag: skip exception intercept on the next instruction upon mreturn
IMPL_MROUTINE(mrt_pf_dtlb_handler) IMPL_MRT(mrt_pf_dtlb_handler)
{ {
vaddr_t vaddr; vaddr_t vaddr;
METAL_RMR(METAL_REG_MER2, vaddr); RMR(MREG_MER2, vaddr);
if (vmm_map_page(vaddr, false) == 0) { if (vmm_map_page(vaddr, false) == 0) {
// on successful translation just RFI // on successful translation just RFI
return MEXIT_FLAG_RFI; return MEXIT_FLAG_RFI;
@ -186,11 +186,11 @@ IMPL_MROUTINE(mrt_pf_dtlb_handler)
} }
} }
IMPL_MROUTINE(mrt_pf_itlb_handler) IMPL_MRT(mrt_pf_itlb_handler)
{ {
vaddr_t vaddr; vaddr_t vaddr;
METAL_RMR(METAL_REG_MER2, vaddr); RMR(MREG_MER2, vaddr);
if (vmm_map_page(vaddr, true) == 0) { if (vmm_map_page(vaddr, true) == 0) {
return MEXIT_FLAG_RFI; return MEXIT_FLAG_RFI;
} else { } else {
@ -198,25 +198,25 @@ IMPL_MROUTINE(mrt_pf_itlb_handler)
} }
} }
IMPL_MROUTINE(mrt_set_mptb) IMPL_MRT(mrt_set_mptb)
{ {
unsigned int idx; unsigned int idx;
int ret = 0; int ret = 0;
METAL_MROUTINE_GETARG(0, idx); MRT_GETARG(0, idx);
regval_t mptb; regval_t mptb;
METAL_MROUTINE_GETARG(1, mptb); MRT_GETARG(1, mptb);
switch (idx) { switch (idx) {
case MRT_SET_MPTB_USER: { case MRT_SET_MPTB_USER: {
METAL_WMR(METAL_REG_MPTB_USER, mptb); WMCR(MGREG_MPTB_USER, mptb);
break; break;
} }
case MRT_SET_MPTB_DMAP: { case MRT_SET_MPTB_DMAP: {
METAL_WMR(METAL_REG_MPTB_DMAP, mptb); WMCR(MGREG_MPTB_DMAP, mptb);
break; break;
} }
case MRT_SET_MPTB_XMEM: { case MRT_SET_MPTB_XMEM: {
METAL_WMR(METAL_REG_MPTB_XMEM, mptb); WMCR(MGREG_MPTB_XMEM, mptb);
break; break;
} }
default: { default: {
@ -224,17 +224,17 @@ IMPL_MROUTINE(mrt_set_mptb)
} }
} }
METAL_MROUTINE_SETRET(0, ret); MRT_SETRET(0, ret);
return 0; return 0;
} }
IMPL_MROUTINE(mrt_set_mtp) IMPL_MRT(mrt_set_mtp)
{ {
uint64_t mtp; uint64_t mtp;
METAL_MROUTINE_GETARG(0, mtp); MRT_GETARG(0, mtp);
METAL_WMR(METAL_REG_MTP, mtp); WMCR(MCREG_MTP, mtp);
return 0; return 0;
} }

View File

@ -46,18 +46,18 @@ void vm_early_paging_init()
// set page table base // set page table base
paddr_t ptb = (paddr_t)DMVA2PA(&boot_pt); paddr_t ptb = (paddr_t)DMVA2PA(&boot_pt);
int idx = MRT_SET_MPTB_DMAP; int idx = MRT_SET_MPTB_DMAP;
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_IDX, idx); MRT_SETARG(MRT_SET_MPTB_ARG_IDX, idx);
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_PTB, ptb); MRT_SETARG(MRT_SET_MPTB_ARG_PTB, ptb);
METAL_MENTER(MRT_SET_MPTB_IDX); MENTER(MRT_SET_MPTB_IDX);
METAL_MROUTINE_GETRET(MRT_SET_MPTB_RET_STATUS, ret); MRT_GETRET(MRT_SET_MPTB_RET_STATUS, ret);
if (ret != 0) { if (ret != 0) {
Halt(); Halt();
} }
// set page table attribute override bits // set page table attribute override bits
uint64_t mtp = MTP_KERNEL; uint64_t mtp = MTP_KERNEL;
METAL_MROUTINE_SETARG(MRT_SET_MTP_ARG_MTP, mtp); MRT_SETARG(MRT_SET_MTP_ARG_MTP, mtp);
METAL_MENTER(MRT_SET_MTP_IDX); MENTER(MRT_SET_MTP_IDX);
// // set MAIR // // set MAIR
// #define MAIR_VAL ((0b11111111) | (0b00000000 << 8)) // #define MAIR_VAL ((0b11111111) | (0b00000000 << 8))

View File

@ -171,30 +171,30 @@ PMap_LoadAS(AS *space)
// set dmap region // set dmap region
int idx = MRT_SET_MPTB_DMAP; int idx = MRT_SET_MPTB_DMAP;
paddr_t paddr = DMVA2PA(space->dmap_tbl); paddr_t paddr = DMVA2PA(space->dmap_tbl);
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_IDX, idx); MRT_SETARG(MRT_SET_MPTB_ARG_IDX, idx);
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_PTB, paddr); MRT_SETARG(MRT_SET_MPTB_ARG_PTB, paddr);
METAL_MENTER(MRT_SET_MPTB_IDX); MENTER(MRT_SET_MPTB_IDX);
METAL_MROUTINE_GETRET(MRT_SET_MPTB_RET_STATUS, ret); MRT_GETRET(MRT_SET_MPTB_RET_STATUS, ret);
if (ret != 0) if (ret != 0)
Panic("Failed to load DMAP page table."); Panic("Failed to load DMAP page table.");
// set xmem region // set xmem region
idx = MRT_SET_MPTB_XMEM; idx = MRT_SET_MPTB_XMEM;
paddr = DMVA2PA(space->xmem_tbl); paddr = DMVA2PA(space->xmem_tbl);
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_IDX, idx); MRT_SETARG(MRT_SET_MPTB_ARG_IDX, idx);
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_PTB, paddr); MRT_SETARG(MRT_SET_MPTB_ARG_PTB, paddr);
METAL_MENTER(MRT_SET_MPTB_IDX); MENTER(MRT_SET_MPTB_IDX);
METAL_MROUTINE_GETRET(MRT_SET_MPTB_RET_STATUS, ret); MRT_GETRET(MRT_SET_MPTB_RET_STATUS, ret);
if (ret != 0) if (ret != 0)
Panic("Failed to load XMEM page table."); Panic("Failed to load XMEM page table.");
// set userspace // set userspace
idx = MRT_SET_MPTB_USER; idx = MRT_SET_MPTB_USER;
paddr = DMVA2PA(space->user_tbl); paddr = DMVA2PA(space->user_tbl);
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_IDX, idx); MRT_SETARG(MRT_SET_MPTB_ARG_IDX, idx);
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_PTB, paddr); MRT_SETARG(MRT_SET_MPTB_ARG_PTB, paddr);
METAL_MENTER(MRT_SET_MPTB_IDX); MENTER(MRT_SET_MPTB_IDX);
METAL_MROUTINE_GETRET(MRT_SET_MPTB_RET_STATUS, ret); MRT_GETRET(MRT_SET_MPTB_RET_STATUS, ret);
if (ret != 0) if (ret != 0)
Panic("Failed to load USER page table."); Panic("Failed to load USER page table.");

View File

@ -21,36 +21,68 @@
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
// Metal Registers // Metal Registers
MASM_RMR(METAL_REG_MO4, AARCH_REG_X0) RMR_GAS(MREG_MO8, REG_X0)
MASM_RMR(METAL_REG_MO5, AARCH_REG_X1) RMR_GAS(MREG_MO9, REG_X1)
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
MASM_RMR(METAL_REG_MO2, AARCH_REG_X0) RMR_GAS(MREG_MO6, REG_X0)
MASM_RMR(METAL_REG_MO3, AARCH_REG_X1) RMR_GAS(MREG_MO7, REG_X1)
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
MASM_RMR(METAL_REG_MO0, AARCH_REG_X0) RMR_GAS(MREG_MO4, REG_X0)
MASM_RMR(METAL_REG_MO1, AARCH_REG_X1) RMR_GAS(MREG_MO5, REG_X1)
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
MASM_RMR(METAL_REG_MR2, AARCH_REG_X0) RMR_GAS(MREG_MO2, REG_X0)
MASM_RMR(METAL_REG_MR3, AARCH_REG_X1) RMR_GAS(MREG_MO3, REG_X1)
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
MASM_RMR(METAL_REG_MR0, AARCH_REG_X0) RMR_GAS(MREG_MO0, REG_X0)
MASM_RMR(METAL_REG_MR1, AARCH_REG_X1) RMR_GAS(MREG_MO1, REG_X1)
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
MASM_RMR(METAL_REG_MI4, AARCH_REG_X0) RMR_GAS(MREG_MR10, REG_X0)
MASM_RMR(METAL_REG_MI5, AARCH_REG_X1) RMR_GAS(MREG_MR11, REG_X1)
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
MASM_RMR(METAL_REG_MI2, AARCH_REG_X0) RMR_GAS(MREG_MR8, REG_X0)
MASM_RMR(METAL_REG_MI3, AARCH_REG_X1) RMR_GAS(MREG_MR9, REG_X1)
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
MASM_RMR(METAL_REG_MI0, AARCH_REG_X0) RMR_GAS(MREG_MR6, REG_X0)
MASM_RMR(METAL_REG_MI1, AARCH_REG_X1) RMR_GAS(MREG_MR7, REG_X1)
stp x0, x1, [sp, #-16]!
RMR_GAS(MREG_MR4, REG_X0)
RMR_GAS(MREG_MR5, REG_X1)
stp x0, x1, [sp, #-16]!
RMR_GAS(MREG_MR2, REG_X0)
RMR_GAS(MREG_MR3, REG_X1)
stp x0, x1, [sp, #-16]!
RMR_GAS(MREG_MR0, REG_X0)
RMR_GAS(MREG_MR1, REG_X1)
stp x0, x1, [sp, #-16]!
RMR_GAS(MREG_MI8, REG_X0)
RMR_GAS(MREG_MI9, REG_X1)
stp x0, x1, [sp, #-16]!
RMR_GAS(MREG_MI6, REG_X0)
RMR_GAS(MREG_MI7, REG_X1)
stp x0, x1, [sp, #-16]!
RMR_GAS(MREG_MI4, REG_X0)
RMR_GAS(MREG_MI5, REG_X1)
stp x0, x1, [sp, #-16]!
RMR_GAS(MREG_MI2, REG_X0)
RMR_GAS(MREG_MI3, REG_X1)
stp x0, x1, [sp, #-16]!
RMR_GAS(MREG_MI0, REG_X0)
RMR_GAS(MREG_MI1, REG_X1)
stp x0, x1, [sp, #-16]! stp x0, x1, [sp, #-16]!
// ELR and SPSR // ELR and SPSR
@ -77,36 +109,68 @@
msr spsr_el1, x1 msr spsr_el1, x1
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
MASM_WMR(METAL_REG_MI0, AARCH_REG_X0) WMR_GAS(MREG_MI0, REG_X0)
MASM_WMR(METAL_REG_MI1, AARCH_REG_X1) WMR_GAS(MREG_MI1, REG_X1)
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
MASM_WMR(METAL_REG_MI2, AARCH_REG_X0) WMR_GAS(MREG_MI2, REG_X0)
MASM_WMR(METAL_REG_MI3, AARCH_REG_X1) WMR_GAS(MREG_MI3, REG_X1)
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
MASM_WMR(METAL_REG_MI4, AARCH_REG_X0) WMR_GAS(MREG_MI4, REG_X0)
MASM_WMR(METAL_REG_MI5, AARCH_REG_X1) WMR_GAS(MREG_MI5, REG_X1)
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
MASM_WMR(METAL_REG_MR0, AARCH_REG_X0) WMR_GAS(MREG_MI6, REG_X0)
MASM_WMR(METAL_REG_MR1, AARCH_REG_X1) WMR_GAS(MREG_MI7, REG_X1)
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
MASM_WMR(METAL_REG_MR2, AARCH_REG_X0) WMR_GAS(MREG_MI8, REG_X0)
MASM_WMR(METAL_REG_MR3, AARCH_REG_X1) WMR_GAS(MREG_MI9, REG_X1)
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
MASM_WMR(METAL_REG_MO0, AARCH_REG_X0) WMR_GAS(MREG_MR0, REG_X0)
MASM_WMR(METAL_REG_MO1, AARCH_REG_X1) WMR_GAS(MREG_MR1, REG_X1)
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
MASM_WMR(METAL_REG_MO2, AARCH_REG_X0) WMR_GAS(MREG_MR2, REG_X0)
MASM_WMR(METAL_REG_MO3, AARCH_REG_X1) WMR_GAS(MREG_MR3, REG_X1)
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
MASM_WMR(METAL_REG_MO4, AARCH_REG_X0) WMR_GAS(MREG_MR4, REG_X0)
MASM_WMR(METAL_REG_MO5, AARCH_REG_X1) WMR_GAS(MREG_MR5, REG_X1)
ldp x0, x1, [sp], #16
WMR_GAS(MREG_MR6, REG_X0)
WMR_GAS(MREG_MR7, REG_X1)
ldp x0, x1, [sp], #16
WMR_GAS(MREG_MR8, REG_X0)
WMR_GAS(MREG_MR9, REG_X1)
ldp x0, x1, [sp], #16
WMR_GAS(MREG_MR10, REG_X0)
WMR_GAS(MREG_MR11, REG_X1)
ldp x0, x1, [sp], #16
WMR_GAS(MREG_MO0, REG_X0)
WMR_GAS(MREG_MO1, REG_X1)
ldp x0, x1, [sp], #16
WMR_GAS(MREG_MO2, REG_X0)
WMR_GAS(MREG_MO3, REG_X1)
ldp x0, x1, [sp], #16
WMR_GAS(MREG_MO4, REG_X0)
WMR_GAS(MREG_MO5, REG_X1)
ldp x0, x1, [sp], #16
WMR_GAS(MREG_MO6, REG_X0)
WMR_GAS(MREG_MO7, REG_X1)
ldp x0, x1, [sp], #16
WMR_GAS(MREG_MO8, REG_X0)
WMR_GAS(MREG_MO9, REG_X1)
ldp x0, x1, [sp], #16 ldp x0, x1, [sp], #16
ldp x2, x3, [sp], #16 ldp x2, x3, [sp], #16