Statistics
| Branch: | Revision:

root / hw / puv3_intc.c @ 7830cf78

History | View | Annotate | Download (3.2 kB)

1 5c8556a6 Guan Xuetao
/*
2 5c8556a6 Guan Xuetao
 * INTC device simulation in PKUnity SoC
3 5c8556a6 Guan Xuetao
 *
4 5c8556a6 Guan Xuetao
 * Copyright (C) 2010-2012 Guan Xuetao
5 5c8556a6 Guan Xuetao
 *
6 5c8556a6 Guan Xuetao
 * This program is free software; you can redistribute it and/or modify
7 5c8556a6 Guan Xuetao
 * it under the terms of the GNU General Public License version 2 as
8 5c8556a6 Guan Xuetao
 * published by the Free Software Foundation, or any later version.
9 5c8556a6 Guan Xuetao
 * See the COPYING file in the top-level directory.
10 5c8556a6 Guan Xuetao
 */
11 5c8556a6 Guan Xuetao
#include "sysbus.h"
12 5c8556a6 Guan Xuetao
13 5c8556a6 Guan Xuetao
#undef DEBUG_PUV3
14 5c8556a6 Guan Xuetao
#include "puv3.h"
15 5c8556a6 Guan Xuetao
16 5c8556a6 Guan Xuetao
typedef struct {
17 5c8556a6 Guan Xuetao
    SysBusDevice busdev;
18 5c8556a6 Guan Xuetao
    MemoryRegion iomem;
19 5c8556a6 Guan Xuetao
    qemu_irq parent_irq;
20 5c8556a6 Guan Xuetao
21 5c8556a6 Guan Xuetao
    uint32_t reg_ICMR;
22 5c8556a6 Guan Xuetao
    uint32_t reg_ICPR;
23 5c8556a6 Guan Xuetao
} PUV3INTCState;
24 5c8556a6 Guan Xuetao
25 5c8556a6 Guan Xuetao
/* Update interrupt status after enabled or pending bits have been changed.  */
26 5c8556a6 Guan Xuetao
static void puv3_intc_update(PUV3INTCState *s)
27 5c8556a6 Guan Xuetao
{
28 5c8556a6 Guan Xuetao
    if (s->reg_ICMR & s->reg_ICPR) {
29 5c8556a6 Guan Xuetao
        qemu_irq_raise(s->parent_irq);
30 5c8556a6 Guan Xuetao
    } else {
31 5c8556a6 Guan Xuetao
        qemu_irq_lower(s->parent_irq);
32 5c8556a6 Guan Xuetao
    }
33 5c8556a6 Guan Xuetao
}
34 5c8556a6 Guan Xuetao
35 5c8556a6 Guan Xuetao
/* Process a change in an external INTC input. */
36 5c8556a6 Guan Xuetao
static void puv3_intc_handler(void *opaque, int irq, int level)
37 5c8556a6 Guan Xuetao
{
38 5c8556a6 Guan Xuetao
    PUV3INTCState *s = opaque;
39 5c8556a6 Guan Xuetao
40 5c8556a6 Guan Xuetao
    DPRINTF("irq 0x%x, level 0x%x\n", irq, level);
41 5c8556a6 Guan Xuetao
    if (level) {
42 5c8556a6 Guan Xuetao
        s->reg_ICPR |= (1 << irq);
43 5c8556a6 Guan Xuetao
    } else {
44 5c8556a6 Guan Xuetao
        s->reg_ICPR &= ~(1 << irq);
45 5c8556a6 Guan Xuetao
    }
46 5c8556a6 Guan Xuetao
    puv3_intc_update(s);
47 5c8556a6 Guan Xuetao
}
48 5c8556a6 Guan Xuetao
49 a8170e5e Avi Kivity
static uint64_t puv3_intc_read(void *opaque, hwaddr offset,
50 5c8556a6 Guan Xuetao
        unsigned size)
51 5c8556a6 Guan Xuetao
{
52 5c8556a6 Guan Xuetao
    PUV3INTCState *s = opaque;
53 5c8556a6 Guan Xuetao
    uint32_t ret = 0;
54 5c8556a6 Guan Xuetao
55 5c8556a6 Guan Xuetao
    switch (offset) {
56 5c8556a6 Guan Xuetao
    case 0x04: /* INTC_ICMR */
57 5c8556a6 Guan Xuetao
        ret = s->reg_ICMR;
58 5c8556a6 Guan Xuetao
        break;
59 5c8556a6 Guan Xuetao
    case 0x0c: /* INTC_ICIP */
60 5c8556a6 Guan Xuetao
        ret = s->reg_ICPR; /* the same value with ICPR */
61 5c8556a6 Guan Xuetao
        break;
62 5c8556a6 Guan Xuetao
    default:
63 5c8556a6 Guan Xuetao
        DPRINTF("Bad offset %x\n", (int)offset);
64 5c8556a6 Guan Xuetao
    }
65 5c8556a6 Guan Xuetao
    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
66 5c8556a6 Guan Xuetao
    return ret;
67 5c8556a6 Guan Xuetao
}
68 5c8556a6 Guan Xuetao
69 a8170e5e Avi Kivity
static void puv3_intc_write(void *opaque, hwaddr offset,
70 5c8556a6 Guan Xuetao
        uint64_t value, unsigned size)
