23
#include "qemu/osdep.h"
24
#include "qapi/error.h"
25
#include "qemu/error-report.h"
26
#include "qemu/units.h"
27
#include "hw/rx/rx62n.h"
30
#include "hw/qdev-properties.h"
31
#include "sysemu/sysemu.h"
32
#include "qapi/qmp/qlist.h"
33
#include "qom/object.h"
38
#define RX62N_IRAM_BASE 0x00000000
39
#define RX62N_DFLASH_BASE 0x00100000
40
#define RX62N_CFLASH_BASE 0xfff80000
46
#define RX62N_ICU_BASE 0x00087000
47
#define RX62N_TMR_BASE 0x00088200
48
#define RX62N_CMT_BASE 0x00088000
49
#define RX62N_SCI_BASE 0x00088240
55
#define RX62N_TMR_IRQ 174
56
#define RX62N_CMT_IRQ 28
57
#define RX62N_SCI_IRQ 214
59
#define RX62N_XTAL_MIN_HZ (8 * 1000 * 1000)
60
#define RX62N_XTAL_MAX_HZ (14 * 1000 * 1000)
61
#define RX62N_PCLK_MAX_HZ (50 * 1000 * 1000)
65
DeviceClass parent_class;
69
uint64_t rom_flash_size;
70
uint64_t data_flash_size;
72
typedef struct RX62NClass RX62NClass;
74
DECLARE_CLASS_CHECKERS(RX62NClass, RX62N_MCU,
83
static const uint8_t ipr_table[NR_IRQS] = {
84
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
85
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
86
0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x02,
87
0xff, 0xff, 0xff, 0x03, 0x04, 0x05, 0x06, 0x07,
88
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
89
0x10, 0x11, 0x12, 0x13, 0x14, 0x14, 0x14, 0x14,
90
0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff,
91
0x18, 0x18, 0x18, 0x18, 0x18, 0x1d, 0x1e, 0x1f,
92
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
93
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
94
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
95
0xff, 0xff, 0x3a, 0x3b, 0x3c, 0xff, 0xff, 0xff,
96
0x40, 0xff, 0x44, 0x45, 0xff, 0xff, 0x48, 0xff,
97
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
98
0xff, 0xff, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52,
99
0x52, 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x56,
100
0x56, 0x57, 0x57, 0x57, 0x57, 0x58, 0x59, 0x59,
101
0x59, 0x59, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c,
102
0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f,
103
0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x62, 0x62,
104
0x62, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x66,
105
0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68,
106
0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b,
107
0x6b, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x71,
109
0x72, 0x73, 0x74, 0x75, 0xff, 0xff, 0xff, 0xff,
110
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80,
111
0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82,
112
0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0xff, 0xff,
113
0xff, 0xff, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86,
114
0x86, 0x86, 0xff, 0xff, 0xff, 0xff, 0x88, 0x89,
115
0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91,
123
static const uint8_t levelirq[] = {
124
16, 21, 32, 44, 47, 48, 51, 64, 65, 66,
125
67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
126
77, 78, 79, 90, 91, 170, 171, 172, 173, 214,
127
217, 218, 221, 222, 225, 226, 229, 234, 237, 238,
128
241, 246, 249, 250, 253,
131
static void register_icu(RX62NState *s)
135
QList *ipr_map, *trigger_level;
137
object_initialize_child(OBJECT(s), "icu", &s->icu, TYPE_RX_ICU);
138
icu = SYS_BUS_DEVICE(&s->icu);
140
ipr_map = qlist_new();
141
for (i = 0; i < NR_IRQS; i++) {
142
qlist_append_int(ipr_map, ipr_table[i]);
144
qdev_prop_set_array(DEVICE(icu), "ipr-map", ipr_map);
146
trigger_level = qlist_new();
147
for (i = 0; i < ARRAY_SIZE(levelirq); i++) {
148
qlist_append_int(trigger_level, levelirq[i]);
150
qdev_prop_set_array(DEVICE(icu), "trigger-level", trigger_level);
151
sysbus_realize(icu, &error_abort);
153
sysbus_connect_irq(icu, 0, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_IRQ));
154
sysbus_connect_irq(icu, 1, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_FIR));
155
sysbus_connect_irq(icu, 2, qdev_get_gpio_in(DEVICE(&s->icu), SWI));
156
sysbus_mmio_map(icu, 0, RX62N_ICU_BASE);
159
static void register_tmr(RX62NState *s, int unit)
164
object_initialize_child(OBJECT(s), "tmr[*]",
165
&s->tmr[unit], TYPE_RENESAS_TMR);
166
tmr = SYS_BUS_DEVICE(&s->tmr[unit]);
167
qdev_prop_set_uint64(DEVICE(tmr), "input-freq", s->pclk_freq_hz);
168
sysbus_realize(tmr, &error_abort);
170
irqbase = RX62N_TMR_IRQ + TMR_NR_IRQ * unit;
171
for (i = 0; i < TMR_NR_IRQ; i++) {
172
sysbus_connect_irq(tmr, i,
173
qdev_get_gpio_in(DEVICE(&s->icu), irqbase + i));
175
sysbus_mmio_map(tmr, 0, RX62N_TMR_BASE + unit * 0x10);
178
static void register_cmt(RX62NState *s, int unit)
183
object_initialize_child(OBJECT(s), "cmt[*]",
184
&s->cmt[unit], TYPE_RENESAS_CMT);
185
cmt = SYS_BUS_DEVICE(&s->cmt[unit]);
186
qdev_prop_set_uint64(DEVICE(cmt), "input-freq", s->pclk_freq_hz);
187
sysbus_realize(cmt, &error_abort);
189
irqbase = RX62N_CMT_IRQ + CMT_NR_IRQ * unit;
190
for (i = 0; i < CMT_NR_IRQ; i++) {
191
sysbus_connect_irq(cmt, i,
192
qdev_get_gpio_in(DEVICE(&s->icu), irqbase + i));
194
sysbus_mmio_map(cmt, 0, RX62N_CMT_BASE + unit * 0x10);
197
static void register_sci(RX62NState *s, int unit)
202
object_initialize_child(OBJECT(s), "sci[*]",
203
&s->sci[unit], TYPE_RENESAS_SCI);
204
sci = SYS_BUS_DEVICE(&s->sci[unit]);
205
qdev_prop_set_chr(DEVICE(sci), "chardev", serial_hd(unit));
206
qdev_prop_set_uint64(DEVICE(sci), "input-freq", s->pclk_freq_hz);
207
sysbus_realize(sci, &error_abort);
209
irqbase = RX62N_SCI_IRQ + SCI_NR_IRQ * unit;
210
for (i = 0; i < SCI_NR_IRQ; i++) {
211
sysbus_connect_irq(sci, i,
212
qdev_get_gpio_in(DEVICE(&s->icu), irqbase + i));
214
sysbus_mmio_map(sci, 0, RX62N_SCI_BASE + unit * 0x08);
217
static void rx62n_realize(DeviceState *dev, Error **errp)
219
RX62NState *s = RX62N_MCU(dev);
220
RX62NClass *rxc = RX62N_MCU_GET_CLASS(dev);
222
if (s->xtal_freq_hz == 0) {
223
error_setg(errp, "\"xtal-frequency-hz\" property must be provided.");
227
if (s->xtal_freq_hz < RX62N_XTAL_MIN_HZ
228
|| s->xtal_freq_hz > RX62N_XTAL_MAX_HZ) {
229
error_setg(errp, "\"xtal-frequency-hz\" property in incorrect range.");
233
s->pclk_freq_hz = 4 * s->xtal_freq_hz;
235
assert(s->pclk_freq_hz <= RX62N_PCLK_MAX_HZ);
237
memory_region_init_ram(&s->iram, OBJECT(dev), "iram",
238
rxc->ram_size, &error_abort);
239
memory_region_add_subregion(s->sysmem, RX62N_IRAM_BASE, &s->iram);
240
memory_region_init_rom(&s->d_flash, OBJECT(dev), "flash-data",
241
rxc->data_flash_size, &error_abort);
242
memory_region_add_subregion(s->sysmem, RX62N_DFLASH_BASE, &s->d_flash);
243
memory_region_init_rom(&s->c_flash, OBJECT(dev), "flash-code",
244
rxc->rom_flash_size, &error_abort);
245
memory_region_add_subregion(s->sysmem, RX62N_CFLASH_BASE, &s->c_flash);
248
object_initialize_child(OBJECT(s), "cpu", &s->cpu, TYPE_RX62N_CPU);
249
qdev_realize(DEVICE(&s->cpu), NULL, &error_abort);
252
s->cpu.env.ack = qdev_get_gpio_in_named(DEVICE(&s->icu), "ack", 0);
260
static Property rx62n_properties[] = {
261
DEFINE_PROP_LINK("main-bus", RX62NState, sysmem, TYPE_MEMORY_REGION,
263
DEFINE_PROP_BOOL("load-kernel", RX62NState, kernel, false),
264
DEFINE_PROP_UINT32("xtal-frequency-hz", RX62NState, xtal_freq_hz, 0),
265
DEFINE_PROP_END_OF_LIST(),
268
static void rx62n_class_init(ObjectClass *klass, void *data)
270
DeviceClass *dc = DEVICE_CLASS(klass);
272
dc->realize = rx62n_realize;
273
device_class_set_props(dc, rx62n_properties);
276
static void r5f562n7_class_init(ObjectClass *oc, void *data)
278
RX62NClass *rxc = RX62N_MCU_CLASS(oc);
280
rxc->ram_size = 64 * KiB;
281
rxc->rom_flash_size = 384 * KiB;
282
rxc->data_flash_size = 32 * KiB;
285
static void r5f562n8_class_init(ObjectClass *oc, void *data)
287
RX62NClass *rxc = RX62N_MCU_CLASS(oc);
289
rxc->ram_size = 96 * KiB;
290
rxc->rom_flash_size = 512 * KiB;
291
rxc->data_flash_size = 32 * KiB;
294
static const TypeInfo rx62n_types[] = {
296
.name = TYPE_R5F562N7_MCU,
297
.parent = TYPE_RX62N_MCU,
298
.class_init = r5f562n7_class_init,
300
.name = TYPE_R5F562N8_MCU,
301
.parent = TYPE_RX62N_MCU,
302
.class_init = r5f562n8_class_init,
304
.name = TYPE_RX62N_MCU,
305
.parent = TYPE_DEVICE,
306
.instance_size = sizeof(RX62NState),
307
.class_size = sizeof(RX62NClass),
308
.class_init = rx62n_class_init,
313
DEFINE_TYPES(rx62n_types)