RISC-V Patches for the 5.0 Soft Freeze, Part 2

This is a fairly light-weight pull request, but I wanted to send it out to
 avoid the Goldfish stuff getting buried as the next PR should contain the H
 extension implementation.
 
 As far as this PR goes, it contains:
 
 * The addition of syscon device tree nodes for reboot and poweroff, which
   allows Linux to control QEMU without an additional driver.  The existing
   device was already compatible with the syscon interface.
 * A fix to our GDB stub to avoid confusing XLEN and FLEN, specifically useful
   for rv32id-based systems.
 * A device emulation for the Goldfish RTC device, a simple memory-mapped RTC.
 * The addition of the Goldfish RTC device to the RISC-V virt board.
 
 This passes "make check" and boots buildroot for me.
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCgAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAl5ByuQTHHBhbG1lckBk
 YWJiZWx0LmNvbQAKCRAuExnzX7sYid5gD/44YscK7P2tcFl+yDPJkUNV1Hja7iRM
 K14kuSHw2UoZ4DwQ69pmBJekrMDKHiI3HltXk51xLA6tQ9geubt6BAlwUeJfuIJQ
 DC9f9cN4x5OsJQZaFXcelR1vfpGntqQuKU6SXNHYTUTCL3fOEgpxaFm89pDevvxI
 Rvalg3OLrx4uAfjlllkpzKtcRjdytq08QJ8H6F0VbFY+uAwYosfxhst4M29XCLdA
 ESHqL8IgXNWcownIsx6cYwNkjOC7hE1vYwBjxbyLY85Y8frijnbB6JwVXH1YQWPz
 lTfCDCmBwBt7z5W16djZiib6A3Nlb7UMmOXuMFVWa9j6fECwCtC3Huvg80ofVtHB
 FBO03mT1FrElTZ5unJInTx8gQX2dHaDF8v6rEzYTeroaAbdexX401boWPKUYoqhR
 kDcdcAx4EsNfBOVQc40jAEyLHEs3yZ81os8G1H/ZafW2yj2Sob9NNvV57v8moVdp
 nZ+B4NNXrK+/lASnuW0eoIAcExTjhA9WDztacJR5mafTw4RmeIkbRrNPsekn8cHb
 FjaMFgA4+r44cUYMjuLO2zx20y3fCCmYUFP9heBbsvRhkTy0VMvMbt9B2zIY1v8n
 IQgVvqcrN9Epxvq+8vgC842p3TJii0KaAiF/YLZ1nHAfxRI1ax8gXDP3ak2abs0a
 xjC5FaAaeE0VRw==
 =D4dQ
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-5.0-sf2' into staging

RISC-V Patches for the 5.0 Soft Freeze, Part 2

This is a fairly light-weight pull request, but I wanted to send it out to
avoid the Goldfish stuff getting buried as the next PR should contain the H
extension implementation.

As far as this PR goes, it contains:

* The addition of syscon device tree nodes for reboot and poweroff, which
  allows Linux to control QEMU without an additional driver.  The existing
  device was already compatible with the syscon interface.
* A fix to our GDB stub to avoid confusing XLEN and FLEN, specifically useful
  for rv32id-based systems.
* A device emulation for the Goldfish RTC device, a simple memory-mapped RTC.
* The addition of the Goldfish RTC device to the RISC-V virt board.

This passes "make check" and boots buildroot for me.

# gpg: Signature made Mon 10 Feb 2020 21:28:04 GMT
# gpg:                using RSA key 2B3C3747446843B24A943A7A2E1319F35FBB1889
# gpg:                issuer "palmer@dabbelt.com"
# gpg: Good signature from "Palmer Dabbelt <palmer@dabbelt.com>" [unknown]
# gpg:                 aka "Palmer Dabbelt <palmer@sifive.com>" [unknown]
# gpg:                 aka "Palmer Dabbelt <palmerdabbelt@google.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 00CE 76D1 8349 60DF CE88  6DF8 EF4C A150 2CCB AB41
#      Subkey fingerprint: 2B3C 3747 4468 43B2 4A94  3A7A 2E13 19F3 5FBB 1889

