1 /* 2 * RX62N Microcontroller 3 * 4 * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware 5 * (Rev.1.40 R01UH0033EJ0140) 6 * 7 * Copyright (c) 2019 Yoshinori Sato 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms and conditions of the GNU General Public License, 11 * version 2 or later, as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 * more details. 17 * 18 * You should have received a copy of the GNU General Public License along with 19 * this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include "qemu/osdep.h" 23 #include "qapi/error.h" 24 #include "qemu/error-report.h" 25 #include "hw/hw.h" 26 #include "hw/rx/rx62n.h" 27 #include "hw/loader.h" 28 #include "hw/sysbus.h" 29 #include "hw/qdev-properties.h" 30 #include "sysemu/sysemu.h" 31 #include "sysemu/qtest.h" 32 #include "cpu.h" 33 34 /* 35 * RX62N Internal Memory 36 */ 37 #define RX62N_IRAM_BASE 0x00000000 38 #define RX62N_DFLASH_BASE 0x00100000 39 #define RX62N_CFLASH_BASE 0xfff80000 40 41 /* 42 * RX62N Peripheral Address 43 * See users manual section 5 44 */ 45 #define RX62N_ICU_BASE 0x00087000 46 #define RX62N_TMR_BASE 0x00088200 47 #define RX62N_CMT_BASE 0x00088000 48 #define RX62N_SCI_BASE 0x00088240 49 50 /* 51 * RX62N Peripheral IRQ 52 * See users manual section 11 53 */ 54 #define RX62N_TMR_IRQ 174 55 #define RX62N_CMT_IRQ 28 56 #define RX62N_SCI_IRQ 214 57 58 /* 59 * IRQ -> IPR mapping table 60 * 0x00 - 0x91: IPR no (IPR00 to IPR91) 61 * 0xff: IPR not assigned 62 * See "11.3.1 Interrupt Vector Table" in hardware manual. 63 */ 64 static const uint8_t ipr_table[NR_IRQS] = { 65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 15 */ 67 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x02, 68 0xff, 0xff, 0xff, 0x03, 0x04, 0x05, 0x06, 0x07, /* 31 */ 69 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 70 0x10, 0x11, 0x12, 0x13, 0x14, 0x14, 0x14, 0x14, /* 47 */ 71 0x15, 0x15, 0x15, 0x15, 0xff, 0xff, 0xff, 0xff, 72 0x18, 0x18, 0x18, 0x18, 0x18, 0x1d, 0x1e, 0x1f, /* 63 */ 73 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 74 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 79 */ 75 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 76 0xff, 0xff, 0x3a, 0x3b, 0x3c, 0xff, 0xff, 0xff, /* 95 */ 77 0x40, 0xff, 0x44, 0x45, 0xff, 0xff, 0x48, 0xff, 78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 111 */ 79 0xff, 0xff, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 80 0x52, 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x56, /* 127 */ 81 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, 0x59, 0x59, 82 0x59, 0x59, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, /* 143 */ 83 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 84 0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x62, 0x62, /* 159 */ 85 0x62, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x66, 86 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, /* 175 */ 87 0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 88 0x6b, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 191 */ 89 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x71, 90 0x72, 0x73, 0x74, 0x75, 0xff, 0xff, 0xff, 0xff, /* 207 */ 91 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 92 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, /* 223 */ 93 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0xff, 0xff, 94 0xff, 0xff, 0x85, 0x85, 0x85, 0x85, 0x86, 0x86, /* 239 */ 95 0x86, 0x86, 0xff, 0xff, 0xff, 0xff, 0x88, 0x89, 96 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, /* 255 */ 97 }; 98 99 /* 100 * Level triggerd IRQ list 101 * Not listed IRQ is Edge trigger. 102 * See "11.3.1 Interrupt Vector Table" in hardware manual. 103 */ 104 static const uint8_t levelirq[] = { 105 16, 21, 32, 44, 47, 48, 51, 64, 65, 66, 106 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 107 77, 78, 79, 90, 91, 170, 171, 172, 173, 214, 108 217, 218, 221, 222, 225, 226, 229, 234, 237, 238, 109 241, 246, 249, 250, 253, 110 }; 111 112 static void register_icu(RX62NState *s) 113 { 114 int i; 115 SysBusDevice *icu; 116 117 object_initialize_child(OBJECT(s), "icu", &s->icu, TYPE_RX_ICU); 118 icu = SYS_BUS_DEVICE(&s->icu); 119 qdev_prop_set_uint32(DEVICE(icu), "len-ipr-map", NR_IRQS); 120 for (i = 0; i < NR_IRQS; i++) { 121 char propname[32]; 122 snprintf(propname, sizeof(propname), "ipr-map[%d]", i); 123 qdev_prop_set_uint32(DEVICE(icu), propname, ipr_table[i]); 124 } 125 qdev_prop_set_uint32(DEVICE(icu), "len-trigger-level", 126 ARRAY_SIZE(levelirq)); 127 for (i = 0; i < ARRAY_SIZE(levelirq); i++) { 128 char propname[32]; 129 snprintf(propname, sizeof(propname), "trigger-level[%d]", i); 130 qdev_prop_set_uint32(DEVICE(icu), propname, levelirq[i]); 131 } 132 133 for (i = 0; i < NR_IRQS; i++) { 134 s->irq[i] = qdev_get_gpio_in(DEVICE(icu), i); 135 } 136 sysbus_realize(icu, &error_abort); 137 sysbus_connect_irq(icu, 0, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_IRQ)); 138 sysbus_connect_irq(icu, 1, qdev_get_gpio_in(DEVICE(&s->cpu), RX_CPU_FIR)); 139 sysbus_connect_irq(icu, 2, s->irq[SWI]); 140 sysbus_mmio_map(SYS_BUS_DEVICE(icu), 0, RX62N_ICU_BASE); 141 } 142 143 static void register_tmr(RX62NState *s, int unit) 144 { 145 SysBusDevice *tmr; 146 int i, irqbase; 147 148 object_initialize_child(OBJECT(s), "tmr[*]", 149 &s->tmr[unit], TYPE_RENESAS_TMR); 150 tmr = SYS_BUS_DEVICE(&s->tmr[unit]); 151 qdev_prop_set_uint64(DEVICE(tmr), "input-freq", RX62N_PCLK); 152 sysbus_realize(tmr, &error_abort); 153 154 irqbase = RX62N_TMR_IRQ + TMR_NR_IRQ * unit; 155 for (i = 0; i < TMR_NR_IRQ; i++) { 156 sysbus_connect_irq(tmr, i, s->irq[irqbase + i]); 157 } 158 sysbus_mmio_map(tmr, 0, RX62N_TMR_BASE + unit * 0x10); 159 } 160 161 static void register_cmt(RX62NState *s, int unit) 162 { 163 SysBusDevice *cmt; 164 int i, irqbase; 165 166 object_initialize_child(OBJECT(s), "cmt[*]", 167 &s->cmt[unit], TYPE_RENESAS_CMT); 168 cmt = SYS_BUS_DEVICE(&s->cmt[unit]); 169 qdev_prop_set_uint64(DEVICE(cmt), "input-freq", RX62N_PCLK); 170 sysbus_realize(cmt, &error_abort); 171 172 irqbase = RX62N_CMT_IRQ + CMT_NR_IRQ * unit; 173 for (i = 0; i < CMT_NR_IRQ; i++) { 174 sysbus_connect_irq(cmt, i, s->irq[irqbase + i]); 175 } 176 sysbus_mmio_map(cmt, 0, RX62N_CMT_BASE + unit * 0x10); 177 } 178 179 static void register_sci(RX62NState *s, int unit) 180 { 181 SysBusDevice *sci; 182 int i, irqbase; 183 184 object_initialize_child(OBJECT(s), "sci[*]", 185 &s->sci[unit], TYPE_RENESAS_SCI); 186 sci = SYS_BUS_DEVICE(&s->sci[unit]); 187 qdev_prop_set_chr(DEVICE(sci), "chardev", serial_hd(unit)); 188 qdev_prop_set_uint64(DEVICE(sci), "input-freq", RX62N_PCLK); 189 sysbus_realize(sci, &error_abort); 190 191 irqbase = RX62N_SCI_IRQ + SCI_NR_IRQ * unit; 192 for (i = 0; i < SCI_NR_IRQ; i++) { 193 sysbus_connect_irq(sci, i, s->irq[irqbase + i]); 194 } 195 sysbus_mmio_map(sci, 0, RX62N_SCI_BASE + unit * 0x08); 196 } 197 198 static void rx62n_realize(DeviceState *dev, Error **errp) 199 { 200 RX62NState *s = RX62N_MCU(dev); 201 202 memory_region_init_ram(&s->iram, OBJECT(dev), "iram", 203 RX62N_IRAM_SIZE, &error_abort); 204 memory_region_add_subregion(s->sysmem, RX62N_IRAM_BASE, &s->iram); 205 memory_region_init_rom(&s->d_flash, OBJECT(dev), "flash-data", 206 RX62N_DFLASH_SIZE, &error_abort); 207 memory_region_add_subregion(s->sysmem, RX62N_DFLASH_BASE, &s->d_flash); 208 memory_region_init_rom(&s->c_flash, OBJECT(dev), "flash-code", 209 RX62N_CFLASH_SIZE, &error_abort); 210 memory_region_add_subregion(s->sysmem, RX62N_CFLASH_BASE, &s->c_flash); 211 212 if (!s->kernel) { 213 if (bios_name) { 214 rom_add_file_fixed(bios_name, RX62N_CFLASH_BASE, 0); 215 } else if (!qtest_enabled()) { 216 error_report("No bios or kernel specified"); 217 exit(1); 218 } 219 } 220 221 /* Initialize CPU */ 222 object_initialize_child(OBJECT(s), "cpu", &s->cpu, TYPE_RX62N_CPU); 223 qdev_realize(DEVICE(&s->cpu), NULL, &error_abort); 224 225 register_icu(s); 226 s->cpu.env.ack = qdev_get_gpio_in_named(DEVICE(&s->icu), "ack", 0); 227 register_tmr(s, 0); 228 register_tmr(s, 1); 229 register_cmt(s, 0); 230 register_cmt(s, 1); 231 register_sci(s, 0); 232 } 233 234 static Property rx62n_properties[] = { 235 DEFINE_PROP_LINK("main-bus", RX62NState, sysmem, TYPE_MEMORY_REGION, 236 MemoryRegion *), 237 DEFINE_PROP_BOOL("load-kernel", RX62NState, kernel, false), 238 DEFINE_PROP_END_OF_LIST(), 239 }; 240 241 static void rx62n_class_init(ObjectClass *klass, void *data) 242 { 243 DeviceClass *dc = DEVICE_CLASS(klass); 244 245 dc->realize = rx62n_realize; 246 device_class_set_props(dc, rx62n_properties); 247 } 248 249 static const TypeInfo rx62n_info = { 250 .name = TYPE_RX62N_MCU, 251 .parent = TYPE_DEVICE, 252 .instance_size = sizeof(RX62NState), 253 .class_init = rx62n_class_init, 254 }; 255 256 static void rx62n_register_types(void) 257 { 258 type_register_static(&rx62n_info); 259 } 260 261 type_init(rx62n_register_types) 262