summaryrefslogtreecommitdiff
path: root/firmware/target/sh
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/sh')
-rw-r--r--firmware/target/sh/debug-sh.c186
-rw-r--r--firmware/target/sh/debug-target.h1
2 files changed, 182 insertions, 5 deletions
diff --git a/firmware/target/sh/debug-sh.c b/firmware/target/sh/debug-sh.c
index 3502cfade0..78d0032199 100644
--- a/firmware/target/sh/debug-sh.c
+++ b/firmware/target/sh/debug-sh.c
@@ -22,13 +22,65 @@
22#include "config.h" 22#include "config.h"
23#include "system.h" 23#include "system.h"
24#include <stdbool.h> 24#include <stdbool.h>
25#include <string.h>
25#include "font.h" 26#include "font.h"
26#include "lcd.h" 27#include "lcd.h"
27#include "button.h" 28#include "button.h"
28#include "powermgmt.h" 29#include "powermgmt.h"
29#include "adc.h" 30#include "adc.h"
31#include "hwcompat.h" /* ROM_VERSION */
32#include "crc32.h"
30#include "debug-target.h" 33#include "debug-target.h"
31 34
35
36/* Tool function to read the flash manufacturer and type, if available.
37 Only chips which could be reprogrammed in system will return values.
38 (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
39 /* In IRAM to avoid problems when running directly from Flash */
40static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
41 unsigned addr1, unsigned addr2)
42 ICODE_ATTR __attribute__((noinline));
43static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
44 unsigned addr1, unsigned addr2)
45{
46 unsigned not_manu, not_id; /* read values before switching to ID mode */
47 unsigned manu, id; /* read values when in ID mode */
48
49 volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
50 int old_level; /* saved interrupt level */
51
52 not_manu = flash[0]; /* read the normal content */
53 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
54
55 /* disable interrupts, prevent any stray flash access */
56 old_level = disable_irq_save();
57
58 flash[addr1] = 0xAA; /* enter command mode */
59 flash[addr2] = 0x55;
60 flash[addr1] = 0x90; /* ID command */
61 /* Atmel wants 20ms pause here */
62 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
63
64 manu = flash[0]; /* read the IDs */
65 id = flash[1];
66
67 flash[0] = 0xF0; /* reset flash (back to normal read mode) */
68 /* Atmel wants 20ms pause here */
69 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
70
71 restore_irq(old_level); /* enable interrupts again */
72 /* I assume success if the obtained values are different from
73 the normal flash content. This is not perfectly bulletproof, they
74 could theoretically be the same by chance, causing us to fail. */
75 if (not_manu != manu || not_id != id) /* a value has changed */
76 {
77 *p_manufacturer = manu; /* return the results */
78 *p_device = id;
79 return true; /* success */
80 }
81 return false; /* fail */
82}
83
32bool dbg_ports(void) 84bool dbg_ports(void)
33{ 85{
34 int adc_battery_voltage; 86 int adc_battery_voltage;
@@ -58,11 +110,11 @@ bool dbg_ports(void)
58 adc_battery_voltage % 1000, adc_battery_level); 110 adc_battery_voltage % 1000, adc_battery_level);
59 111
60 lcd_update(); 112 lcd_update();
61 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) 113
62 { 114 while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL));
63 lcd_setfont(FONT_UI); 115
64 return false; 116 lcd_setfont(FONT_UI);
65 } 117
66#else /* !HAVE_LCD_BITMAP */ 118#else /* !HAVE_LCD_BITMAP */
67 119
68 if (currval == 0) { 120 if (currval == 0) {
@@ -101,3 +153,127 @@ bool dbg_ports(void)
101 } 153 }
102 return false; 154 return false;
103} 155}
156
157bool dbg_hw_info(void)
158{
159#ifndef HAVE_LCD_BITMAP
160 int button;
161 int currval = 0;
162#else
163 int bitmask = HW_MASK;
164#endif
165 int rom_version = ROM_VERSION;
166 unsigned manu, id; /* flash IDs */
167 bool got_id; /* flag if we managed to get the flash IDs */
168 unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
169 bool has_bootrom; /* flag for boot ROM present */
170 int oldmode; /* saved memory guard mode */
171
172 oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
173
174 /* get flash ROM type */
175 got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
176 if (!got_id)
177 got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
178
179 /* check if the boot ROM area is a flash mirror */
180 has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
181 if (has_bootrom) /* if ROM and Flash different */
182 {
183 /* calculate CRC16 checksum of boot ROM */
184 rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
185 }
186
187 system_memory_guard(oldmode); /* re-enable memory guard */
188
189 lcd_clear_display();
190
191#ifdef HAVE_LCD_BITMAP
192 lcd_setfont(FONT_SYSFIXED);
193
194 lcd_puts(0, 0, "[Hardware info]");
195
196 lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
197
198 lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
199 if (got_id)
200 lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
201 else
202 lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
203
204 if (has_bootrom)
205 {
206 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
207 lcd_puts(0, 4, "Boot ROM: V1");
208 else
209 lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
210 }
211 else
212 {
213 lcd_puts(0, 4, "Boot ROM: none");
214 }
215
216 lcd_update();
217
218 /* wait for exit */
219 while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL));
220
221 lcd_setfont(FONT_UI);
222
223#else /* !HAVE_LCD_BITMAP */
224 lcd_puts(0, 0, "[HW Info]");
225 while(1)
226 {
227 switch(currval)
228 {
229 case 0:
230 lcd_putsf(0, 1, "ROM: %d.%02d",
231 rom_version/100, rom_version%100);
232 break;
233 case 1:
234 if (got_id)
235 lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
236 else
237 lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
238 break;
239 case 2:
240 if (has_bootrom)
241 {
242 if (rom_crc == 0x56DBA4EE) /* known Version 1 */
243 lcd_puts(0, 1, "BootROM: V1");
244 else if (rom_crc == 0x358099E8)
245 lcd_puts(0, 1, "BootROM: V2");
246 /* alternative boot ROM found in one single player so far */
247 else
248 lcd_putsf(0, 1, "R: %08x", rom_crc);
249 }
250 else
251 lcd_puts(0, 1, "BootROM: no");
252 }
253
254 lcd_update();
255
256 button = button_get_w_tmo(HZ/10);
257
258 switch(button)
259 {
260 case BUTTON_STOP:
261 return false;
262
263 case BUTTON_LEFT:
264 currval--;
265 if(currval < 0)
266 currval = 2;
267 break;
268
269 case BUTTON_RIGHT:
270 currval++;
271 if(currval > 2)
272 currval = 0;
273 break;
274 }
275 }
276#endif
277 return false;
278}
279
diff --git a/firmware/target/sh/debug-target.h b/firmware/target/sh/debug-target.h
index 4e25b81948..f738795ea6 100644
--- a/firmware/target/sh/debug-target.h
+++ b/firmware/target/sh/debug-target.h
@@ -25,3 +25,4 @@
25# define DEBUG_CANCEL BUTTON_MENU 25# define DEBUG_CANCEL BUTTON_MENU
26#endif 26#endif
27bool dbg_ports(void); 27bool dbg_ports(void);
28bool dbg_hw_info(void);