2 * RX QEMU GDB simulator
4 * Copyright (c) 2019 Yoshinori Sato
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2 or later, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
20 #include "qemu/cutils.h"
21 #include "qemu/error-report.h"
22 #include "qapi/error.h"
23 #include "qemu-common.h"
26 #include "hw/sysbus.h"
27 #include "hw/loader.h"
28 #include "hw/rx/rx62n.h"
29 #include "sysemu/sysemu.h"
30 #include "sysemu/qtest.h"
31 #include "sysemu/device_tree.h"
32 #include "hw/boards.h"
34 /* Same address of GDB integrated simulator */
35 #define SDRAM_BASE EXT_CS_BASE
37 typedef struct RxGdbSimMachineClass
{
39 MachineClass parent_class
;
42 uint32_t xtal_freq_hz
;
43 } RxGdbSimMachineClass
;
45 typedef struct RxGdbSimMachineState
{
47 MachineState parent_obj
;
50 } RxGdbSimMachineState
;
52 #define TYPE_RX_GDBSIM_MACHINE MACHINE_TYPE_NAME("rx62n-common")
54 #define RX_GDBSIM_MACHINE(obj) \
55 OBJECT_CHECK(RxGdbSimMachineState, (obj), TYPE_RX_GDBSIM_MACHINE)
57 #define RX_GDBSIM_MACHINE_CLASS(klass) \
58 OBJECT_CLASS_CHECK(RxGdbSimMachineClass, (klass), TYPE_RX_GDBSIM_MACHINE)
59 #define RX_GDBSIM_MACHINE_GET_CLASS(obj) \
60 OBJECT_GET_CLASS(RxGdbSimMachineClass, (obj), TYPE_RX_GDBSIM_MACHINE)
62 static void rx_load_image(RXCPU
*cpu
, const char *filename
,
63 uint32_t start
, uint32_t size
)
65 static uint32_t extable
[32];
69 kernel_size
= load_image_targphys(filename
, start
, size
);
70 if (kernel_size
< 0) {
71 fprintf(stderr
, "qemu: could not load kernel '%s'\n", filename
);
76 /* setup exception trap trampoline */
77 /* linux kernel only works little-endian mode */
78 for (i
= 0; i
< ARRAY_SIZE(extable
); i
++) {
79 extable
[i
] = cpu_to_le32(0x10 + i
* 4);
81 rom_add_blob_fixed("extable", extable
, sizeof(extable
), VECTOR_TABLE_BASE
);
84 static void rx_gdbsim_init(MachineState
*machine
)
86 MachineClass
*mc
= MACHINE_GET_CLASS(machine
);
87 RxGdbSimMachineState
*s
= RX_GDBSIM_MACHINE(machine
);
88 RxGdbSimMachineClass
*rxc
= RX_GDBSIM_MACHINE_GET_CLASS(machine
);
89 MemoryRegion
*sysmem
= get_system_memory();
90 const char *kernel_filename
= machine
->kernel_filename
;
91 const char *dtb_filename
= machine
->dtb
;
93 if (machine
->ram_size
< mc
->default_ram_size
) {
94 char *sz
= size_to_str(mc
->default_ram_size
);
95 error_report("Invalid RAM size, should be more than %s", sz
);
99 /* Allocate memory space */
100 memory_region_add_subregion(sysmem
, SDRAM_BASE
, machine
->ram
);
103 object_initialize_child(OBJECT(machine
), "mcu", &s
->mcu
, rxc
->mcu_name
);
104 object_property_set_link(OBJECT(&s
->mcu
), "main-bus", OBJECT(sysmem
),
106 object_property_set_uint(OBJECT(&s
->mcu
), "xtal-frequency-hz",
107 rxc
->xtal_freq_hz
, &error_abort
);
108 object_property_set_bool(OBJECT(&s
->mcu
), "load-kernel",
109 kernel_filename
!= NULL
, &error_abort
);
110 qdev_realize(DEVICE(&s
->mcu
), NULL
, &error_abort
);
112 /* Load kernel and dtb */
113 if (kernel_filename
) {
114 ram_addr_t kernel_offset
;
117 * The kernel image is loaded into
118 * the latter half of the SDRAM space.
120 kernel_offset
= machine
->ram_size
/ 2;
121 rx_load_image(RXCPU(first_cpu
), kernel_filename
,
122 SDRAM_BASE
+ kernel_offset
, kernel_offset
);
124 ram_addr_t dtb_offset
;
128 dtb
= load_device_tree(dtb_filename
, &dtb_size
);
130 error_report("Couldn't open dtb file %s", dtb_filename
);
133 if (machine
->kernel_cmdline
&&
134 qemu_fdt_setprop_string(dtb
, "/chosen", "bootargs",
135 machine
->kernel_cmdline
) < 0) {
136 error_report("Couldn't set /chosen/bootargs");
139 /* DTB is located at the end of SDRAM space. */
140 dtb_offset
= machine
->ram_size
- dtb_size
;
141 rom_add_blob_fixed("dtb", dtb
, dtb_size
,
142 SDRAM_BASE
+ dtb_offset
);
143 /* Set dtb address to R1 */
144 RXCPU(first_cpu
)->env
.regs
[1] = SDRAM_BASE
+ dtb_offset
;
149 static void rx_gdbsim_class_init(ObjectClass
*oc
, void *data
)
151 MachineClass
*mc
= MACHINE_CLASS(oc
);
153 mc
->init
= rx_gdbsim_init
;
154 mc
->default_cpu_type
= TYPE_RX62N_CPU
;
155 mc
->default_ram_size
= 16 * MiB
;
156 mc
->default_ram_id
= "ext-sdram";
159 static void rx62n7_class_init(ObjectClass
*oc
, void *data
)
161 RxGdbSimMachineClass
*rxc
= RX_GDBSIM_MACHINE_CLASS(oc
);
162 MachineClass
*mc
= MACHINE_CLASS(oc
);
164 rxc
->mcu_name
= TYPE_R5F562N7_MCU
;
165 rxc
->xtal_freq_hz
= 12 * 1000 * 1000;
166 mc
->desc
= "gdb simulator (R5F562N7 MCU and external RAM)";
169 static void rx62n8_class_init(ObjectClass
*oc
, void *data
)
171 RxGdbSimMachineClass
*rxc
= RX_GDBSIM_MACHINE_CLASS(oc
);
172 MachineClass
*mc
= MACHINE_CLASS(oc
);
174 rxc
->mcu_name
= TYPE_R5F562N8_MCU
;
175 rxc
->xtal_freq_hz
= 12 * 1000 * 1000;
176 mc
->desc
= "gdb simulator (R5F562N8 MCU and external RAM)";
179 static const TypeInfo rx_gdbsim_types
[] = {
181 .name
= MACHINE_TYPE_NAME("gdbsim-r5f562n7"),
182 .parent
= TYPE_RX_GDBSIM_MACHINE
,
183 .class_init
= rx62n7_class_init
,
185 .name
= MACHINE_TYPE_NAME("gdbsim-r5f562n8"),
186 .parent
= TYPE_RX_GDBSIM_MACHINE
,
187 .class_init
= rx62n8_class_init
,
189 .name
= TYPE_RX_GDBSIM_MACHINE
,
190 .parent
= TYPE_MACHINE
,
191 .instance_size
= sizeof(RxGdbSimMachineState
),
192 .class_size
= sizeof(RxGdbSimMachineClass
),
193 .class_init
= rx_gdbsim_class_init
,
198 DEFINE_TYPES(rx_gdbsim_types
)