On 6/6/2026 2:16 AM, Icenowy Zheng wrote:
在 2026-06-05五的 23:33 -0300,Daniel Henrique Barboza写道:
On 6/5/2026 7:24 PM, Andrew Jones wrote:
On Fri, Jun 05, 2026 at 05:48:18PM -0300, Daniel Henrique Barboza
wrote:
...
You're correct. We're not initializing satp_mode to
max_satp_mode, so the
default value is being set to sv39. This seems to be the case
for all
CPUs, not just this one. For some reason I thought we were
defaulting
to the max_satp_mode. I need to understand why sv39 is being
set as
default (i.e. why not BARE?).
Got an update. It turns out that what we're seeing is something
that is
only happening to this CPU we're trying to add.
The way satp mode is set on QEMU assuming no command line input:
- "Bare" CPUs, aka CPUs that has just I or E enabled: default to
BARE;
- Profile CPUs: default to the minimum required by the spec.
E.g. for
RVA23 the default is set to sv39;
- all other CPUs: default to satp_mode_max from the CPU
definition.
The riscv-server-ref CPU is a BARE CPU that is using the profile
framework
to enable extensions. So for all intents and purposes the code
is treating
it as a profile CPU with extra stuff. Which is good, but then
the
satp setting from RVA23 (sv39) is overwriting satp_mode_max from
the
CPU definition.
I believe the way we're creating riscv-server-ref here is
correct, so what
I'm going to do is send a couple of fixes to allow riscv-server-
ref to use
RVA23 as a base and honor its satp_mode_max value too.
But setting satp_mode_max to sv48 is not correct if that really
means
_max_ since we want the reference platform to default to the
minimum
(sv48) but also support the supported optional extensions and sv57
is
a supported optional extension.
QEMU only works this way for profile CPUs.
For non-profile CPUs: cpu.max_satp_mode is set internally as part of
the CPU definition. This is the maximum satp value that the CPU
allows
users to set via cmd line. If the user does not provide a satp mode
then we'll do curr_satp_mode = max_satp_mode.
E.g. the thead vendor CPU defines .cfg.max_satp_mode = VM_1_10_SV39.
In the command line we can't set anything higher than that:
$ ./build/qemu-system-riscv64 -M virt -cpu thead-c906,sv57=on
qemu-system-riscv64: satp_mode sv57 is higher than hw max capability
sv39
For profile CPUs things are different: they are bare_cpu types, which
are
initialized with max_satp_mode sv57, and then during profile init we
set the current satp_mode (current, not max_satp_mode) to the minimum
the profile requires. Thus the rva23s64 CPU, by default, starts with
sv39 but it can go up to sv57.
From what I'm understanding we want the riscv-server-ref CPU to work
like profile CPUs. In fact I believe we can make it official by
adding a 'default_satp_mode' setting in the CPU definition and
allowing
all CPUs to define a default satp and a max satp. CPUs defs that
don't
set a default mode will keep working as today (default_satp_mode ==
max_satp_mode
if no user input).
I think we can just make RVSP a profile, and rvsp-ref CPU a BARE CPU
based on that profile; then set the profile's min SATP to Sv48, and the
BARE CPU's max SATP to Sv57.
In this case if any other CPU complying to RVSP is added, it can just
reuse the profile.
Having riscv-server-ref being a profile CPU seems compelling indeed ...
new CPUs could instance it with .profile = &rvserver-ref to have everything
already sorted out, we would also have a flag to enable the profile for
existing cpus, e.g. -cpu rv64,rvserver-ref=on.
Drew, any thoughts?
Daniel
Thanks,
Icenowy
I'll make changes and see how it goes. Cheers,
Daniel
Thanks,
drew