summaryrefslogtreecommitdiff
path: root/utils/hwstub
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub')
-rw-r--r--utils/hwstub/tools/lua/fiiox1.lua145
-rw-r--r--utils/hwstub/tools/lua/jz.lua4
-rw-r--r--utils/hwstub/tools/lua/jz/gpio.lua82
-rw-r--r--utils/hwstub/tools/lua/jz/lcd.lua4
-rw-r--r--utils/hwstub/tools/lua/jz/nand.lua451
5 files changed, 686 insertions, 0 deletions
diff --git a/utils/hwstub/tools/lua/fiiox1.lua b/utils/hwstub/tools/lua/fiiox1.lua
new file mode 100644
index 0000000000..c038f4077b
--- /dev/null
+++ b/utils/hwstub/tools/lua/fiiox1.lua
@@ -0,0 +1,145 @@
1--
2-- Fiio X1
3--
4FIIOX1 = {}
5
6-- 0 is PF3, 1 is PE1
7function FIIOX1.get_backlight_type()
8 return FIIOX1.bl_type
9end
10
11-- 0 is V2, 1 is V1
12function FIIOX1.get_hw_type()
13 return FIIOX1.hw_type
14end
15
16function FIIOX1.hw_detect()
17 -- PA12 is used to detect hardware version
18 JZ.gpio.pin(0, 12).std_gpio_out(1)
19 FIIOX1.hw_type = JZ.gpio.pin(0, 12).read()
20 -- PA13 is used to detect backlight type
21 JZ.gpio.pin(0, 13).std_gpio_out(1)
22 FIIOX1.bl_type = JZ.gpio.pin(0, 13).read()
23
24 if FIIOX1.hw_type == 1 then
25 print("Fiio X1: hardware version: V01")
26 else
27 print("Fiio X1: hardware version: V02")
28 end
29 print(string.format("Fiio X1: backlight type: %s", FIIOX1.bl_type))
30end
31
32function FIIOX1.get_backlight_pin()
33 if FIIOX1.get_backlight_type() == 0 then
34 -- PF3
35 return JZ.gpio.pin(5, 3)
36 else
37 -- PE1
38 return JZ.gpio.pin(4, 1)
39 end
40end
41
42function FIIOX1.init_backligt()
43 -- setup as output, high level to make no change
44 FIIOX1.get_backlight_pin().std_gpio_out(1)
45end
46
47function FIIOX1.enable_backlight(en)
48 local pin = FIIOX1.get_backlight_pin()
49 pin.clr()
50 hwstub.mdelay(1)
51 if en then
52 pin.set()
53 end
54end
55
56function FIIOX1.test_backlight()
57 print("backlight test")
58 print("enable backlight")
59 FIIOX1.enable_backlight(true)
60 print("sleep for 1 sec")
61 hwstub.mdelay(1000)
62 print("disable backlight")
63 FIIOX1.enable_backlight(false)
64 print("sleep for 1 sec")
65 hwstub.mdelay(1000)
66 print("enable backlight")
67 FIIOX1.enable_backlight(true)
68end
69
70function FIIOX1.setup_fiio_lcd_pins()
71 -- PE4: reset pin
72 JZ.gpio.pin(4, 4).std_gpio_out(1)
73 -- PC9: unknown
74 JZ.gpio.pin(2, 9).std_gpio_out(0)
75 -- PC2: unknown
76 JZ.gpio.pin(2, 2).std_gpio_out(1)
77 -- PF0: unknown
78 JZ.gpio.pin(5, 0).std_gpio_out(1)
79end
80
81function FIIOX1.lcd_reset()
82 local pin = JZ.gpio.pin(4, 4)
83 pin.set()
84 hwstub.mdelay(50)
85 pin.clr()
86 hwstub.mdelay(50)
87 pin.set()
88 hwstub.mdelay(150)
89end
90
91function FIIOX1.init_lcd()
92 -- setup Fiio X1 specific pins
93 FIIOX1.setup_fiio_lcd_pins()
94 -- reset lcd
95 JZ.lcd_reset()
96end
97
98-- call with nil to get automatic name
99function FIIOX1.dump_ipl(file)
100 FIIOX1.hw_detect()
101 if file == nil then
102 file = "fiiox1_ipl_hw_v" .. FIIOX1.hw_type .. ".bin"
103 end
104 print("Dumping IPL to " .. file .." ...")
105 JZ.nand.rom.init()
106 JZ.nand.rom.read_flags()
107 local ipl = JZ.nand.rom.read_bootloader()
108 JZ.nand.rom.write_to_file(file, ipl)
109end
110
111-- call with nil to get automatic name
112function FIIOX1.dump_spl(file)
113 FIIOX1.hw_detect()
114 if file == nil then
115 file = "fiiox1_spl_hw_v" .. FIIOX1.hw_type .. ".bin"
116 end
117 print("Dumping SPL to " .. file .." ...")
118 -- hardcoded parameters are specific to the Fiio X1
119 local nand_params = {
120 bus_width = 16,
121 row_cycle = 2,
122 col_cycle = 2,
123 page_size = 2048,
124 page_per_block = 64,
125 oob_size = 64,
126 badblock_pos = 0,
127 badblock_page = 0,
128 ecc_pos = 4,
129 ecc_size = 13,
130 ecc_level = 8,
131 addr_setup_time = 4,
132 addr_hold_time = 4,
133 write_strobe_time = 4,
134 read_strobe_time = 4,
135 recovery_time = 13,
136 }
137 local spl = JZ.nand.rom.read_spl(nand_params, 0x400, 0x200)
138 JZ.nand.rom.write_to_file(file, spl)
139end
140
141function FIIOX1.init()
142 FIIOX1.init_backligt()
143 FIIOX1.test_backlight()
144 FIIOX1.init_lcd()
145end
diff --git a/utils/hwstub/tools/lua/jz.lua b/utils/hwstub/tools/lua/jz.lua
index ab2cb8658f..b192c51b3c 100644
--- a/utils/hwstub/tools/lua/jz.lua
+++ b/utils/hwstub/tools/lua/jz.lua
@@ -24,3 +24,7 @@ function JZ.init()
24 print("Looking for soc " .. desc .. ": not found. Please load a soc by hand.") 24 print("Looking for soc " .. desc .. ": not found. Please load a soc by hand.")
25 end 25 end
26end 26end
27
28require "jz/gpio"
29require "jz/lcd"
30require "jz/nand" \ No newline at end of file
diff --git a/utils/hwstub/tools/lua/jz/gpio.lua b/utils/hwstub/tools/lua/jz/gpio.lua
new file mode 100644
index 0000000000..d85529f9bb
--- /dev/null
+++ b/utils/hwstub/tools/lua/jz/gpio.lua
@@ -0,0 +1,82 @@
1---
2--- GPIO
3---
4JZ.gpio = {}
5
6
7function JZ.gpio.pinmask(bank, mask)
8 local t = {}
9 t.read = function()
10 return bit32.band(HW.GPIO.IN[bank].read(), mask)
11 end
12
13 t.write = function(val)
14 if val then t.set() else t.clr() end
15 end
16
17 t.set = function()
18 HW.GPIO.OUT[bank].SET.write(mask)
19 end
20
21 t.clr = function()
22 HW.GPIO.OUT[bank].CLR.write(mask)
23 end
24
25 t.gpio = function()
26 HW.GPIO.FUN[bank].CLR.write(mask)
27 HW.GPIO.SEL[bank].CLR.write(mask)
28 end
29
30 t.dir = function(out)
31 if out then
32 HW.GPIO.DIR[bank].SET.write(mask)
33 else
34 HW.GPIO.DIR[bank].CLR.write(mask)
35 end
36 end
37
38 t.pull = function(val)
39 if val then
40 HW.GPIO.PULL[bank].CLR.write(mask)
41 else
42 HW.GPIO.PULL[bank].SET.write(mask)
43 end
44 end
45
46 t.std_gpio_out = function(data)
47 t.gpio()
48 t.dir(true)
49 t.pull(false)
50 t.write(data)
51 end
52
53 t.gpio_in = function(data)
54 t.gpio()
55 t.dir(false)
56 end
57
58 t.std_function = function(fun_nr)
59 HW.GPIO.FUN[bank].SET.write(mask)
60 if fun_nr >= 2 then
61 HW.GPIO.TRG[bank].SET.write(mask)
62 fun_nr = fun_nr - 2
63 else
64 HW.GPIO.TRG[bank].CLR.write(mask)
65 end
66 if fun_nr >= 2 then
67 HW.GPIO.SEL[bank].SET.write(mask)
68 else
69 HW.GPIO.SEL[bank].CLR.write(mask)
70 end
71 end
72 return t
73end
74
75function JZ.gpio.pin(bank,pin)
76 local mask = bit32.lshift(1, pin)
77 local t = JZ.gpio.pinmask(bank,mask)
78 t.read = function()
79 return bit32.extract(HW.GPIO.IN[bank].read(), pin)
80 end
81 return t
82end \ No newline at end of file
diff --git a/utils/hwstub/tools/lua/jz/lcd.lua b/utils/hwstub/tools/lua/jz/lcd.lua
new file mode 100644
index 0000000000..2e626e903f
--- /dev/null
+++ b/utils/hwstub/tools/lua/jz/lcd.lua
@@ -0,0 +1,4 @@
1---
2--- GPIO
3---
4JZ.lcd = {}
diff --git a/utils/hwstub/tools/lua/jz/nand.lua b/utils/hwstub/tools/lua/jz/nand.lua
new file mode 100644
index 0000000000..2db8ab050b
--- /dev/null
+++ b/utils/hwstub/tools/lua/jz/nand.lua
@@ -0,0 +1,451 @@
1---
2--- GPIO
3---
4JZ.nand = {}
5JZ.nand.rom = {}
6
7function JZ.nand.init_pins(buswidth)
8 -- PA[21,19,18]: cs1, fre, fwe
9 JZ.gpio.pinmask(0, 0x2c0000).std_function(0)
10 JZ.gpio.pinmask(0, 0x2c0000).pull(false)
11 if buswidth == 16 then
12 -- PA[15:0]: d{15-0}
13 JZ.gpio.pinmask(0, 0xffff).std_function(0)
14 else
15 -- PA[7:0]: d{7-0}
16 JZ.gpio.pinmask(0, 0xff).std_function(0)
17 end
18 -- PB[1:0]: ale, cle
19 JZ.gpio.pinmask(1, 3).std_function(0)
20 JZ.gpio.pinmask(1, 3).pull(false)
21 -- PA20: rb#
22 JZ.gpio.pin(0, 20).gpio_in()
23end
24
25function JZ.nand.send_cmd(cmd)
26 DEV.write8(0xba400000, cmd)
27end
28
29function JZ.nand.send_addr(addr)
30 DEV.write8(0xba800000, addr)
31end
32
33function JZ.nand.read_data8()
34 return DEV.read8(0xba000000)
35end
36
37function JZ.nand.read_data32()
38 -- Boot ROM cannot do 16-bit read/write (those end up being 2x8-bit)
39 return DEV.read32(0xba000000)
40end
41
42function JZ.nand.wait_ready()
43 local pin = JZ.gpio.pin(0, 20)
44 -- wait ready
45 while pin.read() == 0 do end
46end
47
48function JZ.nand.set_buswidth(buswidth)
49 if buswidth == 8 then
50 HW.NEMC.SMC[1].BW.write("8BIT")
51 elseif buswidth == 16 then
52 HW.NEMC.SMC[1].BW.write("16BIT")
53 else
54 error("invalid buswidth")
55 end
56end
57-- {row,col}cycle must be 2 or 3
58-- buswidth must be 8 or 16
59-- count is the number of bytes to read (must be multiple of 2 is buswidth is 16)
60-- function returns a table of bytes
61function JZ.nand.read_page(col,colcycle,row,rowcycle,buswidth,count)
62 JZ.nand.set_buswidth(buswidth)
63 -- read page first cycle
64 JZ.nand.send_cmd(0)
65 -- column
66 JZ.nand.send_addr(col)
67 JZ.nand.send_addr(bit32.rshift(col, 8))
68 if colcycle == 3 then
69 JZ.nand.send_addr(bit32.rshift(col, 16))
70 end
71 -- row
72 JZ.nand.send_addr(row)
73 JZ.nand.send_addr(bit32.rshift(row, 8))
74 if rowcycle == 3 then
75 JZ.nand.send_addr(bit32.rshift(row, 16))
76 end
77 -- read page second cycle
78 JZ.nand.send_cmd(0x30)
79 -- wait ready
80 JZ.nand.wait_ready()
81 -- read
82 return JZ.nand.read_page_data(buswidth,count)
83end
84
85function JZ.nand.read_page2(params,col,row,count)
86 return JZ.nand.read_page(col,params.col_cycle,row,params.row_cycle,params.bus_width,count)
87end
88
89-- read data, assuming read page command was sent
90function JZ.nand.read_page_data(buswidth,count)
91 -- read
92 data = {}
93 if buswidth == 8 then
94 for i=0, count-1 do
95 data[i] = JZ.nand.read_data8()
96 end
97 else
98 for i=0, count-1, 4 do
99 local hw = JZ.nand.read_data32()
100 data[i] = bit32.band(hw, 0xff)
101 data[i + 1] = bit32.band(bit32.rshift(hw, 8), 0xff)
102 data[i + 2] = bit32.band(bit32.rshift(hw, 16), 0xff)
103 data[i + 3] = bit32.band(bit32.rshift(hw, 24), 0xff)
104 end
105 end
106 return data
107end
108
109function JZ.nand.read_oob(params,page)
110--[[
111NAND flash are magic, every setup is different, so basically:
112- if the page size is 512, that's a special case and we need to use a special
113 command to read OOB, also note that 512-byte NAND only have one cycle column address
114- otherwise, assume OOB is after the data (so at offset page_size in bytes),
115 but beware that for 16-bit bus, column address is in words, not bytes
116For simplicity, we do not support 512-byte NAND at the moment
117]]
118 -- compute column address of OOB data
119 local col_addr = params.page_size
120 if params.bus_width == 16 then
121 col_addr = params.page_size / 2
122 end
123 -- read page
124 return JZ.nand.read_page2(params,col_addr,page,params.oob_size)
125end
126
127--[[
128setup NAND parameters, the table should contain:
129- bus_width: 8 or 16,
130- addr_setup_time: in cycles
131- addr_hold_time: in cycles
132- write_strobe_time: in cycles
133- read_strobe_time: in cycles
134- recovery_time: in cycles
135]]
136function JZ.nand.setup(params)
137 JZ.nand.init_pins(params.bus_width)
138 HW.NEMC.SMC[1].BL.write(params.bus_width == 8 and "8" or "16")
139 HW.NEMC.SMC[1].TAS.write(params.addr_setup_time)
140 HW.NEMC.SMC[1].TAH.write(params.addr_hold_time)
141 HW.NEMC.SMC[1].TBP.write(params.write_strobe_time)
142 HW.NEMC.SMC[1].TAW.write(params.read_strobe_time)
143 HW.NEMC.SMC[1].STRV.write(params.recovery_time)
144end
145
146function JZ.nand.reset()
147 print("NAND: reset")
148 JZ.nand.send_cmd(0xff)
149 JZ.nand.wait_ready()
150end
151
152-- init nand like ROM
153function JZ.nand.rom.init()
154 -- init pins to 16-bit in doubt
155 JZ.nand.init_pins(16)
156 -- take safest setting: 8-bit, max TAS, max TAH, max read/write strobe wait
157 HW.NEMC.SMC[1].write(0xfff7700)
158 -- enable flash on CS1 with CS# always asserted
159 HW.NEMC.NFC.write(3)
160 -- reset
161 JZ.nand.reset()
162end
163
164function JZ.nand.rom.parse_flag(data, offset)
165 local cnt_55 = 0
166 local cnt_aa = 0
167 for i = offset,offset + 31 do
168 if data[i] == 0x55 then
169 cnt_55 = cnt_55 + 1
170 elseif data[i] == 0xaa then
171 cnt_aa = cnt_aa + 1
172 end
173 end
174 if cnt_55 >= 7 then
175 return 0x55
176 elseif cnt_aa >= 7 then
177 return 0xaa
178 else
179 return 0xff
180 end
181end
182
183function JZ.nand.rom.read_page(col,row,count)
184 return JZ.nand.read_page(col, JZ.nand.rom.colcycle, row, JZ.nand.rom.rowcycle,
185 JZ.nand.rom.buswidth, count)
186end
187
188function JZ.nand.rom.read_page_data(count)
189 return JZ.nand.read_page_data(JZ.nand.rom.buswidth, count)
190end
191
192-- read flash parameters
193function JZ.nand.rom.read_flags()
194 local flags = nil
195 -- read first page
196 for colcycle = 2,3 do
197 flags = JZ.nand.read_page(0,colcycle,0,3,8,160)
198 local buswidth_flag = JZ.nand.rom.parse_flag(flags, 0)
199 if buswidth_flag == 0x55 then
200 -- set to 8-bit
201 JZ.nand.rom.colcycle = colcycle
202 JZ.nand.rom.buswidth = 8
203 break
204 elseif buswidth_flag == 0xaa then
205 -- set to 16-bit
206 JZ.nand.rom.colcycle = colcycle
207 JZ.nand.rom.buswidth = 16
208 break
209 end
210 end
211 if JZ.nand.rom.buswidth == nil then
212 error("Cannot read flags")
213 end
214 print("NAND: colcycle = " .. JZ.nand.rom.colcycle)
215 print("NAND: buswidth = " .. JZ.nand.rom.buswidth)
216 -- reread flags correctly now
217 flags = JZ.nand.read_page(0,JZ.nand.rom.colcycle,0,3,JZ.nand.rom.buswidth,160)
218 -- rowcycle
219 local rowcycle_flag = JZ.nand.rom.parse_flag(flags, 64)
220 if rowcycle_flag == 0x55 then
221 JZ.nand.rom.rowcycle = 2
222 elseif rowcycle_flag == 0xaa then
223 JZ.nand.rom.rowcycle = 3
224 else
225 error("invalid rowcycle flag")
226 end
227 print("NAND: rowcycle = " .. JZ.nand.rom.rowcycle)
228 -- pagesize
229 local pagesize1_flag = JZ.nand.rom.parse_flag(flags, 96)
230 local pagesize0_flag = JZ.nand.rom.parse_flag(flags, 128)
231 if pagesize1_flag == 0x55 and pagesize0_flag == 0x55 then
232 JZ.nand.rom.pagesize = 512
233 elseif pagesize1_flag == 0x55 and pagesize0_flag == 0xaa then
234 JZ.nand.rom.pagesize = 2048
235 elseif pagesize1_flag == 0xaa and pagesize0_flag == 0x55 then
236 JZ.nand.rom.pagesize = 4096
237 elseif pagesize1_flag == 0xaa and pagesize0_flag == 0xaa then
238 JZ.nand.rom.pagesize = 8192
239 else
240 error(string.format("invalid pagesize flag: %#x,%#x", pagesize1_flag, pagesize0_flag))
241 end
242 print("NAND: pagesize = " .. JZ.nand.rom.pagesize)
243end
244
245-- read bootloader
246function JZ.nand.rom.read_bootloader()
247 -- computer number of blocks per page
248 local bl_size = 256
249 local bl_per_page = JZ.nand.rom.pagesize / bl_size
250 local ecc_per_bl = 39
251 local bootloader_size = 8 * 1024
252 local bootloader = {}
253
254 local page_offset = 0
255 while true do
256 local all_ok = true
257 print("NAND: try at page offset " .. page_offset)
258 for page = 0, bootloader_size / JZ.nand.rom.pagesize - 1 do
259 print("NAND: page " .. page)
260 -- enable randomizer
261 HW.NEMC.PNC.write(3)
262 -- read ECC
263 local ecc = JZ.nand.rom.read_page(0, page_offset + 2 * page + 1, ecc_per_bl * bl_per_page)
264 -- disable randomizer
265 HW.NEMC.PNC.write(0)
266 HW.NEMC.NFC.write(0)
267 HW.NEMC.NFC.write(3)
268 -- send read page commannd, but don't read the data just yet
269 JZ.nand.rom.read_page(0, page_offset + 2 * page, 0)
270 -- for each block
271 for bl = 0, bl_per_page - 1 do
272 print("NAND: block " .. bl)
273 -- enable randomizer (except for first block of first page)
274 if page ~=0 or bl ~= 0 then
275 HW.NEMC.PNC.write(3)
276 end
277 -- read data
278 local data = JZ.nand.rom.read_page_data(bl_size)
279 -- disable randomizer
280 HW.NEMC.PNC.write(0)
281 -- setup bch
282 HW.BCH.INTS.write(0xffffffff)
283 HW.BCH.CTRL.SET.write(0x2b)
284 HW.BCH.CTRL.CLR.write(0x4)
285 HW.BCH.COUNT.DEC.write((bl_size + ecc_per_bl) * 2)
286 for i = 0, bl_size - 1 do
287 HW.BCH.DATA.write(data[i])
288 end
289 for i = 0, ecc_per_bl - 1 do
290 HW.BCH.DATA.write(ecc[bl * ecc_per_bl + i])
291 end
292 while HW.BCH.INTS.DECF.read() == 0 do
293 end
294 HW.BCH.CTRL.CLR.write(1)
295 print(string.format("NAND: ecc = 0x%x", HW.BCH.INTS.read()))
296 -- now fix the errors
297 if HW.BCH.INTS.UNCOR.read() == 1 then
298 print("NAND: uncorrectable errors !")
299 all_ok = false
300 end
301 print(string.format("NAND: correcting %d errors", HW.BCH.INTS.ERRC.read()))
302 if HW.BCH.INTS.ERRC.read() > 0 then
303 error("Error correction is not implemented for now")
304 end
305 for i = 0, bl_size - 1 do
306 bootloader[(page * bl_per_page + bl) * bl_size + i] = data[i]
307 end
308 end
309 end
310 if all_ok then
311 break
312 end
313 page_offset = page_offset + 16 * 1024 / JZ.nand.rom.pagesize
314 end
315 return bootloader
316end
317
318--[[
319read SPL: offset and size in pages, the param table should contain:
320- page_size: page size in bytes (exclusing spare)
321- oob_size: spare data size in bytes
322- page_per_block: number of pages per block
323- ecc_pos: offset within spare of the ecc data
324- badblock_pos: offset within spare of the badblock marker (only one page per block is marked)
325- badblock_page: page number within block of the page containing badblock marker in spare
326- col_cycle: number of cycles for column address
327- row_cycle: number of cycles for row address
328- ecc_size: ECC size in bytes
329- ecc_level: level of error correction in bits: 4, 8, 12, ...
330]]
331function JZ.nand.rom.read_spl(params, offset, size)
332--[[
333On-flash format: each block contains page_per_block pages,
334where each page contains page_size bytes, follows by oob_size spare bytes.
335The spare area contains a bad block marker at offset badblock_pos and
336the ECC data at offset ecc_pos. Note that only one page within each block
337actually contains the bad block marker: this page is badblock_page. The marker
338is 0xff is the block is valid. Any invalid block is skipped.
339The ECC is computed on a per-512-block basis. Since a page contains several such
340blocks, the ECC data contains consecutive ecc blocks, one for each 512-byte data
341block.
342
343+---------------------+
344|page0|page1|...|pageN| <--- block
345+---------------------+
346
347+-------------------------------+
348|data(page_size)|spare(oob_size)| <--- page
349+-------------------------------+
350
351+---------------------------------------------+
352|xxxx|badblock marker(1)|xxxxx|ECC data()|xxxx| <-- spare
353+---------------------------------------------+
354]]
355 local bootloader = {}
356 if (offset % params.page_per_block) ~= 0 then
357 print("Warning: SPL is not block-aligned")
358 end
359 -- setup parameters
360 JZ.nand.setup(params)
361 -- enable NAND
362 HW.NEMC.NFC.write(3)
363 -- reset
364 JZ.nand.reset()
365 -- read SPL !
366 local checked_block = false
367 local cur_page = offset
368 local loaded_pages = 0
369 while loaded_pages < size do
370 ::load_loop::
371 -- if we just crossed a page boundary, reset the block check flag
372 if (cur_page % params.page_per_block) == 0 then
373 checked_block = false
374 end
375 -- check block for bad block marker if needed
376 if not checked_block then
377 print("Reading bad block marker for block " .. (cur_page / params.page_per_block) .. "...")
378 -- read OOB data
379 local oob_data = JZ.nand.read_oob(params,cur_page + params.badblock_page)
380 if oob_data[params.badblock_pos] ~= 0xff then
381 print("Bad block at " .. (cur_page / page_per_block))
382 -- skip block
383 cur_page = ((cur_page + params.page_per_block) / params.page_per_block) * params.page_per_block
384 -- lua has no continue...
385 goto load_loop
386 end
387 checked_block = true
388 end
389
390 print("Reading page " .. cur_page .. "...")
391 -- send read page command
392 JZ.nand.read_page2(params,0,cur_page, 0)
393 local page_data = JZ.nand.read_page_data(params.bus_width,params.page_size)
394 local oob_data = JZ.nand.read_page_data(params.bus_width,params.oob_size)
395 -- handle each 512-byte block for ECC
396 local bl_size = 512
397 for bl = 0,params.page_size/bl_size-1 do
398 print("Checking subblock " .. bl .. "...")
399 -- setup bch
400 HW.BCH.INTS.write(0xffffffff)
401 HW.BCH.CTRL.CLR.BSEL.write() -- clear level
402 HW.BCH.CTRL.SET.BSEL.write(params.ecc_level / 4 - 1) -- set level
403 HW.BCH.CTRL.SET.write(3) -- enable and reset
404 HW.BCH.CTRL.CLR.ENCE.write(0x4) -- decode
405 -- write ecc data count
406 HW.BCH.COUNT.DEC.write((bl_size + params.ecc_size) * 2)
407 -- write data
408 for j = 0, bl_size - 1 do
409 HW.BCH.DATA.write(page_data[bl_size * bl + j])
410 end
411 -- write ecc data
412 for j = 0, params.ecc_size - 1 do
413 HW.BCH.DATA.write(oob_data[params.ecc_pos + bl * params.ecc_size + j])
414 end
415 -- wait until bch is done
416 while HW.BCH.INTS.DECF.read() == 0 do
417 end
418 -- disable bch
419 HW.BCH.CTRL.CLR.write(1)
420 print(string.format("NAND: ecc = 0x%x", HW.BCH.INTS.read()))
421 -- now fix the errors
422 if HW.BCH.INTS.UNCOR.read() == 1 then
423 error("NAND: uncorrectable errors !")
424 end
425 print(string.format("NAND: correcting %d errors", HW.BCH.INTS.ERRC.read()))
426 if HW.BCH.INTS.ERRC.read() > 0 then
427 error("Error correction is not implemented for now")
428 end
429 for i = 0, bl_size - 1 do
430 bootloader[loaded_pages * params.page_size + bl * bl_size + i] = page_data[bl_size * bl + i]
431 end
432 end
433 cur_page = cur_page + 1
434 loaded_pages = loaded_pages + 1
435 end
436 -- disable NAND
437 HW.NEMC.NFC.write(0)
438 return bootloader
439end
440
441-- dump data
442function JZ.nand.rom.write_to_file(file, data)
443 local f = io.open(file, "w")
444 if f == nil then error("Cannot open file or write to nil") end
445 local i = 0
446 while type(data[i]) == "number" do
447 f:write(string.char(data[i]))
448 i = i + 1
449 end
450 io.close(f)
451end \ No newline at end of file