Skip to content
This repository has been archived by the owner on Apr 13, 2019. It is now read-only.

SiFive CLIC (Core Level Interrupt Controller) test-beta1 #157

Open
wants to merge 41 commits into
base: qemu-for-upstream
Choose a base branch
from

Conversation

michaeljclark
Copy link
Collaborator

PLEASE DO NOT MERGE - QEMU CLIC BETA TEST V1

  • Implements draft clic-spec (20180728)

    • Implements non-vectored mode and vectored mode
    • Implements mode+level+priority configuration
    • Implements mode+level+priority preemption model
    • Seperated M-mode (mtvec) and S-mode (stvec) delivery
    • CLIC supports backwards compatible CLINT mode for
      legacy interrupts using MIE/MIP,SIE/SIP (irq < 16)
      depending on mtvec (MTI,MSI) and stvec (STI,SSI)
    • CLINT mode supports S-mode stimecmp{h} and ssip{h}
  • QEMU CLINT/CLIC Test Cases

  • Adds two experimental machines

    • SiFive Freedom E-Series with CLIC
      • Implements M-mode CLINT/CLIC config memory map
      • Parameters
        • CLICINTBITS=4
        • CLICCFGMBITS=0
        • CLICCFGLBITS=4
      • Invocation
        • qemu-system-riscv{32,64} -machine sifive_ex
    • SiFive Freedom U-Series with CLIC
      • Implements M-mode and S-mode CLINT/CLIC memory map
      • Parameters
        • CLICINTBITS=8
        • CLICCFGMBITS=2
        • CLICCFGLBITS=4
      • Invocation
        • qemu-system-riscv{32,64} -machine sifive_ux
  • CLIC combined CLINT/CLIC memory map

    • M-Mode CLINT = 0x02000000
      • msip = 0x02000000 + hartid * 4
      • mtimecmp = 0x02004000 + hartid * 4
      • mtime = 0x0200bff8
    • S-Mode CLINT = 0x02020000
    • M-mode CLIC = 0x02080000
      • clicintip = 0x02080000 + hartid * 0x1000 + 0x000
      • clicintie = 0x02080000 + hartid * 0x1000 + 0x400
      • clicintcfg = 0x02080000 + hartid * 0x1000 + 0x800
      • cliccfg = 0x02080000 + hartid * 0x1000 + 0xc00
    • S-Mode CLIC = 0x020c0000
      • clicintip = 0x020c0000 + hartid * 0x1000 + 0x000
      • clicintie = 0x020c0000 + hartid * 0x1000 + 0x400
      • clicintcfg = 0x020c0000 + hartid * 0x1000 + 0x800
  • Adds CLIC interrupt tracing (-d trace:riscv_trap,...)

    • riscv_trap # existing core interrupt tracing
    • sifive_clic_cfg # CLIC global configuration
    • sifive_clic_intcfg # CLIC interrupt configuration
    • sifive_clic_intie # CliC interrupt enable
    • sifive_clic_intip # CLIC interrupt pending
    • sifive_clic_irq # CLIC irq entry
  • Notes / Limitations

    • Enforces clicintcfg writes based on cliccfg and mode
    • Reads/writes to intcfg/intie/intip in lower mode MMIO
      apetures are currently allowed. Access checks need to
      be added to suppress writes and hardwire read reults to
      zero for any entries that where mode < clicintcfg.mode
    • Interrupts pending bits are writable by software.
      Edge/Level configuration needs to be added to control
      software access to interrupt pending bits
    • Selective vectoring in non-vectored mode is unimplemented
    • PLIC is currently not routed via the CLIC however pending
      bits can be written by software to test pre-emption.
    • mnxti/snxti sets mstatus flags but returns 0 (slow path).
      The CLIC state is currenetly not accessible from target/riscv
      as cpu implementations can't include anything from include/hw
      so the CLIC state needs to be in a CPU accessible structure.
    • Potential race condition if an interrupt is posted
      before the CPU has received and processed an outstanding
      interrupt due to env->exccode being overwritten.
      Needs changes to the interface from the CLIC so that the
      CPU interrupt handler pulls the highest priority interrupt
      from the CLIC at the time it is woken up. This requires the
      CLIC state to be accessible from the CPU similarly to mnxti
    • CPU core changes are relatively intrusive. The CPU interrupt
      handling requires some abstraction/hooks for a more modular
      CLIC implementation. CLIC state needs to be attached to
      the CPU, and accessible to the MMIO device with hooks in
      riscv_cpu_exec_interrupt and riscv_cpu_do_interrupt

