This is a collection of RISC-V patches for 5.1.

This incldues removing deprecated features and part of the OpenTitan
 support series.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEE9sSsRtSTSGjTuM6PIeENKd+XcFQFAl7Xy/sACgkQIeENKd+X
 cFRCwgf/TuoYbjfgHhYqcn52e4ZQpOPfB6F6BPmTkjZktPwcVZcNb0TstiYTSgey
 DvrJzZRPb9T8f/Hy3KzTjmXxR5+qhJPhMPkaC1qRiu+4KF2QqBzSfm80/EnUZ8+/
 KSDTxmD2v88k7SNhbTL3rKl0WsKNAZMkv5GkehdigpjzsVhmrtV+kB0jvkz1n35b
 x/hvg6Ry67++tc1WaLXyagUScYwG2yCFWu7agwD4/b4jKRv6Tuh9SJct/6IXJW31
 JGPPAr+UdvdacF3rPNdc2BvYgwAyHdZze4N3XnGuuodIMbzJGLGBbZKfKWZpvEQm
 DU1m8KTZNqJcW5++i0RqpEgO/+bW6w==
 =c0qu
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20200603' into staging

This is a collection of RISC-V patches for 5.1.

This incldues removing deprecated features and part of the OpenTitan
support series.

# gpg: Signature made Wed 03 Jun 2020 17:12:43 BST
# gpg:                using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full]
# Primary key fingerprint: F6C4 AC46 D493 4868 D3B8  CE8F 21E1 0D29 DF97 7054

* remotes/alistair/tags/pull-riscv-to-apply-20200603:
  riscv: Initial commit of OpenTitan machine
  target/riscv: Add the lowRISC Ibex CPU
  target/riscv: Don't set PMP feature in the cpu init
  target/riscv: Disable the MMU correctly
  target/riscv: Don't overwrite the reset vector
  riscv/boot: Add a missing header include
  riscv: sifive_e: Manually define the machine
  docs: deprecated: Update the -bios documentation
  target/riscv: Drop support for ISA spec version 1.09.1
  target/riscv: Remove the deprecated CPUs
  hw/riscv: spike: Remove deprecated ISA specific machines
  hw/riscv: virt: Remove the riscv_ prefix of the machine* functions
  hw/riscv: sifive_u: Remove the riscv_ prefix of the soc* functions
  riscv: Change the default behavior if no -bios option is specified
  riscv: Suppress the error report for QEMU testing with riscv_find_firmware()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-06-04 11:38:47 +01:00
commit 66234fee9c
24 changed files with 481 additions and 574 deletions

View File

@ -1238,6 +1238,15 @@ F: pc-bios/canyonlands.dt[sb]
F: pc-bios/u-boot-sam460ex-20100605.bin
F: roms/u-boot-sam460ex
RISC-V Machines
---------------
OpenTitan
M: Alistair Francis <Alistair.Francis@wdc.com>
L: qemu-riscv@nongnu.org
S: Supported
F: hw/riscv/opentitan.c
F: include/hw/riscv/opentitan.h
SH4 Machines
------------
R2D

View File

@ -10,3 +10,4 @@ CONFIG_SPIKE=y
CONFIG_SIFIVE_E=y
CONFIG_SIFIVE_U=y
CONFIG_RISCV_VIRT=y
CONFIG_OPENTITAN=y

View File

@ -1,3 +1,12 @@
# Default configuration for riscv64-softmmu
include riscv32-softmmu.mak
# Uncomment the following lines to disable these optional devices:
#
#CONFIG_PCI_DEVICES=n
# Boards:
#
CONFIG_SPIKE=y
CONFIG_SIFIVE_E=y
CONFIG_SIFIVE_U=y
CONFIG_RISCV_VIRT=y

View File

