summary refs log tree commit diff stats
path: root/hw/intc/riscv_aclint.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* hw/intc: Save timers array in RISC-V mtimer VMStateTANG Tiancheng2025-10-031-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The current 'timecmp' field in vmstate_riscv_mtimer is insufficient to keep timers functional after migration. If an mtimer's entry in 'mtimer->timers' is active at the time the snapshot is taken, it means riscv_aclint_mtimer_write_timecmp() has written to 'mtimecmp' and scheduled a timer into QEMU's main loop 'timer_list'. During snapshot save, these active timers must also be migrated; otherwise, after snapshot load there is no mechanism to restore 'mtimer->timers' back into the 'timer_list', and any pending timer events would be lost. QEMU's migration framework commonly uses VMSTATE_TIMER_xxx macros to save and restore 'QEMUTimer' variables. However, 'timers' is a pointer array with variable length, and vmstate.h did not previously provide a helper macro for such type. This commit adds a new macro, 'VMSTATE_TIMER_PTR_VARRAY', to handle saving and restoring a variable-length array of 'QEMUTimer *'. We then use this macro to migrate the 'mtimer->timers' array, ensuring that timer events remain scheduled correctly after snapshot load. Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> Signed-off-by: TANG Tiancheng <lyndra@linux.alibaba.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20250911-timers-v3-3-60508f640050@linux.alibaba.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw/intc: Save time_delta in RISC-V mtimer VMStateTANG Tiancheng2025-10-021-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In QEMU's RISC-V ACLINT timer model, 'mtime' is not stored directly as a state variable. It is computed on demand as: mtime = rtc_r + time_delta where: - 'rtc_r' is the current VM virtual time (in ticks) obtained via cpu_riscv_read_rtc_raw() from QEMU_CLOCK_VIRTUAL. - 'time_delta' is an offset applied when the guest writes a new 'mtime' value via riscv_aclint_mtimer_write(): time_delta = value - rtc_r Under this design, 'rtc_r' is assumed to be monotonically increasing during VM execution. Even if the guest writes an 'mtime' value smaller than the current one (making 'time_delta' negative in signed arithmetic, or underflow in unsigned arithmetic), the computed 'mtime' remains correct because 'rtc_r_new > rtc_r_old': mtime_new = rtc_r_new + (value - rtc_r_old) However, this monotonicity assumption breaks on snapshot load. Before restoring a snapshot, QEMU resets the guest, which calls riscv_aclint_mtimer_reset_enter() to set 'mtime' to 0 and recompute 'time_delta' as: time_delta = 0 - rtc_r_reset Here, the time_delta differs from the value that was present when the snapshot was saved. As a result, subsequent reads produce a fixed offset from the true mtime. This can be observed with the 'date' command inside the guest: after loading a snapshot, the reported time appears "frozen" at the save point, and only resumes correctly after the guest has run long enough to compensate for the erroneous offset. The fix is to treat 'time_delta' as part of the device's migratable state and save/restore it via vmstate. This preserves the correct relation between 'rtc_r' and 'mtime' across snapshot save/load, ensuring 'mtime' continues incrementing from the precise saved value after restore. Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Signed-off-by: TANG Tiancheng <lyndra@linux.alibaba.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20250911-timers-v3-1-60508f640050@linux.alibaba.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw/intc: riscv_aclint: Fix mtime write for sstc extensionJim Shu2025-07-041-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When changing the mtime value, the period of [s|vs]timecmp timers should also be updated, similar to the period of mtimecmp timer. The period of the stimecmp timer is the time until the next S-mode timer IRQ. The value is calculated as "stimecmp - time". [1] It is equal to "stimecmp - mtime" since the time CSR is a read-only shadow of the memory-mapped mtime register. Thus, changing mtime value will update the period of stimecmp timer. Similarly, the period of vstimecmp timer is calculated as "vstimecmp - (mtime + htimedelta)" [2], so changing mtime value will update the period of vstimecmp timer. [1] RISC-V Priv spec ch 9.1.1. Supervisor Timer (stimecmp) Register A supervisor timer interrupt becomes pending, as reflected in the STIP bit in the mip and sip registers whenever time contains a value greater than or equal to stimecmp. [2] RISC-V Priv spec ch19.2.1. Virtual Supervisor Timer (vstimecmp) Register A virtual supervisor timer interrupt becomes pending, as reflected in the VSTIP bit in the hip register, whenever (time + htimedelta), truncated to 64 bits, contains a value greater than or equal to vstimecmp Signed-off-by: Jim Shu <jim.shu@sifive.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20250519143518.11086-3-jim.shu@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* qom: Have class_init() take a const data argumentPhilippe Mathieu-Daudé2025-04-251-2/+2
| | | | | | | | | | Mechanical change using gsed, then style manually adapted to pass checkpatch.pl script. Suggested-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20250424194905.82506-4-philmd@linaro.org>
* include/hw/qdev-properties: Remove DEFINE_PROP_END_OF_LISTRichard Henderson2024-12-191-2/+0
| | | | | | | | | | | | | | Now that all of the Property arrays are counted, we can remove the terminator object from each array. Update the assertions in device_class_set_props to match. With struct Property being 88 bytes, this was a rather large form of terminator. Saves 30k from qemu-system-aarch64. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Lei Yang <leiyang@redhat.com> Link: https://lore.kernel.org/r/20241218134251.4724-21-richard.henderson@linaro.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* hw/intc: Constify all PropertyRichard Henderson2024-12-151-2/+2
| | | | | | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
* hw/intc: Constify VMStateRichard Henderson2023-12-291-1/+1
| | | | | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20231221031652.119827-35-richard.henderson@linaro.org>
* accel/tcg: Replace CPUState.env_ptr with cpu_env()Richard Henderson2023-10-041-6/+6
| | | | | Reviewed-by: Anton Johansson <anjo@rev.ng> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
* hw/intc: Make rtc variable names consistentJason Chien2023-09-111-3/+3
| | | | | | | | | | | The variables whose values are given by cpu_riscv_read_rtc() should be named "rtc". The variables whose value are given by cpu_riscv_read_rtc_raw() should be named "rtc_r". Signed-off-by: Jason Chien <jason.chien@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20230728082502.26439-2-jason.chien@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw/intc: Fix upper/lower mtime write calculationJason Chien2023-09-111-2/+3
| | | | | | | | | | | When writing the upper mtime, we should keep the original lower mtime whose value is given by cpu_riscv_read_rtc() instead of cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime. Signed-off-by: Jason Chien <jason.chien@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20230728082502.26439-1-jason.chien@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw: intc: Use cpu_by_arch_id to fetch CPU stateMayuresh Chitale2023-03-051-8/+8
| | | | | | | | | | | | | | Qemu_get_cpu uses the logical CPU id assigned during init to fetch the CPU state. However APLIC, IMSIC and ACLINT contain registers and states which are specific to physical hart Ids. The hart Ids in any given system might be sparse and hence calls to qemu_get_cpu need to be replaced by cpu_by_arch_id which performs lookup based on the sparse physical hart IDs. Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com> Signed-off-by: Anup Patel <apatel@ventanamicro.com> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Message-ID: <20230303065055.915652-3-mchitale@ventanamicro.com> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
* hw/intc: Move mtimer/mtimecmp to aclintAtish Patra2022-09-071-14/+34
| | | | | | | | | | | | | | | | Historically, The mtime/mtimecmp has been part of the CPU because they are per hart entities. However, they actually belong to aclint which is a MMIO device. Move them to the ACLINT device. This also emulates the real hardware more closely. Reviewed-by: Anup Patel <anup@brainfault.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Signed-off-by: Atish Patra <atishp@rivosinc.com> Message-Id: <20220824221357.41070-2-atishp@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* Fix 'writeable' typosPeter Maydell2022-06-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | We have about 30 instances of the typo/variant spelling 'writeable', and over 500 of the more common 'writable'. Standardize on the latter. Change produced with: sed -i -e 's/\([Ww][Rr][Ii][Tt]\)[Ee]\([Aa][Bb][Ll][Ee]\)/\1\2/g' $(git grep -il writeable) and then hand-undoing the instance in linux-headers/linux/kvm.h. Most of these changes are in comments or documentation; the exceptions are: * a local variable in accel/hvf/hvf-accel-ops.c * a local variable in accel/kvm/kvm-all.c * the PMCR_WRITABLE_MASK macro in target/arm/internals.h * the EPT_VIOLATION_GPA_WRITABLE macro in target/i386/hvf/vmcs.h (which is never used anywhere) * the AR_TYPE_WRITABLE_MASK macro in target/i386/hvf/vmx.h (which is never used anywhere) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Stefan Weil <sw@weilnetz.de> Message-id: 20220505095015.2714666-1-peter.maydell@linaro.org
* hw/intc: Pass correct hartid while updating mtimecmpAtish Patra2022-05-241-1/+2
| | | | | | | | | | | | | | | timecmp update function should be invoked with hartid for which timecmp is being updated. The following patch passes the incorrect hartid to the update function. Fixes: e2f01f3c2e13 ("hw/intc: Make RISC-V ACLINT mtime MMIO register writable") Signed-off-by: Atish Patra <atishp@rivosinc.com> Reviewed-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20220513221458.1192933-1-atishp@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw/intc: riscv_aclint: Add reset function of ACLINT devicesJim Shu2022-04-221-0/+39
| | | | | | | | | | | | | | This commit implements reset function of all ACLINT devices. ACLINT device reset will clear MTIME and MSIP register to 0. Depend on RISC-V ACLINT spec v1.0-rc4: https://github.com/riscv/riscv-aclint/blob/v1.0-rc4/riscv-aclint.adoc Signed-off-by: Jim Shu <jim.shu@sifive.com> Reviewed-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20220420080901.14655-5-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw/intc: Make RISC-V ACLINT mtime MMIO register writableFrank Chang2022-04-221-21/+50
| | | | | | | | | | | | | | | | | | RISC-V privilege spec defines that mtime is exposed as a memory-mapped machine-mode read-write register. However, as QEMU uses host monotonic timer as timer source, this makes mtime to be read-only in RISC-V ACLINT. This patch makes mtime to be writable by recording the time delta value between the mtime value to be written and the timer value at the time mtime is written. Time delta value is then added back whenever the timer value is retrieved. Signed-off-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Jim Shu <jim.shu@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20220420080901.14655-4-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw/intc: Support 32/64-bit mtimecmp and mtime accesses in RISC-V ACLINTFrank Chang2022-04-221-15/+27
| | | | | | | | | | | | | | | | | | RISC-V privilege spec defines that: * In RV32, memory-mapped writes to mtimecmp modify only one 32-bit part of the register. * For RV64, naturally aligned 64-bit memory accesses to the mtime and mtimecmp registers are additionally supported and are atomic. It's possible to perform both 32/64-bit read/write accesses to both mtimecmp and mtime registers. Signed-off-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Jim Shu <jim.shu@sifive.com> Message-Id: <20220420080901.14655-3-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw/intc: Add .impl.[min|max]_access_size declaration in RISC-V ACLINTFrank Chang2022-04-221-0/+4
| | | | | | | | | | | | | | If device's MemoryRegion doesn't have .impl.[min|max]_access_size declaration, the default access_size_min would be 1 byte and access_size_max would be 4 bytes (see: softmmu/memory.c). This will cause a 64-bit memory access to ACLINT to be splitted into two 32-bit memory accesses. Signed-off-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Jim Shu <jim.shu@sifive.com> Message-Id: <20220420080901.14655-2-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* Use g_new() & friends where that makes obvious senseMarkus Armbruster2022-03-211-3/+3
| | | | | | | | | | | | | | | | | | | | | | | g_new(T, n) is neater than g_malloc(sizeof(T) * n). It's also safer, for two reasons. One, it catches multiplication overflowing size_t. Two, it returns T * rather than void *, which lets the compiler catch more type errors. This commit only touches allocations with size arguments of the form sizeof(T). Patch created mechanically with: $ spatch --in-place --sp-file scripts/coccinelle/use-g_new-etc.cocci \ --macro-file scripts/cocci-macro-file.h FILES... Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Message-Id: <20220315144156.1595462-4-armbru@redhat.com> Reviewed-by: Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
* hw/intc: Upgrade the SiFive CLINT implementation to RISC-V ACLINTAnup Patel2021-09-211-114/+259
| | | | | | | | | | | | | The RISC-V ACLINT is more modular and backward compatible with original SiFive CLINT so instead of duplicating the original SiFive CLINT implementation we upgrade the current SiFive CLINT implementation to RISC-V ACLINT implementation. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Message-id: 20210831110603.338681-3-anup.patel@wdc.com Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* hw/intc: Rename sifive_clint sources to riscv_aclint sourcesAnup Patel2021-09-211-0/+315
We will be upgrading SiFive CLINT implementation into RISC-V ACLINT implementation so let's first rename the sources. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Message-id: 20210831110603.338681-2-anup.patel@wdc.com Signed-off-by: Alistair Francis <alistair.francis@wdc.com>