Commit 2dc9f4117c90c799bcdaacb3d29d2f0625bcc81c
1 parent
dde2367e
Introduce BP_CPU as a breakpoint type (Jan Kiszka)
Add another breakpoint/watchpoint type to BP_GDB: BP_CPU. This type is intended for hardware-assisted break/watchpoint emulations like the x86 architecture requires. To keep the highest priority for BP_GDB breakpoints, this type is always inserted at the head of break/watchpoint lists, thus is found first when looking up the origin of a debug interruption. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5746 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
39 additions
and
8 deletions
cpu-all.h
... | ... | @@ -768,6 +768,7 @@ void cpu_reset_interrupt(CPUState *env, int mask); |
768 | 768 | #define BP_STOP_BEFORE_ACCESS 0x04 |
769 | 769 | #define BP_WATCHPOINT_HIT 0x08 |
770 | 770 | #define BP_GDB 0x10 |
771 | +#define BP_CPU 0x20 | |
771 | 772 | |
772 | 773 | int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags, |
773 | 774 | CPUBreakpoint **breakpoint); | ... | ... |
exec.c
... | ... | @@ -1302,7 +1302,7 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len, |
1302 | 1302 | int flags, CPUWatchpoint **watchpoint) |
1303 | 1303 | { |
1304 | 1304 | target_ulong len_mask = ~(len - 1); |
1305 | - CPUWatchpoint *wp; | |
1305 | + CPUWatchpoint *wp, *prev_wp; | |
1306 | 1306 | |
1307 | 1307 | /* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */ |
1308 | 1308 | if ((len != 1 && len != 2 && len != 4 && len != 8) || (addr & ~len_mask)) { |
... | ... | @@ -1318,11 +1318,26 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len, |
1318 | 1318 | wp->len_mask = len_mask; |
1319 | 1319 | wp->flags = flags; |
1320 | 1320 | |
1321 | - wp->next = env->watchpoints; | |
1322 | - wp->prev = NULL; | |
1321 | + /* keep all GDB-injected watchpoints in front */ | |
1322 | + if (!(flags & BP_GDB) && env->watchpoints) { | |
1323 | + prev_wp = env->watchpoints; | |
1324 | + while (prev_wp->next != NULL && (prev_wp->next->flags & BP_GDB)) | |
1325 | + prev_wp = prev_wp->next; | |
1326 | + } else { | |
1327 | + prev_wp = NULL; | |
1328 | + } | |
1329 | + | |
1330 | + /* Insert new watchpoint */ | |
1331 | + if (prev_wp) { | |
1332 | + wp->next = prev_wp->next; | |
1333 | + prev_wp->next = wp; | |
1334 | + } else { | |
1335 | + wp->next = env->watchpoints; | |
1336 | + env->watchpoints = wp; | |
1337 | + } | |
1323 | 1338 | if (wp->next) |
1324 | 1339 | wp->next->prev = wp; |
1325 | - env->watchpoints = wp; | |
1340 | + wp->prev = prev_wp; | |
1326 | 1341 | |
1327 | 1342 | tlb_flush_page(env, addr); |
1328 | 1343 | |
... | ... | @@ -1378,7 +1393,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags, |
1378 | 1393 | CPUBreakpoint **breakpoint) |
1379 | 1394 | { |
1380 | 1395 | #if defined(TARGET_HAS_ICE) |
1381 | - CPUBreakpoint *bp; | |
1396 | + CPUBreakpoint *bp, *prev_bp; | |
1382 | 1397 | |
1383 | 1398 | bp = qemu_malloc(sizeof(*bp)); |
1384 | 1399 | if (!bp) |
... | ... | @@ -1387,11 +1402,26 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags, |
1387 | 1402 | bp->pc = pc; |
1388 | 1403 | bp->flags = flags; |
1389 | 1404 | |
1390 | - bp->next = env->breakpoints; | |
1391 | - bp->prev = NULL; | |
1405 | + /* keep all GDB-injected breakpoints in front */ | |
1406 | + if (!(flags & BP_GDB) && env->breakpoints) { | |
1407 | + prev_bp = env->breakpoints; | |
1408 | + while (prev_bp->next != NULL && (prev_bp->next->flags & BP_GDB)) | |
1409 | + prev_bp = prev_bp->next; | |
1410 | + } else { | |
1411 | + prev_bp = NULL; | |
1412 | + } | |
1413 | + | |
1414 | + /* Insert new breakpoint */ | |
1415 | + if (prev_bp) { | |
1416 | + bp->next = prev_bp->next; | |
1417 | + prev_bp->next = bp; | |
1418 | + } else { | |
1419 | + bp->next = env->breakpoints; | |
1420 | + env->breakpoints = bp; | |
1421 | + } | |
1392 | 1422 | if (bp->next) |
1393 | 1423 | bp->next->prev = bp; |
1394 | - env->breakpoints = bp; | |
1424 | + bp->prev = prev_bp; | |
1395 | 1425 | |
1396 | 1426 | breakpoint_invalidate(env, pc); |
1397 | 1427 | ... | ... |