@ -138,25 +138,23 @@ the backing storage specified with ``-mem-path`` can actually provide
the guest RAM configured with ``-m`` and QEMU will fail to start up if
RAM allocation is unsuccessful.
RISC-V ``-bios`` (since 4.1)
RISC-V ``-bios`` (since 5.1)
''''''''''''''''''''''''''''
QEMU 4.1 introduced support for the -bios option in QEMU for RISC-V for the
RISC-V virt machine and sifive_u machine.
RISC-V virt machine and sifive_u machine. QEMU 4.1 had no changes to the
default behaviour to avoid breakages.
QEMU 4.1 has no changes to the default behaviour to avoid breakages. This
default will change in a future QEMU release, so please prepare now. All users
of the virt or sifive_u machine must change their command line usage.
QEMU 5.1 changes the default behaviour from ``-bios none`` to ``-bios default``.
QEMU 4.1 has three options, please migrate to one of these three:
1. ``-bios none`` - This is the current default behavior if no -bios option
is included. QEMU will not automatically load any firmware. It is up
QEMU 5.1 has three options:
1. ``-bios default`` - This is the current default behavior if no -bios option
is included. This option will load the default OpenSBI firmware automatically.
The firmware is included with the QEMU release and no user interaction is
required. All a user needs to do is specify the kernel they want to boot
with the -kernel option
2. ``-bios none`` - QEMU will not automatically load any firmware. It is up
to the user to load all the images they need.
2. ``-bios default`` - In a future QEMU release this will become the default
behaviour if no -bios option is specified. This option will load the
default OpenSBI firmware automatically. The firmware is included with
the QEMU release and no user interaction is required. All a user needs
to do is specify the kernel they want to boot with the -kernel option
3. ``-bios <file>`` - Tells QEMU to load the specified file as the firmwrae.
``-tb-size`` option (since 5.0)
@ -301,34 +299,9 @@ The ``acl_show``, ``acl_reset``, ``acl_policy``, ``acl_add``, and
``acl_remove`` commands are deprecated with no replacement. Authorization
for VNC should be performed using the pluggable QAuthZ objects.
Guest Emulator ISAs
-------------------
RISC-V ISA privledge specification version 1.09.1 (since 4.1)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The RISC-V ISA privledge specification version 1.09.1 has been deprecated.
QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
should be used instead of the 1.09.1 version.
System emulator CPUS
--------------------
RISC-V ISA CPUs (since 4.1)
'''''''''''''''''''''''''''
The RISC-V cpus with the ISA version in the CPU name have been depcreated. The
four CPUs are: ``rv32gcsu-v1.9.1``, ``rv32gcsu-v1.10.0``, ``rv64gcsu-v1.9.1`` and
``rv64gcsu-v1.10.0``. Instead the version can be specified via the CPU ``priv_spec``
option when using the ``rv32`` or ``rv64`` CPUs.
RISC-V ISA CPUs (since 4.1)
'''''''''''''''''''''''''''
The RISC-V no MMU cpus have been depcreated. The two CPUs: ``rv32imacu-nommu`` and
``rv64imacu-nommu`` should no longer be used. Instead the MMU status can be specified
via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
``compat`` property of server class POWER CPUs (since 5.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
@ -379,13 +352,6 @@ This machine has been renamed ``fuloong2e``.
These machine types are very old and likely can not be used for live migration
from old QEMU versions anymore. A newer machine type should be used instead.
``spike_v1.9.1`` and ``spike_v1.10`` (since 4.1)
''''''''''''''''''''''''''''''''''''''''''''''''
The version specific Spike machines have been deprecated in favour of the
generic ``spike`` machine. If you need to specify an older version of the RISC-V
spec you can use the ``-cpu rv64gcsu,priv_spec=v1.9.1`` command line argument.
Device options
--------------
@ -493,6 +459,44 @@ The ``hub_id`` parameter of ``hostfwd_add`` / ``hostfwd_remove`` (removed in 5.0
The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and
'hostfwd_remove' HMP commands has been replaced by ``netdev_id``.
Guest Emulator ISAs
-------------------
RISC-V ISA privledge specification version 1.09.1 (removed in 5.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The RISC-V ISA privledge specification version 1.09.1 has been removed.
QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
should be used instead of the 1.09.1 version.
System emulator CPUS
--------------------
RISC-V ISA Specific CPUs (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''
The RISC-V cpus with the ISA version in the CPU name have been removed. The
four CPUs are: ``rv32gcsu-v1.9.1``, ``rv32gcsu-v1.10.0``, ``rv64gcsu-v1.9.1`` and
``rv64gcsu-v1.10.0``. Instead the version can be specified via the CPU ``priv_spec``
option when using the ``rv32`` or ``rv64`` CPUs.
RISC-V no MMU CPUs (removed in 5.1)
'''''''''''''''''''''''''''''''''''
The RISC-V no MMU cpus have been removed. The two CPUs: ``rv32imacu-nommu`` and
``rv64imacu-nommu`` can no longer be used. Instead the MMU status can be specified
via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
System emulator machines
------------------------
``spike_v1.9.1`` and ``spike_v1.10`` (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''''''''''''''
The version specific Spike machines have been removed in favour of the
generic ``spike`` machine. If you need to specify an older version of the RISC-V
spec you can use the ``-cpu rv64gcsu,priv_spec=v1.10.0`` command line argument.
Related binaries
----------------

View File

@ -27,6 +27,11 @@ config SPIKE
select HTIF
select SIFIVE
config OPENTITAN
bool
select HART
select UNIMP
config RISCV_VIRT
bool
imply PCI_DEVICES

View File

@ -1,6 +1,7 @@
obj-y += boot.o
obj-$(CONFIG_SPIKE) += riscv_htif.o
obj-$(CONFIG_HART) += riscv_hart.o
obj-$(CONFIG_OPENTITAN) += opentitan.o
obj-$(CONFIG_SIFIVE_E) += sifive_e.o
obj-$(CONFIG_SIFIVE_E) += sifive_e_prci.o
obj-$(CONFIG_SIFIVE) += sifive_clint.o

View File

@ -41,34 +41,11 @@ void riscv_find_and_load_firmware(MachineState *machine,
{
char *firmware_filename = NULL;
if (!machine->firmware) {
if ((!machine->firmware) || (!strcmp(machine->firmware, "default"))) {
/*
* The user didn't specify -bios.
* At the moment we default to loading nothing when this hapens.
* In the future this defaul will change to loading the prebuilt
* OpenSBI firmware. Let's warn the user and then continue.
*/
if (!qtest_enabled()) {
warn_report("No -bios option specified. Not loading a firmware.");
warn_report("This default will change in a future QEMU release. " \
"Please use the -bios option to avoid breakages when "\
"this happens.");
warn_report("See QEMU's deprecation documentation for details.");
}
return;
}
if (!strcmp(machine->firmware, "default")) {
/*
* The user has specified "-bios default". That means we are going to
* load the OpenSBI binary included in the QEMU source.
*
* We can't load the binary by default as it will break existing users
* as users are already loading their own firmware.
*
* Let's try to get everyone to specify the -bios option at all times,
* so then in the future we can make "-bios default" the default option
* if no -bios option is set without breaking anything.
* The user didn't specify -bios, or has specified "-bios default".
* That means we are going to load the OpenSBI binary included in
* the QEMU source.
*/
firmware_filename = riscv_find_firmware(default_machine_firmware);
} else if (strcmp(machine->firmware, "none")) {
@ -88,9 +65,17 @@ char *riscv_find_firmware(const char *firmware_filename)
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware_filename);
if (filename == NULL) {
error_report("Unable to load the RISC-V firmware \"%s\"",
firmware_filename);
exit(1);
if (!qtest_enabled()) {
/*
* We only ship plain binary bios images in the QEMU source.
* With Spike machine that uses ELF images as the default bios,
* running QEMU test will complain hence let's suppress the error
* report for QEMU testing.
*/
error_report("Unable to load the RISC-V firmware \"%s\"",
firmware_filename);
exit(1);
}
}
return filename;

184
hw/riscv/opentitan.c Normal file
View File

@ -0,0 +1,184 @@
/*
* QEMU RISC-V Board Compatible with OpenTitan FPGA platform
*
* Copyright (c) 2020 Western Digital
*
* Provides a board compatible with the OpenTitan FPGA platform:
*
* 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 "hw/riscv/opentitan.h"
#include "qapi/error.h"
#include "hw/boards.h"
#include "hw/misc/unimp.h"
#include "hw/riscv/boot.h"
#include "exec/address-spaces.h"
static const struct MemmapEntry {
hwaddr base;
hwaddr size;
} ibex_memmap[] = {
[IBEX_ROM] = { 0x00008000, 0xc000 },
[IBEX_RAM] = { 0x10000000, 0x10000 },
[IBEX_FLASH] = { 0x20000000, 0x80000 },
[IBEX_UART] = { 0x40000000, 0x10000 },
[IBEX_GPIO] = { 0x40010000, 0x10000 },
[IBEX_SPI] = { 0x40020000, 0x10000 },
[IBEX_FLASH_CTRL] = { 0x40030000, 0x10000 },
[IBEX_PINMUX] = { 0x40070000, 0x10000 },
[IBEX_RV_TIMER] = { 0x40080000, 0x10000 },
[IBEX_PLIC] = { 0x40090000, 0x10000 },
[IBEX_PWRMGR] = { 0x400A0000, 0x10000 },
[IBEX_RSTMGR] = { 0x400B0000, 0x10000 },
[IBEX_CLKMGR] = { 0x400C0000, 0x10000 },
[IBEX_AES] = { 0x40110000, 0x10000 },
[IBEX_HMAC] = { 0x40120000, 0x10000 },
[IBEX_ALERT_HANDLER] = { 0x40130000, 0x10000 },
[IBEX_NMI_GEN] = { 0x40140000, 0x10000 },
[IBEX_USBDEV] = { 0x40150000, 0x10000 },
[IBEX_PADCTRL] = { 0x40160000, 0x10000 }
};
static void riscv_opentitan_init(MachineState *machine)
{
const struct MemmapEntry *memmap = ibex_memmap;
OpenTitanState *s = g_new0(OpenTitanState, 1);
MemoryRegion *sys_mem = get_system_memory();
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
/* Initialize SoC */
object_initialize_child(OBJECT(machine), "soc", &s->soc,
sizeof(s->soc), TYPE_RISCV_IBEX_SOC,
&error_abort, NULL);
object_property_set_bool(OBJECT(&s->soc), true, "realized",
&error_abort);
memory_region_init_ram(main_mem, NULL, "riscv.lowrisc.ibex.ram",
memmap[IBEX_RAM].size, &error_fatal);
memory_region_add_subregion(sys_mem,
memmap[IBEX_RAM].base, main_mem);
if (machine->firmware) {
riscv_load_firmware(machine->firmware, memmap[IBEX_RAM].base, NULL);
}
if (machine->kernel_filename) {
riscv_load_kernel(machine->kernel_filename, NULL);
}
}
static void riscv_opentitan_machine_init(MachineClass *mc)
{
mc->desc = "RISC-V Board compatible with OpenTitan";
mc->init = riscv_opentitan_init;
mc->max_cpus = 1;
mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
}
DEFINE_MACHINE("opentitan", riscv_opentitan_machine_init)
static void riscv_lowrisc_ibex_soc_init(Object *obj)
{
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
object_initialize_child(obj, "cpus", &s->cpus,
sizeof(s->cpus), TYPE_RISCV_HART_ARRAY,
&error_abort, NULL);
}
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
{
const struct MemmapEntry *memmap = ibex_memmap;
MachineState *ms = MACHINE(qdev_get_machine());
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
MemoryRegion *sys_mem = get_system_memory();
object_property_set_str(OBJECT(&s->cpus), ms->cpu_type, "cpu-type",
&error_abort);
object_property_set_int(OBJECT(&s->cpus), ms->smp.cpus, "num-harts",
&error_abort);
object_property_set_bool(OBJECT(&s->cpus), true, "realized",
&error_abort);
/* Boot ROM */
memory_region_init_rom(&s->rom, OBJECT(dev_soc), "riscv.lowrisc.ibex.rom",
memmap[IBEX_ROM].size, &error_fatal);
memory_region_add_subregion(sys_mem,
memmap[IBEX_ROM].base, &s->rom);
/* Flash memory */
memory_region_init_rom(&s->flash_mem, OBJECT(dev_soc), "riscv.lowrisc.ibex.flash",
memmap[IBEX_FLASH].size, &error_fatal);
memory_region_add_subregion(sys_mem, memmap[IBEX_FLASH].base,
&s->flash_mem);
create_unimplemented_device("riscv.lowrisc.ibex.uart",
memmap[IBEX_UART].base, memmap[IBEX_UART].size);
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
memmap[IBEX_GPIO].base, memmap[IBEX_GPIO].size);
create_unimplemented_device("riscv.lowrisc.ibex.spi",
memmap[IBEX_SPI].base, memmap[IBEX_SPI].size);
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
memmap[IBEX_FLASH_CTRL].base, memmap[IBEX_FLASH_CTRL].size);
create_unimplemented_device("riscv.lowrisc.ibex.rv_timer",
memmap[IBEX_RV_TIMER].base, memmap[IBEX_RV_TIMER].size);
create_unimplemented_device("riscv.lowrisc.ibex.pwrmgr",
memmap[IBEX_PWRMGR].base, memmap[IBEX_PWRMGR].size);
create_unimplemented_device("riscv.lowrisc.ibex.rstmgr",
memmap[IBEX_RSTMGR].base, memmap[IBEX_RSTMGR].size);
create_unimplemented_device("riscv.lowrisc.ibex.clkmgr",
memmap[IBEX_CLKMGR].base, memmap[IBEX_CLKMGR].size);
create_unimplemented_device("riscv.lowrisc.ibex.aes",
memmap[IBEX_AES].base, memmap[IBEX_AES].size);
create_unimplemented_device("riscv.lowrisc.ibex.hmac",
memmap[IBEX_HMAC].base, memmap[IBEX_HMAC].size);
create_unimplemented_device("riscv.lowrisc.ibex.plic",
memmap[IBEX_PLIC].base, memmap[IBEX_PLIC].size);
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
memmap[IBEX_PINMUX].base, memmap[IBEX_PINMUX].size);
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
memmap[IBEX_ALERT_HANDLER].base, memmap[IBEX_ALERT_HANDLER].size);
create_unimplemented_device("riscv.lowrisc.ibex.nmi_gen",
memmap[IBEX_NMI_GEN].base, memmap[IBEX_NMI_GEN].size);
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
memmap[IBEX_USBDEV].base, memmap[IBEX_USBDEV].size);
create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
memmap[IBEX_PADCTRL].base, memmap[IBEX_PADCTRL].size);
}
static void riscv_lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
dc->realize = riscv_lowrisc_ibex_soc_realize;
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
dc->user_creatable = false;
}
static const TypeInfo riscv_lowrisc_ibex_soc_type_info = {
.name = TYPE_RISCV_IBEX_SOC,
.parent = TYPE_DEVICE,
.instance_size = sizeof(LowRISCIbexSoCState),
.instance_init = riscv_lowrisc_ibex_soc_init,
.class_init = riscv_lowrisc_ibex_soc_class_init,
};
static void riscv_lowrisc_ibex_soc_register_types(void)
{
type_register_static(&riscv_lowrisc_ibex_soc_type_info);
}
type_init(riscv_lowrisc_ibex_soc_register_types)