Michael Clark and others added 30 commits July 25, 2018 13:41
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
- Inline PTE_TABLE check for better readability
- Change access checks from ternary operator to if
- Improve readibility of User page U mode and SUM test
- Disallow non U mode from fetching from User pages
- Add reserved PTE flag check: W or W|X
- Add misaligned PPN check
- Set READ protection for PTE X flag and mstatus.mxr
- Use memory_region_is_ram in pte update

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
The PLIC previously used a mutex to protect against concurrent
access to the claimed and pending bitfields. Instead of using
a mutex, we update the bitfields using atomic_cmpxchg.

Rename sifive_plic_num_irqs_pending to sifive_plic_irqs_pending
and add an early out if any interrupts are pending as the
count of pending interrupts is not used.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is intended to improve readability.
There is no change to the logic.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Change the API of riscv_set_local_interrupt to take a
write mask and value to allow setting and clearing of
multiple local interrupts atomically in a single call.
Rename the new function to riscv_cpu_update_mip.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
This patch makes op_helper.c contain only instruction
operation helpers used by translate.c and moves any
unrelated cpu helpers into cpu_helper.c. No logic is
changed by this patch.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
* Add user-mode CSR defininitions.
* Reorder CSR definitions to match the specification.
* Change H mode interrupt comment to 'reserved'.
* Remove unused X_COP interrupt.
* Add user-mode interrupts.
* Remove erroneous until comments on machine mode interrupts.
* Move together paging mode and page table bit definitions.
* Move together interrupt and exception cause definitions.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Previous CSR code uses csr_read_helper and csr_write_helper
to update CSR registers however this interface prevents
atomic read/modify/write CSR operations; in addition
there is no trap-free method to access to CSRs due
to the monolithic CSR functions call longjmp.

The current iCSR interface is not safe to be called by
target/riscv/gdbstub.c as privilege checks or missing CSRs
may call longjmp to generate exceptions. It needs to
indicate existence so traps can be generated in the
CSR instruction helpers.

This commit moves CSR access from the monolithic switch
statements in target/riscv/op_helper.c into modular
read/write functions in target/riscv/csr.c using a new
function pointer table for dispatch (which can later
be used to allow CPUs to hook up model specific CSRs).

A read/modify/write interface is added to support atomic
CSR operations and a non-trapping interface is added
to allow exception-free access to CSRs by the debugger.

The CSR functions and CSR dispatch table are ordered
to match The RISC-V Instruction Set Manual, Volume II:
Privileged Architecture Version 1.10, 2.2 CSR Listing.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Use the new CSR read/modify/write interface to implement
atomic updates to mip/sip.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
CSR predicate functions are added to the CSR table.
mstatus.FS and counter enable checks are moved
to predicate functions and two new predicates are
added to check misa.S for s* CSRs and a new PMP
CPU feature for pmp* CSRs.

Processors that don't implement S-mode will trap
on access to s* CSRs and processors that don't
implement PMP will trap on accesses to pmp* CSRs.

PMP checks are disabled in riscv_cpu_handle_mmu_fault
when the PMP CPU feature is not present.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Cc: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Michael Clark <mjc@sifive.com>
Modifed from Richard Henderson's patch [1] to integrate
with the new control and status register implementation.

[1] https://lists.nongnu.org/archive/html/qemu-devel/2018-03/msg07034.html

Note: the f* CSRs already mark mstatus.FS dirty using
env->mstatus |= mstatus.FS so the bug in the first
spin of this patch has been fixed in a prior commit.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Cc: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Michael Clark <mjc@sifive.com>

Co-authored-by: Richard Henderson <richard.henderson@linaro.org>
Co-authored-by: Michael Clark <mjc@sifive.com>
This adds the necessary minimum to support S-mode
virtualization for priv ISA >= v1.10

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Cc: Matthew Suozzo <msuozzo@google.com>
Signed-off-by: Michael Clark <mjc@sifive.com>

Co-authored-by: Matthew Suozzo <msuozzo@google.com>
Co-authored-by: Michael Clark <mjc@sifive.com>
This allows hardware and/or derived cpu instances
to override or implement new CSR operations.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Add carriage return that was erroneously removed
when converting to qemu_log. Change hard coded
core number to the actual hartid.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
* Add riscv prefix to raise_exception function
* Add riscv prefix to CSR read/write functions
* Add riscv prefix to signal handler function
* Add riscv prefix to get fflags function
* Remove redundant declaration of riscv_cpu_init
  and rename cpu_riscv_init to riscv_cpu_init
* rename riscv_set_mode to riscv_cpu_set_mode

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
The mode variable only uses the lower 4-bits (M,H,S,U) so
replace the GCC specific __builtin_popcount with ctpop8.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
We can't allow the supervisor to control SEIP as this would allow the
supervisor to clear a pending external interrupt which will result in
lost a interrupt in the case a PLIC is attached. The SEIP bit must be
hardware controlled when a PLIC is attached.

This logic was previously hard-coded so SEIP was always masked even
if no PLIC was attached. This patch adds riscv_cpu_claim_interrupts
so that the PLIC can register control of SEIP. In the case of models
without a PLIC (spike), the SEIP bit remains software controlled.

