summaryrefslogtreecommitdiff
path: root/utils/hwstub/tools/lua/xburst.lua
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/tools/lua/xburst.lua')
-rw-r--r--utils/hwstub/tools/lua/xburst.lua238
1 files changed, 238 insertions, 0 deletions
diff --git a/utils/hwstub/tools/lua/xburst.lua b/utils/hwstub/tools/lua/xburst.lua
new file mode 100644
index 0000000000..ddaf7fbc66
--- /dev/null
+++ b/utils/hwstub/tools/lua/xburst.lua
@@ -0,0 +1,238 @@
1XBURST = {}
2
3function XBURST.read_cp0(reg, sel)
4 return DEV.read32_cop({0, reg, sel})
5end
6
7function XBURST.write_cp0(reg, sel, val)
8 DEV.write32_cop({0, reg, sel}, val)
9end
10
11XBURST.prid_table = {
12 [0x0ad0024f] = "JZ4740",
13 [0x1ed0024f] = "JZ4755",
14 [0x2ed0024f] = "JZ4760(B)",
15 [0x3ee1024f] = "JZ4780"
16}
17
18XBURST.at_table = {
19 [0] = "MIPS32",
20 [1] = "MIPS64 with 32-bit segments",
21 [2] = "MIPS64"
22}
23
24XBURST.ar_table = {
25 [0] = "Release 1",
26 [1] = "Release 2 (or more)"
27}
28
29XBURST.mt_table = {
30 [0] = "None",
31 [1] = "Standard TLB",
32 [2] = "BAT",
33 [3] = "Fixed Mapping",
34 [4] = "Dual VTLB and FTLB"
35}
36
37XBURST.is_table = {
38 [0] = 64,
39 [1] = 128,
40 [2] = 256,
41 [3] = 512,
42 [4] = 1024,
43 [5] = 2048,
44 [6] = 4096,
45 [7] = 32
46}
47
48XBURST.il_table = {
49 [0] = 0,
50 [1] = 4,
51 [2] = 8,
52 [3] = 16,
53 [4] = 32,
54 [5] = 64,
55 [6] = 128
56}
57
58function XBURST.get_table_or(tbl, index, dflt)
59 if tbl[index] ~= nil then
60 return tbl[index]
61 else
62 return dflt
63 end
64end
65
66function XBURST.do_ebase_test()
67 XBURST.write_cp0(15, 1, 0x80000000)
68 print(string.format(" Value after writing 0x80000000: 0x%x", XBURST.read_cp0(15, 1)))
69 if XBURST.read_cp0(15, 1) ~= 0x80000000 then
70 return "Value 0x8000000 does not stick, EBASE is probably not working"
71 end
72 XBURST.write_cp0(15, 1, 0x80040000)
73 print(string.format(" Value after writing 0x80040000: 0x%x", XBURST.read_cp0(15, 1)))
74 if XBURST.read_cp0(15, 1) ~= 0x80040000 then
75 return "Value 0x80040000 does not stick, EBASE is probably not working"
76 end
77 return "EBase seems to work"
78end
79
80function XBURST.do_ebase_cfg7gate_test()
81 -- test gate in config7
82 config7_old = XBURST.read_cp0(16, 7)
83 XBURST.write_cp0(16, 7, bit32.replace(config7_old, 0, 7)) -- disable EBASE[30] modification
84 print(string.format(" Disable config7 gate: write 0x%x to Config7", bit32.replace(config7_old, 0, 7)))
85 XBURST.write_cp0(15, 1, 0xfffff000)
86 print(string.format(" Value after writing 0xfffff000: 0x%x", XBURST.read_cp0(15, 1)))
87 if XBURST.read_cp0(15, 1) == 0xfffff000 then
88 return "Config7 gate has no effect but modifications are allowed anyway"
89 end
90 XBURST.write_cp0(16, 7, bit32.replace(config7_old, 1, 7)) -- enable EBASE[30] modification
91 print(string.format(" Enable config7 gate: write 0x%x to Config7", bit32.replace(config7_old, 1, 7)))
92 XBURST.write_cp0(15, 1, 0xc0000000)
93 print(string.format(" Value after writing 0xc0000000: 0x%x", XBURST.read_cp0(15, 1)))
94 if XBURST.read_cp0(15, 1) ~= 0xc0000000 then
95 return "Config7 gate does not work"
96 end
97 XBURST.write_cp0(16, 7, config7_old)
98 return "Config7 gate seems to work"
99end
100
101function XBURST.do_ebase_exc_test(mem_addr)
102 if (mem_addr % 0x1000) ~= 0 then
103 return " memory address for exception test must aligned on a 0x1000 boundary";
104 end
105 print(string.format("Exception test with EBASE at 0x%x...", mem_addr))
106 print(" Writing instructions to memory")
107 -- create instructions in memory
108 exc_addr = mem_addr + 0x180 -- general exception vector
109 data_addr = mem_addr + 0x300
110 -- lui k0,<low part of data_addr>
111 -- ori k0,k0,<high part>
112 DEV.write32(exc_addr + 0, 0x3c1a0000 + bit32.rshift(data_addr, 16))
113 DEV.write32(exc_addr + 4, 0x375a0000 + bit32.band(data_addr, 0xffff))
114 -- lui k1,0xdead
115 -- ori k1,k1,0xbeef
116 DEV.write32(exc_addr + 8, 0x3c1bdead)
117 DEV.write32(exc_addr + 12, 0x377bbeef)
118 -- sw k1,0(k0)
119 DEV.write32(exc_addr + 16, 0xaf5b0000)
120 -- mfc0 k0,c0_epc
121 -- addi k0,k0,4
122 -- mtc0 k0,c0_epc
123 DEV.write32(exc_addr + 20, 0x401a7000)
124 DEV.write32(exc_addr + 24, 0x235a0004)
125 DEV.write32(exc_addr + 28, 0x409a7000)
126 -- eret
127 -- nop
128 DEV.write32(exc_addr + 32, 0x42000018)
129 DEV.write32(exc_addr + 36, 0)
130 -- fill data with some initial value
131 DEV.write32(data_addr, 0xcafebabe)
132 -- write instructions to trigger an interrupt
133 bug_addr = mem_addr
134 -- syscall
135 DEV.write32(bug_addr + 0, 0x0000000c)
136 -- jr ra
137 -- nop
138 DEV.write32(bug_addr + 4, 0x03e00008)
139 DEV.write32(bug_addr + 8, 0)
140
141 -- make sure we are the right shape for the test: SR should have BEV cleared,
142 -- mask all interrupts, enable interrupts
143 old_sr = XBURST.read_cp0(12, 0)
144 print(string.format(" Old SR: 0x%x", old_sr))
145 XBURST.write_cp0(12, 0, 0xfc00) -- BEV set to 0, all interrupts masked and interrupt disabled
146 print(string.format(" New SR: 0x%x", XBURST.read_cp0(12, 0)))
147 -- change EBASE
148 old_ebase = XBURST.read_cp0(15, 1)
149 XBURST.write_cp0(15, 1, mem_addr)
150 print(string.format(" EBASE: %x", XBURST.read_cp0(15, 1)))
151 -- test
152 print(string.format(" Before: %x", DEV.read32(data_addr)))
153 DEV.call(bug_addr)
154 print(string.format(" After: %x", DEV.read32(data_addr)))
155 success = DEV.read32(data_addr) == 0xdeadbeef
156 -- restore SR and EBASE
157 XBURST.write_cp0(12, 0, old_sr)
158 XBURST.write_cp0(15, 1, ebase_old)
159
160 return success and "Exception and EBASE are working" or "Exception and EBASE are NOT working"
161end
162
163function XBURST.test_ebase(mem_addr)
164 -- EBase
165 ebase_old = XBURST.read_cp0(15, 1)
166 sr_old = XBURST.read_cp0(12, 0)
167 print("Testing EBASE...")
168 print(" Disable BEV")
169 XBURST.write_cp0(12, 0, bit32.replace(sr_old, 0, 22)) -- clear BEV
170 print(string.format(" SR value: 0x%x", XBURST.read_cp0(12, 0)))
171 print(string.format(" EBASE value: 0x%x", ebase_old))
172 print(" Test result: " .. XBURST.do_ebase_test())
173 print(" Config7 result: " .. XBURST.do_ebase_cfg7gate_test())
174 XBURST.write_cp0(12, 0, sr_old)
175 XBURST.write_cp0(15, 1, ebase_old)
176 -- now try with actual exceptions
177 if mem_addr == nil then
178 print(" Not doing exception test, please specify memory to use: sram, ram")
179 return
180 end
181 print(" Exception result: " .. XBURST.do_ebase_exc_test(mem_addr))
182end
183
184function XBURST.init()
185 -- enable CP1 in SR
186 sr_old = XBURST.read_cp0(12, 0)
187 XBURST.write_cp0(12, 0, bit32.replace(sr_old, 1, 29)) -- set CU1
188 print("XBurst:")
189 -- PRId
190 XBURST.prid = XBURST.read_cp0(15, 0)
191 print(string.format(" PRId: 0x%x", XBURST.prid))
192 print(" CPU: " .. XBURST.get_table_or(XBURST.prid_table, XBURST.prid, "unknown"))
193 -- Config
194 XBURST.config = XBURST.read_cp0(16, 0)
195 print(string.format(" Config: 0x%x", XBURST.config))
196 print(" Architecture Type: " .. XBURST.get_table_or(XBURST.at_table,
197 bit32.extract(XBURST.config, 13, 2), "unknown"))
198 print(" Architecture Level: " .. XBURST.get_table_or(XBURST.ar_table,
199 bit32.extract(XBURST.config, 10, 3), "unknown"))
200 print(" MMU Type: " .. XBURST.get_table_or(XBURST.mt_table,
201 bit32.extract(XBURST.config, 7, 3), "unknown"))
202 -- Config1
203 XBURST.config1 = XBURST.read_cp0(16, 1)
204 print(string.format(" Config1: 0x%x", XBURST.config1))
205 -- don't print of no MMU
206 if bit32.extract(XBURST.config, 7, 3) ~= 0 then
207 print(string.format(" MMU Size: %d", bit32.extract(XBURST.config1, 25, 6) + 1))
208 end
209 print(" ICache")
210 print(" Sets per way: " .. XBURST.get_table_or(XBURST.is_table,
211 bit32.extract(XBURST.config1, 22, 3), "unknown"))
212 print(" Ways: " .. (1 + bit32.extract(XBURST.config1, 16, 3)))
213 print(" Line size: " .. XBURST.get_table_or(XBURST.il_table,
214 bit32.extract(XBURST.config1, 19, 3), "unknown"))
215 print(" DCache")
216 print(" Sets per way: " .. XBURST.get_table_or(XBURST.is_table,
217 bit32.extract(XBURST.config1, 13, 3), "unknown"))
218 print(" Ways: " .. (1 + bit32.extract(XBURST.config1, 7, 3)))
219 print(" Line size: " .. XBURST.get_table_or(XBURST.il_table,
220 bit32.extract(XBURST.config1, 10, 3), "unknown"))
221 print(" FPU: " .. (bit32.extract(XBURST.config1, 0) == 1 and "yes" or "no"))
222
223 -- Config 2
224 XBURST.config2 = XBURST.read_cp0(16, 2)
225 print(string.format(" Config2: 0x%x", XBURST.config2))
226
227 -- Config 3
228 XBURST.config3 = XBURST.read_cp0(16, 3)
229 print(string.format(" Config3: 0x%x", XBURST.config3))
230 print(" Vectored interrupt: " .. (bit32.extract(XBURST.config2, 5) and "yes" or "no"))
231
232 -- Config 7
233 XBURST.config7 = XBURST.read_cp0(16, 7)
234 print(string.format(" Config7: 0x%x", XBURST.config7))
235
236 -- restore SR
237 XBURST.write_cp0(12, 0, sr_old)
238end