summaryrefslogtreecommitdiffstats
path: root/firmware/target/sh
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2011-06-05 10:26:06 +0000
committerMarcin Bukat <marcin.bukat@gmail.com>2011-06-05 10:26:06 +0000
commitdceceef05264cdeff0e2c60b8cb00719d7d7baeb (patch)
treeeb8573dbe429755165372a91a620435e8b14e4bd /firmware/target/sh
parentdace72166e5250e2ea0a9beb6451f5e4da9e50e2 (diff)
downloadrockbox-dceceef05264cdeff0e2c60b8cb00719d7d7baeb.tar.gz
rockbox-dceceef05264cdeff0e2c60b8cb00719d7d7baeb.zip
Move dbg_hw_info() into target tree. FS#11735 by me
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29964 a1c6a512-1295-4272-9138-f99709370657
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 @@
#include "config.h"
#include "system.h"
#include <stdbool.h>
+#include <string.h>
#include "font.h"
#include "lcd.h"
#include "button.h"
#include "powermgmt.h"
#include "adc.h"
+#include "hwcompat.h" /* ROM_VERSION */
+#include "crc32.h"
#include "debug-target.h"
+
+/* Tool function to read the flash manufacturer and type, if available.
+ Only chips which could be reprogrammed in system will return values.
+ (The mode switch addresses vary between flash manufacturers, hence addr1/2) */
+ /* In IRAM to avoid problems when running directly from Flash */
+static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
+ unsigned addr1, unsigned addr2)
+ ICODE_ATTR __attribute__((noinline));
+static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
+ unsigned addr1, unsigned addr2)
+{
+ unsigned not_manu, not_id; /* read values before switching to ID mode */
+ unsigned manu, id; /* read values when in ID mode */
+
+ volatile unsigned char* flash = (unsigned char*)0x2000000; /* flash mapping */
+ int old_level; /* saved interrupt level */
+
+ not_manu = flash[0]; /* read the normal content */
+ not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
+
+ /* disable interrupts, prevent any stray flash access */
+ old_level = disable_irq_save();
+
+ flash[addr1] = 0xAA; /* enter command mode */
+ flash[addr2] = 0x55;
+ flash[addr1] = 0x90; /* ID command */
+ /* Atmel wants 20ms pause here */
+ /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
+
+ manu = flash[0]; /* read the IDs */
+ id = flash[1];
+
+ flash[0] = 0xF0; /* reset flash (back to normal read mode) */
+ /* Atmel wants 20ms pause here */
+ /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
+
+ restore_irq(old_level); /* enable interrupts again */
+ /* I assume success if the obtained values are different from
+ the normal flash content. This is not perfectly bulletproof, they
+ could theoretically be the same by chance, causing us to fail. */
+ if (not_manu != manu || not_id != id) /* a value has changed */
+ {
+ *p_manufacturer = manu; /* return the results */
+ *p_device = id;
+ return true; /* success */
+ }
+ return false; /* fail */
+}
+
bool dbg_ports(void)
{
int adc_battery_voltage;
@@ -58,11 +110,11 @@ bool dbg_ports(void)
adc_battery_voltage % 1000, adc_battery_level);
lcd_update();
- if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
- {
- lcd_setfont(FONT_UI);
- return false;
- }
+
+ while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL));
+
+ lcd_setfont(FONT_UI);
+
#else /* !HAVE_LCD_BITMAP */
if (currval == 0) {
@@ -101,3 +153,127 @@ bool dbg_ports(void)
}
return false;
}
+
+bool dbg_hw_info(void)
+{
+#ifndef HAVE_LCD_BITMAP
+ int button;
+ int currval = 0;
+#else
+ int bitmask = HW_MASK;
+#endif
+ int rom_version = ROM_VERSION;
+ unsigned manu, id; /* flash IDs */
+ bool got_id; /* flag if we managed to get the flash IDs */
+ unsigned rom_crc = 0xffffffff; /* CRC32 of the boot ROM */
+ bool has_bootrom; /* flag for boot ROM present */
+ int oldmode; /* saved memory guard mode */
+
+ oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
+
+ /* get flash ROM type */
+ got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
+ if (!got_id)
+ got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
+
+ /* check if the boot ROM area is a flash mirror */
+ has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
+ if (has_bootrom) /* if ROM and Flash different */
+ {
+ /* calculate CRC16 checksum of boot ROM */
+ rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
+ }
+
+ system_memory_guard(oldmode); /* re-enable memory guard */
+
+ lcd_clear_display();
+
+#ifdef HAVE_LCD_BITMAP
+ lcd_setfont(FONT_SYSFIXED);
+
+ lcd_puts(0, 0, "[Hardware info]");
+
+ lcd_putsf(0, 1, "ROM: %d.%02d", rom_version/100, rom_version%100);
+
+ lcd_putsf(0, 2, "Mask: 0x%04x", bitmask);
+ if (got_id)
+ lcd_putsf(0, 3, "Flash: M=%02x D=%02x", manu, id);
+ else
+ lcd_puts(0, 3, "Flash: M=?? D=??"); /* unknown, sorry */
+
+ if (has_bootrom)
+ {
+ if (rom_crc == 0x56DBA4EE) /* known Version 1 */
+ lcd_puts(0, 4, "Boot ROM: V1");
+ else
+ lcd_putsf(0, 4, "ROMcrc: 0x%08x", rom_crc);
+ }
+ else
+ {
+ lcd_puts(0, 4, "Boot ROM: none");
+ }
+
+ lcd_update();
+
+ /* wait for exit */
+ while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL));
+
+ lcd_setfont(FONT_UI);
+
+#else /* !HAVE_LCD_BITMAP */
+ lcd_puts(0, 0, "[HW Info]");
+ while(1)
+ {
+ switch(currval)
+ {
+ case 0:
+ lcd_putsf(0, 1, "ROM: %d.%02d",
+ rom_version/100, rom_version%100);
+ break;
+ case 1:
+ if (got_id)
+ lcd_putsf(0, 1, "Flash:%02x,%02x", manu, id);
+ else
+ lcd_puts(0, 1, "Flash:??,??"); /* unknown, sorry */
+ break;
+ case 2:
+ if (has_bootrom)
+ {
+ if (rom_crc == 0x56DBA4EE) /* known Version 1 */
+ lcd_puts(0, 1, "BootROM: V1");
+ else if (rom_crc == 0x358099E8)
+ lcd_puts(0, 1, "BootROM: V2");
+ /* alternative boot ROM found in one single player so far */
+ else
+ lcd_putsf(0, 1, "R: %08x", rom_crc);
+ }
+ else
+ lcd_puts(0, 1, "BootROM: no");
+ }
+
+ lcd_update();
+
+ button = button_get_w_tmo(HZ/10);
+
+ switch(button)
+ {
+ case BUTTON_STOP:
+ return false;
+
+ case BUTTON_LEFT:
+ currval--;
+ if(currval < 0)
+ currval = 2;
+ break;
+
+ case BUTTON_RIGHT:
+ currval++;
+ if(currval > 2)
+ currval = 0;
+ break;
+ }
+ }
+#endif
+ return false;
+}
+
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 @@
# define DEBUG_CANCEL BUTTON_MENU
#endif
bool dbg_ports(void);
+bool dbg_hw_info(void);