This interface allows for hardware control of supervisor timer and
software interrupts by other interrupt controller models.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
gen methods should access state from DisasContext. Add misa
field to the DisasContext struct and remove CPURISCVState
argument from all gen methods.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Cc: Emilio G. Cota <cota@braap.org>
Signed-off-by: Michael Clark <mjc@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Add misa checks for M, A, F and D extensions and if they are
not present generate illegal instructions. This improves
emulation accurary for harts with a limited set of extensions.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Cc: Emilio G. Cota <cota@braap.org>
Signed-off-by: Michael Clark <mjc@sifive.com>
This patch adds support for writing misa. misa is validated based
on rules in the ISA specification. 'E' is mutually exclusive with
all other extensions. 'D' depends on 'F' so 'D' bit is dropped
if 'F' is not present. A conservative approach to consistency is
taken by flushing the translation cache on misa writes. misa_mask
is added to the CPU struct to store the original set of extensions.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
A missing shift made updates to the low order bits
of timecmp erroneously copy the old low order bits
into the high order bits of the 64-bit timecmp
register. Add the missing shift and rename timecmp
local variables to timecmp_hi and timecmp_lo.

This bug didn't show up as the low order bits are
usually written first followed by the high order
bits meaning the high order bits contained an invalid
value between the timecmp_lo and timecmp_hi update.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Co-Authored-by: Johannes Haring <johannes.haring@gmx.net>
Signed-off-by: Michael Clark <mjc@sifive.com>
The address calculation for the pending bitfield had
a copy paste bug. This bug went unnoticed because the Linux
PLIC driver does not read the pending bitfield, rather it
reads pending interrupt numbers from the claim register
and writes acknowledgements back to the claim register.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Reported-by: Vincent Siles <vincent.siles@ens-lyon.org>
Signed-off-by: Michael Clark <mjc@sifive.com>
Previously the second UARTs on the sifive_e and sifive_u machines
where disabled due to check-qtest-riscv32 and check-qtest-riscv64
failures. Recent changes in the QEMU core serial code have
resolved these failures so the second UARTs can be instantiated.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Remove machine generated constraints that are not
referenced by the pseudo-instruction constraints.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Refer to the RISC-V PSABI specification for details:

- https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

Cc: Michael Tokarev <mjt@tls.msk.ru>
Cc: Richard Henderson <richard.henderson@linaro.org>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Michael Clark <mjc@sifive.com>
This change checks elf_flags for EF_RISCV_RVE and if
present uses the RVE linux syscall ABI which uses t0
for the syscall number instead of a7.

Warn and exit if a non-RVE ABI binary is run on a
cpu with the RVE extension as it is incompatible.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Co-authored-by: Kito Cheng <kito.cheng@gmail.com>
Co-authored-by: Michael Clark <mjc@sifive.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Support for separate firmware and kernel payload is added
by updating BBL to read optional preloaded kernel address
attributes from device-tree using a similar mechanism to
that used to pass init ramdisk addresses to linux kernel.

    chosen {
        riscv,kernel-start = <0x00000000 0x80200000>;
        riscv,kernel-end = <0x00000000 0x80590634>;
    };

These attributes are added by QEMU and read by BBL when combining
-bios <firmware-image> and -kernel <kernel-image> options. e.g.

$ qemu-system-riscv64 -machine virt -bios bbl -kernel vmlinux

With this change, bbl can be compiled without --with-payload
and the dummy payload alignment is altered to make the memory
footprint of the firmware-only bbl smaller. The dummy payload
message is updated to indicate the alternative load method.

This load method could also be supported by a first stage boot
loader that reads seperate firmware and kernel from SPI flash.
The main advantage of this new mechanism is that it eases kernel
development by avoiding the riscv-pk packaging step after kernel
builds, makes building per repository artefacts for CI simpler,
and mimics bootloaders on other platforms that can load a kernel
image file directly. Ultimately BBL should use an SPI driver to
load the kernel image however this mechanism supports use cases
such such as QEMU's -bios, -kernel and -initrd options following
examples from other platforms that pass kernel entry to firmware
via device-tree.

The board is also changed to use the firmware address from the
loaded firmware or combined firmware+kernel. This is normally
equal to the DRAM base address of 0x8000_0000, however now it
is possible to boot firmware at different load addresses because
the reset code jumps to the actual firmware entry address.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Michael Clark and others added 10 commits July 25, 2018 14:12
This effectively changes riscv_cpu_update_mip
from edge to level. i.e. cpu_interrupt or
cpu_reset_interrupt are called regardless of
the current interrupt level.

Fixes WFI doesn't return when a IPI is issued:

- riscvarchive#132

To test:

1) Apply RISC-V Linux CPU hotplug patch:

