diff options
| author | Jens Arnold <amiconn@rockbox.org> | 2004-08-30 19:52:45 +0000 |
|---|---|---|
| committer | Jens Arnold <amiconn@rockbox.org> | 2004-08-30 19:52:45 +0000 |
| commit | 06cb237af682fbc45a72c4e43e3f8126b2c9cac6 (patch) | |
| tree | a0eb1898429941f00da446e1e8c8efdd35864ff9 /firmware | |
| parent | 56fd6f9316ee196bfd16a2f102469cb6b040d397 (diff) | |
| download | rockbox-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.h | 11 | ||||
| -rw-r--r-- | firmware/system.c | 48 |
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; } |