View File

@ -79,7 +79,7 @@ static void riscv_sifive_e_init(MachineState *machine)
{
const struct MemmapEntry *memmap = sifive_e_memmap;
SiFiveEState *s = g_new0(SiFiveEState, 1);
SiFiveEState *s = RISCV_E_MACHINE(machine);
MemoryRegion *sys_mem = get_system_memory();
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
int i;
@ -115,6 +115,35 @@ static void riscv_sifive_e_init(MachineState *machine)
}
}
static void sifive_e_machine_instance_init(Object *obj)
{
}
static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
mc->desc = "RISC-V Board compatible with SiFive E SDK";
mc->init = riscv_sifive_e_init;
mc->max_cpus = 1;
mc->default_cpu_type = SIFIVE_E_CPU;
}
static const TypeInfo sifive_e_machine_typeinfo = {
.name = MACHINE_TYPE_NAME("sifive_e"),
.parent = TYPE_MACHINE,
.class_init = sifive_e_machine_class_init,
.instance_init = sifive_e_machine_instance_init,
.instance_size = sizeof(SiFiveEState),
};
static void sifive_e_machine_init_register_types(void)
{
type_register_static(&sifive_e_machine_typeinfo);
}
type_init(sifive_e_machine_init_register_types)
static void riscv_sifive_e_soc_init(Object *obj)
{
MachineState *ms = MACHINE(qdev_get_machine());
@ -214,16 +243,6 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
&s->xip_mem);
}
static void riscv_sifive_e_machine_init(MachineClass *mc)
{
mc->desc = "RISC-V Board compatible with SiFive E SDK";
mc->init = riscv_sifive_e_init;
mc->max_cpus = 1;
mc->default_cpu_type = SIFIVE_E_CPU;
}
DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init)
static void riscv_sifive_e_soc_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);