- http://lists.infradead.org/pipermail/linux-riscv/2018-May/000603.html

2) Enable CONFIG_CPU_HOTPLUG in linux .config

3) Try to offline and online cpus:

  echo 1 > /sys/devices/system/cpu/cpu2/online
  echo 0 > /sys/devices/system/cpu/cpu2/online
  echo 1 > /sys/devices/system/cpu/cpu2/online

Reported-by: Atish Patra <atishp04@gmail.com>
Cc: Atish Patra <atishp04@gmail.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Add the SiFive Test device to 'sifive_e' and 'sifive_u'
machines so that test cases can shutdown QEMU and signal
an exit code. The SiFive Test Finisher is a real device
that exists in the RTL to allow exiting simulations.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
If vectored interrupts are enabled (bits[1:0]
of mtvec/stvec == 1) then use the following
logic for trap entry address calculation:

 pc = mtvec + cause * 4

In addition to adding support for vectored interrupts
this patch simplifies the interrupt delivery logic
by making sync/async cause decoding and encoding
steps distinct.

The cause code and the sign bit indicating sync/async
is split at the beginning of the function and fixed
cause is renamed to cause. The MSB setting for async
traps is delayed until setting mcause/scause to allow
redundant variables to be eliminated. Some variables
are renamed for conciseness and moved so that decls
are at the start of the block.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Writes to the SiFive PRCI registers are preserved while leaving the
ready bits set for the HFX/HFR oscillators and the lock bit set for the
PLL.

Signed-off-by: Nathaniel Graff <nathaniel.graff@sifive.com>
Reviewed-by: Michael Clark <mjc@sifive.com>
The watermark bits are set in the interrupt pending register according
to the configuration of txcnt and rxcnt in the txctrl and rxctrl
registers.

Since the UART TX does not implement a FIFO, the txwm bit is set as long
as the TX watermark level is greater than zero.

Signed-off-by: Nathaniel Graff <nathaniel.graff@sifive.com>
Reviewed-by: Michael Clark <mjc@sifive.com>
According to the RISC-V priv. v1.10 ISA document,
pmpaddr register stores (base_addr | (size/2 - 1)) >> 2 for a
NAPOT-encoded address.
However, the current code decodes (base_addr | (size - 1)) >> 3 which
leads to a wrong base address and size.

Signed-off-by: Dayeol Lee <dayeol@berkeley.edu>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Michael Clark <mjc@sifive.com>
A wrong address is passed to `pmp_is_in_range` while checking if a
memory access is within a PMP range.
Since the ending address of the pmp range (i.e., pmp_state.addr[i].ea)
is set to the last address in the range (i.e., pmp base + pmp size - 1),
memory accesses containg the last address in the range will always fail.

For example, assume that a PMP range is 4KB from 0x87654000 such that
the last address within the range is 0x87654fff.
1-byte access to 0x87654fff should be considered to be fully inside the
PMP range.
However the access now fails and complains partial inclusion because
pmp_is_in_range(env, i, addr + size) returns 0 whereas
pmp_is_in_range(env, i, addr) returns 1.

Signed-off-by: Dayeol Lee <dayeol@berkeley.edu>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Michael Clark <mjc@sifive.com>
cpu_init() was removed since 2.12, so drop the define that is now unused.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Michael Clark <mjc@sifive.com>
@michaeljclark
Copy link
Collaborator Author

Below is output from the tests in: https://github.com/michaeljclark/qemu-riscv-tests

The tests are limited to testing CLIC configuration, WARL behaviour, interrupt delivery via CLIC. We still need to add pre-emption tests (internal software based pre-emption tests by writing to clicintip, and external tests using GPIO agitation), and sync up with the verification team on the hardware/software test harness. The current test scripts check which machines QEMU supports to decide which tests can be run. On older version of QEMU, only the CLINT tests will run. Currently it is a very simple/pragmatic harness.

