diff --git a/include/gint/ubc.h b/include/gint/ubc.h index d858948..97f6371 100644 --- a/include/gint/ubc.h +++ b/include/gint/ubc.h @@ -27,6 +27,10 @@ void ubc_debug_handler(gdb_cpu_state_t* cpu_state); the UBC is reached. */ void ubc_set_debug_handler(void (*h)(gdb_cpu_state_t*)); +/* ubc_dbh_lock: Lock set by ubc_dbh() when a UBC break is currently being + handled. */ +extern uint8_t ubc_dbh_lock; + /* UBC Breakpoint types */ typedef enum { UBC_BREAK_BEFORE, /* Break before the instruction is executed */ diff --git a/src/ubc/ubc.S b/src/ubc/ubc.S index da31041..fc956f6 100644 --- a/src/ubc/ubc.S +++ b/src/ubc/ubc.S @@ -39,6 +39,11 @@ _ubc_dbh: stc.l R1_BANK, @-r15 stc.l R0_BANK, @-r15 + /* We set the ubc_dbh_lock before enabling interrupts */ + mov.l .ubc_dbh_lock, r0 + mov #1, r1 + mov.b r1, @r0 + /* Enable interrupts and switch register bank Original SR is kept in r8 */ stc sr, r8 @@ -55,6 +60,12 @@ _ubc_dbh: /* Restore original SR to access the correct register bank */ ldc r8, sr + /* We can release the ubc_dbh_lock now that interrupts have been + disabled */ + mov.l .ubc_dbh_lock, r0 + mov #0, r1 + mov.b r1, @r0 + ldc.l @r15+, R0_BANK ldc.l @r15+, R1_BANK ldc.l @r15+, R2_BANK @@ -83,7 +94,12 @@ _ubc_dbh: .align 4 .handler: .long _ubc_debug_handler +.ubc_dbh_lock: .long _ubc_dbh_lock .sr_mask: .long ~0x300000f0 /* IMASK = 0 : mask no interrupts BL = 0 : do not block interrupts RB = 0 : use register BANK0 */ + +.data +.global _ubc_dbh_lock +_ubc_dbh_lock: .byte 0