Statistics
| Branch: | Revision:

root / hw / sbi.c @ a1e47211

History | View | Annotate | Download (4.1 kB)

1
/*
2
 * QEMU Sparc SBI interrupt controller emulation
3
 *
4
 * Based on slavio_intctl, copyright (c) 2003-2005 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
#include "sysbus.h"
26

    
27
//#define DEBUG_IRQ
28

    
29
#ifdef DEBUG_IRQ
30
#define DPRINTF(fmt, ...)                                       \
31
    do { printf("IRQ: " fmt , ## __VA_ARGS__); } while (0)
32
#else
33
#define DPRINTF(fmt, ...)
34
#endif
35

    
36
#define MAX_CPUS 16
37

    
38
#define SBI_NREGS 16
39

    
40
typedef struct SBIState {
41
    SysBusDevice busdev;
42
    MemoryRegion iomem;
43
    uint32_t regs[SBI_NREGS];
44
    uint32_t intreg_pending[MAX_CPUS];
45
    qemu_irq cpu_irqs[MAX_CPUS];
46
    uint32_t pil_out[MAX_CPUS];
47
} SBIState;
48

    
49
#define SBI_SIZE (SBI_NREGS * 4)
50

    
51
static void sbi_set_irq(void *opaque, int irq, int level)
52
{
53
}
54

    
55
static uint64_t sbi_mem_read(void *opaque, target_phys_addr_t addr,
56
                             unsigned size)
57
{
58
    SBIState *s = opaque;
59
    uint32_t saddr, ret;
60

    
61
    saddr = addr >> 2;
62
    switch (saddr) {
63
    default:
64
        ret = s->regs[saddr];
65
        break;
66
    }
67
    DPRINTF("read system reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
68

    
69
    return ret;
70
}
71

    
72
static void sbi_mem_write(void *opaque, target_phys_addr_t addr,
73
                          uint64_t val, unsigned dize)
74
{
75
    SBIState *s = opaque;
76
    uint32_t saddr;
77

    
78
    saddr = addr >> 2;
79
    DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, (int)val);
80
    switch (saddr) {
81
    default:
82
        s->regs[saddr] = val;
83
        break;
84
    }
85
}
86

    
87
static const MemoryRegionOps sbi_mem_ops = {
88
    .read = sbi_mem_read,
89
    .write = sbi_mem_write,
90
    .endianness = DEVICE_NATIVE_ENDIAN,
91
    .valid = {
92
        .min_access_size = 4,
93
        .max_access_size = 4,
94
    },
95
};
96

    
97
static const VMStateDescription vmstate_sbi = {
98
    .name ="sbi",
99
    .version_id = 1,
100
    .minimum_version_id = 1,
101
    .minimum_version_id_old = 1,
102
    .fields      = (VMStateField []) {
103
        VMSTATE_UINT32_ARRAY(intreg_pending, SBIState, MAX_CPUS),
104
        VMSTATE_END_OF_LIST()
105
    }
106
};
107

    
108
static void sbi_reset(DeviceState *d)
109
{
110
    SBIState *s = container_of(d, SBIState, busdev.qdev);
111
    unsigned int i;
112

    
113
    for (i = 0; i < MAX_CPUS; i++) {
114
        s->intreg_pending[i] = 0;
115
    }
116
}
117

    
118
static int sbi_init1(SysBusDevice *dev)
119
{
120
    SBIState *s = FROM_SYSBUS(SBIState, dev);
121
    unsigned int i;
122

    
123
    qdev_init_gpio_in(&dev->qdev, sbi_set_irq, 32 + MAX_CPUS);
124
    for (i = 0; i < MAX_CPUS; i++) {
125
        sysbus_init_irq(dev, &s->cpu_irqs[i]);
126
    }
127

    
128
    memory_region_init_io(&s->iomem, &sbi_mem_ops, s, "sbi", SBI_SIZE);
129
    sysbus_init_mmio(dev, &s->iomem);
130

    
131
    return 0;
132
}
133

    
134
static void sbi_class_init(ObjectClass *klass, void *data)
135
{
136
    DeviceClass *dc = DEVICE_CLASS(klass);
137
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
138

    
139
    k->init = sbi_init1;
140
    dc->reset = sbi_reset;
141
    dc->vmsd = &vmstate_sbi;
142
}
143

    
144
static TypeInfo sbi_info = {
145
    .name          = "sbi",
146
    .parent        = TYPE_SYS_BUS_DEVICE,
147
    .instance_size = sizeof(SBIState),
148
    .class_init    = sbi_class_init,
149
};
150

    
151
static void sbi_register_types(void)
152
{
153
    type_register_static(&sbi_info);
154
}
155

    
156
type_init(sbi_register_types)