mjc@miqi:~/src/sifive/qemu-riscv-tests$ make check
> test-rv32-clint-timer-interrupt-sifive_e	PASS
> test-rv32-clint-timer-interrupt-sifive_u	PASS
> test-rv32-clint-vectored-interrupt-sifive_e	PASS
> test-rv32-clint-vectored-interrupt-sifive_u	PASS
> test-rv32-clint-timer-interrupt-sifive_ex	PASS
> test-rv32-clint-timer-interrupt-sifive_ux	PASS
> test-rv32-clint-vectored-interrupt-sifive_ex	PASS
> test-rv32-clint-vectored-interrupt-sifive_ux	PASS
> test-rv32-clic-configure-cfg-e-sifive_ex	PASS
> test-rv32-clic-configure-cfg-u-sifive_ux	PASS
> test-rv32-clic-configure-intcfg-e-sifive_ex	PASS
> test-rv32-clic-configure-intcfg-u-sifive_ux	PASS
> test-rv32-clic-configure-intie-e-sifive_ex	PASS
> test-rv32-clic-configure-intie-u-sifive_ux	PASS
> test-rv32-clic-timer-interrupt-sifive_ex	PASS
> test-rv32-clic-timer-interrupt-sifive_ux	PASS
> test-rv64-clint-timer-interrupt-sifive_e	PASS
> test-rv64-clint-timer-interrupt-sifive_u	PASS
> test-rv64-clint-vectored-interrupt-sifive_e	PASS
> test-rv64-clint-vectored-interrupt-sifive_u	PASS
> test-rv64-clint-timer-interrupt-sifive_ex	PASS
> test-rv64-clint-timer-interrupt-sifive_ux	PASS
> test-rv64-clint-vectored-interrupt-sifive_ex	PASS
> test-rv64-clint-vectored-interrupt-sifive_ux	PASS
> test-rv64-clic-configure-cfg-e-sifive_ex	PASS
> test-rv64-clic-configure-cfg-u-sifive_ux	PASS
> test-rv64-clic-configure-intcfg-e-sifive_ex	PASS
> test-rv64-clic-configure-intcfg-u-sifive_ux	PASS
> test-rv64-clic-configure-intie-e-sifive_ex	PASS
> test-rv64-clic-configure-intie-u-sifive_ux	PASS
> test-rv64-clic-timer-interrupt-sifive_ex	PASS
> test-rv64-clic-timer-interrupt-sifive_ux	PASS

@michaeljclark
Copy link
Collaborator Author

Below are the tests invoked with verbose interrupt and CLIC tracing (VERBOSE=1 TRACE=intr). The VERBOSE flag shows the command invocations.

