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

@ -122,7 +122,7 @@ bool dbg_os(void)
usage = thread_stack_usage(currval);
snprintf(buf, 32, "%d: %d%% ", currval, usage);
lcd_puts(0, 1, buf);
button = button_get_w_tmo(HZ/10);
switch(button)
@ -130,7 +130,7 @@ bool dbg_os(void)
case BUTTON_STOP:
return false;
case BUTTON_LEFT:
case BUTTON_LEFT:
currval--;
if(currval < 0)
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 */
unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
bool has_bootrom; /* flag for boot ROM present */
int oldmode; /* saved memory guard mode */
if(PADR & 0x400)
usb_polarity = 0; /* Negative */
@ -312,6 +313,8 @@ bool dbg_hw_info(void)
else
pr_polarity = 1; /* Positive */
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)
@ -325,6 +328,8 @@ bool dbg_hw_info(void)
rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
}
system_memory_guard(oldmode); /* re-enable memory guard */
lcd_setmargins(0, 0);
lcd_setfont(FONT_SYSFIXED);
lcd_clear_display();
@ -389,12 +394,15 @@ bool dbg_hw_info(void)
bool got_id; /* flag if we managed to get the flash IDs */
unsigned rom_crc = 0xFFFF; /* CRC16 of the boot ROM */
bool has_bootrom; /* flag for boot ROM present */
int oldmode; /* saved memory guard mode */
if(PADR & 0x400)
usb_polarity = 0; /* Negative */
else
usb_polarity = 1; /* Positive */
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)
@ -407,6 +415,8 @@ bool dbg_hw_info(void)
/* calculate CRC16 checksum of boot ROM */
rom_crc = crc_16((unsigned char*)0x0000, 64*1024);
}
system_memory_guard(oldmode); /* re-enable memory guard */
lcd_clear_display();
@ -579,7 +589,7 @@ bool dbg_ports(void)
snprintf(buf, 32, "ATA: %s, 0x%x",
ata_device?"slave":"master", ata_io_address);
lcd_puts(0, 7, buf);
lcd_update();
button = button_get_w_tmo(HZ/10);
@ -1440,6 +1450,7 @@ static bool dbg_disk_info(void)
bool dbg_save_roms(void)
{
int fd;
int oldmode = system_memory_guard(MEMGUARD_NONE);
fd = creat("/internal_rom_0000-FFFF.bin", O_WRONLY);
if(fd >= 0)
@ -1455,6 +1466,7 @@ bool dbg_save_roms(void)
close(fd);
}
system_memory_guard(oldmode);
return false;
}
@ -1510,6 +1522,21 @@ bool dbg_screendump(void)
}
#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)
{
int m;
@ -1524,6 +1551,7 @@ bool debug_menu(void)
#endif /* HAVE_RTC */
#endif /* HAVE_LCD_BITMAP */
{ "View OS stacks", dbg_os },
{ "Catch mem accesses", dbg_set_memory_guard },
#ifdef HAVE_MAS3507D
{ "View MAS info", dbg_mas_info },
#endif

View file

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

View file

@ -51,7 +51,7 @@
#ifdef PLUGIN
#if defined(DEBUG) || defined(SIMULATOR)
#define DEBUGF rb->debugf
#define DEBUGF rb->debugf
#define LDEBUGF rb->debugf
#else
#define DEBUGF(...)
@ -60,7 +60,7 @@
#endif
/* 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
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,
int max_offset, unsigned long last_header);
unsigned long (*mpeg_get_last_header)(void);
#ifndef SIMULATOR
int (*system_memory_guard)(int newmode);
#endif
};
/* 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)
{
int oldmode;
/* 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
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 */
/* now go ahead and have fun! */
oldmode = rb->system_memory_guard(MEMGUARD_NONE); /*disable memory guard */
DoUserDialog((char*) parameter);
rb->system_memory_guard(oldmode); /* re-enable memory guard */
return PLUGIN_OK;
}

View file

@ -977,6 +977,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{
char* filename;
bool show_greet;
int oldmode;
/* 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
@ -997,7 +998,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb = api; /* copy to global api pointer */
/* now go ahead and have fun! */
oldmode = rb->system_memory_guard(MEMGUARD_NONE); /*disable memory guard */
DoUserDialog(filename, show_greet);
rb->system_memory_guard(oldmode); /* re-enable memory guard */
return PLUGIN_OK;
}

View file

@ -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

View file

@ -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;
}