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"
33 #include "qom/object.h"
35 /* Same address of GDB integrated simulator */
36 #define SDRAM_BASE EXT_CS_BASE
38 struct RxGdbSimMachineClass
{
40 MachineClass parent_class
;
43 uint32_t xtal_freq_hz
;
45 typedef struct RxGdbSimMachineClass RxGdbSimMachineClass
;
47 struct RxGdbSimMachineState
{
49 MachineState parent_obj
;
53 typedef struct RxGdbSimMachineState RxGdbSimMachineState
;
55 #define TYPE_RX_GDBSIM_MACHINE MACHINE_TYPE_NAME("rx62n-common")
57 DECLARE_OBJ_CHECKERS(RxGdbSimMachineState
, RxGdbSimMachineClass
,
58 RX_GDBSIM_MACHINE
, TYPE_RX_GDBSIM_MACHINE
)
61 static void rx_load_image(RXCPU
*cpu
, const char *filename
,
62 uint32_t start
, uint32_t size
)
64 static uint32_t extable
[32];
68 kernel_size
= load_image_targphys(filename
, start
, size
);
69 if (kernel_size
< 0) {
70 fprintf(stderr
, "qemu: could not load kernel '%s'\n", filename
);
75 /* setup exception trap trampoline */
76 /* linux kernel only works little-endian mode */
77 for (i
= 0; i
< ARRAY_SIZE(extable
); i
++) {
78 extable
[i
] = cpu_to_le32(0x10 + i
* 4);
80 rom_add_blob_fixed("extable", extable
, sizeof(extable
), VECTOR_TABLE_BASE
);
83 static void rx_gdbsim_init(MachineState
*machine
)
85 MachineClass
*mc
= MACHINE_GET_CLASS(machine
);
86 RxGdbSimMachineState
*s
= RX_GDBSIM_MACHINE(machine
);
87 RxGdbSimMachineClass
*rxc
= RX_GDBSIM_MACHINE_GET_CLASS(machine
);
88 MemoryRegion
*sysmem
= get_system_memory();
89 const char *kernel_filename
= machine
->kernel_filename
;
90 const char *dtb_filename
= machine
->dtb
;
92 if (machine
->ram_size
< mc
->default_ram_size
) {
93 char *sz
= size_to_str(mc
->default_ram_size
);
94 error_report("Invalid RAM size, should be more than %s", sz
);
98 /* Allocate memory space */
99 memory_region_add_subregion(sysmem
, SDRAM_BASE
, machine
->ram
);
102 object_initialize_child(OBJECT(machine
), "mcu", &s
->mcu
, rxc
->mcu_name
);
103 object_property_set_link(OBJECT(&s
->mcu
), "main-bus", OBJECT(sysmem
),
105 object_property_set_uint(OBJECT(&s
->mcu
), "xtal-frequency-hz",
106 rxc
->xtal_freq_hz
, &error_abort
);
107 object_property_set_bool(OBJECT(&s
->mcu
), "load-kernel",
108 kernel_filename
!= NULL
, &error_abort
);
110 if (!kernel_filename
) {
111 if (machine
->firmware
) {
112 rom_add_file_fixed(machine
->firmware
, RX62N_CFLASH_BASE
, 0);
113 } else if (!qtest_enabled()) {
114 error_report("No bios or kernel specified");
119 qdev_realize(DEVICE(&s
->mcu
), NULL
, &error_abort
);
121 /* Load kernel and dtb */
122 if (kernel_filename
) {
123 ram_addr_t kernel_offset
;
126 * The kernel image is loaded into
127 * the latter half of the SDRAM space.
129 kernel_offset
= machine
->ram_size
/ 2;
130 rx_load_image(RX_CPU(first_cpu
), kernel_filename
,
131 SDRAM_BASE
+ kernel_offset
, kernel_offset
);
133 ram_addr_t dtb_offset
;
135 g_autofree
void *dtb
= load_device_tree(dtb_filename
, &dtb_size
);
138 error_report("Couldn't open dtb file %s", dtb_filename
);
141 if (machine
->kernel_cmdline
&&
142 qemu_fdt_setprop_string(dtb
, "/chosen", "bootargs",
143 machine
->kernel_cmdline
) < 0) {
144 error_report("Couldn't set /chosen/bootargs");
147 /* DTB is located at the end of SDRAM space. */
148 dtb_offset
= machine
->ram_size
- dtb_size
;
149 rom_add_blob_fixed("dtb", dtb
, dtb_size
,
150 SDRAM_BASE
+ dtb_offset
);
151 /* Set dtb address to R1 */
152 RX_CPU(first_cpu
)->env
.regs
[1] = SDRAM_BASE
+ dtb_offset
;
157 static void rx_gdbsim_class_init(ObjectClass
*oc
, void *data
)
159 MachineClass
*mc
= MACHINE_CLASS(oc
);
161 mc
->init
= rx_gdbsim_init
;
162 mc
->default_cpu_type
= TYPE_RX62N_CPU
;
163 mc
->default_ram_size
= 16 * MiB
;
164 mc
->default_ram_id
= "ext-sdram";
167 static void rx62n7_class_init(ObjectClass
*oc
, void *data
)
169 RxGdbSimMachineClass
*rxc
= RX_GDBSIM_MACHINE_CLASS(oc
);
170 MachineClass
*mc
= MACHINE_CLASS(oc
);
172 rxc
->mcu_name
= TYPE_R5F562N7_MCU
;
173 rxc
->xtal_freq_hz
= 12 * 1000 * 1000;
174 mc
->desc
= "gdb simulator (R5F562N7 MCU and external RAM)";
177 static void rx62n8_class_init(ObjectClass
*oc
, void *data
)
179 RxGdbSimMachineClass
*rxc
= RX_GDBSIM_MACHINE_CLASS(oc
);
180 MachineClass
*mc
= MACHINE_CLASS(oc
);
182 rxc
->mcu_name
= TYPE_R5F562N8_MCU
;
183 rxc
->xtal_freq_hz
= 12 * 1000 * 1000;
184 mc
->desc
= "gdb simulator (R5F562N8 MCU and external RAM)";
187 static const TypeInfo rx_gdbsim_types
[] = {
189 .name
= MACHINE_TYPE_NAME("gdbsim-r5f562n7"),
190 .parent
= TYPE_RX_GDBSIM_MACHINE
,
191 .class_init
= rx62n7_class_init
,
193 .name
= MACHINE_TYPE_NAME("gdbsim-r5f562n8"),
194 .parent
= TYPE_RX_GDBSIM_MACHINE
,
195 .class_init
= rx62n8_class_init
,
197 .name
= TYPE_RX_GDBSIM_MACHINE
,
198 .parent
= TYPE_MACHINE
,
199 .instance_size
= sizeof(RxGdbSimMachineState
),
200 .class_size
= sizeof(RxGdbSimMachineClass
),
201 .class_init
= rx_gdbsim_class_init
,
206 DEFINE_TYPES(rx_gdbsim_types
)