mjc@miqi:~/src/sifive/qemu-riscv-tests$ make check VERBOSE=1 TRACE=intr
> test-rv32-clint-timer-interrupt-sifive_e	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_e -kernel build/bin/rv32/clint-timer-interrupt-sifive_e
2020@1533028252.015109:riscv_trap hart:0, async:1, cause:0x7, epc:0x20400036, tval:0x0, desc=m_timer
PASS
> test-rv32-clint-timer-interrupt-sifive_u	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_u -kernel build/bin/rv32/clint-timer-interrupt-sifive_u
2025@1533028252.040029:riscv_trap hart:0, async:1, cause:0x7, epc:0x80000036, tval:0x0, desc=m_timer
PASS
> test-rv32-clint-vectored-interrupt-sifive_e	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_e -kernel build/bin/rv32/clint-vectored-interrupt-sifive_e
2030@1533028252.066614:riscv_trap hart:0, async:1, cause:0x7, epc:0x20400042, tval:0x0, desc=m_timer
PASS
> test-rv32-clint-vectored-interrupt-sifive_u	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_u -kernel build/bin/rv32/clint-vectored-interrupt-sifive_u
2035@1533028252.089101:riscv_trap hart:0, async:1, cause:0x7, epc:0x80000042, tval:0x0, desc=m_timer
PASS
> test-rv32-clint-timer-interrupt-sifive_ex	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv32/clint-timer-interrupt-sifive_e
2040@1533028252.111739:riscv_trap hart:0, async:1, cause:0x7, epc:0x20400036, tval:0x0, desc=m_timer
PASS
> test-rv32-clint-timer-interrupt-sifive_ux	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv32/clint-timer-interrupt-sifive_u
2045@1533028252.136271:riscv_trap hart:0, async:1, cause:0x7, epc:0x80000036, tval:0x0, desc=m_timer
PASS
> test-rv32-clint-vectored-interrupt-sifive_ex	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv32/clint-vectored-interrupt-sifive_e
2050@1533028252.161586:riscv_trap hart:0, async:1, cause:0x7, epc:0x20400042, tval:0x0, desc=m_timer
PASS
> test-rv32-clint-vectored-interrupt-sifive_ux	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv32/clint-vectored-interrupt-sifive_u
2055@1533028252.182408:riscv_trap hart:0, async:1, cause:0x7, epc:0x80000042, tval:0x0, desc=m_timer
PASS
> test-rv32-clic-configure-cfg-e-sifive_ex	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv32/clic-configure-cfg-e-sifive_e
2060@1533028252.193228:sifive_clic_cfg hart:0, nmbits:0, nlbits:0, nvbits:0
2060@1533028252.193249:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
2060@1533028252.193257:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
2060@1533028252.193264:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:1
2060@1533028252.193271:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
PASS
> test-rv32-clic-configure-cfg-u-sifive_ux	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv32/clic-configure-cfg-u-sifive_u
2065@1533028252.203664:sifive_clic_cfg hart:0, nmbits:0, nlbits:0, nvbits:0
2065@1533028252.203688:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
2065@1533028252.203697:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
2065@1533028252.203703:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:1
2065@1533028252.203710:sifive_clic_cfg hart:0, nmbits:2, nlbits:4, nvbits:0
PASS
> test-rv32-clic-configure-intcfg-e-sifive_ex	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv32/clic-configure-intcfg-e-sifive_e
2070@1533028252.217569:sifive_clic_intcfg mode:3 hart:0, irq:7, val:0
2070@1533028252.217597:sifive_clic_intcfg mode:3 hart:0, irq:7, val:240
2070@1533028252.217608:sifive_clic_intcfg mode:3 hart:0, irq:7, val:240
PASS
> test-rv32-clic-configure-intcfg-u-sifive_ux	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv32/clic-configure-intcfg-u-sifive_u
2075@1533028252.228556:sifive_clic_cfg hart:0, nmbits:2, nlbits:4, nvbits:0
2075@1533028252.228583:sifive_clic_intcfg mode:1 hart:0, irq:7, val:0
2075@1533028252.228599:sifive_clic_intcfg mode:1 hart:0, irq:7, val:127
PASS
> test-rv32-clic-configure-intie-e-sifive_ex	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv32/clic-configure-intie-e-sifive_e
2080@1533028252.244787:sifive_clic_intie mode:3 hart:0, irq:7, val:1
2080@1533028252.244816:sifive_clic_intie mode:3 hart:0, irq:7, val:0
2080@1533028252.244826:sifive_clic_intie mode:3 hart:0, irq:7, val:2
PASS
> test-rv32-clic-configure-intie-u-sifive_ux	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv32/clic-configure-intie-u-sifive_u
2085@1533028252.255870:sifive_clic_intie mode:1 hart:0, irq:7, val:1
2085@1533028252.255893:sifive_clic_intie mode:1 hart:0, irq:7, val:0
2085@1533028252.255903:sifive_clic_intie mode:1 hart:0, irq:7, val:2
PASS
> test-rv32-clic-timer-interrupt-sifive_ex	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv32/clic-timer-interrupt-sifive_e
2090@1533028252.267185:sifive_clic_cfg hart:0, nmbits:0, nlbits:2, nvbits:0
2090@1533028252.267205:sifive_clic_intie mode:3 hart:0, irq:7, val:1
2090@1533028252.267210:sifive_clic_intip mode:3 hart:0, irq:7, val:0
2090@1533028252.277241:sifive_clic_intip mode:3 hart:0, irq:7, val:1
2090@1533028252.277269:riscv_trap hart:0, async:0, cause:0x30800007, epc:0x2040006a, tval:0x0, desc=(clic-interrupt)
PASS
> test-rv32-clic-timer-interrupt-sifive_ux	
+ qemu-system-riscv32 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv32/clic-timer-interrupt-sifive_u
2095@1533028252.288833:sifive_clic_cfg hart:0, nmbits:0, nlbits:2, nvbits:0
2095@1533028252.288851:sifive_clic_intie mode:3 hart:0, irq:7, val:1
2095@1533028252.288856:sifive_clic_intip mode:3 hart:0, irq:7, val:0
2095@1533028252.298917:sifive_clic_intip mode:3 hart:0, irq:7, val:1
2095@1533028252.298948:riscv_trap hart:0, async:0, cause:0x30800007, epc:0x8000006a, tval:0x0, desc=(clic-interrupt)
PASS
> test-rv64-clint-timer-interrupt-sifive_e	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_e -kernel build/bin/rv64/clint-timer-interrupt-sifive_e
2100@1533028252.323491:riscv_trap hart:0, async:1, cause:0x7, epc:0x20400036, tval:0x0, desc=m_timer
PASS
> test-rv64-clint-timer-interrupt-sifive_u	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_u -kernel build/bin/rv64/clint-timer-interrupt-sifive_u
2105@1533028252.348013:riscv_trap hart:0, async:1, cause:0x7, epc:0x80000036, tval:0x0, desc=m_timer
PASS
> test-rv64-clint-vectored-interrupt-sifive_e	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_e -kernel build/bin/rv64/clint-vectored-interrupt-sifive_e
2110@1533028252.370019:riscv_trap hart:0, async:1, cause:0x7, epc:0x20400042, tval:0x0, desc=m_timer
PASS
> test-rv64-clint-vectored-interrupt-sifive_u	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_u -kernel build/bin/rv64/clint-vectored-interrupt-sifive_u
2115@1533028252.391693:riscv_trap hart:0, async:1, cause:0x7, epc:0x80000042, tval:0x0, desc=m_timer
PASS
> test-rv64-clint-timer-interrupt-sifive_ex	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv64/clint-timer-interrupt-sifive_e
2120@1533028252.416081:riscv_trap hart:0, async:1, cause:0x7, epc:0x20400036, tval:0x0, desc=m_timer
PASS
> test-rv64-clint-timer-interrupt-sifive_ux	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv64/clint-timer-interrupt-sifive_u
2125@1533028252.442403:riscv_trap hart:0, async:1, cause:0x7, epc:0x80000036, tval:0x0, desc=m_timer
PASS
> test-rv64-clint-vectored-interrupt-sifive_ex	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv64/clint-vectored-interrupt-sifive_e
2130@1533028252.466542:riscv_trap hart:0, async:1, cause:0x7, epc:0x20400042, tval:0x0, desc=m_timer
PASS
> test-rv64-clint-vectored-interrupt-sifive_ux	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv64/clint-vectored-interrupt-sifive_u
2137@1533028252.488195:riscv_trap hart:0, async:1, cause:0x7, epc:0x80000042, tval:0x0, desc=m_timer
PASS
> test-rv64-clic-configure-cfg-e-sifive_ex	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv64/clic-configure-cfg-e-sifive_e
2142@1533028252.499944:sifive_clic_cfg hart:0, nmbits:0, nlbits:0, nvbits:0
2142@1533028252.499969:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
2142@1533028252.499979:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
2142@1533028252.499987:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:1
2142@1533028252.499995:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
PASS
> test-rv64-clic-configure-cfg-u-sifive_ux	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv64/clic-configure-cfg-u-sifive_u
2156@1533028252.511721:sifive_clic_cfg hart:0, nmbits:0, nlbits:0, nvbits:0
2156@1533028252.511750:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
2156@1533028252.511759:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:0
2156@1533028252.511767:sifive_clic_cfg hart:0, nmbits:0, nlbits:4, nvbits:1
2156@1533028252.511774:sifive_clic_cfg hart:0, nmbits:2, nlbits:4, nvbits:0
PASS
> test-rv64-clic-configure-intcfg-e-sifive_ex	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv64/clic-configure-intcfg-e-sifive_e
2161@1533028252.526023:sifive_clic_intcfg mode:3 hart:0, irq:7, val:0
2161@1533028252.526052:sifive_clic_intcfg mode:3 hart:0, irq:7, val:240
2161@1533028252.526062:sifive_clic_intcfg mode:3 hart:0, irq:7, val:240
PASS
> test-rv64-clic-configure-intcfg-u-sifive_ux	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv64/clic-configure-intcfg-u-sifive_u
2166@1533028252.537549:sifive_clic_cfg hart:0, nmbits:2, nlbits:4, nvbits:0
2166@1533028252.537581:sifive_clic_intcfg mode:1 hart:0, irq:7, val:0
2166@1533028252.537594:sifive_clic_intcfg mode:1 hart:0, irq:7, val:127
PASS
> test-rv64-clic-configure-intie-e-sifive_ex	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv64/clic-configure-intie-e-sifive_e
2171@1533028252.551327:sifive_clic_intie mode:3 hart:0, irq:7, val:1
2171@1533028252.551390:sifive_clic_intie mode:3 hart:0, irq:7, val:0
2171@1533028252.551403:sifive_clic_intie mode:3 hart:0, irq:7, val:2
PASS
> test-rv64-clic-configure-intie-u-sifive_ux	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv64/clic-configure-intie-u-sifive_u
2176@1533028252.565292:sifive_clic_intie mode:1 hart:0, irq:7, val:1
2176@1533028252.565322:sifive_clic_intie mode:1 hart:0, irq:7, val:0
2176@1533028252.565334:sifive_clic_intie mode:1 hart:0, irq:7, val:2
PASS
> test-rv64-clic-timer-interrupt-sifive_ex	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ex -kernel build/bin/rv64/clic-timer-interrupt-sifive_e
2181@1533028252.577775:sifive_clic_cfg hart:0, nmbits:0, nlbits:2, nvbits:0
2181@1533028252.577799:sifive_clic_intie mode:3 hart:0, irq:7, val:1
2181@1533028252.577805:sifive_clic_intip mode:3 hart:0, irq:7, val:0
2181@1533028252.587836:sifive_clic_intip mode:3 hart:0, irq:7, val:1
2181@1533028252.587899:riscv_trap hart:0, async:0, cause:0x30800007, epc:0x2040006a, tval:0x0, desc=(clic-interrupt)
PASS
> test-rv64-clic-timer-interrupt-sifive_ux	
+ qemu-system-riscv64 -nographic -d trace:riscv_trap,trace:sifive_clic_cfg,trace:sifive_clic_intcfg,trace:sifive_clic_intie,trace:sifive_clic_intip,trace:sifive_clic_irq -machine sifive_ux -kernel build/bin/rv64/clic-timer-interrupt-sifive_u
2186@1533028252.599654:sifive_clic_cfg hart:0, nmbits:0, nlbits:2, nvbits:0
2186@1533028252.599675:sifive_clic_intie mode:3 hart:0, irq:7, val:1
2186@1533028252.599681:sifive_clic_intip mode:3 hart:0, irq:7, val:0
2186@1533028252.609749:sifive_clic_intip mode:3 hart:0, irq:7, val:1
2186@1533028252.609819:riscv_trap hart:0, async:0, cause:0x30800007, epc:0x8000006a, tval:0x0, desc=(clic-interrupt)
PASS