View File

@ -481,7 +481,7 @@ static void sifive_u_machine_init_register_types(void)
type_init(sifive_u_machine_init_register_types)
static void riscv_sifive_u_soc_init(Object *obj)
static void sifive_u_soc_instance_init(Object *obj)
{
MachineState *ms = MACHINE(qdev_get_machine());
SiFiveUSoCState *s = RISCV_U_SOC(obj);
@ -520,7 +520,7 @@ static void riscv_sifive_u_soc_init(Object *obj)
TYPE_CADENCE_GEM);
}
static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
{
MachineState *ms = MACHINE(qdev_get_machine());
SiFiveUSoCState *s = RISCV_U_SOC(dev);
@ -635,32 +635,32 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
}
static Property riscv_sifive_u_soc_props[] = {
static Property sifive_u_soc_props[] = {
DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL),
DEFINE_PROP_END_OF_LIST()
};
static void riscv_sifive_u_soc_class_init(ObjectClass *oc, void *data)
static void sifive_u_soc_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
device_class_set_props(dc, riscv_sifive_u_soc_props);
dc->realize = riscv_sifive_u_soc_realize;
device_class_set_props(dc, sifive_u_soc_props);
dc->realize = sifive_u_soc_realize;
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
dc->user_creatable = false;
}
static const TypeInfo riscv_sifive_u_soc_type_info = {
static const TypeInfo sifive_u_soc_type_info = {
.name = TYPE_RISCV_U_SOC,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SiFiveUSoCState),
.instance_init = riscv_sifive_u_soc_init,
.class_init = riscv_sifive_u_soc_class_init,
.instance_init = sifive_u_soc_instance_init,
.class_init = sifive_u_soc_class_init,
};
static void riscv_sifive_u_soc_register_types(void)
static void sifive_u_soc_register_types(void)
{
type_register_static(&riscv_sifive_u_soc_type_info);
type_register_static(&sifive_u_soc_type_info);
}
type_init(riscv_sifive_u_soc_register_types)
type_init(sifive_u_soc_register_types)

View File