* remotes/palmer/tags/riscv-for-master-5.0-sf2:
  MAINTAINERS: Add maintainer entry for Goldfish RTC
  riscv: virt: Use Goldfish RTC device
  hw: rtc: Add Goldfish RTC device
  riscv: Separate FPU register size from core register size in gdbstub [v2]
  riscv/virt: Add syscon reboot and poweroff DT nodes

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-02-14 18:37:11 +00:00
commit 971b2a1e5b
11 changed files with 401 additions and 15 deletions

View File

@ -562,6 +562,14 @@ F: include/hw/arm/digic.h
F: hw/*/digic*
F: include/hw/*/digic*
Goldfish RTC
M: Anup Patel <anup.patel@wdc.com>
M: Alistair Francis <Alistair.Francis@wdc.com>
L: qemu-riscv@nongnu.org
S: Maintained
F: hw/rtc/goldfish_rtc.c
F: include/hw/rtc/goldfish_rtc.h
Gumstix
M: Peter Maydell <peter.maydell@linaro.org>
R: Philippe Mathieu-Daudé <f4bug@amsat.org>

4
configure vendored
View File

@ -7739,13 +7739,13 @@ case "$target_name" in
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
mttcg=yes
gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-32bit-csr.xml riscv-32bit-virtual.xml"
gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-csr.xml riscv-32bit-virtual.xml"
;;
riscv64)
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
mttcg=yes
gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml riscv-64bit-csr.xml riscv-64bit-virtual.xml"
gdb_xml_files="riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-csr.xml riscv-64bit-virtual.xml"
;;
sh4|sh4eb)
TARGET_ARCH=sh4

View File

@ -34,6 +34,7 @@ config RISCV_VIRT
select PCI
select HART
select SERIAL
select GOLDFISH_RTC
select VIRTIO_MMIO
select PCI_EXPRESS_GENERIC_BRIDGE
select PFLASH_CFI01

View File

