Commit 2dc9f4117c90c799bcdaacb3d29d2f0625bcc81c

Authored by aliguori
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);
... ...
... ... @@ -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  
... ...