71 5c8556a6 Guan Xuetao
{
72 5c8556a6 Guan Xuetao
    PUV3INTCState *s = opaque;
73 5c8556a6 Guan Xuetao
74 5c8556a6 Guan Xuetao
    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
75 5c8556a6 Guan Xuetao
    switch (offset) {
76 5c8556a6 Guan Xuetao
    case 0x00: /* INTC_ICLR */
77 5c8556a6 Guan Xuetao
    case 0x14: /* INTC_ICCR */
78 5c8556a6 Guan Xuetao
        break;
79 5c8556a6 Guan Xuetao
    case 0x04: /* INTC_ICMR */
80 5c8556a6 Guan Xuetao
        s->reg_ICMR = value;
81 5c8556a6 Guan Xuetao
        break;
82 5c8556a6 Guan Xuetao
    default:
83 5c8556a6 Guan Xuetao
        DPRINTF("Bad offset 0x%x\n", (int)offset);
84 5c8556a6 Guan Xuetao
        return;
85 5c8556a6 Guan Xuetao
    }
86 5c8556a6 Guan Xuetao
    puv3_intc_update(s);
87 5c8556a6 Guan Xuetao
}
88 5c8556a6 Guan Xuetao
89 5c8556a6 Guan Xuetao
static const MemoryRegionOps puv3_intc_ops = {
90 5c8556a6 Guan Xuetao
    .read = puv3_intc_read,
91 5c8556a6 Guan Xuetao
    .write = puv3_intc_write,
92 5c8556a6 Guan Xuetao
    .impl = {
93 5c8556a6 Guan Xuetao
        .min_access_size = 4,
94 5c8556a6 Guan Xuetao
        .max_access_size = 4,
95 5c8556a6 Guan Xuetao
    },
96 5c8556a6 Guan Xuetao
    .endianness = DEVICE_NATIVE_ENDIAN,
97 5c8556a6 Guan Xuetao
};
98 5c8556a6 Guan Xuetao
99 5c8556a6 Guan Xuetao
static int puv3_intc_init(SysBusDevice *dev)
100 5c8556a6 Guan Xuetao
{
101 5c8556a6 Guan Xuetao
    PUV3INTCState *s = FROM_SYSBUS(PUV3INTCState, dev);
102 5c8556a6 Guan Xuetao
103 5c8556a6 Guan Xuetao
    qdev_init_gpio_in(&s->busdev.qdev, puv3_intc_handler, PUV3_IRQS_NR);
104 5c8556a6 Guan Xuetao
    sysbus_init_irq(&s->busdev, &s->parent_irq);
105 5c8556a6 Guan Xuetao
106 5c8556a6 Guan Xuetao
    s->reg_ICMR = 0;
107 5c8556a6 Guan Xuetao
    s->reg_ICPR = 0;
108 5c8556a6 Guan Xuetao
109 5c8556a6 Guan Xuetao
    memory_region_init_io(&s->iomem, &puv3_intc_ops, s, "puv3_intc",
110 5c8556a6 Guan Xuetao
            PUV3_REGS_OFFSET);
111 5c8556a6 Guan Xuetao
    sysbus_init_mmio(dev, &s->iomem);
112 5c8556a6 Guan Xuetao
113 5c8556a6 Guan Xuetao
    return 0;
114 5c8556a6 Guan Xuetao
}
115 5c8556a6 Guan Xuetao
116 5c8556a6 Guan Xuetao
static void puv3_intc_class_init(ObjectClass *klass, void *data)
117 5c8556a6 Guan Xuetao
{
118 5c8556a6 Guan Xuetao
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
119 5c8556a6 Guan Xuetao
120 5c8556a6 Guan Xuetao
    sdc->init = puv3_intc_init;
121 5c8556a6 Guan Xuetao
}
122 5c8556a6 Guan Xuetao
123 5c8556a6 Guan Xuetao
static const TypeInfo puv3_intc_info = {
124 5c8556a6 Guan Xuetao
    .name = "puv3_intc",
125 5c8556a6 Guan Xuetao
    .parent = TYPE_SYS_BUS_DEVICE,
126 5c8556a6 Guan Xuetao
    .instance_size = sizeof(PUV3INTCState),
127 5c8556a6 Guan Xuetao
    .class_init = puv3_intc_class_init,
128 5c8556a6 Guan Xuetao
};
129 5c8556a6 Guan Xuetao
130 5c8556a6 Guan Xuetao
static void puv3_intc_register_type(void)
131 5c8556a6 Guan Xuetao
{
132 5c8556a6 Guan Xuetao
    type_register_static(&puv3_intc_info);
133 5c8556a6 Guan Xuetao
}
134 5c8556a6 Guan Xuetao
135 5c8556a6 Guan Xuetao
type_init(puv3_intc_register_type)