UPDATE 2: short answer is rdmsr 0x00030200
. The harder question is how to determine the "MSR" values? this is done by using ARM64_WINDBG_SYSREG macro which is defined as follows:
#define ARM64_WINDBG_SYSREG(op0, op1, crn, crm, op2) \
( ((op0) << 16) | \
((op1) << 12) | \
((crn) << 8) | \
((crm) << 4) | \
((op2) << 0) )
or in python:
def ARM64_WINDBG_SYSREG(op0, op1, crn, crm, op2):
return ( ((op0) << 16) | ((op1) << 12) | ((crn) << 8) | ((crm) << 4) | ((op2) << 0) )
And by using the following arguments the result is 0x30200:
Name Op0 CRn Op1 CRm Op2 Width
TTBR0_EL1 3 c2 0 c0 0 64
As mentioned before in the comments the parameters for this macro for other System Registers or "MSRs" can be found here.
UPDATE 1:
There is also an option of looking at a cached version of the registers values through (since the registers don't change after initialization during boot then this is not a bad option):
KPCR->KPRCB->ProcessorState->ArchState
kd> !pcr
KPCR for Processor 0 at fffff803ed4a0000:
Major 1 Minor 1
Panic Stack 00000000
Dpc Stack 00000000
Irql addresses:
Mask fffff803ed4a0000
Table fffff803ed4a0000
Routine fffff803ed4a0000
kd> dt nt!_KARM64_ARCH_STATE fffff803ed4a0000+0x980+0x40+0xa0
+0x000 Midr_El1 : 0x410fd4c0
+0x008 Sctlr_El1 : 0x30d0595d
+0x010 Actlr_El1 : 0
+0x018 Cpacr_El1 : 0x300000
+0x020 Tcr_El1 : 0x00000015`b5513511
+0x028 Ttbr0_El1 : 0x00010000`008ef000
+0x030 Ttbr1_El1 : 0x00010000`008ef800
+0x038 Esr_El1 : 0xf200f002
+0x040 Far_El1 : 0xffff8180`ed005540
+0x048 Pmcr_El0 : 0
+0x050 Pmcntenset_El0 : 0
+0x058 Pmccntr_El0 : 0
+0x060 Pmxevcntr_El0 : [31] 0
+0x158 Pmxevtyper_El0 : [31] 0
+0x250 Pmovsclr_El0 : 0
+0x258 Pmselr_El0 : 0
+0x260 Pmuserenr_El0 : 0
+0x268 Mair_El1 : 0x444400ff`444400ff
+0x270 Vbar_El1 : 0xfffff803`f1a02800
Original Answer:
Short answer is, AFAIK there isn't currently a way to do that.
I think it might be implemented in the future.
You would expect that arm64 should have a command like rdmsr 0xc0000082
to read these system registers like ttbr0_el1 but unfortunately I couldn't find one.
Alternatively, another option to show these registers contents would be the rm 0x4f
to set the bit mask for the r
command... but that although shows a bit more than the regular Integer registers is not the solution either.
example output for r
and rm
commands:
kd> rm
Register output mask is 4f:
2 - Integer state (64-bit)
4 - Floating-point state
8 - Debug registers
40 - NEON registers
kd> r
x0=fffff803ed538aa0 x1=fffff803ed538a30 x2=0000000000000003 x3=fffff803ed538a10
x4=0000000000000000 x5=fffff803f241c000 x6=ffffd785df80a7f0 x7=0000000000000000
x8=000000000000d7c3 x9=0000000000011000 x10=0000000000004550 x11=000000000000001f
x12=fffff803f22ad000 x13=0000000000001001 x14=ffffd785df802000 x15=0000000000000600
x16=0000000000000003 x17=fffff803ed538820 x18=fffff803f1bbba34 x19=fffff803ed538aa0
x20=fffff803ec5113c0 x21=fffff803ec5113d0 x22=fffff803f2451d00 x23=0000000000000003
x24=fffff803ed538b20 x25=fffff803f2451000 x26=fffff803ed538b20 x27=fffff803f1800000
x28=0000000000000000 fp=fffff803ed538a20 lr=fffff803f1b373d4 sp=fffff803ed538a20
pc=fffff803f1a08908 psr=60000044 -ZC- EL1
d0= 2.13309995079e-313 d1= 8.33242166252e-316
d2= 6.22223872451e+088 d3= 1.39791210144e-308
d4= 1.88719426152e+122 d5= 5.12400221257e+102
d6= 8.33215452122e-316 d7= 6.94122434598e+228
d8= 0 d9= 0
d10= 0 d11= 0
d12= 0 d13= 0
d14= 0 d15= 0
d16= 0 d17= -3.19883464952e+307
d18= 1.24348953375e-311 d19= 3.60833840091e-313
d20= 0 d21= 0
d22= 0 d23= 0
d24= 6.99621747986e+253 d25= -1.37025872537e+182
d26= 4.46817589305e+076 d27= 0.0184873304943
d28= 7.13506166131e+257 d29= -6.03392682883e-270
d30= 2.36740574464e+237 d31= 1.80548526765e+125
q0=0 0 1.4013e-044 7.06966e-031
q1=2.82689e+023 2.24208e-044 0 6.80798e-033
q2=3365.96 2.22601e+011 2.39744e+011 49.3168
q3=845.255 3.36312e-044 9.23136e-040 8.4754e+011
q4=9.23133e-040 3381.34 3.69912e+015 5.99516e+010
q5=1.34876e+013 837109 1.33523e+013 3.36312e-044
q6=7.0696e+028 3.36312e-044 0 6.80401e-033
q7=3.60554e-042 6.97764e+022 7.49922e+028 1.69282e+022
q8=0 0 0 0
q9=0 0 0 0
q10=0 0 0 0
q11=0 0 0 0
q12=0 0 0 0
q13=0 0 0 0
q14=0 0 0 0
q15=0 0 0 0
q16=0 0 0 0
q17=-1.#QNAN -1.94827e+019 -1.#QNAN 0
q18=4.62428e-044 4.2039e-044 8.21161e-043 6.96445e-043
q19=4.2039e-044 1.4013e-045 2.38221e-044 3.0127e-038
q20=0 0 0 0
q21=0 0 0 0
q22=0 0 0 0
q23=0 0 0 0
q24=-1.01884e-031 -2.08158e+029 1.03368e+032 6.35816e+009
q25=-6.85105e-038 9.00862e+021 -1.13638e+023 1.93203e+022
q26=-3.64747 -6.30615e-031 7.27112e+009 -1.8081e-011
q27=-1.47062e-019 -8.19573e-019 1.1479 -0.95345
q28=9.89469e+033 -1.67433e-015 3.14073e+032 1.67504e+022
q29=-1.0893e-025 -6.0525e+022 -4.13779e-034 -3.07939e+023
q30=-2.74816e+025 -1.43784e-006 9.07498e+029 69.093
q31=-5.55539e-013 -6.043e-028 8.4819e+015 0.00020481
kbvr[0] =0000000000000000 kbcr[0] =00000000
kbvr[1] =0000000000000000 kbcr[1] =00000000
kwvr[0] =0000000000000000 kwcr[0] =00000000
What's left to do is to wait for someone to wake up in MSFT in the windbg team and hopefully do something about this, until then we are left only with debug prints and using the MRS opcode (or actually _ReadStatusReg intrinsic) such as this example:
ARM64_SYSREG is a macro defined as:
#define ARM64_SYSREG(op0, op1, crn, crm, op2) \
( ((op0 & 1) << 14) | \
((op1 & 7) << 11) | \
((crn & 15) << 7) | \
((crm & 15) << 3) | \
((op2 & 7) << 0) )
and in python:
def ARM64_SYSREG(op0, op1, crn, crm, op2):
return ( ((op0 & 1) << 14) | ((op1 & 7) << 11) | ((crn & 15) << 7) | ((crm & 15) << 3) | ((op2 & 7) << 0) )
ARM64_SYSREG purpose is to encode arguments into a unique constant that represents a system register.
You can find a mapping of all system registers and their arguments for this macro here.