cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

pxa2xx_pic.c (10540B)


      1/*
      2 * Intel XScale PXA Programmable Interrupt Controller.
      3 *
      4 * Copyright (c) 2006 Openedhand Ltd.
      5 * Copyright (c) 2006 Thorsten Zitterell
      6 * Written by Andrzej Zaborowski <balrog@zabor.org>
      7 *
      8 * This code is licensed under the GPL.
      9 */
     10
     11#include "qemu/osdep.h"
     12#include "qapi/error.h"
     13#include "qemu/module.h"
     14#include "qemu/log.h"
     15#include "cpu.h"
     16#include "hw/arm/pxa.h"
     17#include "hw/sysbus.h"
     18#include "migration/vmstate.h"
     19#include "qom/object.h"
     20
     21#define ICIP	0x00	/* Interrupt Controller IRQ Pending register */
     22#define ICMR	0x04	/* Interrupt Controller Mask register */
     23#define ICLR	0x08	/* Interrupt Controller Level register */
     24#define ICFP	0x0c	/* Interrupt Controller FIQ Pending register */
     25#define ICPR	0x10	/* Interrupt Controller Pending register */
     26#define ICCR	0x14	/* Interrupt Controller Control register */
     27#define ICHP	0x18	/* Interrupt Controller Highest Priority register */
     28#define IPR0	0x1c	/* Interrupt Controller Priority register 0 */
     29#define IPR31	0x98	/* Interrupt Controller Priority register 31 */
     30#define ICIP2	0x9c	/* Interrupt Controller IRQ Pending register 2 */
     31#define ICMR2	0xa0	/* Interrupt Controller Mask register 2 */
     32#define ICLR2	0xa4	/* Interrupt Controller Level register 2 */
     33#define ICFP2	0xa8	/* Interrupt Controller FIQ Pending register 2 */
     34#define ICPR2	0xac	/* Interrupt Controller Pending register 2 */
     35#define IPR32	0xb0	/* Interrupt Controller Priority register 32 */
     36#define IPR39	0xcc	/* Interrupt Controller Priority register 39 */
     37
     38#define PXA2XX_PIC_SRCS	40
     39
     40#define TYPE_PXA2XX_PIC "pxa2xx_pic"
     41OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPICState, PXA2XX_PIC)
     42
     43struct PXA2xxPICState {
     44    /*< private >*/
     45    SysBusDevice parent_obj;
     46    /*< public >*/
     47
     48    MemoryRegion iomem;
     49    ARMCPU *cpu;
     50    uint32_t int_enabled[2];
     51    uint32_t int_pending[2];
     52    uint32_t is_fiq[2];
     53    uint32_t int_idle;
     54    uint32_t priority[PXA2XX_PIC_SRCS];
     55};
     56
     57static void pxa2xx_pic_update(void *opaque)
     58{
     59    uint32_t mask[2];
     60    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
     61    CPUState *cpu = CPU(s->cpu);
     62
     63    if (cpu->halted) {
     64        mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
     65        mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
     66        if (mask[0] || mask[1]) {
     67            cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
     68        }
     69    }
     70
     71    mask[0] = s->int_pending[0] & s->int_enabled[0];
     72    mask[1] = s->int_pending[1] & s->int_enabled[1];
     73
     74    if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1])) {
     75        cpu_interrupt(cpu, CPU_INTERRUPT_FIQ);
     76    } else {
     77        cpu_reset_interrupt(cpu, CPU_INTERRUPT_FIQ);
     78    }
     79
     80    if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1])) {
     81        cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
     82    } else {
     83        cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
     84    }
     85}
     86
     87/* Note: Here level means state of the signal on a pin, not
     88 * IRQ/FIQ distinction as in PXA Developer Manual.  */
     89static void pxa2xx_pic_set_irq(void *opaque, int irq, int level)
     90{
     91    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
     92    int int_set = (irq >= 32);
     93    irq &= 31;
     94
     95    if (level)
     96        s->int_pending[int_set] |= 1 << irq;
     97    else
     98        s->int_pending[int_set] &= ~(1 << irq);
     99
    100    pxa2xx_pic_update(opaque);
    101}
    102
    103static inline uint32_t pxa2xx_pic_highest(PXA2xxPICState *s) {
    104    int i, int_set, irq;
    105    uint32_t bit, mask[2];
    106    uint32_t ichp = 0x003f003f;	/* Both IDs invalid */
    107
    108    mask[0] = s->int_pending[0] & s->int_enabled[0];
    109    mask[1] = s->int_pending[1] & s->int_enabled[1];
    110
    111    for (i = PXA2XX_PIC_SRCS - 1; i >= 0; i --) {
    112        irq = s->priority[i] & 0x3f;
    113        if ((s->priority[i] & (1U << 31)) && irq < PXA2XX_PIC_SRCS) {
    114            /* Source peripheral ID is valid.  */
    115            bit = 1 << (irq & 31);
    116            int_set = (irq >= 32);
    117
    118            if (mask[int_set] & bit & s->is_fiq[int_set]) {
    119                /* FIQ asserted */
    120                ichp &= 0xffff0000;
    121                ichp |= (1 << 15) | irq;
    122            }
    123
    124            if (mask[int_set] & bit & ~s->is_fiq[int_set]) {
    125                /* IRQ asserted */
    126                ichp &= 0x0000ffff;
    127                ichp |= (1U << 31) | (irq << 16);
    128            }
    129        }
    130    }
    131
    132    return ichp;
    133}
    134
    135static uint64_t pxa2xx_pic_mem_read(void *opaque, hwaddr offset,
    136                                    unsigned size)
    137{
    138    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
    139
    140    switch (offset) {
    141    case ICIP:	/* IRQ Pending register */
    142        return s->int_pending[0] & ~s->is_fiq[0] & s->int_enabled[0];
    143    case ICIP2:	/* IRQ Pending register 2 */
    144        return s->int_pending[1] & ~s->is_fiq[1] & s->int_enabled[1];
    145    case ICMR:	/* Mask register */
    146        return s->int_enabled[0];
    147    case ICMR2:	/* Mask register 2 */
    148        return s->int_enabled[1];
    149    case ICLR:	/* Level register */
    150        return s->is_fiq[0];
    151    case ICLR2:	/* Level register 2 */
    152        return s->is_fiq[1];
    153    case ICCR:	/* Idle mask */
    154        return (s->int_idle == 0);
    155    case ICFP:	/* FIQ Pending register */
    156        return s->int_pending[0] & s->is_fiq[0] & s->int_enabled[0];
    157    case ICFP2:	/* FIQ Pending register 2 */
    158        return s->int_pending[1] & s->is_fiq[1] & s->int_enabled[1];
    159    case ICPR:	/* Pending register */
    160        return s->int_pending[0];
    161    case ICPR2:	/* Pending register 2 */
    162        return s->int_pending[1];
    163    case IPR0  ... IPR31:
    164        return s->priority[0  + ((offset - IPR0 ) >> 2)];
    165    case IPR32 ... IPR39:
    166        return s->priority[32 + ((offset - IPR32) >> 2)];
    167    case ICHP:	/* Highest Priority register */
    168        return pxa2xx_pic_highest(s);
    169    default:
    170        qemu_log_mask(LOG_GUEST_ERROR,
    171                      "pxa2xx_pic_mem_read: bad register offset 0x%" HWADDR_PRIx
    172                      "\n", offset);
    173        return 0;
    174    }
    175}
    176
    177static void pxa2xx_pic_mem_write(void *opaque, hwaddr offset,
    178                                 uint64_t value, unsigned size)
    179{
    180    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
    181
    182    switch (offset) {
    183    case ICMR:	/* Mask register */
    184        s->int_enabled[0] = value;
    185        break;
    186    case ICMR2:	/* Mask register 2 */
    187        s->int_enabled[1] = value;
    188        break;
    189    case ICLR:	/* Level register */
    190        s->is_fiq[0] = value;
    191        break;
    192    case ICLR2:	/* Level register 2 */
    193        s->is_fiq[1] = value;
    194        break;
    195    case ICCR:	/* Idle mask */
    196        s->int_idle = (value & 1) ? 0 : ~0;
    197        break;
    198    case IPR0  ... IPR31:
    199        s->priority[0  + ((offset - IPR0 ) >> 2)] = value & 0x8000003f;
    200        break;
    201    case IPR32 ... IPR39:
    202        s->priority[32 + ((offset - IPR32) >> 2)] = value & 0x8000003f;
    203        break;
    204    default:
    205        qemu_log_mask(LOG_GUEST_ERROR,
    206                      "pxa2xx_pic_mem_write: bad register offset 0x%"
    207                      HWADDR_PRIx "\n", offset);
    208        return;
    209    }
    210    pxa2xx_pic_update(opaque);
    211}
    212
    213/* Interrupt Controller Coprocessor Space Register Mapping */
    214static const int pxa2xx_cp_reg_map[0x10] = {
    215    [0x0 ... 0xf] = -1,
    216    [0x0] = ICIP,
    217    [0x1] = ICMR,
    218    [0x2] = ICLR,
    219    [0x3] = ICFP,
    220    [0x4] = ICPR,
    221    [0x5] = ICHP,
    222    [0x6] = ICIP2,
    223    [0x7] = ICMR2,
    224    [0x8] = ICLR2,
    225    [0x9] = ICFP2,
    226    [0xa] = ICPR2,
    227};
    228
    229static uint64_t pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri)
    230{
    231    int offset = pxa2xx_cp_reg_map[ri->crn];
    232    return pxa2xx_pic_mem_read(ri->opaque, offset, 4);
    233}
    234
    235static void pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
    236                                uint64_t value)
    237{
    238    int offset = pxa2xx_cp_reg_map[ri->crn];
    239    pxa2xx_pic_mem_write(ri->opaque, offset, value, 4);
    240}
    241
    242#define REGINFO_FOR_PIC_CP(NAME, CRN) \
    243    { .name = NAME, .cp = 6, .crn = CRN, .crm = 0, .opc1 = 0, .opc2 = 0, \
    244      .access = PL1_RW, .type = ARM_CP_IO, \
    245      .readfn = pxa2xx_pic_cp_read, .writefn = pxa2xx_pic_cp_write }
    246
    247static const ARMCPRegInfo pxa_pic_cp_reginfo[] = {
    248    REGINFO_FOR_PIC_CP("ICIP", 0),
    249    REGINFO_FOR_PIC_CP("ICMR", 1),
    250    REGINFO_FOR_PIC_CP("ICLR", 2),
    251    REGINFO_FOR_PIC_CP("ICFP", 3),
    252    REGINFO_FOR_PIC_CP("ICPR", 4),
    253    REGINFO_FOR_PIC_CP("ICHP", 5),
    254    REGINFO_FOR_PIC_CP("ICIP2", 6),
    255    REGINFO_FOR_PIC_CP("ICMR2", 7),
    256    REGINFO_FOR_PIC_CP("ICLR2", 8),
    257    REGINFO_FOR_PIC_CP("ICFP2", 9),
    258    REGINFO_FOR_PIC_CP("ICPR2", 0xa),
    259    REGINFO_SENTINEL
    260};
    261
    262static const MemoryRegionOps pxa2xx_pic_ops = {
    263    .read = pxa2xx_pic_mem_read,
    264    .write = pxa2xx_pic_mem_write,
    265    .endianness = DEVICE_NATIVE_ENDIAN,
    266};
    267
    268static int pxa2xx_pic_post_load(void *opaque, int version_id)
    269{
    270    pxa2xx_pic_update(opaque);
    271    return 0;
    272}
    273
    274DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
    275{
    276    DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
    277    PXA2xxPICState *s = PXA2XX_PIC(dev);
    278
    279    s->cpu = cpu;
    280
    281    s->int_pending[0] = 0;
    282    s->int_pending[1] = 0;
    283    s->int_enabled[0] = 0;
    284    s->int_enabled[1] = 0;
    285    s->is_fiq[0] = 0;
    286    s->is_fiq[1] = 0;
    287
    288    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    289
    290    qdev_init_gpio_in(dev, pxa2xx_pic_set_irq, PXA2XX_PIC_SRCS);
    291
    292    /* Enable IC memory-mapped registers access.  */
    293    memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_pic_ops, s,
    294                          "pxa2xx-pic", 0x00100000);
    295    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
    296    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
    297
    298    /* Enable IC coprocessor access.  */
    299    define_arm_cp_regs_with_opaque(cpu, pxa_pic_cp_reginfo, s);
    300
    301    return dev;
    302}
    303
    304static const VMStateDescription vmstate_pxa2xx_pic_regs = {
    305    .name = "pxa2xx_pic",
    306    .version_id = 0,
    307    .minimum_version_id = 0,
    308    .post_load = pxa2xx_pic_post_load,
    309    .fields = (VMStateField[]) {
    310        VMSTATE_UINT32_ARRAY(int_enabled, PXA2xxPICState, 2),
    311        VMSTATE_UINT32_ARRAY(int_pending, PXA2xxPICState, 2),
    312        VMSTATE_UINT32_ARRAY(is_fiq, PXA2xxPICState, 2),
    313        VMSTATE_UINT32(int_idle, PXA2xxPICState),
    314        VMSTATE_UINT32_ARRAY(priority, PXA2xxPICState, PXA2XX_PIC_SRCS),
    315        VMSTATE_END_OF_LIST(),
    316    },
    317};
    318
    319static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
    320{
    321    DeviceClass *dc = DEVICE_CLASS(klass);
    322
    323    dc->desc = "PXA2xx PIC";
    324    dc->vmsd = &vmstate_pxa2xx_pic_regs;
    325}
    326
    327static const TypeInfo pxa2xx_pic_info = {
    328    .name          = TYPE_PXA2XX_PIC,
    329    .parent        = TYPE_SYS_BUS_DEVICE,
    330    .instance_size = sizeof(PXA2xxPICState),
    331    .class_init    = pxa2xx_pic_class_init,
    332};
    333
    334static void pxa2xx_pic_register_types(void)
    335{
    336    type_register_static(&pxa2xx_pic_info);
    337}
    338
    339type_init(pxa2xx_pic_register_types)