@ -257,221 +257,6 @@ static void spike_board_init(MachineState *machine)
false);
}
static void spike_v1_10_0_board_init(MachineState *machine)
{
const struct MemmapEntry *memmap = spike_memmap;
SpikeState *s = g_new0(SpikeState, 1);
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
int i;
unsigned int smp_cpus = machine->smp.cpus;
if (!qtest_enabled()) {
info_report("The Spike v1.10.0 machine has been deprecated. "
"Please use the generic spike machine and specify the ISA "
"versions using -cpu.");
}
/* Initialize SOC */
object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
TYPE_RISCV_HART_ARRAY, &error_abort, NULL);
object_property_set_str(OBJECT(&s->soc), SPIKE_V1_10_0_CPU, "cpu-type",
&error_abort);
object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts",
&error_abort);
object_property_set_bool(OBJECT(&s->soc), true, "realized",
&error_abort);
/* register system main memory (actual RAM) */
memory_region_init_ram(main_mem, NULL, "riscv.spike.ram",
machine->ram_size, &error_fatal);
memory_region_add_subregion(system_memory, memmap[SPIKE_DRAM].base,
main_mem);
/* create device tree */
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
/* boot rom */
memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom",
memmap[SPIKE_MROM].size, &error_fatal);
memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
mask_rom);
if (machine->kernel_filename) {
riscv_load_kernel(machine->kernel_filename, htif_symbol_callback);
}
/* reset vector */
uint32_t reset_vec[8] = {
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
0xf1402573, /* csrr a0, mhartid */
#if defined(TARGET_RISCV32)
0x0182a283, /* lw t0, 24(t0) */
#elif defined(TARGET_RISCV64)
0x0182b283, /* ld t0, 24(t0) */
#endif
0x00028067, /* jr t0 */
0x00000000,
memmap[SPIKE_DRAM].base, /* start: .dword DRAM_BASE */
0x00000000,
/* dtb: */
};
/* copy in the reset vector in little_endian byte order */
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
reset_vec[i] = cpu_to_le32(reset_vec[i]);
}
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
memmap[SPIKE_MROM].base, &address_space_memory);
/* copy in the device tree */
if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) >
memmap[SPIKE_MROM].size - sizeof(reset_vec)) {
error_report("not enough space to store device-tree");
exit(1);
}
qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt));
rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt),
memmap[SPIKE_MROM].base + sizeof(reset_vec),
&address_space_memory);
/* initialize HTIF using symbols found in load_kernel */
htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0));
/* Core Local Interruptor (timer and IPI) */
sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
false);
}
static void spike_v1_09_1_board_init(MachineState *machine)
{
const struct MemmapEntry *memmap = spike_memmap;
SpikeState *s = g_new0(SpikeState, 1);
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
int i;
unsigned int smp_cpus = machine->smp.cpus;
if (!qtest_enabled()) {
info_report("The Spike v1.09.1 machine has been deprecated. "
"Please use the generic spike machine and specify the ISA "
"versions using -cpu.");
}
/* Initialize SOC */
object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
TYPE_RISCV_HART_ARRAY, &error_abort, NULL);
object_property_set_str(OBJECT(&s->soc), SPIKE_V1_09_1_CPU, "cpu-type",
&error_abort);
object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts",
&error_abort);
object_property_set_bool(OBJECT(&s->soc), true, "realized",
&error_abort);
/* register system main memory (actual RAM) */
memory_region_init_ram(main_mem, NULL, "riscv.spike.ram",
machine->ram_size, &error_fatal);
memory_region_add_subregion(system_memory, memmap[SPIKE_DRAM].base,
main_mem);
/* boot rom */
memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom",
memmap[SPIKE_MROM].size, &error_fatal);
memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
mask_rom);
if (machine->kernel_filename) {
riscv_load_kernel(machine->kernel_filename, htif_symbol_callback);
}
/* reset vector */
uint32_t reset_vec[8] = {
0x297 + memmap[SPIKE_DRAM].base - memmap[SPIKE_MROM].base, /* lui */
0x00028067, /* jump to DRAM_BASE */
0x00000000, /* reserved */
memmap[SPIKE_MROM].base + sizeof(reset_vec), /* config string pointer */
0, 0, 0, 0 /* trap vector */
};
/* part one of config string - before memory size specified */
const char *config_string_tmpl =
"platform {\n"
" vendor ucb;\n"
" arch spike;\n"
"};\n"
"rtc {\n"
" addr 0x%" PRIx64 "x;\n"
"};\n"
"ram {\n"
" 0 {\n"
" addr 0x%" PRIx64 "x;\n"
" size 0x%" PRIx64 "x;\n"
" };\n"
"};\n"
"core {\n"
" 0" " {\n"
" " "0 {\n"
" isa %s;\n"
" timecmp 0x%" PRIx64 "x;\n"
" ipi 0x%" PRIx64 "x;\n"
" };\n"
" };\n"
"};\n";
/* build config string with supplied memory size */
char *isa = riscv_isa_string(&s->soc.harts[0]);
char *config_string = g_strdup_printf(config_string_tmpl,
(uint64_t)memmap[SPIKE_CLINT].base + SIFIVE_TIME_BASE,
(uint64_t)memmap[SPIKE_DRAM].base,
(uint64_t)ram_size, isa,
(uint64_t)memmap[SPIKE_CLINT].base + SIFIVE_TIMECMP_BASE,
(uint64_t)memmap[SPIKE_CLINT].base + SIFIVE_SIP_BASE);
g_free(isa);
size_t config_string_len = strlen(config_string);
/* copy in the reset vector in little_endian byte order */
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
reset_vec[i] = cpu_to_le32(reset_vec[i]);
}
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
memmap[SPIKE_MROM].base, &address_space_memory);
/* copy in the config string */
rom_add_blob_fixed_as("mrom.reset", config_string, config_string_len,
memmap[SPIKE_MROM].base + sizeof(reset_vec),
&address_space_memory);
/* initialize HTIF using symbols found in load_kernel */
htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0));
/* Core Local Interruptor (timer and IPI) */
sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
false);
g_free(config_string);
}
static void spike_v1_09_1_machine_init(MachineClass *mc)
{
mc->desc = "RISC-V Spike Board (Privileged ISA v1.9.1)";
mc->init = spike_v1_09_1_board_init;
mc->max_cpus = 1;
}
static void spike_v1_10_0_machine_init(MachineClass *mc)
{
mc->desc = "RISC-V Spike Board (Privileged ISA v1.10)";
mc->init = spike_v1_10_0_board_init;
mc->max_cpus = 1;
}
static void spike_machine_init(MachineClass *mc)
{
mc->desc = "RISC-V Spike Board";
@ -481,6 +266,4 @@ static void spike_machine_init(MachineClass *mc)
mc->default_cpu_type = SPIKE_V1_10_0_CPU;
}
DEFINE_MACHINE("spike_v1.9.1", spike_v1_09_1_machine_init)
DEFINE_MACHINE("spike_v1.10", spike_v1_10_0_machine_init)
DEFINE_MACHINE("spike", spike_machine_init)

View File

