qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

hw/rx: RX62N microcontroller (MCU)

rx62n - RX62N cpu.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
[PMD: Use TYPE_RX62N_CPU, use #define for RX62N_NR_TMR/CMT/SCI,
renamed CPU -> MCU, device -> microcontroller]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200224141923.82118-18-ysato@users.sourceforge.jp>
[PMD: Rebased on b77b5b3dc7, split of machine, use &error_abort]
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

authored by

Yoshinori Sato and committed by
Philippe Mathieu-Daudé
0c80f50f 645194c7

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