1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Jens Arnold 2004-08-30 19:52:45 +00:00
parent 56fd6f9316
commit 06cb237af6
7 changed files with 104 additions and 6 deletions

View file

@ -130,7 +130,7 @@ bool dbg_os(void)
case BUTTON_STOP: case BUTTON_STOP:
return false; return false;
case BUTTON_LEFT: case BUTTON_LEFT:
currval--; currval--;
if(currval < 0) if(currval < 0)
currval = num_threads-1; currval = num_threads-1;
@ -301,6 +301,7 @@ bool dbg_hw_info(void)
bool got_id; /* flag if we managed to get the flash IDs */ bool got_id; /* flag if we managed to get the flash IDs */
unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */ unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
bool has_bootrom; /* flag for boot ROM present */ bool has_bootrom; /* flag for boot ROM present */
int oldmode; /* saved memory guard mode */
if(PADR & 0x400) if(PADR & 0x400)
usb_polarity = 0; /* Negative */ usb_polarity = 0; /* Negative */
@ -312,6 +313,8 @@ bool dbg_hw_info(void)
else else
pr_polarity = 1; /* Positive */ pr_polarity = 1; /* Positive */
oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
/* get flash ROM type */ /* get flash ROM type */
got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
if (!got_id) if (!got_id)
@ -325,6 +328,8 @@ bool dbg_hw_info(void)
rom_crc = crc_16((unsigned char*)0x0000, 64*1024); rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
} }
system_memory_guard(oldmode); /* re-enable memory guard */
lcd_setmargins(0, 0); lcd_setmargins(0, 0);
lcd_setfont(FONT_SYSFIXED); lcd_setfont(FONT_SYSFIXED);
lcd_clear_display(); lcd_clear_display();
@ -389,12 +394,15 @@ bool dbg_hw_info(void)
bool got_id; /* flag if we managed to get the flash IDs */ bool got_id; /* flag if we managed to get the flash IDs */
unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */ unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
bool has_bootrom; /* flag for boot ROM present */ bool has_bootrom; /* flag for boot ROM present */
int oldmode; /* saved memory guard mode */
if(PADR & 0x400) if(PADR & 0x400)
usb_polarity = 0; /* Negative */ usb_polarity = 0; /* Negative */
else else
usb_polarity = 1; /* Positive */ usb_polarity = 1; /* Positive */
oldmode = system_memory_guard(MEMGUARD_NONE); /* disable memory guard */
/* get flash ROM type */ /* get flash ROM type */
got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
if (!got_id) if (!got_id)
@ -408,6 +416,8 @@ bool dbg_hw_info(void)
rom_crc = crc_16((unsigned char*)0x0000, 64*1024); rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
} }
system_memory_guard(oldmode); /* re-enable memory guard */
lcd_clear_display(); lcd_clear_display();
lcd_puts(0, 0, "[HW Info]"); lcd_puts(0, 0, "[HW Info]");
@ -1440,6 +1450,7 @@ static bool dbg_disk_info(void)
bool dbg_save_roms(void) bool dbg_save_roms(void)
{ {
int fd; int fd;
int oldmode = system_memory_guard(MEMGUARD_NONE);
fd = creat("/internal_rom_0000-FFFF.bin", O_WRONLY); fd = creat("/internal_rom_0000-FFFF.bin", O_WRONLY);
if(fd >= 0) if(fd >= 0)
@ -1455,6 +1466,7 @@ bool dbg_save_roms(void)
close(fd); close(fd);
} }
system_memory_guard(oldmode);
return false; return false;
} }
@ -1510,6 +1522,21 @@ bool dbg_screendump(void)
} }
#endif #endif
bool dbg_set_memory_guard(void)
{
static const struct opt_items names[MAXMEMGUARD] = {
{ "None", -1 },
{ "Flash ROM writes", -1 },
{ "Zero area (all)", -1 }
};
int mode = system_memory_guard(MEMGUARD_KEEP);
set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
system_memory_guard(mode);
return false;
}
bool debug_menu(void) bool debug_menu(void)
{ {
int m; int m;
@ -1524,6 +1551,7 @@ bool debug_menu(void)
#endif /* HAVE_RTC */ #endif /* HAVE_RTC */
#endif /* HAVE_LCD_BITMAP */ #endif /* HAVE_LCD_BITMAP */
{ "View OS stacks", dbg_os }, { "View OS stacks", dbg_os },
{ "Catch mem accesses", dbg_set_memory_guard },
#ifdef HAVE_MAS3507D #ifdef HAVE_MAS3507D
{ "View MAS info", dbg_mas_info }, { "View MAS info", dbg_mas_info },
#endif #endif

View file

@ -259,6 +259,9 @@ static const struct plugin_api rockbox_api = {
mpeg_get_file_pos, mpeg_get_file_pos,
find_next_frame, find_next_frame,
mpeg_get_last_header, mpeg_get_last_header,
#ifndef SIMULATOR
system_memory_guard,
#endif
}; };
int plugin_load(const char* plugin, void* parameter) int plugin_load(const char* plugin, void* parameter)

View file

@ -51,7 +51,7 @@
#ifdef PLUGIN #ifdef PLUGIN
#if defined(DEBUG) || defined(SIMULATOR) #if defined(DEBUG) || defined(SIMULATOR)
#define DEBUGF rb->debugf #define DEBUGF rb->debugf
#define LDEBUGF rb->debugf #define LDEBUGF rb->debugf
#else #else
#define DEBUGF(...) #define DEBUGF(...)
@ -60,7 +60,7 @@
#endif #endif
/* increase this every time the api struct changes */ /* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 26 #define PLUGIN_API_VERSION 27
/* update this to latest version if a change to the api struct breaks /* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any backwards compatibility (and please take the opportunity to sort in any
@ -295,6 +295,9 @@ struct plugin_api {
unsigned long (*find_next_frame)(int fd, int *offset, unsigned long (*find_next_frame)(int fd, int *offset,
int max_offset, unsigned long last_header); int max_offset, unsigned long last_header);
unsigned long (*mpeg_get_last_header)(void); unsigned long (*mpeg_get_last_header)(void);
#ifndef SIMULATOR
int (*system_memory_guard)(int newmode);
#endif
}; };
/* defined by the plugin loader (plugin.c) */ /* defined by the plugin loader (plugin.c) */

View file

@ -1010,6 +1010,8 @@ void DoUserDialog(char* filename)
enum plugin_status plugin_start(struct plugin_api* api, void* parameter) enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{ {
int oldmode;
/* this macro should be called as the first thing you do in the plugin. /* this macro should be called as the first thing you do in the plugin.
it test that the api version and model the plugin was compiled for it test that the api version and model the plugin was compiled for
matches the machine it is running on */ matches the machine it is running on */
@ -1018,7 +1020,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb = api; /* copy to global api pointer */ rb = api; /* copy to global api pointer */
/* now go ahead and have fun! */ /* now go ahead and have fun! */
oldmode = rb->system_memory_guard(MEMGUARD_NONE); /*disable memory guard */
DoUserDialog((char*) parameter); DoUserDialog((char*) parameter);
rb->system_memory_guard(oldmode); /* re-enable memory guard */
return PLUGIN_OK; return PLUGIN_OK;
} }

View file

@ -977,6 +977,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{ {
char* filename; char* filename;
bool show_greet; bool show_greet;
int oldmode;
/* this macro should be called as the first thing you do in the plugin. /* this macro should be called as the first thing you do in the plugin.
it test that the api version and model the plugin was compiled for it test that the api version and model the plugin was compiled for
@ -997,7 +998,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb = api; /* copy to global api pointer */ rb = api; /* copy to global api pointer */
/* now go ahead and have fun! */ /* now go ahead and have fun! */
oldmode = rb->system_memory_guard(MEMGUARD_NONE); /*disable memory guard */
DoUserDialog(filename, show_greet); DoUserDialog(filename, show_greet);
rb->system_memory_guard(oldmode); /* re-enable memory guard */
return PLUGIN_OK; return PLUGIN_OK;
} }

View file

@ -165,6 +165,17 @@ static inline int cas2 (volatile int *pointer1,volatile int *pointer2,int reques
return 0; 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 #endif
#endif #endif

View file

@ -315,7 +315,7 @@ void system_reboot (void)
ICR = 0; ICR = 0;
asm volatile ("jmp @%0; mov.l @%1,r15" : : 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 */ 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. */ WCR1 = 0x4000; /* Long wait states for CS6 (ATA), short for the rest. */
WCR3 = 0x8000; /* WAIT is pulled up, 1 state inserted for CS6 */ WCR3 = 0x8000; /* WAIT is pulled up, 1 state inserted for CS6 */
#endif #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;
} }