@ -471,7 +471,7 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
return dev;
}
static void riscv_virt_board_init(MachineState *machine)
static void virt_machine_init(MachineState *machine)
{
const struct MemmapEntry *memmap = virt_memmap;
RISCVVirtState *s = RISCV_VIRT_MACHINE(machine);
@ -632,32 +632,32 @@ static void riscv_virt_board_init(MachineState *machine)
g_free(plic_hart_config);
}
static void riscv_virt_machine_instance_init(Object *obj)
static void virt_machine_instance_init(Object *obj)
{
}
static void riscv_virt_machine_class_init(ObjectClass *oc, void *data)
static void virt_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
mc->desc = "RISC-V VirtIO board";
mc->init = riscv_virt_board_init;
mc->init = virt_machine_init;
mc->max_cpus = 8;
mc->default_cpu_type = VIRT_CPU;
mc->pci_allow_0_address = true;
}
static const TypeInfo riscv_virt_machine_typeinfo = {
static const TypeInfo virt_machine_typeinfo = {
.name = MACHINE_TYPE_NAME("virt"),
.parent = TYPE_MACHINE,
.class_init = riscv_virt_machine_class_init,
.instance_init = riscv_virt_machine_instance_init,
.class_init = virt_machine_class_init,
.instance_init = virt_machine_instance_init,
.instance_size = sizeof(RISCVVirtState),
};
static void riscv_virt_machine_init_register_types(void)
static void virt_machine_init_register_types(void)
{
type_register_static(&riscv_virt_machine_typeinfo);
type_register_static(&virt_machine_typeinfo);
}
type_init(riscv_virt_machine_init_register_types)
type_init(virt_machine_init_register_types)

View File

@ -21,6 +21,7 @@
#define RISCV_BOOT_H
#include "exec/cpu-defs.h"
#include "hw/loader.h"
void riscv_find_and_load_firmware(MachineState *machine,
const char *default_machine_firmware,

View File

@ -0,0 +1,68 @@
/*
* QEMU RISC-V Board Compatible with OpenTitan FPGA platform
*
* Copyright (c) 2020 Western Digital
*
* 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_OPENTITAN_H
#define HW_OPENTITAN_H
#include "hw/riscv/riscv_hart.h"
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
#define RISCV_IBEX_SOC(obj) \
OBJECT_CHECK(LowRISCIbexSoCState, (obj), TYPE_RISCV_IBEX_SOC)
typedef struct LowRISCIbexSoCState {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
RISCVHartArrayState cpus;
MemoryRegion flash_mem;
MemoryRegion rom;
} LowRISCIbexSoCState;
typedef struct OpenTitanState {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
LowRISCIbexSoCState soc;
} OpenTitanState;
enum {
IBEX_ROM,
IBEX_RAM,
IBEX_FLASH,
IBEX_UART,
IBEX_GPIO,
IBEX_SPI,
IBEX_FLASH_CTRL,
IBEX_RV_TIMER,
IBEX_AES,
IBEX_HMAC,
IBEX_PLIC,
IBEX_PWRMGR,
IBEX_RSTMGR,
IBEX_CLKMGR,
IBEX_PINMUX,
IBEX_ALERT_HANDLER,
IBEX_NMI_GEN,
IBEX_USBDEV,
IBEX_PADCTRL,
};
#endif

View File

@ -47,6 +47,10 @@ typedef struct SiFiveEState {
SiFiveESoCState soc;
} SiFiveEState;
#define TYPE_RISCV_E_MACHINE MACHINE_TYPE_NAME("sifive_e")
#define RISCV_E_MACHINE(obj) \
OBJECT_CHECK(SiFiveEState, (obj), TYPE_RISCV_E_MACHINE)
enum {
SIFIVE_E_DEBUG,
SIFIVE_E_MROM,

View File

@ -39,11 +39,9 @@ enum {
};
#if defined(TARGET_RISCV32)
#define SPIKE_V1_09_1_CPU TYPE_RISCV_CPU_RV32GCSU_V1_09_1
#define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_RV32GCSU_V1_10_0
#define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_BASE32
#elif defined(TARGET_RISCV64)
#define SPIKE_V1_09_1_CPU TYPE_RISCV_CPU_RV64GCSU_V1_09_1
#define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_RV64GCSU_V1_10_0
#define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_BASE64
#endif
#endif

View File

@ -133,16 +133,7 @@ static void riscv_base32_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
/* We set this in the realise function */
set_misa(env, 0);
}
static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_09_1);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_MMU);
set_feature(env, RISCV_FEATURE_PMP);
}
static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
@ -151,8 +142,15 @@ static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_MMU);
set_feature(env, RISCV_FEATURE_PMP);
}
static void rv32imcu_nommu_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, 0x8090);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
}
static void rv32imacu_nommu_cpu_init(Object *obj)
@ -161,7 +159,7 @@ static void rv32imacu_nommu_cpu_init(Object *obj)
set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_PMP);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
}
static void rv32imafcu_nommu_cpu_init(Object *obj)
@ -170,7 +168,7 @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_PMP);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
}
#elif defined(TARGET_RISCV64)
@ -180,16 +178,7 @@ static void riscv_base64_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
/* We set this in the realise function */
set_misa(env, 0);
}
static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_09_1);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_MMU);
set_feature(env, RISCV_FEATURE_PMP);
}
static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
@ -198,8 +187,6 @@ static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_MMU);
set_feature(env, RISCV_FEATURE_PMP);
}
static void rv64imacu_nommu_cpu_init(Object *obj)
@ -208,7 +195,7 @@ static void rv64imacu_nommu_cpu_init(Object *obj)
set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_PMP);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
}
#endif
@ -388,8 +375,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
priv_version = PRIV_VERSION_1_11_0;
} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
priv_version = PRIV_VERSION_1_10_0;
} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.9.1")) {
priv_version = PRIV_VERSION_1_09_1;
} else {
error_setg(errp,
"Unsupported privilege spec version '%s'",
@ -399,7 +384,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
}
set_priv_version(env, priv_version);
set_resetvec(env, DEFAULT_RSTVEC);
if (cpu->cfg.mmu) {
set_feature(env, RISCV_FEATURE_MMU);
@ -618,21 +602,14 @@ static const TypeInfo riscv_cpu_type_infos[] = {
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
#if defined(TARGET_RISCV32)
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
/* Depreacted */
DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init)
#elif defined(TARGET_RISCV64)
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
/* Deprecated */
DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init)
#endif
};

View File

@ -35,18 +35,12 @@
#define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any")
#define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
#define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
#define TYPE_RISCV_CPU_SIFIVE_E34 RISCV_CPU_TYPE_NAME("sifive-e34")
#define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51")
#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
/* Deprecated */
#define TYPE_RISCV_CPU_RV32IMACU_NOMMU RISCV_CPU_TYPE_NAME("rv32imacu-nommu")
#define TYPE_RISCV_CPU_RV32GCSU_V1_09_1 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.9.1")
#define TYPE_RISCV_CPU_RV32GCSU_V1_10_0 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.10.0")
#define TYPE_RISCV_CPU_RV64IMACU_NOMMU RISCV_CPU_TYPE_NAME("rv64imacu-nommu")
#define TYPE_RISCV_CPU_RV64GCSU_V1_09_1 RISCV_CPU_TYPE_NAME("rv64gcsu-v1.9.1")
#define TYPE_RISCV_CPU_RV64GCSU_V1_10_0 RISCV_CPU_TYPE_NAME("rv64gcsu-v1.10.0")
#define RV32 ((target_ulong)1 << (TARGET_LONG_BITS - 2))
#define RV64 ((target_ulong)2 << (TARGET_LONG_BITS - 2))
@ -80,7 +74,6 @@ enum {
RISCV_FEATURE_MISA
};
#define PRIV_VERSION_1_09_1 0x00010901
#define PRIV_VERSION_1_10_0 0x00011000
#define PRIV_VERSION_1_11_0 0x00011100

View File