@ -58,6 +58,7 @@ static const struct MemmapEntry {
[VIRT_DEBUG] = { 0x0, 0x100 },
[VIRT_MROM] = { 0x1000, 0x11000 },
[VIRT_TEST] = { 0x100000, 0x1000 },
[VIRT_RTC] = { 0x101000, 0x1000 },
[VIRT_CLINT] = { 0x2000000, 0x10000 },
[VIRT_PLIC] = { 0xc000000, 0x4000000 },
[VIRT_UART0] = { 0x10000000, 0x100 },
@ -182,11 +183,10 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
uint64_t mem_size, const char *cmdline)
{
void *fdt;
int cpu;
int cpu, i;
uint32_t *cells;
char *nodename;
uint32_t plic_phandle, phandle = 1;
int i;
uint32_t plic_phandle, test_phandle, phandle = 1;
hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
@ -356,16 +356,35 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
create_pcie_irq_map(fdt, nodename, plic_phandle);
g_free(nodename);
test_phandle = phandle++;
nodename = g_strdup_printf("/test@%lx",
(long)memmap[VIRT_TEST].base);
qemu_fdt_add_subnode(fdt, nodename);
{
const char compat[] = "sifive,test1\0sifive,test0";
const char compat[] = "sifive,test1\0sifive,test0\0syscon";
qemu_fdt_setprop(fdt, nodename, "compatible", compat, sizeof(compat));
}
qemu_fdt_setprop_cells(fdt, nodename, "reg",
0x0, memmap[VIRT_TEST].base,
0x0, memmap[VIRT_TEST].size);
qemu_fdt_setprop_cell(fdt, nodename, "phandle", test_phandle);
test_phandle = qemu_fdt_get_phandle(fdt, nodename);
g_free(nodename);
nodename = g_strdup_printf("/reboot");
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_string(fdt, nodename, "compatible", "syscon-reboot");
qemu_fdt_setprop_cell(fdt, nodename, "regmap", test_phandle);
qemu_fdt_setprop_cell(fdt, nodename, "offset", 0x0);
qemu_fdt_setprop_cell(fdt, nodename, "value", FINISHER_RESET);
g_free(nodename);
nodename = g_strdup_printf("/poweroff");
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_string(fdt, nodename, "compatible", "syscon-poweroff");
qemu_fdt_setprop_cell(fdt, nodename, "regmap", test_phandle);
qemu_fdt_setprop_cell(fdt, nodename, "offset", 0x0);
qemu_fdt_setprop_cell(fdt, nodename, "value", FINISHER_PASS);
g_free(nodename);
nodename = g_strdup_printf("/uart@%lx",
@ -386,6 +405,18 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
}
g_free(nodename);
nodename = g_strdup_printf("/rtc@%lx",
(long)memmap[VIRT_RTC].base);
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_string(fdt, nodename, "compatible",
"google,goldfish-rtc");
qemu_fdt_setprop_cells(fdt, nodename, "reg",
0x0, memmap[VIRT_RTC].base,
0x0, memmap[VIRT_RTC].size);
qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
qemu_fdt_setprop_cell(fdt, nodename, "interrupts", RTC_IRQ);
g_free(nodename);
nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
qemu_fdt_add_subnode(s->fdt, nodename);
qemu_fdt_setprop_string(s->fdt, nodename, "compatible", "cfi-flash");
@ -583,6 +614,9 @@ static void riscv_virt_board_init(MachineState *machine)
0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
serial_hd(0), DEVICE_LITTLE_ENDIAN);
sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,
qdev_get_gpio_in(DEVICE(s->plic), RTC_IRQ));
virt_flash_create(s);
for (i = 0; i < ARRAY_SIZE(s->flash); i++) {

View File

@ -22,3 +22,6 @@ config MC146818RTC
config SUN4V_RTC
bool
config GOLDFISH_RTC
bool

View File

@ -11,3 +11,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
common-obj-$(CONFIG_ASPEED_SOC) += aspeed_rtc.o
common-obj-$(CONFIG_GOLDFISH_RTC) += goldfish_rtc.o

285
hw/rtc/goldfish_rtc.c Normal file
View File

@ -0,0 +1,285 @@
/*
* Goldfish virtual platform RTC
*
* Copyright (C) 2019 Western Digital Corporation or its affiliates.
*
* For more details on Google Goldfish virtual platform refer:
* https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-2.0-release/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2 or later, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "hw/rtc/goldfish_rtc.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "qemu/bitops.h"
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "trace.h"
#define RTC_TIME_LOW 0x00
#define RTC_TIME_HIGH 0x04
#define RTC_ALARM_LOW 0x08
#define RTC_ALARM_HIGH 0x0c
#define RTC_IRQ_ENABLED 0x10
#define RTC_CLEAR_ALARM 0x14
#define RTC_ALARM_STATUS 0x18
#define RTC_CLEAR_INTERRUPT 0x1c
static void goldfish_rtc_update(GoldfishRTCState *s)
{
qemu_set_irq(s->irq, (s->irq_pending & s->irq_enabled) ? 1 : 0);
}
static void goldfish_rtc_interrupt(void *opaque)
{
GoldfishRTCState *s = (GoldfishRTCState *)opaque;
s->alarm_running = 0;
s->irq_pending = 1;
goldfish_rtc_update(s);
}
static uint64_t goldfish_rtc_get_count(GoldfishRTCState *s)
{
return s->tick_offset + (uint64_t)qemu_clock_get_ns(rtc_clock);
}
static void goldfish_rtc_clear_alarm(GoldfishRTCState *s)
{
timer_del(s->timer);
s->alarm_running = 0;
}
static void goldfish_rtc_set_alarm(GoldfishRTCState *s)
{
uint64_t ticks = goldfish_rtc_get_count(s);
uint64_t event = s->alarm_next;
if (event <= ticks) {
goldfish_rtc_clear_alarm(s);
goldfish_rtc_interrupt(s);
} else {
/*
* We should be setting timer expiry to:
* qemu_clock_get_ns(rtc_clock) + (event - ticks)
* but this is equivalent to:
* event - s->tick_offset
*/
timer_mod(s->timer, event - s->tick_offset);
s->alarm_running = 1;
}
}
static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
unsigned size)
{
GoldfishRTCState *s = opaque;
uint64_t r = 0;
switch (offset) {
case RTC_TIME_LOW:
r = goldfish_rtc_get_count(s) & 0xffffffff;
break;
case RTC_TIME_HIGH:
r = goldfish_rtc_get_count(s) >> 32;
break;
case RTC_ALARM_LOW:
r = s->alarm_next & 0xffffffff;
break;
case RTC_ALARM_HIGH:
r = s->alarm_next >> 32;
break;
case RTC_IRQ_ENABLED:
r = s->irq_enabled;
break;
case RTC_ALARM_STATUS:
r = s->alarm_running;
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: offset 0x%x is UNIMP.\n", __func__, (uint32_t)offset);
break;
}
trace_goldfish_rtc_read(offset, r);
return r;
}
static void goldfish_rtc_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
GoldfishRTCState *s = opaque;
uint64_t current_tick, new_tick;
switch (offset) {
case RTC_TIME_LOW:
current_tick = goldfish_rtc_get_count(s);
new_tick = deposit64(current_tick, 0, 32, value);
s->tick_offset += new_tick - current_tick;
break;
case RTC_TIME_HIGH:
current_tick = goldfish_rtc_get_count(s);
new_tick = deposit64(current_tick, 32, 32, value);
s->tick_offset += new_tick - current_tick;
break;
case RTC_ALARM_LOW:
s->alarm_next = deposit64(s->alarm_next, 0, 32, value);
goldfish_rtc_set_alarm(s);
break;
case RTC_ALARM_HIGH:
s->alarm_next = deposit64(s->alarm_next, 32, 32, value);
break;
case RTC_IRQ_ENABLED:
s->irq_enabled = (uint32_t)(value & 0x1);
goldfish_rtc_update(s);
break;
case RTC_CLEAR_ALARM:
goldfish_rtc_clear_alarm(s);
break;
case RTC_CLEAR_INTERRUPT:
s->irq_pending = 0;
goldfish_rtc_update(s);
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: offset 0x%x is UNIMP.\n", __func__, (uint32_t)offset);
break;
}
trace_goldfish_rtc_write(offset, value);
}
static int goldfish_rtc_pre_save(void *opaque)
{
uint64_t delta;
GoldfishRTCState *s = opaque;
/*
* We want to migrate this offset, which sounds straightforward.
* Unfortunately, we cannot directly pass tick_offset because
* rtc_clock on destination Host might not be same source Host.
*
* To tackle, this we pass tick_offset relative to vm_clock from
* source Host and make it relative to rtc_clock at destination Host.
*/
delta = qemu_clock_get_ns(rtc_clock) -
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->tick_offset_vmstate = s->tick_offset + delta;
return 0;
}
static int goldfish_rtc_post_load(void *opaque, int version_id)
{
uint64_t delta;
GoldfishRTCState *s = opaque;
/*
* We extract tick_offset from tick_offset_vmstate by doing
* reverse math compared to pre_save() function.
*/
delta = qemu_clock_get_ns(rtc_clock) -
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->tick_offset = s->tick_offset_vmstate - delta;
return 0;
}
static const MemoryRegionOps goldfish_rtc_ops = {
.read = goldfish_rtc_read,
.write = goldfish_rtc_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4
}
};
static const VMStateDescription goldfish_rtc_vmstate = {
.name = TYPE_GOLDFISH_RTC,
.version_id = 1,
.pre_save = goldfish_rtc_pre_save,
.post_load = goldfish_rtc_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT64(tick_offset_vmstate, GoldfishRTCState),
VMSTATE_UINT64(alarm_next, GoldfishRTCState),
VMSTATE_UINT32(alarm_running, GoldfishRTCState),
VMSTATE_UINT32(irq_pending, GoldfishRTCState),
VMSTATE_UINT32(irq_enabled, GoldfishRTCState),
VMSTATE_END_OF_LIST()
}
};
static void goldfish_rtc_reset(DeviceState *dev)
{
GoldfishRTCState *s = GOLDFISH_RTC(dev);
struct tm tm;
timer_del(s->timer);
qemu_get_timedate(&tm, 0);
s->tick_offset = mktimegm(&tm);
s->tick_offset *= NANOSECONDS_PER_SECOND;
s->tick_offset -= qemu_clock_get_ns(rtc_clock);
s->tick_offset_vmstate = 0;
s->alarm_next = 0;
s->alarm_running = 0;
s->irq_pending = 0;
s->irq_enabled = 0;
}
static void goldfish_rtc_realize(DeviceState *d, Error **errp)
{
SysBusDevice *dev = SYS_BUS_DEVICE(d);
GoldfishRTCState *s = GOLDFISH_RTC(d);
memory_region_init_io(&s->iomem, OBJECT(s), &goldfish_rtc_ops, s,
"goldfish_rtc", 0x24);
sysbus_init_mmio(dev, &s->iomem);
sysbus_init_irq(dev, &s->irq);
s->timer = timer_new_ns(rtc_clock, goldfish_rtc_interrupt, s);
}
static void goldfish_rtc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = goldfish_rtc_realize;
dc->reset = goldfish_rtc_reset;
dc->vmsd = &goldfish_rtc_vmstate;
}
static const TypeInfo goldfish_rtc_info = {
.name = TYPE_GOLDFISH_RTC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(GoldfishRTCState),
.class_init = goldfish_rtc_class_init,
};
static void goldfish_rtc_register_types(void)
{
type_register_static(&goldfish_rtc_info);
}
type_init(goldfish_rtc_register_types)

