From cf8aa3fed958f2368be671c78dcb9b056c035bad Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sun, 16 Jan 2022 21:55:00 +0100 Subject: [PATCH] Map special registers Backported from https://github.com/Ebiroll/ghidra-xtensa. --- data/languages/xtensa.sinc | 113 +++++++++++++++++++++++-- data/languages/xtensaInstructions.sinc | 29 ++++--- 2 files changed, 119 insertions(+), 23 deletions(-) diff --git a/data/languages/xtensa.sinc b/data/languages/xtensa.sinc index 860c9f7..5989c96 100644 --- a/data/languages/xtensa.sinc +++ b/data/languages/xtensa.sinc @@ -4,28 +4,52 @@ define alignment=1; define space ram type=ram_space size=4 default; define space register type=register_space size=4; +# Special registers (SR). Not all are actually 32 bit, but for the sake of +# simplicity they are here. +define register offset=0x00 size=4 [ LBEG LEND LCOUNT SAR BR LITBASE ]; +define register offset=0x30 size=4 [ SCOMPARE1 ]; +define register offset=0x40 size=4 [ ACCLO ACCHI ]; +define register offset=0x80 size=4 [ M0 M1 M2 M3 ]; +define register offset=0x120 size=4 [ WindowBase WindowStart ]; +define register offset=0x14c size=4 [ PTEVADDR ]; +define register offset=0x164 size=4 [ MMID RASID ITLBCFG DTLBCFG ]; +define register offset=0x180 size=4 [ IBREAKENABLE ]; +define register offset=0x184 size=4 [ MEMCTL ]; +define register offset=0x188 size=4 [ CACHEATTR ATOMCTL ]; +define register offset=0x1a0 size=4 [ DDR ]; +define register offset=0x1a8 size=4 [ MEPC MEPS MESAVE MESR MECR MEVADDR ]; +define register offset=0x200 size=4 [ IBREAKA0 IBREAKA1 ]; +define register offset=0x240 size=4 [ DBREAKA0 DBREAKA1 ]; +define register offset=0x280 size=4 [ DBREAKC0 DBREAKC1 ]; +define register offset=0x2c4 size=4 [ EPC1 EPC2 EPC3 EPC4 EPC5 EPC6 EPC7 ]; +define register offset=0x300 size=4 [ DEPC ]; +define register offset=0x308 size=4 [ EPS2 EPS3 EPS4 EPS5 EPS6 EPS7 ]; +define register offset=0x344 size=4 [ EXCSAVE1 EXCSAVE2 EXCSAVE3 EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 ]; +define register offset=0x380 size=4 [ CPENABLE ]; +define register offset=0x384 size=4 [ INTERRUPT INTSET INTCLEAR INTENABLE ]; +define register offset=0x398 size=4 [ PS VECBASE EXCCAUSE DEBUGCAUSE CCOUNT PRID ICOUNT ICOUNTLEVEL EXCVADDR ]; +define register offset=0x3c0 size=4 [ CCOMPARE0 CCOMPARE1 CCOMPARE2 ]; +define register offset=0x3d0 size=4 [ MISC0 MISC1 MISC2 MISC3 ]; + # Address registers (AR). -define register offset=0x0000 size=4 [ +define register offset=0x8000 size=4 [ a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 ]; # Floating Point registers (FR + FCR (control) + FSR (status)). # TODO: FCR and FSR seem unused? -define register offset=0x0100 size=4 [ +define register offset=0x8100 size=4 [ f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 fcr fsr ]; # Boolean registers (BR). -define register offset=0x0200 size=1 [ +define register offset=0x8200 size=1 [ b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 ]; # Program counter. -define register offset=0x1000 size=4 [ pc ]; - -# Shift amount register. (TODO: other special registers) -define register offset=0x2000 size=1 [ sar ]; +define register offset=0x8300 size=4 [ pc ]; # Regular 24-bit instruction. define token insn(24) @@ -37,6 +61,7 @@ define token insn(24) as = (8,11) fs = (8,11) bs = (8,11) + sr = (8,15) at = (4,7) ft = (4,7) bt = (4,7) @@ -94,6 +119,78 @@ define token narrowinsn(16) ; +attach variables [ sr ] [ +# 0x...0 0x...4 0x...8 0x...c + LBEG LEND LCOUNT SAR # 0x0_ + BR LITBASE _ _ # 0x1_ + _ _ _ _ # 0x2_ + SCOMPARE1 _ _ _ # 0x3_ + ACCLO ACCHI _ _ # 0x4_ + _ _ _ _ # 0x5_ + _ _ _ _ # 0x6_ + _ _ _ _ # 0x7_ + M0 M1 M2 M3 # 0x8_ + _ _ _ _ # 0x9_ + _ _ _ _ # 0xa_ + _ _ _ _ # 0xb_ + _ _ _ _ # 0xc_ + _ _ _ _ # 0xd_ + _ _ _ _ # 0xe_ + _ _ _ _ # 0xf_ +# 0x...0 0x...4 0x...8 0x...c + _ _ _ _ # 0x10_ + _ _ _ _ # 0x11_ + WindowBase WindowStart _ _ # 0x12_ + _ _ _ _ # 0x13_ + _ _ _ PTEVADDR # 0x14_ + _ _ _ _ # 0x15_ + _ MMID RASID ITLBCFG # 0x16_ + DTLBCFG _ _ _ # 0x17_ + IBREAKENABLE MEMCTL CACHEATTR ATOMCTL # 0x18_ + _ _ _ _ # 0x19_ + DDR _ MEPC MEPS # 0x1a_ + MESAVE MESR MECR MEVADDR # 0x1b_ + _ _ _ _ # 0x1c_ + _ _ _ _ # 0x1d_ + _ _ _ _ # 0x1e_ + _ _ _ _ # 0x1f_ +# 0x...0 0x...4 0x...8 0x...c + IBREAKA0 IBREAKA1 _ _ # 0x20_ + _ _ _ _ # 0x21_ + _ _ _ _ # 0x22_ + _ _ _ _ # 0x23_ + DBREAKA0 DBREAKA1 _ _ # 0x24_ + _ _ _ _ # 0x25_ + _ _ _ _ # 0x26_ + _ _ _ _ # 0x27_ + DBREAKC0 DBREAKC1 _ _ # 0x28_ + _ _ _ _ # 0x29_ + _ _ _ _ # 0x2a_ + _ _ _ _ # 0x2b_ + _ EPC1 EPC2 EPC3 # 0x2c_ + EPC4 EPC5 EPC6 EPC7 # 0x2d_ + _ _ _ _ # 0x2e_ + _ _ _ _ # 0x2f_ +# 0x...0 0x...4 0x...8 0x...c + DEPC _ EPS2 EPS3 # 0x30_ + EPS4 EPS5 EPS6 EPS7 # 0x31_ + _ _ _ _ # 0x32_ + _ _ _ _ # 0x33_ + _ EXCSAVE1 EXCSAVE2 EXCSAVE3 # 0x34_ + EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 # 0x35_ + _ _ _ _ # 0x36_ + _ _ _ _ # 0x37_ + CPENABLE INTERRUPT INTSET INTCLEAR # 0x38_ + INTENABLE _ PS VECBASE # 0x39_ + EXCCAUSE DEBUGCAUSE CCOUNT PRID # 0x3a_ + ICOUNT ICOUNTLEVEL EXCVADDR _ # 0x3b_ + CCOMPARE0 CCOMPARE1 CCOMPARE2 _ # 0x3c_ + MISC0 MISC1 MISC2 MISC3 # 0x3d_ + _ _ _ _ # 0x3e_ + _ _ _ _ # 0x3f_ +# 0x...0 0x...4 0x...8 0x...c +]; + attach variables [ ar as at n_ar n_as n_at ] [ a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 ]; @@ -260,7 +357,6 @@ define pcodeop rfwu; define pcodeop ritlb0; define pcodeop ritlb1; define pcodeop rsil; -define pcodeop rsr; # TODO: Map known special registers. define pcodeop rsync; define pcodeop rur; define pcodeop s32c1i; @@ -274,6 +370,5 @@ define pcodeop waiti; define pcodeop wdtlb; define pcodeop wer; define pcodeop witlb; -define pcodeop wsr; # TODO: Map known special registers. define pcodeop wur; define pcodeop xsr; diff --git a/data/languages/xtensaInstructions.sinc b/data/languages/xtensaInstructions.sinc index 7c4d599..54ae7f6 100644 --- a/data/languages/xtensaInstructions.sinc +++ b/data/languages/xtensaInstructions.sinc @@ -1005,8 +1005,9 @@ macro extract_bit(val, bit, result) { } # RSR - Read Special Register, pg. 500. -:rsr at, u8_8.15 is op0 = 0 & op1 = 0b0011 & u8_8.15 & at & op0 = 0 { - at = rsr(u8_8.15:1); +:rsr at, sr is op0 = 0 & op1 = 0b0011 & sr & at & op0 = 0 { + local src:4 = zext(sr); + at = *[register]:4 src; } # RSYNC - Register Read Synchronize, pg. 502. @@ -1085,7 +1086,7 @@ macro extract_bit(val, bit, result) { # SLL - Shift Left Logical, pg. 524. :sll ar, as is op2 = 0b1010 & op1 = 0b0001 & ar & as & at = 0 & op0 = 0 { - local sa:1 = 32 - sar; + local sa = 32 - SAR; ar = as << sa; } @@ -1096,7 +1097,7 @@ macro extract_bit(val, bit, result) { # SRA - Shift Right Arithmetic, pg. 526. :sra ar, at is op2 = 0b1011 & op1 = 0b0001 & ar & as = 0 & at & op0 = 0 { - ar = at s>> sar; + ar = at s>> SAR; } # SRAI - Shift Right Arithmetic Immediate, pg. 527. @@ -1109,13 +1110,13 @@ macro extract_bit(val, bit, result) { local s64:8 = zext(as); local t64:8 = zext(at); local combined:8 = (s64 << 32) | t64; - local shifted:8 = combined >> sar; + local shifted:8 = combined >> SAR; ar = shifted:4; } # SRL - Shift Right Logical, pg. 529. :srl ar, at is op2 = 0b1001 & op1 = 0b0001 & ar & as = 0 & at & op0 = 0 { - ar = at >> sar; + ar = at >> SAR; } # SRLI - Shift Right Logical Immediate, pg. 530. @@ -1126,18 +1127,17 @@ macro extract_bit(val, bit, result) { # SSA8B - Set Shift Amount for BE Byte Shift, pg. 531. :ssa8b as is op2 = 0b0100 & op1 = 0 & ar = 0b0011 & as & at = 0 & op0 = 0 { local lsa:4 = (as&3)*8; - sar = 32 - lsa:1; + SAR = 32 - lsa; } # SSA8L - Set Shift Amount for LE Byte Shift, pg. 532. :ssa8l as is op2 = 0b0100 & op1 = 0 & ar = 0b0010 & as & at = 0 & op0 = 0 { - local rsa:4 = (as&3)*8; - sar = rsa:1; + SAR = (as&3)*8; } # SSAI - Set Shift Amount Immediate, pg. 533. :ssai u5_8.11_4 is op2 = 0b0100 & op1 = 0 & ar = 0b0100 & u5_8.11_4 & u3_5.7 = 0 & op0 = 0 { - sar = u5_8.11_4:1; + SAR = zext(u5_8.11_4); } # SSI - Store Single Immediate, pg. 534. @@ -1155,12 +1155,12 @@ macro extract_bit(val, bit, result) { # SSL - Set Shift Amount for Left Shift, pg. 538. :ssl as is op2 = 0b0100 & op1 = 0 & ar = 0b0001 & as & at = 0 & op0 = 0 { - sar = 32 - (as:1 & 0x1f); + SAR = 32 - (as & 0x1f); } # SSR - Set Shift Amount for Right Shift, pg. 539. :ssr as is op2 = 0b0100 & op1 = 0 & ar = 0 & as & at = 0 & op0 = 0 { - sar = (as:1 & 0x1f); + SAR = (as & 0x1f); } # SSX - Store Singe Indexed, pg. 540. @@ -1278,8 +1278,9 @@ macro extract_bit(val, bit, result) { } # WSR - Write Special Register, pg. 561. -:wsr at, u8_8.15 is op2 = 0b0001 & op1 = 0b0011 & u8_8.15 & at & op0 = 0 { - wsr(u8_8.15:1, at); +:wsr at, sr is op2 = 0b0001 & op1 = 0b0011 & sr & at & op0 = 0 { + local dst:4 = zext(sr); + *[register]:4 dst = at; } # WUR - Write User Register, pg. 563.