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