View File

@ -23,3 +23,7 @@ m48txx_nvram_io_read(uint64_t addr, uint64_t value) "io read addr:0x%04" PRIx64
m48txx_nvram_io_write(uint64_t addr, uint64_t value) "io write addr:0x%04" PRIx64 " value:0x%02" PRIx64
m48txx_nvram_mem_read(uint32_t addr, uint32_t value) "mem read addr:0x%04x value:0x%02x"
m48txx_nvram_mem_write(uint32_t addr, uint32_t value) "mem write addr:0x%04x value:0x%02x"
# goldfish_rtc.c
goldfish_rtc_read(uint64_t addr, uint64_t value) "addr 0x%02" PRIx64 " value 0x%08" PRIx64
goldfish_rtc_write(uint64_t addr, uint64_t value) "addr 0x%02" PRIx64 " value 0x%08" PRIx64

View File

@ -44,6 +44,7 @@ enum {
VIRT_DEBUG,
VIRT_MROM,
VIRT_TEST,
VIRT_RTC,
VIRT_CLINT,
VIRT_PLIC,
VIRT_UART0,
@ -57,6 +58,7 @@ enum {
enum {
UART0_IRQ = 10,
RTC_IRQ = 11,
VIRTIO_IRQ = 1, /* 1 to 8 */
VIRTIO_COUNT = 8,
PCIE_IRQ = 0x20, /* 32 to 35 */

View File

@ -0,0 +1,46 @@
/*
* Goldfish virtual platform RTC
*
* Copyright (C) 2019 Western Digital Corporation or its affiliates.
*
* For more details on Google Goldfish virtual platform refer:
* https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2 or later, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HW_RTC_GOLDFISH_RTC_H
#define HW_RTC_GOLDFISH_RTC_H
#include "hw/sysbus.h"
#define TYPE_GOLDFISH_RTC "goldfish_rtc"
#define GOLDFISH_RTC(obj) \
OBJECT_CHECK(GoldfishRTCState, (obj), TYPE_GOLDFISH_RTC)
typedef struct GoldfishRTCState {
SysBusDevice parent_obj;
MemoryRegion iomem;
QEMUTimer *timer;
qemu_irq irq;
uint64_t tick_offset;
uint64_t tick_offset_vmstate;
uint64_t alarm_next;
uint32_t alarm_running;
uint32_t irq_pending;
uint32_t irq_enabled;
} GoldfishRTCState;
#endif

View File

@ -303,7 +303,12 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
{
if (n < 32) {
return gdb_get_reg64(mem_buf, env->fpr[n]);
if (env->misa & RVD) {
return gdb_get_reg64(mem_buf, env->fpr[n]);
}
if (env->misa & RVF) {
return gdb_get_reg32(mem_buf, env->fpr[n]);
}
/* there is hole between ft11 and fflags in fpu.xml */
} else if (n < 36 && n > 32) {
target_ulong val = 0;
@ -403,23 +408,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
#if defined(TARGET_RISCV32)
if (env->misa & RVF) {
if (env->misa & RVD) {
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
36, "riscv-64bit-fpu.xml", 0);
} else if (env->misa & RVF) {
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
36, "riscv-32bit-fpu.xml", 0);
}
#if defined(TARGET_RISCV32)
gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
240, "riscv-32bit-csr.xml", 0);
gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
1, "riscv-32bit-virtual.xml", 0);
#elif defined(TARGET_RISCV64)
if (env->misa & RVF) {
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
36, "riscv-64bit-fpu.xml", 0);
}
gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
240, "riscv-64bit-csr.xml", 0);