summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-01-23 22:48:42 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2017-01-24 15:25:14 +0100
commit8e07d6845277efb96e067306f1ec9bc378c58bc0 (patch)
tree579e455a36e85f09cfe542fc45128b53a77dbc96
parent50eaa2d9ac3e23c5212ba2d0cd1dba4a995ab2c1 (diff)
downloadrockbox-8e07d6845277efb96e067306f1ec9bc378c58bc0.tar.gz
rockbox-8e07d6845277efb96e067306f1ec9bc378c58bc0.zip
hwstub: add various jz stuff and xburst tests
The JZ misc allows to enable and test SRAM. The XBurst code uses the coprocessor interface to analyse the cpu. It also provides a test platform for various features like EBASE and exceptions. I was able to test and confirm that on jz4760b (thus xburst), EBASE works (but top 2 bits are not controllable and always 01). The processor claims to support vector interrupts but this is untested. The values in ConfigX are not to be trusted blindly, clearly some are wrong. I tried to use the JZ4780 Config7 "ebase gate" to change bit 30 of EBASE but it does not work, which suggests that JZ480 uses a newer version of XBurst. Detailled log below: > ./hwstub_shell -q -f lua/xburst.lua -e "XBURST.init()" [...] XBurst: PRId: 0x2ed0024f CPU: JZ4760(B) Config: 0x80000483 Architecture Type: MIPS32 Architecture Level: Release 2 (or more) MMU Type: Standard TLB Config1: 0x3e63318a MMU Size: 32 ICache Sets per way: 128 Ways: 4 Line size: 32 DCache Sets per way: 128 Ways: 4 Line size: 32 FPU: no Config2: 0x80000000 Config3: 0x20 Vectored interrupt: yes Config7: 0x0 > ./hwstub_shell -q -e 'require("jz/misc"); JZ.misc.enable_sram()' \ -f lua/xburst.lua -e "XBURST.test_ebase(0x80000000);XBURST.test_ebase(0xb32d0000) [...] Testing EBASE... Disable BEV SR value: 0x2000fc00 EBASE value: 0x80000000 Value after writing 0x80000000: 0x80000000 Value after writing 0x80040000: 0x80040000 Test result: EBase seems to work Disable config7 gate: write 0x0 to Config7 Value after writing 0xfffff000: 0xbffff000 Enable config7 gate: write 0x80 to Config7 Value after writing 0xc0000000: 0x80000000 Config7 result: Config7 gate does not work Exception test with EBASE at 0x80000000... Writing instructions to memory Old SR: 0x2000fc00 New SR: 0xfc00 EBASE: 80000000 Before: cafebabe After: deadbeef Exception result: Exception and EBASE are working Testing EBASE... Disable BEV SR value: 0x2000fc00 EBASE value: 0x80000000 Value after writing 0x80000000: 0x80000000 Value after writing 0x80040000: 0x80040000 Test result: EBase seems to work Disable config7 gate: write 0x0 to Config7 Value after writing 0xfffff000: 0xbffff000 Enable config7 gate: write 0x80 to Config7 Value after writing 0xc0000000: 0x80000000 Config7 result: Config7 gate does not work Exception test with EBASE at 0xb32d0000... Writing instructions to memory Old SR: 0x2000fc00 New SR: 0xfc00 EBASE: b32d0000 Before: cafebabe After: deadbeef Exception result: Exception and EBASE are working Change-Id: I894227981a141a8c14419b36ed9f519baf145ad1
-rw-r--r--utils/hwstub/tools/lua/jz/misc.lua43
-rw-r--r--utils/hwstub/tools/lua/xburst.lua238
2 files changed, 281 insertions, 0 deletions
diff --git a/utils/hwstub/tools/lua/jz/misc.lua b/utils/hwstub/tools/lua/jz/misc.lua
new file mode 100644
index 0000000000..fb4185de33
--- /dev/null
+++ b/utils/hwstub/tools/lua/jz/misc.lua
@@ -0,0 +1,43 @@
1----------
2-- MISC --
3----------
4
5JZ.misc = {}
6
7function JZ.misc.enable_sram()
8 HW.CPM.CLKGATE1.SRAM.clr()
9 HW.CPM.CLKGATE1.AHB1.clr()
10end
11
12function JZ.misc.test_sram()
13 DEV.write32(0xb32d0000, 0xaaaa5555)
14 if DEV.read32(0xb32d0000) ~= 0xaaaa5555 then
15 error("SRAM is not working")
16 end
17 DEV.write32(0xb32d0000, 0xdeadbeef)
18 if DEV.read32(0xb32d0000) ~= 0xdeadbeef then
19 error("SRAM is not working")
20 end
21 print("SRAM seems to be working")
22 size = 0
23 for i=4,64*1024,4 do
24 DEV.write32(0xb32d0000, 0xdeadbeef)
25 DEV.write32(0xb32d0000 + i, 0xcafebabe)
26 if DEV.read32(0xb32d0000 + i) ~= 0xcafebabe or DEV.read32(0xb32d0000) == 0xcafebabe then
27 size = i
28 break
29 end
30 end
31 print(string.format("SRAM size: 0x%x (%d KiB)", size, size / 1024))
32 -- double check
33 for i=0,size-1,2 do
34 DEV.write16(0xb32d0000 + i, i)
35 end
36 for i=0,size-1,2 do
37 if DEV.read16(0xb32d0000 + i) ~= i then
38 error(string.format("SRAM size is not confirmed: read @%x gives %d instead of %d",
39 0xb32d0000 + i, DEV.read16(0xb32d0000 + i), i))
40 end
41 end
42 print("SRAM size confirmed and working")
43end
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