- Implements draft clic-spec (20180728)
  - Implements non-vectored mode and vectored mode
  - Implements mode+level+priority configuration
  - Implements mode+level+priority preemption model
  - Seperated M-mode (mtvec) and S-mode (stvec) delivery
  - CLIC supports backwards compatible CLINT mode for
    legacy interrupts using MIE/MIP,SIE/SIP (irq < 16)
    depending on mtvec (MTI,MSI) and stvec (STI,SSI)
  - CLINT mode supports S-mode stimecmp{h} and ssip{h}

- QEMU CLINT/CLIC Test Cases
  - https://github.com/michaeljclark/qemu-riscv-tests

- Adds two experimental machines
  - SiFive Freedom E-Series with CLIC
    - Implements M-mode CLINT/CLIC config memory map
    - Parameters
      - CLICINTBITS=4
      - CLICCFGMBITS=0
      - CLICCFGLBITS=4
    - Invocation
      - qemu-system-riscv{32,64} -machine sifive_ex
  - SiFive Freedom U-Series with CLIC
    - Implements M-mode and S-mode CLINT/CLIC memory map
    - Parameters
      - CLICINTBITS=8
      - CLICCFGMBITS=2
      - CLICCFGLBITS=4
    - Invocation
      - qemu-system-riscv{32,64} -machine sifive_ux