@ -364,57 +364,36 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
mxr = get_field(env->vsstatus, MSTATUS_MXR);
}
if (env->priv_ver >= PRIV_VERSION_1_10_0) {
if (first_stage == true) {
if (use_background) {
base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT;
vm = get_field(env->vsatp, SATP_MODE);
} else {
base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
vm = get_field(env->satp, SATP_MODE);
}
widened = 0;
if (first_stage == true) {
if (use_background) {
base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT;
vm = get_field(env->vsatp, SATP_MODE);
} else {
base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT;
vm = get_field(env->hgatp, HGATP_MODE);
widened = 2;
base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
vm = get_field(env->satp, SATP_MODE);
}
sum = get_field(env->mstatus, MSTATUS_SUM);
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
case VM_1_10_SV39:
levels = 3; ptidxbits = 9; ptesize = 8; break;
case VM_1_10_SV48:
levels = 4; ptidxbits = 9; ptesize = 8; break;
case VM_1_10_SV57:
levels = 5; ptidxbits = 9; ptesize = 8; break;
case VM_1_10_MBARE:
*physical = addr;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
default:
g_assert_not_reached();
}
} else {
widened = 0;
base = (hwaddr)(env->sptbr) << PGSHIFT;
sum = !get_field(env->mstatus, MSTATUS_PUM);
vm = get_field(env->mstatus, MSTATUS_VM);
switch (vm) {
case VM_1_09_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
case VM_1_09_SV39:
levels = 3; ptidxbits = 9; ptesize = 8; break;
case VM_1_09_SV48:
levels = 4; ptidxbits = 9; ptesize = 8; break;
case VM_1_09_MBARE:
*physical = addr;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
default:
g_assert_not_reached();
}
} else {
base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT;
vm = get_field(env->hgatp, HGATP_MODE);
widened = 2;
}
sum = get_field(env->mstatus, MSTATUS_SUM);
switch (vm) {
case VM_1_10_SV32:
levels = 2; ptidxbits = 10; ptesize = 4; break;
case VM_1_10_SV39:
levels = 3; ptidxbits = 9; ptesize = 8; break;
case VM_1_10_SV48:
levels = 4; ptidxbits = 9; ptesize = 8; break;
case VM_1_10_SV57:
levels = 5; ptidxbits = 9; ptesize = 8; break;
case VM_1_10_MBARE:
*physical = addr;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
default:
g_assert_not_reached();
}
CPUState *cs = env_cpu(env);
@ -588,7 +567,6 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
int page_fault_exceptions;
if (first_stage) {
page_fault_exceptions =
(env->priv_ver >= PRIV_VERSION_1_10_0) &&
get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
!pmp_violation;
} else {
@ -941,8 +919,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
}
s = env->mstatus;
s = set_field(s, MSTATUS_SPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
get_field(s, MSTATUS_SIE) : get_field(s, MSTATUS_UIE << env->priv));
s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
s = set_field(s, MSTATUS_SPP, env->priv);
s = set_field(s, MSTATUS_SIE, 0);
env->mstatus = s;
@ -979,8 +956,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
}
s = env->mstatus;
s = set_field(s, MSTATUS_MPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
get_field(s, MSTATUS_MIE) : get_field(s, MSTATUS_UIE << env->priv));
s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
s = set_field(s, MSTATUS_MPP, env->priv);
s = set_field(s, MSTATUS_MIE, 0);
env->mstatus = s;

View File

