]>
Commit | Line | Data |
---|---|---|
7d85892b BS |
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 | */ | |
7fc06735 | 24 | |
7d85892b BS |
25 | #include "hw.h" |
26 | #include "sun4m.h" | |
27 | #include "console.h" | |
7fc06735 | 28 | #include "sysbus.h" |
7d85892b BS |
29 | |
30 | //#define DEBUG_IRQ | |
31 | ||
32 | #ifdef DEBUG_IRQ | |
001faf32 BS |
33 | #define DPRINTF(fmt, ...) \ |
34 | do { printf("IRQ: " fmt , ## __VA_ARGS__); } while (0) | |
7d85892b | 35 | #else |
001faf32 | 36 | #define DPRINTF(fmt, ...) |
7d85892b BS |
37 | #endif |
38 | ||
39 | #define MAX_CPUS 16 | |
40 | ||
41 | #define SBI_NREGS 16 | |
42 | ||
43 | typedef struct SBIState { | |
7fc06735 | 44 | SysBusDevice busdev; |
7d85892b BS |
45 | uint32_t regs[SBI_NREGS]; |
46 | uint32_t intreg_pending[MAX_CPUS]; | |
7fc06735 | 47 | qemu_irq cpu_irqs[MAX_CPUS]; |
7d85892b BS |
48 | uint32_t pil_out[MAX_CPUS]; |
49 | } SBIState; | |
50 | ||
51 | #define SBI_SIZE (SBI_NREGS * 4) | |
7d85892b | 52 | |
7d85892b BS |
53 | static void sbi_set_irq(void *opaque, int irq, int level) |
54 | { | |
55 | } | |
56 | ||
7d85892b BS |
57 | static uint32_t sbi_mem_readl(void *opaque, target_phys_addr_t addr) |
58 | { | |
59 | SBIState *s = opaque; | |
60 | uint32_t saddr, ret; | |
61 | ||
e64d7d59 | 62 | saddr = addr >> 2; |
7d85892b BS |
63 | switch (saddr) { |
64 | default: | |
65 | ret = s->regs[saddr]; | |
66 | break; | |
67 | } | |
68 | DPRINTF("read system reg 0x" TARGET_FMT_plx " = %x\n", addr, ret); | |
69 | ||
70 | return ret; | |
71 | } | |
72 | ||
73 | static void sbi_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) | |
74 | { | |
75 | SBIState *s = opaque; | |
76 | uint32_t saddr; | |
77 | ||
e64d7d59 | 78 | saddr = addr >> 2; |
7d85892b BS |
79 | DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, val); |
80 | switch (saddr) { | |
81 | default: | |
82 | s->regs[saddr] = val; | |
83 | break; | |
84 | } | |
85 | } | |
86 | ||
87 | static CPUReadMemoryFunc *sbi_mem_read[3] = { | |
7c560456 BS |
88 | NULL, |
89 | NULL, | |
7d85892b BS |
90 | sbi_mem_readl, |
91 | }; | |
92 | ||
93 | static CPUWriteMemoryFunc *sbi_mem_write[3] = { | |
7c560456 BS |
94 | NULL, |
95 | NULL, | |
7d85892b BS |
96 | sbi_mem_writel, |
97 | }; | |
98 | ||
99 | static void sbi_save(QEMUFile *f, void *opaque) | |
100 | { | |
101 | SBIState *s = opaque; | |
102 | unsigned int i; | |
103 | ||
104 | for (i = 0; i < MAX_CPUS; i++) { | |
105 | qemu_put_be32s(f, &s->intreg_pending[i]); | |
106 | } | |
107 | } | |
108 | ||
109 | static int sbi_load(QEMUFile *f, void *opaque, int version_id) | |
110 | { | |
111 | SBIState *s = opaque; | |
112 | unsigned int i; | |
113 | ||
114 | if (version_id != 1) | |
115 | return -EINVAL; | |
116 | ||
117 | for (i = 0; i < MAX_CPUS; i++) { | |
118 | qemu_get_be32s(f, &s->intreg_pending[i]); | |
119 | } | |
7d85892b BS |
120 | |
121 | return 0; | |
122 | } | |
123 | ||
124 | static void sbi_reset(void *opaque) | |
125 | { | |
126 | SBIState *s = opaque; | |
127 | unsigned int i; | |
128 | ||
129 | for (i = 0; i < MAX_CPUS; i++) { | |
130 | s->intreg_pending[i] = 0; | |
131 | } | |
7d85892b BS |
132 | } |
133 | ||
7fc06735 BS |
134 | static void sbi_init1(SysBusDevice *dev) |
135 | { | |
136 | SBIState *s = FROM_SYSBUS(SBIState, dev); | |
137 | int sbi_io_memory; | |
138 | unsigned int i; | |
139 | ||
140 | qdev_init_gpio_in(&dev->qdev, sbi_set_irq, 32 + MAX_CPUS); | |
141 | for (i = 0; i < MAX_CPUS; i++) { | |
142 | sysbus_init_irq(dev, &s->cpu_irqs[i]); | |
7d85892b BS |
143 | } |
144 | ||
1eed09cb | 145 | sbi_io_memory = cpu_register_io_memory(sbi_mem_read, sbi_mem_write, s); |
7fc06735 | 146 | sysbus_init_mmio(dev, SBI_SIZE, sbi_io_memory); |
7d85892b | 147 | |
7fc06735 | 148 | register_savevm("sbi", -1, 1, sbi_save, sbi_load, s); |
a08d4367 | 149 | qemu_register_reset(sbi_reset, s); |
7d85892b | 150 | sbi_reset(s); |
7fc06735 BS |
151 | } |
152 | ||
153 | static SysBusDeviceInfo sbi_info = { | |
154 | .init = sbi_init1, | |
155 | .qdev.name = "sbi", | |
156 | .qdev.size = sizeof(SBIState), | |
157 | }; | |
7d85892b | 158 | |
7fc06735 BS |
159 | static void sbi_register_devices(void) |
160 | { | |
161 | sysbus_register_withprop(&sbi_info); | |
7d85892b | 162 | } |
7fc06735 BS |
163 | |
164 | device_init(sbi_register_devices) |