- CLIC combined CLINT/CLIC memory map
  - M-Mode CLINT = 0x02000000
    - msip       = 0x02000000 + hartid * 4
    - mtimecmp   = 0x02004000 + hartid * 4
    - mtime      = 0x0200bff8
  - S-Mode CLINT = 0x02020000
  - M-mode CLIC  = 0x02080000
    - clicintip  = 0x02080000 + hartid * 0x1000 + 0x000
    - clicintie  = 0x02080000 + hartid * 0x1000 + 0x400
    - clicintcfg = 0x02080000 + hartid * 0x1000 + 0x800
    - cliccfg    = 0x02080000 + hartid * 0x1000 + 0xc00
  - S-Mode CLIC  = 0x020c0000
    - clicintip  = 0x020c0000 + hartid * 0x1000 + 0x000
    - clicintie  = 0x020c0000 + hartid * 0x1000 + 0x400
    - clicintcfg = 0x020c0000 + hartid * 0x1000 + 0x800

- Adds CLIC interrupt tracing (`-d trace:riscv_trap,...`)
  - riscv_trap         # existing core interrupt tracing
  - sifive_clic_cfg    # CLIC global configuration
  - sifive_clic_intcfg # CLIC interrupt configuration
  - sifive_clic_intie  # CliC interrupt enable
  - sifive_clic_intip  # CLIC interrupt pending
  - sifive_clic_irq    # CLIC irq entry

- Notes / Limitations
  - Enforces clicintcfg writes based on cliccfg and mode
  - Reads/writes to intcfg/intie/intip in lower mode MMIO
    apetures are currently allowed. Access checks need to
    be added to suppress writes and hardwire read reults to
    zero for any entries that where mode < clicintcfg.mode
  - Interrupts pending bits are writable by software.
    Edge/Level configuration needs to be added to control
    software access to interrupt pending bits
  - Selective vectoring in non-vectored mode is unimplemented
  - PLIC is currently not routed via the CLIC however pending
    bits can be written by software to test pre-emption.
  - mnxti/snxti sets mstatus flags but returns 0 (slow path).
    The CLIC state is currenetly not accessible from target/riscv
    as cpu implementations can't include anything from include/hw
    so the CLIC state needs to be in a CPU accessible structure.
  - Potential race condition if an interrupt is posted
    before the CPU has received and processed an outstanding
    interrupt due to env->exccode being overwritten.
    Needs changes to the interface from the CLIC so that the
    CPU interrupt handler pulls the highest priority interrupt
    from the CLIC at the time it is woken up. This requires the
    CLIC state to be accessible from the CPU similarly to mnxti
  - CPU core changes are relatively intrusive. The CPU interrupt
    handling requires some abstraction/hooks for a more modular
    CLIC implementation. CLIC state needs to be attached to
    the CPU, and accessible to the MMIO device with hooks in
    riscv_cpu_exec_interrupt and riscv_cpu_do_interrupt

Changes since v0

- Fix array index calculation in sifive_clic_realize
- Raise CLIC_LEVEL_BITS to 8 and fix assertion
- Move CLIC parameterization constants to its header
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants