Revision 426f5abc target-arm/helper.c
b/target-arm/helper.c | ||
---|---|---|
470 | 470 |
env->exception_index = -1; |
471 | 471 |
} |
472 | 472 |
|
473 |
/* Structure used to record exclusive memory locations. */ |
|
474 |
typedef struct mmon_state { |
|
475 |
struct mmon_state *next; |
|
476 |
CPUARMState *cpu_env; |
|
477 |
uint32_t addr; |
|
478 |
} mmon_state; |
|
479 |
|
|
480 |
/* Chain of current locks. */ |
|
481 |
static mmon_state* mmon_head = NULL; |
|
482 |
|
|
483 | 473 |
int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
484 | 474 |
int mmu_idx, int is_softmmu) |
485 | 475 |
{ |
... | ... | |
493 | 483 |
return 1; |
494 | 484 |
} |
495 | 485 |
|
496 |
static void allocate_mmon_state(CPUState *env) |
|
497 |
{ |
|
498 |
env->mmon_entry = malloc(sizeof (mmon_state)); |
|
499 |
memset (env->mmon_entry, 0, sizeof (mmon_state)); |
|
500 |
env->mmon_entry->cpu_env = env; |
|
501 |
mmon_head = env->mmon_entry; |
|
502 |
} |
|
503 |
|
|
504 |
/* Flush any monitor locks for the specified address. */ |
|
505 |
static void flush_mmon(uint32_t addr) |
|
506 |
{ |
|
507 |
mmon_state *mon; |
|
508 |
|
|
509 |
for (mon = mmon_head; mon; mon = mon->next) |
|
510 |
{ |
|
511 |
if (mon->addr != addr) |
|
512 |
continue; |
|
513 |
|
|
514 |
mon->addr = 0; |
|
515 |
break; |
|
516 |
} |
|
517 |
} |
|
518 |
|
|
519 |
/* Mark an address for exclusive access. */ |
|
520 |
void HELPER(mark_exclusive)(CPUState *env, uint32_t addr) |
|
521 |
{ |
|
522 |
if (!env->mmon_entry) |
|
523 |
allocate_mmon_state(env); |
|
524 |
/* Clear any previous locks. */ |
|
525 |
flush_mmon(addr); |
|
526 |
env->mmon_entry->addr = addr; |
|
527 |
} |
|
528 |
|
|
529 |
/* Test if an exclusive address is still exclusive. Returns zero |
|
530 |
if the address is still exclusive. */ |
|
531 |
uint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr) |
|
532 |
{ |
|
533 |
int res; |
|
534 |
|
|
535 |
if (!env->mmon_entry) |
|
536 |
return 1; |
|
537 |
if (env->mmon_entry->addr == addr) |
|
538 |
res = 0; |
|
539 |
else |
|
540 |
res = 1; |
|
541 |
flush_mmon(addr); |
|
542 |
return res; |
|
543 |
} |
|
544 |
|
|
545 |
void HELPER(clrex)(CPUState *env) |
|
546 |
{ |
|
547 |
if (!(env->mmon_entry && env->mmon_entry->addr)) |
|
548 |
return; |
|
549 |
flush_mmon(env->mmon_entry->addr); |
|
550 |
} |
|
551 |
|
|
552 | 486 |
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) |
553 | 487 |
{ |
554 | 488 |
return addr; |
... | ... | |
1273 | 1207 |
return phys_addr; |
1274 | 1208 |
} |
1275 | 1209 |
|
1276 |
/* Not really implemented. Need to figure out a sane way of doing this. |
|
1277 |
Maybe add generic watchpoint support and use that. */ |
|
1278 |
|
|
1279 |
void HELPER(mark_exclusive)(CPUState *env, uint32_t addr) |
|
1280 |
{ |
|
1281 |
env->mmon_addr = addr; |
|
1282 |
} |
|
1283 |
|
|
1284 |
uint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr) |
|
1285 |
{ |
|
1286 |
return (env->mmon_addr != addr); |
|
1287 |
} |
|
1288 |
|
|
1289 |
void HELPER(clrex)(CPUState *env) |
|
1290 |
{ |
|
1291 |
env->mmon_addr = -1; |
|
1292 |
} |
|
1293 |
|
|
1294 | 1210 |
void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val) |
1295 | 1211 |
{ |
1296 | 1212 |
int cp_num = (insn >> 8) & 0xf; |
Also available in: Unified diff