-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to build a RISCV64 platform #7
Comments
Should be fairly simple to build a riscv, the CPUs are available - but you will need a binary image etc. |
I'm using qbox v3.0.1 and libqemu v8.2-v0.1.4, and I found some errors while compiling the riscv64 target. The following is the patch I used to fix those errors. The patch for libqemu v8.2-v0.1.4 diff --git a/CMakeLists.txt b/CMakeLists.txt
index fe3f6b1833..dbb2c5bb77 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,7 +5,7 @@ include(GNUInstallDirs)
# Enabled QEMU targets
if(NOT DEFINED LIBQEMU_TARGETS)
- set(LIBQEMU_TARGETS aarch64)
+ set(LIBQEMU_TARGETS aarch64 riscv64)
endif()
# For the arm target, use the aarch64 target which is a superset of the former.
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index 3872e05bb6..ed34941cab 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -297,7 +297,7 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
for (i = 0; i < s->num_harts; i++) {
CPUState *cpu = cpu_by_arch_id(s->hartid_base + i);
RISCVCPU *rvcpu = RISCV_CPU(cpu);
- CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
+ CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
riscv_aclint_mtimer_callback *cb =
g_new0(riscv_aclint_mtimer_callback,1);
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e58b9151e3..db4f6b0520 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1154,7 +1154,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
}
if (cpu->cfg.hartid != -1) {
- env->mhartid = cpu->cfg.hartid;
+ (&cpu->env)->mhartid = cpu->cfg.hartid;
}
riscv_cpu_register_gdb_regs_for_features(cs);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 5bf087db38..4c7bcbf219 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -690,7 +690,7 @@ uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, uint64_t value)
env->mip = (env->mip & ~mask) | (value & mask);
#ifdef CONFIG_LIBQEMU
- libqemu_cpu_riscv_mip_update_cb(CPU(cpu), env->mip);
+ libqemu_cpu_riscv_mip_update_cb(env_cpu(env), env->mip);
#endif
riscv_cpu_interrupt(env); The following is the lua configuration for building a RISCV64 platform. I use a openSBI firmware with Linux kernel payload as binary image. The binary image has been tested on the vanilla QEMU. -- Virtual platform configuration
function top()
local str = debug.getinfo(2, "S").source:sub(2)
if str:match("(.*/)")
then
return str:match("(.*/)")
else
return "./"
end
end
dofile(top().."../fw/utils.lua");
print ("Lua config running. . . ");
INITIAL_DDR_SPACE = 0x80000000
_FW_PAYLOAD_LOAD_ADDR = INITIAL_DDR_SPACE
local IS_SHARED_MEM = false
ACCEL = "tcg"
print("Virtual acceleration: " .. ACCEL)
local UART0 = 0x10000000
platform = {
moduletype="Container";
quantum_ns = 10000000;
router = {
moduletype="router";
log_level=0;
},
ram_0= {
moduletype="gs_memory";
target_socket = {address = INITIAL_DDR_SPACE; size = 0x100000000, bind= "&router.initiator_socket"},
log_level=0,
shared_memory=IS_SHARED_MEM
};
qemu_inst_mgr = {
moduletype = "QemuInstanceManager";
},
qemu_inst= {
moduletype="QemuInstance";
args = {"&platform.qemu_inst_mgr", "RISCV64"};
accel = ACCEL,
tcg_mode="MULTI",
sync_policy = "multithread-unconstrained"
},
charbackend_stdio_0 = {
moduletype = "char_backend_stdio";
read_write = true;
};
pl011_uart_0 = {
moduletype = "Pl011",
dylib_path = "uart-pl011",
target_socket = {address= UART0, size=0x1000, bind = "&router.initiator_socket"},
irq = {bind = "&plic.irq_in_10"},
backend_socket = {bind = "&charbackend_stdio_0.biflow_socket"},
};
fallback_0= {
moduletype="gs_memory";
target_socket = {address = 0x0; size = 0x800000000, bind= "&router.initiator_socket", priority=1},
dmi_allow=false,
log_level=0,
shared_memory=IS_SHARED_MEM};
load = {
moduletype = "loader",
initiator_socket = {bind = "&router.target_socket"};
{ bin_file=top().."fw/Artifacts/fw_payload.elf", address=_FW_PAYLOAD_LOAD_ADDR };
};
plic = {
moduletype = "plic_sifive";
args = {"&platform.qemu_inst"};
};
riscv_aclint_swi = {
moduletype = "riscv_aclint_swi";
args = {"&platform.qemu_inst"};
num_harts = 1;
};
riscv_aclint_mtimer = {
moduletype = "riscv_aclint_mtimer";
args = {"&platform.qemu_inst"};
num_harts = 1;
};
cpu_0 = {
moduletype = "cpu_riscv64";
args = {"&platform.qemu_inst", 0};
mem = {bind = "&router.target_socket"};
};
};
print ("fw_payload is loaded at: 0x"..string.format("%x",_FW_PAYLOAD_LOAD_ADDR)); I tried running the RISCV64 platform but no luck. I found that
gdb result:
I'm wondering if you can help solve this problem. It would be very helpful if you could provide some insight. |
Hello @estarriol43, I am working on replicating the issue with riscv64 and Ill let you know ASAP. |
Hello @estarriol43, Thank you for bringing attention to this issue. We can confirm that building qbox with
Additionally, in the Lua file, please set the components properly and bind them to the router. Please adjust the addresses according to your setup: in conf.lua:
Reference : plic-sifive.h Moreover, to avoid the segmentation fault, you should pass the last cpu (in this case cpu_0, since there is only 1 cpu in your setup) to the interrupt controller to ensure it is initiated before. For example:
Reference: riscv-aclint-swi.h We would also like to mention that we will later add an example for riscv with images, device tree, and conf.lua. Best regards, |
I'm wondering if there is any document about how to build a RISCV64 platform. How can we configure the .lua file to build a platform that supports RISCV64?
The text was updated successfully, but these errors were encountered: