the relationship between mstatus and sstatus in risc-v - riscv

in riscv, there is sstatus in S privilege level and mstatus in M privilege level. sstatus is a subset of mstatus. Can I regard sstatus as a map of mstatus and doesn't have entities(such as fcsr,ffalgs and frm) . sstatus only includes bit-field belonging to S privilege level. The benefit of mapping is to change mstatus in S privilege level directly, without change privilege level from S to M.

Related

Can MSI interrupt route to multiple cpus?

Message signalled interrupts (MSI) is an optional feature that enables PCI devices to request service by writing a system-specified message to a system-specified address (PCI DWORD memory write transaction). The transaction address specifies the message destination while the transaction data specifies the message. System software is expected to initialize the message destination and message during device configuration, allocating one or more non-shared messages to each MSI capable function.
Can MSI interrupt route to multiple cpus?
for example: echo F > /proc/irq/msi_irq/smp_affinity
From my opinion:
MSI interrupt can route to multiple cpus. when cpu receive interrupt message, use the destination info to route interrupts to multiple cpus.
MSI interrupt can not route to multiple cpus. MSI interrupt message can only write to LAPIC, so can only trigger interrupt to one cpu.
But, which opinion is right?
Yes, MSIs can be dispatched to multiple logical CPUs.
Chapter 10.11 (Advanced Programmable Interrupt Controller / Message Signalled Interrupts) of the Intel SDM vol 3 describes the format of the address destination of an MSI:
The RH (Redirection Hint) and DM (Destination mode) fields change the meaning of the Destination ID field:
• When RH is 0, the interrupt is directed to the processor listed in the Destination ID field.
• When RH is 1 and the physical destination mode is used, the Destination ID field must not be set to FFH;
it must point to a processor that is present and enabled to receive the interrupt.
• When RH is 1 and the logical destination mode is active in a system using a flat addressing model, the Destination ID field must be set so that bits set to 1 identify processors that are present and enabled to
receive the interrupt.
• If RH is set to 1 and the logical destination mode is active in a system using cluster addressing model,
then Destination ID field must not be set to FFH; the processors identified with this field must be
present and enabled to receive the interrupt.
If by msi_irq in /proc/irq/msi_irq/smp_affinity you mean an IRQ number that uses MSI then yes, setting that pseudo-file to f will limit said IRQ to the four logical CPUs selected.
In fact, as far as interrupt dispatching goes, only interrupts using the legacy PIC cannot have an affinity. IO-APIC interrupts and MSI can always target a group of processors.

why processor_t::egalize_privilege(ret_t prv) returns PRV_U if (prv == PRV_HS || (prv == PRV_S && !supports_extension('S')))

I cannot understand source code in legalize_privilege() shown below:
reg_t processor_t::legalize_privilege(reg_t prv)
{
if (!supports_extension('U'))
return PRV_M;
if (prv == PRV_HS || (prv == PRV_S && !supports_extension('S')))
return PRV_U;
//according to my understanding, HS mode actually works in Supervisor mode. So PRV_S should be returned here.
return prv;
}
PRV_HS is only used as a dummy privilege level within the simulator for CSR permission checks.
In the H-extension specification, HS-mode takes the place of S-mode (level 1).
The integer value 2 is used for PRV_HS to distinguish it from PRV_S, but that is a reserved value in the RISC-V Privileged Architecture (ISA Manual Vol. 2 § 1.2 Privilege Levels) and not used by the H-extension.
It is therefore illegal to actually set this mode. To set either HS- or S-mode, always use PRV_S.
In the same condition, you can also see that it is illegal to set S-mode if the S-extension is not supported.
Both of these cases are illegal, so the privilege level is instead forced to the lowest level, which is PRV_U.
The only use of PRV_HS is in the permission check segment of processor_t::get_csr (here), where it is used instead of PRV_S if the processor is not in a virtual state (as set by processor_t::set_virt), to permit access to Hypervisor CSRs.
This is because the CSR address encodes the minimum privilege level required for access in bits [9:8], which is defined as 10b = 2 for Hypervisor CSRs, even though there is no such distinct privilege level (ISA Manual Vol. 2 § 2.1 CSR Address Mapping Conventions).

