summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2004-08-30 19:52:45 +0000
committerJens Arnold <amiconn@rockbox.org>2004-08-30 19:52:45 +0000
commit06cb237af682fbc45a72c4e43e3f8126b2c9cac6 (patch)
treea0eb1898429941f00da446e1e8c8efdd35864ff9 /firmware
parent56fd6f9316ee196bfd16a2f102469cb6b040d397 (diff)
downloadrockbox-06cb237af682fbc45a72c4e43e3f8126b2c9cac6.zip
rockbox-06cb237af682fbc45a72c4e43e3f8126b2c9cac6.tar.gz
rockbox-06cb237af682fbc45a72c4e43e3f8126b2c9cac6.tar.bz2
rockbox-06cb237af682fbc45a72c4e43e3f8126b2c9cac6.tar.xz
New debug feature: Use the SH1 user break controller to catch illegal memory accesses
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5026 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/system.h11
-rw-r--r--firmware/system.c48
2 files changed, 58 insertions, 1 deletions
diff --git a/firmware/export/system.h b/firmware/export/system.h
index 0d601e3..0c4a8f1 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -164,6 +164,17 @@ static inline int cas2 (volatile int *pointer1,volatile int *pointer2,int reques
set_irq_level(oldlevel);
return 0;
}
+
+/* Utilize the user break controller to catch invalid memory accesses. */
+int system_memory_guard(int newmode);
+
+enum {
+ MEMGUARD_KEEP = -1, /* don't change the mode; for reading */
+ MEMGUARD_NONE = 0, /* catch nothing */
+ MEMGUARD_FLASH_WRITES, /* catch writes to area 02 (flash ROM) */
+ MEMGUARD_ZERO_AREA, /* catch all accesses to areas 00 and 01 */
+ MAXMEMGUARD
+};
#endif
diff --git a/firmware/system.c b/firmware/system.c
index 33d5fbf..234e294 100644
--- a/firmware/system.c
+++ b/firmware/system.c
@@ -315,7 +315,7 @@ void system_reboot (void)
ICR = 0;
asm volatile ("jmp @%0; mov.l @%1,r15" : :
- "r"(*(int*)0),"r"(4));
+ "r"(*(int*)0),"r"(4));
}
void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
@@ -498,4 +498,50 @@ void system_init(void)
WCR1 = 0x4000; /* Long wait states for CS6 (ATA), short for the rest. */
WCR3 = 0x8000; /* WAIT is pulled up, 1 state inserted for CS6 */
#endif
+
+}
+
+/* Utilize the user break controller to catch invalid memory accesses. */
+int system_memory_guard(int newmode)
+{
+ static const struct {
+ unsigned long addr;
+ unsigned long mask;
+ unsigned short bbr;
+ } modes[MAXMEMGUARD] = {
+ /* catch nothing */
+ { 0x00000000, 0x00000000, 0x0000 },
+ /* catch writes to area 02 (flash ROM) */
+ { 0x02000000, 0x00FFFFFF, 0x00F8 },
+ /* catch all accesses to areas 00 (internal ROM) and 01 (free) */
+ { 0x00000000, 0x01FFFFFF, 0x00FC }
+ };
+
+ int oldmode = MEMGUARD_NONE;
+ int i;
+
+ /* figure out the old mode from what is in the UBC regs. If the register
+ values don't match any mode, assume MEMGUARD_NONE */
+ for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++)
+ {
+ if (BAR == modes[i].addr && BAMR == modes[i].mask &&
+ BBR == modes[i].bbr)
+ {
+ oldmode = i;
+ break;
+ }
+ }
+
+ if (newmode == MEMGUARD_KEEP)
+ newmode = oldmode;
+
+ BBR = 0; /* switch off everything first */
+
+ /* always set the UBC according to the mode, in case the old settings
+ didn't match any valid mode */
+ BAR = modes[newmode].addr;
+ BAMR = modes[newmode].mask;
+ BBR = modes[newmode].bbr;
+
+ return oldmode;
}