Revision dc2a9045 hw/pxa2xx.c

b/hw/pxa2xx.c
324 324
    }
325 325
}
326 326

  
327
/* Performace Monitoring Registers */
328
#define CPPMNC		0	/* Performance Monitor Control register */
329
#define CPCCNT		1	/* Clock Counter register */
330
#define CPINTEN		4	/* Interrupt Enable register */
331
#define CPFLAG		5	/* Overflow Flag register */
332
#define CPEVTSEL	8	/* Event Selection register */
333

  
334
#define CPPMN0		0	/* Performance Count register 0 */
335
#define CPPMN1		1	/* Performance Count register 1 */
336
#define CPPMN2		2	/* Performance Count register 2 */
337
#define CPPMN3		3	/* Performance Count register 3 */
338

  
339
static uint32_t pxa2xx_perf_read(void *opaque, int op2, int reg, int crm)
340
{
341
    PXA2xxState *s = (PXA2xxState *) opaque;
342

  
343
    switch (reg) {
344
    case CPPMNC:
345
        return s->pmnc;
346
    case CPCCNT:
347
        if (s->pmnc & 1)
348
            return qemu_get_clock_ns(vm_clock);
349
        else
350
            return 0;
351
    case CPINTEN:
352
    case CPFLAG:
353
    case CPEVTSEL:
354
        return 0;
355

  
356
    default:
357
        printf("%s: Bad register 0x%x\n", __FUNCTION__, reg);
358
        break;
359
    }
360
    return 0;
361
}
362

  
363
static void pxa2xx_perf_write(void *opaque, int op2, int reg, int crm,
364
                uint32_t value)
365
{
366
    PXA2xxState *s = (PXA2xxState *) opaque;
367

  
368
    switch (reg) {
369
    case CPPMNC:
370
        s->pmnc = value;
371
        break;
372

  
373
    case CPCCNT:
374
    case CPINTEN:
375
    case CPFLAG:
376
    case CPEVTSEL:
377
        break;
378

  
379
    default:
380
        printf("%s: Bad register 0x%x\n", __FUNCTION__, reg);
381
        break;
382
    }
383
}
384

  
385 327
static uint32_t pxa2xx_cp14_read(void *opaque, int op2, int reg, int crm)
386 328
{
387 329
    switch (crm) {
388 330
    case 0:
389 331
        return pxa2xx_clkpwr_read(opaque, op2, reg, crm);
390
    case 1:
391
        return pxa2xx_perf_read(opaque, op2, reg, crm);
392
    case 2:
393
        switch (reg) {
394
        case CPPMN0:
395
        case CPPMN1:
396
        case CPPMN2:
397
        case CPPMN3:
398
            return 0;
399
        }
400
        /* Fall through */
401 332
    default:
402 333
        printf("%s: Bad register 0x%x\n", __FUNCTION__, reg);
403 334
        break;
......
412 343
    case 0:
413 344
        pxa2xx_clkpwr_write(opaque, op2, reg, crm, value);
414 345
        break;
415
    case 1:
416
        pxa2xx_perf_write(opaque, op2, reg, crm, value);
417
        break;
418
    case 2:
419
        switch (reg) {
420
        case CPPMN0:
421
        case CPPMN1:
422
        case CPPMN2:
423
        case CPPMN3:
424
            return;
425
        }
426
        /* Fall through */
427 346
    default:
428 347
        printf("%s: Bad register 0x%x\n", __FUNCTION__, reg);
429 348
        break;
430 349
    }
431 350
}
432 351

  
352
static int pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri,
353
                              uint64_t *value)
354
{
355
    PXA2xxState *s = (PXA2xxState *)ri->opaque;
356
    *value = s->pmnc;
357
    return 0;
358
}
359

  
360
static int pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
361
                               uint64_t value)
362
{
363
    PXA2xxState *s = (PXA2xxState *)ri->opaque;
364
    s->pmnc = value;
365
    return 0;
366
}
367

  
368
static int pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
369
                              uint64_t *value)
370
{
371
    PXA2xxState *s = (PXA2xxState *)ri->opaque;
372
    if (s->pmnc & 1) {
373
        *value = qemu_get_clock_ns(vm_clock);
374
    } else {
375
        *value = 0;
376
    }
377
    return 0;
378
}
379

  
380
static const ARMCPRegInfo pxa_cp_reginfo[] = {
381
    /* cp14 crn==1: perf registers */
382
    { .name = "CPPMNC", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
383
      .access = PL1_RW,
384
      .readfn = pxa2xx_cppmnc_read, .writefn = pxa2xx_cppmnc_write },
385
    { .name = "CPCCNT", .cp = 14, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
386
      .access = PL1_RW,
387
      .readfn = pxa2xx_cpccnt_read, .writefn = arm_cp_write_ignore },
388
    { .name = "CPINTEN", .cp = 14, .crn = 1, .crm = 4, .opc1 = 0, .opc2 = 0,
389
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
390
    { .name = "CPFLAG", .cp = 14, .crn = 1, .crm = 5, .opc1 = 0, .opc2 = 0,
391
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
392
    { .name = "CPEVTSEL", .cp = 14, .crn = 1, .crm = 8, .opc1 = 0, .opc2 = 0,
393
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
394
    /* cp14 crn==2: performance count registers */
395
    { .name = "CPPMN0", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
396
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
397
    { .name = "CPPMN1", .cp = 14, .crn = 2, .crm = 1, .opc1 = 0, .opc2 = 0,
398
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
399
    { .name = "CPPMN2", .cp = 14, .crn = 2, .crm = 2, .opc1 = 0, .opc2 = 0,
400
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
401
    { .name = "CPPMN3", .cp = 14, .crn = 2, .crm = 3, .opc1 = 0, .opc2 = 0,
402
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
403
    REGINFO_SENTINEL
404
};
405

  
406
static void pxa2xx_setup_cp14(PXA2xxState *s)
407
{
408
    define_arm_cp_regs_with_opaque(s->cpu, pxa_cp_reginfo, s);
409
}
410

  
433 411
#define MDCNFG		0x00	/* SDRAM Configuration register */
434 412
#define MDREFR		0x04	/* SDRAM Refresh Control register */
435 413
#define MSC0		0x08	/* Static Memory Control register 0 */
......
2134 2112
    vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
2135 2113

  
2136 2114
    cpu_arm_set_cp_io(&s->cpu->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
2115
    pxa2xx_setup_cp14(s);
2137 2116

  
2138 2117
    s->mm_base = 0x48000000;
2139 2118
    s->mm_regs[MDMRS >> 2] = 0x00020002;
......
2265 2244
    vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
2266 2245

  
2267 2246
    cpu_arm_set_cp_io(&s->cpu->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
2247
    pxa2xx_setup_cp14(s);
2268 2248

  
2269 2249
    s->mm_base = 0x48000000;
2270 2250
    s->mm_regs[MDMRS >> 2] = 0x00020002;

Also available in: Unified diff