How the RISC-V HW can determine the privilege level?

The RISC-V current SW privilege level is not set in any CSR. Nevertheless the spec states that "Attempts to access a CSR without appropriate privilege level ... raise illegal instruction". How can it be implemented then (in the HW)?
Well, on interrupts - "xPP holds the previous privilege mode (x=M,S or U). The xPP fields can only hold privilege modes up to x, so MPP is two bits wide, SPP is one bit wide, and UPP is implicitly zero."
Actually, what I have found now is that the xRET instruction enables the processor to store (internally) the current mode - "The MRET, SRET, or URET instructions are used to return from traps in M-mode, S-mode, or U-mode respectively. When executing an xRET instruction, supposing xPP holds the value y, x IE is set to x PIE; the privilege mode is changed to y; x PIE is set to 1; and xPP is set to U (or M if user-mode is not supported)."
The privilege level is reflected in the MPP bits of the mstatus register.
We have mstatus.mPP. that holdS the previous privilege mode. Current privilege mode is not visible to software.
on interrupt the mstatus.mPP is saved to mcause.mPP.. on mrwt, its just written back to mstatus.mPP.
I found this answer from sifive forums quite helpful when I was looking for the same question.
RISC-V deliberately doesn’t make it easy for code to discover what
mode it is running it because this is a virtualisation hole. As a
general principle, code should be designed for and implicitly know
what mode it will run in. Applications code should assume it is in U
mode. The operating system should assume it is in S mode (it might in
fact be virtualised and running in U mode, with things U mode can’t do
trapped and emulated by the hypervisor).
https://forums.sifive.com/t/how-to-determine-the-current-execution-privilege-mode/2823

control Chip Select manually prior to data read in linux?

Hi I have a SPI touch device with 24 keys, each read will return 3 bytes, containing exact all 24 keys status. My hardware is a custom made beaglebone like device, spi0 is able to read its own write by connecting MISO to MOSI.
Everything (wiring, software) is working perfectly matching this guide: http://communistcode.co.uk/blog/blogPost.php?blogPostID=1
Now my touch device is CS active high device, but it requires to drive the chip select to low and back to high before actual read. I don't seems to have control with SPI cs value, I can only either control it within an actual read phase by specifying CS high or low. From my knowledge I have to use another GPIO to emulate the CS.
Question: any way to control cs freely? (i.e. set 0 or 1 by my code directly?)
I have solved this by pinmux the CS pin to a GPIO, and control it manually prior to actual communication.

Is there a way to find out which core each thread of an app is binding to?

Say, a multi-threading app runs on a 8-core Solaris. Is there a way to list the mapping between each thread and core #?
Thanks,
First off, you can write C code to inquire after each thread in a process
Open /proc/[id]/lwp/[tid]/lwpsinfo there and fetch it into
a lwpsinfo_t struct defined in procfs.h
processorid_t pr_onpro; /* processor which last ran this lwp */
processorid_t pr_bindpro; /* processor to which lwp is bound */
Are the two members of interest to you. Before you waste your time
Next before you waste a lot of time (assuming zones):
prctl -i zone {ZONENAME} run by root in the global zone only. You get output like this:
NAME PRIVILEGE VALUE FLAG ACTION RECIPIENT
zone.max-swap
system 16.0EB max deny -
zone.max-locked-memory
system 16.0EB max deny -
zone.max-shm-memory
system 16.0EB max deny -
zone.max-shm-ids
system 16.8M max deny -
zone.max-sem-ids
system 16.8M max deny -
zone.max-msg-ids
system 16.8M max deny -
zone.max-lwps
system 2.15G max deny -
zone.cpu-cap
privileged 1.20K - deny -
system 4.29G inf deny -
zone.cpu-shares
privileged 1 - none -
system 65.5K max none -
zone.cpu-cap 1.20K means 1200 == means percent. So 1200 means 12 cpus. If I were your admin there is no way a DEV or TEST zone would have 64 cores. So check it first.
Plus, it seems your assumptions are wrong. Unless affinity (processor sets, etc.) is enabled the system assigns cpus to threads using the currently enabled scheduling algorithm (FSS, etc.) This means any thread can go to any available cpu at any time depending on the scheduler and load.

Resources