@ -58,31 +58,11 @@ static int ctr(CPURISCVState *env, int csrno)
#if !defined(CONFIG_USER_ONLY)
CPUState *cs = env_cpu(env);
RISCVCPU *cpu = RISCV_CPU(cs);
uint32_t ctr_en = ~0u;
if (!cpu->cfg.ext_counters) {
/* The Counters extensions is not enabled */
return -1;
}
/*
* The counters are always enabled at run time on newer priv specs, as the
* CSR has changed from controlling that the counters can be read to
* controlling that the counters increment.
*/
if (env->priv_ver > PRIV_VERSION_1_09_1) {
return 0;
}
if (env->priv < PRV_M) {
ctr_en &= env->mcounteren;
}
if (env->priv < PRV_S) {
ctr_en &= env->scounteren;
}
if (!(ctr_en & (1u << (csrno & 31)))) {
return -1;
}
#endif
return 0;
}
@ -293,9 +273,6 @@ static const target_ulong delegable_excps =
(1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
(1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
(1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT));
static const target_ulong sstatus_v1_9_mask = SSTATUS_SIE | SSTATUS_SPIE |
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
SSTATUS_SUM | SSTATUS_SD;
static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
@ -304,20 +281,11 @@ static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
static const target_ulong vsip_writable_mask = MIP_VSSIP;
#if defined(TARGET_RISCV32)
static const char valid_vm_1_09[16] = {
[VM_1_09_MBARE] = 1,
[VM_1_09_SV32] = 1,
};
static const char valid_vm_1_10[16] = {
[VM_1_10_MBARE] = 1,
[VM_1_10_SV32] = 1
};
#elif defined(TARGET_RISCV64)
static const char valid_vm_1_09[16] = {
[VM_1_09_MBARE] = 1,
[VM_1_09_SV39] = 1,
[VM_1_09_SV48] = 1,
};
static const char valid_vm_1_10[16] = {
[VM_1_10_MBARE] = 1,
[VM_1_10_SV39] = 1,
@ -347,8 +315,7 @@ static int read_mstatus(CPURISCVState *env, int csrno, target_ulong *val)
static int validate_vm(CPURISCVState *env, target_ulong vm)
{
return (env->priv_ver >= PRIV_VERSION_1_10_0) ?
valid_vm_1_10[vm & 0xf] : valid_vm_1_09[vm & 0xf];
return valid_vm_1_10[vm & 0xf];
}
static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
@ -358,34 +325,21 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
int dirty;
/* flush tlb on mstatus fields that affect VM */
if (env->priv_ver <= PRIV_VERSION_1_09_1) {
if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP |
MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_VM)) {
tlb_flush(env_cpu(env));
}
mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
MSTATUS_MPP | MSTATUS_MXR |
(validate_vm(env, get_field(val, MSTATUS_VM)) ?
MSTATUS_VM : 0);
if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
MSTATUS_MPRV | MSTATUS_SUM)) {
tlb_flush(env_cpu(env));
}
if (env->priv_ver >= PRIV_VERSION_1_10_0) {
if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
MSTATUS_MPRV | MSTATUS_SUM)) {
tlb_flush(env_cpu(env));
}
mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
MSTATUS_TW;
mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
MSTATUS_TW;
#if defined(TARGET_RISCV64)
/*
* RV32: MPV and MTL are not in mstatus. The current plan is to
* add them to mstatush. For now, we just don't support it.
*/
mask |= MSTATUS_MTL | MSTATUS_MPV;
/*
* RV32: MPV and MTL are not in mstatus. The current plan is to
* add them to mstatush. For now, we just don't support it.
*/
mask |= MSTATUS_MTL | MSTATUS_MPV;
#endif
}
mstatus = (mstatus & ~mask) | (val & mask);
@ -534,18 +488,12 @@ static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val)
{
if (env->priv_ver < PRIV_VERSION_1_10_0) {
return -1;
}
*val = env->mcounteren;
return 0;
}
static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
{
if (env->priv_ver < PRIV_VERSION_1_10_0) {
return -1;
}
env->mcounteren = val;
return 0;
}
@ -553,8 +501,7 @@ static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val)
/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
{
if (env->priv_ver > PRIV_VERSION_1_09_1
&& env->priv_ver < PRIV_VERSION_1_11_0) {
if (env->priv_ver < PRIV_VERSION_1_11_0) {
return -1;
}
*val = env->mcounteren;
@ -564,32 +511,13 @@ static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
{
if (env->priv_ver > PRIV_VERSION_1_09_1
&& env->priv_ver < PRIV_VERSION_1_11_0) {
if (env->priv_ver < PRIV_VERSION_1_11_0) {
return -1;
}
env->mcounteren = val;
return 0;
}
static int read_mucounteren(CPURISCVState *env, int csrno, target_ulong *val)
{
if (env->priv_ver > PRIV_VERSION_1_09_1) {
return -1;
}
*val = env->scounteren;
return 0;
}
static int write_mucounteren(CPURISCVState *env, int csrno, target_ulong val)
{
if (env->priv_ver > PRIV_VERSION_1_09_1) {
return -1;
}
env->scounteren = val;
return 0;
}
/* Machine Trap Handling */
static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val)
{
@ -663,16 +591,14 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
/* Supervisor Trap Setup */
static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
{
target_ulong mask = ((env->priv_ver >= PRIV_VERSION_1_10_0) ?
sstatus_v1_10_mask : sstatus_v1_9_mask);
target_ulong mask = (sstatus_v1_10_mask);
*val = env->mstatus & mask;
return 0;
}
static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
{
target_ulong mask = ((env->priv_ver >= PRIV_VERSION_1_10_0) ?
sstatus_v1_10_mask : sstatus_v1_9_mask);
target_ulong mask = (sstatus_v1_10_mask);
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
return write_mstatus(env, CSR_MSTATUS, newval);
}
@ -722,18 +648,12 @@ static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
static int read_scounteren(CPURISCVState *env, int csrno, target_ulong *val)
{
if (env->priv_ver < PRIV_VERSION_1_10_0) {
return -1;
}
*val = env->scounteren;
return 0;
}
static int write_scounteren(CPURISCVState *env, int csrno, target_ulong val)
{
if (env->priv_ver < PRIV_VERSION_1_10_0) {
return -1;
}
env->scounteren = val;
return 0;
}
@ -812,15 +732,15 @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
{
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
*val = 0;
} else if (env->priv_ver >= PRIV_VERSION_1_10_0) {
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
return -1;
} else {
*val = env->satp;
}
} else {
*val = env->sptbr;
return 0;
}
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
return -1;
} else {
*val = env->satp;
}
return 0;
}
@ -829,13 +749,7 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
return 0;
}
if (env->priv_ver <= PRIV_VERSION_1_09_1 && (val ^ env->sptbr)) {
tlb_flush(env_cpu(env));
env->sptbr = val & (((target_ulong)
1 << (TARGET_PHYS_ADDR_SPACE_BITS - PGSHIFT)) - 1);
}
if (env->priv_ver >= PRIV_VERSION_1_10_0 &&
validate_vm(env, get_field(val, SATP_MODE)) &&
if (validate_vm(env, get_field(val, SATP_MODE)) &&
((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
{
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
@ -1313,8 +1227,6 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_MSTATUSH] = { any, read_mstatush, write_mstatush },
#endif
/* Legacy Counter Setup (priv v1.9.1) */
[CSR_MUCOUNTEREN] = { any, read_mucounteren, write_mucounteren },
[CSR_MSCOUNTEREN] = { any, read_mscounteren, write_mscounteren },
/* Machine Trap Handling */

View File

@ -85,30 +85,21 @@ static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a)
{
#ifndef CONFIG_USER_ONLY
if (ctx->priv_ver >= PRIV_VERSION_1_10_0) {
gen_helper_tlb_flush(cpu_env);
return true;
}
gen_helper_tlb_flush(cpu_env);
return true;
#endif
return false;
}
static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
{
#ifndef CONFIG_USER_ONLY
if (ctx->priv_ver <= PRIV_VERSION_1_09_1) {
gen_helper_tlb_flush(cpu_env);
return true;
}
#endif
return false;
}
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
{
#ifndef CONFIG_USER_ONLY
if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
has_ext(ctx, RVH)) {
if (has_ext(ctx, RVH)) {
/* Hpervisor extensions exist */
/*
* if (env->priv == PRV_M ||
@ -127,8 +118,7 @@ static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a)
{
#ifndef CONFIG_USER_ONLY
if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
has_ext(ctx, RVH)) {
if (has_ext(ctx, RVH)) {
/* Hpervisor extensions exist */
/*
* if (env->priv == PRV_M ||

View File

@ -215,11 +215,6 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
return;
}
if (env->priv_ver < PRIV_VERSION_1_10_0) {
monitor_printf(mon, "Privileged mode < 1.10 unsupported\n");
return;
}
if (!(env->satp & SATP_MODE)) {
monitor_printf(mon, "No translation or protection\n");
return;

View File

@ -84,8 +84,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
}
if (env->priv_ver >= PRIV_VERSION_1_10_0 &&
get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
if (get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
}
@ -119,10 +118,8 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
} else {
prev_priv = get_field(mstatus, MSTATUS_SPP);
mstatus = set_field(mstatus,
env->priv_ver >= PRIV_VERSION_1_10_0 ?
MSTATUS_SIE : MSTATUS_UIE << prev_priv,
get_field(mstatus, MSTATUS_SPIE));
mstatus = set_field(mstatus, MSTATUS_SIE,
get_field(mstatus, MSTATUS_SPIE));
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
env->mstatus = mstatus;
@ -147,10 +144,8 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
target_ulong mstatus = env->mstatus;
target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
mstatus = set_field(mstatus,
env->priv_ver >= PRIV_VERSION_1_10_0 ?
MSTATUS_MIE : MSTATUS_UIE << prev_priv,
get_field(mstatus, MSTATUS_MPIE));
mstatus = set_field(mstatus, MSTATUS_MIE,
get_field(mstatus, MSTATUS_MPIE));
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
#ifdef TARGET_RISCV32
@ -177,7 +172,6 @@ void helper_wfi(CPURISCVState *env)
CPUState *cs = env_cpu(env);
if ((env->priv == PRV_S &&
env->priv_ver >= PRIV_VERSION_1_10_0 &&
get_field(env->mstatus, MSTATUS_TW)) ||
riscv_cpu_virt_enabled(env)) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
@ -193,7 +187,6 @@ void helper_tlb_flush(CPURISCVState *env)
CPUState *cs = env_cpu(env);
if (!(env->priv >= PRV_S) ||
(env->priv == PRV_S &&
env->priv_ver >= PRIV_VERSION_1_10_0 &&
get_field(env->mstatus, MSTATUS_TVM))) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
} else {

View File

@ -54,8 +54,8 @@ static struct arch2cpu cpus_map[] = {
{ "xtensa", "dc233c" },
{ "xtensaeb", "fsf" },
{ "hppa", "hppa" },
{ "riscv64", "rv64gcsu-v1.10.0" },
{ "riscv32", "rv32gcsu-v1.9.1" },
{ "riscv64", "rv64" },
{ "riscv32", "rv32" },
{ "rx", "rx62n" },
};