From patchwork Tue Apr 26 23:08:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Kumar Patra X-Patchwork-Id: 12828060 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7388FC433FE for ; Tue, 26 Apr 2022 23:14:49 +0000 (UTC) Received: from localhost ([::1]:55314 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njUOO-0007kc-IX for qemu-devel@archiver.kernel.org; Tue, 26 Apr 2022 19:14:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45594) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njUIu-0005M3-9U for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:08 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:53093) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1njUIq-0000IP-QN for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:07 -0400 Received: by mail-pj1-x102e.google.com with SMTP id e24so2937489pjt.2 for ; Tue, 26 Apr 2022 16:09:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YBxB19b1LDH2ZngtUHbjc+2JAn1UtWz5r0U4AkPLkb8=; b=hlIwq3u3ZtqHOeR0DpGSrLbV25I0CjUVq061nt9uqSJHnAz0la/QX+qhQA+Bo5J6z0 BiH5yHW2Lzz3uZNbIRHNeKtSxLaernkW6pTZmk9pEiMe4tXsndF1ocy+tx2hVvgzy3lT BxCM0a7B0kT7PVMxU14U5Q4pesh3a6kBSwzXEA0aTKkQNEOoghbmDHfeakIGlGEs1Zut vt0W3eXxnW19c09qtQFyQaaJmopo94v95P9Sp9lXQCW2a6EeiSwuMZ0ioQsO64qOTqPd /jo1pGs92pYdl+OoVKunAgTJDuK30C9NGydtuxeZNqhePAHLXJHHiA6Bgdf65VhyXSYF FMgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YBxB19b1LDH2ZngtUHbjc+2JAn1UtWz5r0U4AkPLkb8=; b=KIgFGhdFtxfcXxK1FqfwPArhZZnJq/S/NUMReOVhvBfPKUmXRb5qkUHcmavJOUDyUF qs4Jubptjv7ZZ195ruCAu2lMADN9JSg1E++CXKJgnJ3CxyQWnYJ8j84IK9AUEp3YDL5X N6OSHRhElMrpJeW5r6jJHIkNRP9xydJNg+z5AsPGr5UOhUDXWS52Cd09Z5T0LFvDIl0y 9+WtP7aQmjZkUu5slLQzEEn+r/4Caf3aR7ysaP0Ir9EBaHAEfXN/YN2JRBeO3QSsCaOC EWZCHxfESZortmo4RK/MXN/AOUOvcVGC8EphaMddCQ46eq4KAGkTDBN/npn18+MTAnvJ 33TA== X-Gm-Message-State: AOAM530yEyN8NU33zHhNM2X8jrRT6Sa+KApfEA43TnmGioZSEGxWoOyv Uohq8qI4eb6WxQ4alzaOp/havt2CH7IOlQ== X-Google-Smtp-Source: ABdhPJxwmF/IyTc+V1n18NhNV1jG8tAYDig1dG2lUKT9Rj5X8tloUmR9riU2YFq8nbByK7m0Ysc6OQ== X-Received: by 2002:a17:902:8f81:b0:154:be2d:1948 with SMTP id z1-20020a1709028f8100b00154be2d1948mr25724641plo.110.1651014542689; Tue, 26 Apr 2022 16:09:02 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id t29-20020a62d15d000000b0050d42864753sm7856490pfl.49.2022.04.26.16.09.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Apr 2022 16:09:02 -0700 (PDT) From: Atish Patra To: qemu-devel@nongnu.org Subject: [PATCH v2 1/5] hw/intc: Move mtimer/mtimecmp to aclint Date: Tue, 26 Apr 2022 16:08:50 -0700 Message-Id: <20220426230855.336292-2-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220426230855.336292-1-atishp@rivosinc.com> References: <20220426230855.336292-1-atishp@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=atishp@rivosinc.com; helo=mail-pj1-x102e.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Juan Quintela , Bin Meng , Atish Patra , "Dr. David Alan Gilbert" , Alistair Francis , Palmer Dabbelt Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Historically, The mtimer/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. Signed-off-by: Atish Patra --- hw/intc/riscv_aclint.c | 27 +++++++++++++++------------ hw/timer/ibex_timer.c | 20 ++++++++------------ include/hw/intc/riscv_aclint.h | 2 ++ include/hw/timer/ibex_timer.h | 2 ++ target/riscv/cpu.h | 2 -- target/riscv/machine.c | 1 - 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c index 0412edc98257..1bddb99bda47 100644 --- a/hw/intc/riscv_aclint.c +++ b/hw/intc/riscv_aclint.c @@ -65,8 +65,8 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, uint64_t rtc_r = cpu_riscv_read_rtc(mtimer); - cpu->env.timecmp = value; - if (cpu->env.timecmp <= rtc_r) { + mtimer->timecmp[hartid] = value; + if (mtimer->timecmp[hartid] <= rtc_r) { /* * If we're setting an MTIMECMP value in the "past", * immediately raise the timer interrupt @@ -77,7 +77,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, /* otherwise, set up the future timer interrupt */ qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]); - diff = cpu->env.timecmp - rtc_r; + diff = mtimer->timecmp[hartid] - rtc_r; /* back to ns (note args switched in muldiv64) */ uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); @@ -102,7 +102,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, next = MIN(next, INT64_MAX); } - timer_mod(cpu->env.timer, next); + timer_mod(mtimer->timers[hartid], next); } /* @@ -133,11 +133,11 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr, "aclint-mtimer: invalid hartid: %zu", hartid); } else if ((addr & 0x7) == 0) { /* timecmp_lo for RV32/RV64 or timecmp for RV64 */ - uint64_t timecmp = env->timecmp; + uint64_t timecmp = mtimer->timecmp[hartid]; return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp; } else if ((addr & 0x7) == 4) { /* timecmp_hi */ - uint64_t timecmp = env->timecmp; + uint64_t timecmp = mtimer->timecmp[hartid]; return (timecmp >> 32) & 0xFFFFFFFF; } else { qemu_log_mask(LOG_UNIMP, @@ -177,7 +177,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, } else if ((addr & 0x7) == 0) { if (size == 4) { /* timecmp_lo for RV32/RV64 */ - uint64_t timecmp_hi = env->timecmp >> 32; + uint64_t timecmp_hi = mtimer->timecmp[hartid] >> 32; riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, timecmp_hi << 32 | (value & 0xFFFFFFFF)); } else { @@ -188,7 +188,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, } else if ((addr & 0x7) == 4) { if (size == 4) { /* timecmp_hi for RV32/RV64 */ - uint64_t timecmp_lo = env->timecmp; + uint64_t timecmp_lo = mtimer->timecmp[hartid]; riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, value << 32 | (timecmp_lo & 0xFFFFFFFF)); } else { @@ -233,7 +233,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, continue; } riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), - i, env->timecmp); + i, mtimer->timecmp[i]); } return; } @@ -283,6 +283,8 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp) s->timer_irqs = g_new(qemu_irq, s->num_harts); qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts); + s->timers = g_malloc0(s->num_harts * sizeof(QEMUTimer)); + s->timecmp = g_new(uint64_t, s->num_harts); /* Claim timer interrupt bits */ for (i = 0; i < s->num_harts; i++) { RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i)); @@ -335,6 +337,7 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, { int i; DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER); + RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev); assert(num_harts <= RISCV_ACLINT_MAX_HARTS); assert(!(addr & 0x7)); @@ -365,11 +368,11 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev); } - cb->s = RISCV_ACLINT_MTIMER(dev); + cb->s = s; cb->num = i; - env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + s->timers[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_aclint_mtimer_cb, cb); - env->timecmp = 0; + s->timecmp[i] = 0; qdev_connect_gpio_out(dev, i, qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER)); diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c index 8c2ca364daab..d7786b35101a 100644 --- a/hw/timer/ibex_timer.c +++ b/hw/timer/ibex_timer.c @@ -30,8 +30,8 @@ #include "qemu/timer.h" #include "hw/timer/ibex_timer.h" #include "hw/irq.h" -#include "hw/qdev-properties.h" #include "target/riscv/cpu.h" +#include "hw/qdev-properties.h" #include "migration/vmstate.h" REG32(ALERT_TEST, 0x00) @@ -60,8 +60,6 @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq) static void ibex_timer_update_irqs(IbexTimerState *s) { - CPUState *cs = qemu_get_cpu(0); - RISCVCPU *cpu = RISCV_CPU(cs); uint64_t value = s->timer_compare_lower0 | ((uint64_t)s->timer_compare_upper0 << 32); uint64_t next, diff; @@ -73,9 +71,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s) } /* Update the CPUs mtimecmp */ - cpu->env.timecmp = value; + s->mtimecmp = value; - if (cpu->env.timecmp <= now) { + if (s->mtimecmp <= now) { /* * If the mtimecmp was in the past raise the interrupt now. */ @@ -91,7 +89,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s) qemu_irq_lower(s->m_timer_irq); qemu_set_irq(s->irq, false); - diff = cpu->env.timecmp - now; + diff = s->mtimecmp - now; next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + muldiv64(diff, NANOSECONDS_PER_SECOND, @@ -99,9 +97,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s) if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) { /* We overflowed the timer, just set it as large as we can */ - timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF); + timer_mod(s->mtimer, 0x7FFFFFFFFFFFFFFF); } else { - timer_mod(cpu->env.timer, next); + timer_mod(s->mtimer, next); } } @@ -120,11 +118,9 @@ static void ibex_timer_reset(DeviceState *dev) { IbexTimerState *s = IBEX_TIMER(dev); - CPUState *cpu = qemu_get_cpu(0); - CPURISCVState *env = cpu->env_ptr; - env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + s->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ibex_timer_cb, s); - env->timecmp = 0; + s->mtimecmp = 0; s->timer_ctrl = 0x00000000; s->timer_cfg0 = 0x00010000; diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h index 26d4048687fb..693415eb6def 100644 --- a/include/hw/intc/riscv_aclint.h +++ b/include/hw/intc/riscv_aclint.h @@ -32,6 +32,8 @@ typedef struct RISCVAclintMTimerState { /*< private >*/ SysBusDevice parent_obj; uint64_t time_delta; + uint64_t *timecmp; + QEMUTimer **timers; /*< public >*/ MemoryRegion mmio; diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h index 1a0a28d5fab5..41f5c82a920b 100644 --- a/include/hw/timer/ibex_timer.h +++ b/include/hw/timer/ibex_timer.h @@ -33,6 +33,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(IbexTimerState, IBEX_TIMER) struct IbexTimerState { /* */ SysBusDevice parent_obj; + uint64_t mtimecmp; + QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */ /* */ MemoryRegion mmio; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 34c22d5d3be3..1119d5201066 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -275,7 +275,6 @@ struct CPUArchState { /* temporary htif regs */ uint64_t mfromhost; uint64_t mtohost; - uint64_t timecmp; /* physical memory protection */ pmp_table_t pmp_state; @@ -330,7 +329,6 @@ struct CPUArchState { float_status fp_status; /* Fields from here on are preserved across CPU reset. */ - QEMUTimer *timer; /* Internal timer */ hwaddr kernel_addr; hwaddr fdt_addr; diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 2a437b29a1ce..14a3c1d775bc 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -334,7 +334,6 @@ const VMStateDescription vmstate_riscv_cpu = { VMSTATE_UINTTL(env.mscratch, RISCVCPU), VMSTATE_UINT64(env.mfromhost, RISCVCPU), VMSTATE_UINT64(env.mtohost, RISCVCPU), - VMSTATE_UINT64(env.timecmp, RISCVCPU), VMSTATE_END_OF_LIST() }, From patchwork Tue Apr 26 23:08:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Kumar Patra X-Patchwork-Id: 12828062 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8DE30C433EF for ; Tue, 26 Apr 2022 23:17:40 +0000 (UTC) Received: from localhost ([::1]:33738 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njUR9-0003yd-C8 for qemu-devel@archiver.kernel.org; Tue, 26 Apr 2022 19:17:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45582) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njUIt-0005L4-Qn for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:07 -0400 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]:34322) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1njUIr-0000Ia-Pp for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:07 -0400 Received: by mail-pf1-x42a.google.com with SMTP id a11so128728pff.1 for ; Tue, 26 Apr 2022 16:09:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LdEjmljNRZQoLffMrBdqTb34Kjoj9AW0utDokXRYpVs=; b=3X/TcEK4QMbY03XIF/HMNBGRbU8YFhl7fYPEgTSdpQ3QuO7tUqsR2OKhGXgPjRjVzo YlsjSWwoBS3S8R0DwTIMFci8x21WVFZbZQinFOT7hb4C7oohw2ECFKTlRgff7Y7ha+vn sU7EL5vcz9SiLwmoHTZmWgWQ9Uo1o6vk+QTyKfIaKlXJXntKbgFVjihJJHJ4c4DPmTaF 0peRoVC2M80C9B0m8QhFr/l+TdlNXrvp6/Lmy6DBGViWsODoHRhuNkqJdzQqm65WkN+i ukWiNCofCb+s5kTYN2sU99A49Tcopvkd2BFy/cJiyC1iHOc5DtOjp9fY9bl/U5V1Tq1t gbkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LdEjmljNRZQoLffMrBdqTb34Kjoj9AW0utDokXRYpVs=; b=a8OVR8gFGCWrJvK/gd/pqpnoWpt8TYDoy3P/VpzxEfdsj+5V/cbLA2Hbcd0E44gs61 nBT9SoEAo1TLP5TSqErdJEENG/h8fALYBUbTNXwFT4g0d3HL7cKejOL1p0odxwUq/EXI cMRclWUZWeaE3hB8cKksIh+BNFDpO+ax4fmIe0f8oKzZYDQ5xQSqNxeDXw0lB8PxSzH/ Z7U1gqXkCpG+IHqNISE+gXY9Lvy3FJbl6qUL0Z5tQyfYsymNq9fs49Zzg6NSvD62KWFJ Kxp6m/gzL0BsxCoBCiCpdwJ+NrvS0VhFCjXd2sTAbn+eZDWrY0KRajPd+Wg1sRXdFbZW H1FQ== X-Gm-Message-State: AOAM53012NhskwCP9/I5/QGTooTF6KZ2mHQ6YmCjemzXuAKDHwDNhE8d GIYsQBk8qkzxnwlr8YeMni12gUMYv+KglA== X-Google-Smtp-Source: ABdhPJxoB0WOyReV7avIFHsHSpBOT0FV94fl1V+SyYHXNLig0LlOZ/MZu87nXpQlGbeDFa+FRneq1w== X-Received: by 2002:a05:6a00:1307:b0:4b0:b1c:6fd9 with SMTP id j7-20020a056a00130700b004b00b1c6fd9mr26692973pfu.27.1651014544089; Tue, 26 Apr 2022 16:09:04 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id t29-20020a62d15d000000b0050d42864753sm7856490pfl.49.2022.04.26.16.09.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Apr 2022 16:09:03 -0700 (PDT) From: Atish Patra To: qemu-devel@nongnu.org Subject: [PATCH v2 2/5] migration: Add 64bit variable array data type Date: Tue, 26 Apr 2022 16:08:51 -0700 Message-Id: <20220426230855.336292-3-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220426230855.336292-1-atishp@rivosinc.com> References: <20220426230855.336292-1-atishp@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42a; envelope-from=atishp@rivosinc.com; helo=mail-pf1-x42a.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Juan Quintela , Bin Meng , Atish Patra , "Dr. David Alan Gilbert" , Alistair Francis , Palmer Dabbelt Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" unsigned 64bit variable array data type support is missing. Add the required code to support it. Signed-off-by: Atish Patra --- include/migration/vmstate.h | 11 +++++++++++ migration/vmstate.c | 2 ++ 2 files changed, 13 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index ad24aa193451..d289caea0143 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -147,6 +147,7 @@ enum VMStateFlags { * VMStateField.struct_version_id to tell which version of the * structure we are referencing to use. */ VMS_VSTRUCT = 0x8000, + VMS_VARRAY_UINT64 = 0x10000, }; typedef enum { @@ -428,6 +429,16 @@ extern const VMStateInfo vmstate_info_qlist; .offset = vmstate_offset_pointer(_state, _field, _type), \ } +#define VMSTATE_VARRAY_UINT64(_field, _state, _field_num, _version, _info, _type) {\ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ + .info = &(_info), \ + .size = sizeof(_type), \ + .flags = VMS_VARRAY_UINT64 | VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, _type), \ +} + #define VMSTATE_VARRAY_UINT16_ALLOC(_field, _state, _field_num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version), \ diff --git a/migration/vmstate.c b/migration/vmstate.c index 36ae8b9e1918..3cd5e37ebe2d 100644 --- a/migration/vmstate.c +++ b/migration/vmstate.c @@ -35,6 +35,8 @@ static int vmstate_n_elems(void *opaque, const VMStateField *field) n_elems = *(int32_t *)(opaque + field->num_offset); } else if (field->flags & VMS_VARRAY_UINT32) { n_elems = *(uint32_t *)(opaque + field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT64) { + n_elems = *(uint64_t *)(opaque + field->num_offset); } else if (field->flags & VMS_VARRAY_UINT16) { n_elems = *(uint16_t *)(opaque + field->num_offset); } else if (field->flags & VMS_VARRAY_UINT8) { From patchwork Tue Apr 26 23:08:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Kumar Patra X-Patchwork-Id: 12828070 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0F9A8C433F5 for ; Tue, 26 Apr 2022 23:20:56 +0000 (UTC) Received: from localhost ([::1]:41972 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njUUH-0001Bq-Vu for qemu-devel@archiver.kernel.org; Tue, 26 Apr 2022 19:20:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45622) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njUIw-0005RM-Bc for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:10 -0400 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]:43713) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1njUIt-0000J1-Mb for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:09 -0400 Received: by mail-pf1-x42d.google.com with SMTP id y14so96088pfe.10 for ; Tue, 26 Apr 2022 16:09:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lIhJjvdtwMf9fN0VbwYUd2bh1ZEqi1po1uEJD0OKMqY=; b=4CPZjG6ELymxTy9E41J/GxO1lqUzuZOPoFXZPEcueFcW3NnmQQGsIYoh4X551oUYQS AtLy0A6S1P8F6mcbwBuE7+9E7A/etQOK5+6sxhfn2rskYAIIQAXsJo9O12S8o6EXJnv3 D8J+YPGnU3ncZF/1optWDlokLrQ37vxrOVHzR6s7pA/bCBta5rSncnCvjF34mL2puVjw o6G2N5ZwepKd9oOGoWEap6ZvK3LonJdsfk2V5JDdS+61IpOT+QQnmUW69MhAHdLR7txx 6jfKSDRMOd9vuR/wBKphOu5+FmyhStqykJYZxBOOer1w9S+JzHMUherNzj1ZMt9LuTkk rQ9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lIhJjvdtwMf9fN0VbwYUd2bh1ZEqi1po1uEJD0OKMqY=; b=aKfl/Y0OVScGuiKHTkRwFh0b8strFoi5qsxDZP0YN0wDxxhiX97aL24+YmI7JhRHJ6 zLGuCyft6wUL/4lhkGmtm2zrXSy+fCcbeJ2IVVdT++J9Vw8XMM+hhGtsQKy5/ioD/EiA EL7l0bk9iaU7NY+LB4Qy/BDh0dXogETYcsYNXu0+mIYmIpoDRdFeY9xVuufqaPIstUwy dQIhTjBOJBO8+4JgfnLojhhGD8ZlVik4QHz6In8IVIHKR0qfBsbOQjpbvSiquTOXJRIS ZqFcfQNdKTIBlQp9GtCwFXz7Dwbg+a0B5fePeP2b8Q0XVjwT/VRV5D5S/orUuW4P9PLK tUWg== X-Gm-Message-State: AOAM533oakQbLp3rGKSUWU/rOiFlf7tw2RsrbsD7GImo92qT9mk7fm3g 7u3YUL4G+Rp6MlE6xC93d/6qVIC60Gz71g== X-Google-Smtp-Source: ABdhPJyDiM4WqaCNdplSxJUfza3RDrKlWx1WtnnlF5sCZQ4Khk+grWaMxtZ8EFvmKiJFvWfNqqZYWQ== X-Received: by 2002:a05:6a00:238b:b0:50d:7e99:86d4 with SMTP id f11-20020a056a00238b00b0050d7e9986d4mr929143pfc.8.1651014545460; Tue, 26 Apr 2022 16:09:05 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id t29-20020a62d15d000000b0050d42864753sm7856490pfl.49.2022.04.26.16.09.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Apr 2022 16:09:04 -0700 (PDT) From: Atish Patra To: qemu-devel@nongnu.org Subject: [PATCH v2 3/5] hw/intc: Support migration of aclint device Date: Tue, 26 Apr 2022 16:08:52 -0700 Message-Id: <20220426230855.336292-4-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220426230855.336292-1-atishp@rivosinc.com> References: <20220426230855.336292-1-atishp@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42d; envelope-from=atishp@rivosinc.com; helo=mail-pf1-x42d.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Juan Quintela , Bin Meng , Atish Patra , "Dr. David Alan Gilbert" , Alistair Francis , Palmer Dabbelt Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" mtimecmp is part of ACLINT device now. This needs to preserved across migration. Signed-off-by: Atish Patra --- hw/intc/riscv_aclint.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c index 1bddb99bda47..0bbc5e65737e 100644 --- a/hw/intc/riscv_aclint.c +++ b/hw/intc/riscv_aclint.c @@ -32,6 +32,7 @@ #include "hw/intc/riscv_aclint.h" #include "qemu/timer.h" #include "hw/irq.h" +#include "migration/vmstate.h" typedef struct riscv_aclint_mtimer_callback { RISCVAclintMTimerState *s; @@ -311,6 +312,18 @@ static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type) riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8); } +static const VMStateDescription vmstate_riscv_mtimer = { + .name = "riscv_mtimer", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT64(timecmp, RISCVAclintMTimerState, + num_harts, 0, + vmstate_info_uint64, uint64_t), + VMSTATE_END_OF_LIST() + } +}; + static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -318,6 +331,7 @@ static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, riscv_aclint_mtimer_properties); ResettableClass *rc = RESETTABLE_CLASS(klass); rc->phases.enter = riscv_aclint_mtimer_reset_enter; + dc->vmsd = &vmstate_riscv_mtimer; } static const TypeInfo riscv_aclint_mtimer_info = { From patchwork Tue Apr 26 23:08:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Kumar Patra X-Patchwork-Id: 12828057 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 19027C433F5 for ; Tue, 26 Apr 2022 23:11:44 +0000 (UTC) Received: from localhost ([::1]:45400 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njULO-00018n-US for qemu-devel@archiver.kernel.org; Tue, 26 Apr 2022 19:11:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45658) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njUIy-0005YQ-9B for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:12 -0400 Received: from mail-pf1-x434.google.com ([2607:f8b0:4864:20::434]:41785) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1njUIv-0000JV-Uz for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:12 -0400 Received: by mail-pf1-x434.google.com with SMTP id p8so102900pfh.8 for ; Tue, 26 Apr 2022 16:09:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2z6E+i2W7q4DGbfz+2BceiqkjfpyfvQdMovsxCIo6Gc=; b=E5hnSRwRWrr3nkm9+47+PqA0WcWCj6xSvXnzsDyz/JBiB4ZkbJCdt/0UssuscODUyA D83dlLsv7lvLR3wFqxzqNSfvqVYCf7F8e8EUucNj64eVh/jrToHMcwyEP4p9/+A2YkH6 KgehR9z+TWM4s2faPeQN3gO5iPu4MHMUrWCHs0aCvlDqP5mNJrSHd4Z3iM5RVrmcmFd3 yxlQ4xQ6Mbz/PVL/BF6xiIJKedVLApCf3E5LENmUo51wpVfhbRtPmXPxs7cnylkEzgbd FazeMr7na8oY+FPOSGJpQCTsMH02qOjHgFTN9exBpAGoItSsLyqLWG2TVArI61EiPPbc UXTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2z6E+i2W7q4DGbfz+2BceiqkjfpyfvQdMovsxCIo6Gc=; b=WP3Hj8vZUKPvfMk3ZUND+lIA2euS4oB0BXPEHkPnH/eos2106tpaxamOnr4cCToIYZ MAs0CyeZv6gKtr/c2kdN7iFCjewG9iVxoEE4qVTIer6USHe5glXEJbcfHSPQmWsROK3P v8USsPvjHffGynuSNdXDJ0eI69s/su3VKb0SaJn1d1IBO+UkFdAWzZr3LIv+y4u5u6LS axbQ4QFe3EIgKHohOceOxRFBqhRPxrg3xscYG3zlFoH/3g7gNuO80k/uOxzXpJPwPIyM /QxRFEzvuJIlFJxm8N1oPn6eoMr46IulAXR3iM1yLnqQMzEvFDchp6Q/7GSWRXF7bx/d 4C1g== X-Gm-Message-State: AOAM5335v1d93ccNPriYAapkNUJMJvcS4Yk2rSzUvjWxJvp/ZOwgYIST mLbUDibPHy5ArXo0Z/tqYH0HGtr+oR76SA== X-Google-Smtp-Source: ABdhPJyq6SogW4wE5jmL44OHBiiSFDBSfr8Ao5qCMICjQZog7cjvEOYtkjHRku3CLctIjrpYmXCV4g== X-Received: by 2002:a63:d13:0:b0:381:f043:c627 with SMTP id c19-20020a630d13000000b00381f043c627mr21643007pgl.168.1651014546902; Tue, 26 Apr 2022 16:09:06 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id t29-20020a62d15d000000b0050d42864753sm7856490pfl.49.2022.04.26.16.09.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Apr 2022 16:09:06 -0700 (PDT) From: Atish Patra To: qemu-devel@nongnu.org Subject: [PATCH v2 4/5] target/riscv: Add stimecmp support Date: Tue, 26 Apr 2022 16:08:53 -0700 Message-Id: <20220426230855.336292-5-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220426230855.336292-1-atishp@rivosinc.com> References: <20220426230855.336292-1-atishp@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::434; envelope-from=atishp@rivosinc.com; helo=mail-pf1-x434.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Juan Quintela , Bin Meng , Atish Patra , "Dr. David Alan Gilbert" , Alistair Francis , Palmer Dabbelt Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" stimecmp allows the supervisor mode to update stimecmp CSR directly to program the next timer interrupt. This CSR is part of the Sstc extension which was ratified recently. Signed-off-by: Atish Patra --- target/riscv/cpu.c | 8 ++++ target/riscv/cpu.h | 5 ++ target/riscv/cpu_bits.h | 4 ++ target/riscv/csr.c | 83 ++++++++++++++++++++++++++++++++ target/riscv/machine.c | 1 + target/riscv/meson.build | 3 +- target/riscv/time_helper.c | 98 ++++++++++++++++++++++++++++++++++++++ target/riscv/time_helper.h | 30 ++++++++++++ 8 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 target/riscv/time_helper.c create mode 100644 target/riscv/time_helper.h diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 0c774056c5c3..6d16aeeacf0c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -23,6 +23,7 @@ #include "qemu/log.h" #include "cpu.h" #include "internals.h" +#include "time_helper.h" #include "exec/exec-all.h" #include "qapi/error.h" #include "qemu/error-report.h" @@ -777,7 +778,12 @@ static void riscv_cpu_init(Object *obj) #ifndef CONFIG_USER_ONLY qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); + + if (cpu->cfg.ext_sstc) { + riscv_timer_init(cpu); + } #endif /* CONFIG_USER_ONLY */ + } static Property riscv_cpu_properties[] = { @@ -804,6 +810,7 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true), DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true), + DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true), DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), @@ -963,6 +970,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len) ISA_EDATA_ENTRY(zbs, ext_zbs), ISA_EDATA_ENTRY(zve32f, ext_zve32f), ISA_EDATA_ENTRY(zve64f, ext_zve64f), + ISA_EDATA_ENTRY(sstc, ext_sstc), ISA_EDATA_ENTRY(svinval, ext_svinval), ISA_EDATA_ENTRY(svnapot, ext_svnapot), ISA_EDATA_ENTRY(svpbmt, ext_svpbmt), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 1119d5201066..9a5e02f217ba 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -276,6 +276,9 @@ struct CPUArchState { uint64_t mfromhost; uint64_t mtohost; + /* Sstc CSRs */ + uint64_t stimecmp; + /* physical memory protection */ pmp_table_t pmp_state; target_ulong mseccfg; @@ -329,6 +332,7 @@ struct CPUArchState { float_status fp_status; /* Fields from here on are preserved across CPU reset. */ + QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ hwaddr kernel_addr; hwaddr fdt_addr; @@ -379,6 +383,7 @@ struct RISCVCPUConfig { bool ext_counters; bool ext_ifencei; bool ext_icsr; + bool ext_sstc; bool ext_svinval; bool ext_svnapot; bool ext_svpbmt; diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 4a9e4f7d09d9..631b7c32b38f 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -212,6 +212,10 @@ #define CSR_STVAL 0x143 #define CSR_SIP 0x144 +/* Sstc supervisor CSRs */ +#define CSR_STIMECMP 0x14D +#define CSR_STIMECMPH 0x15D + /* Supervisor Protection and Translation */ #define CSR_SPTBR 0x180 #define CSR_SATP 0x180 diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 6ba85e7b5da2..c51c05d2ea74 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -21,6 +21,7 @@ #include "qemu/log.h" #include "qemu/timer.h" #include "cpu.h" +#include "time_helper.h" #include "qemu/main-loop.h" #include "exec/exec-all.h" #include "sysemu/cpu-timers.h" @@ -537,6 +538,78 @@ static RISCVException read_timeh(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +static RISCVException sstc(CPURISCVState *env, int csrno) +{ + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + + if (!cpu->cfg.ext_sstc || !env->rdtime_fn) { + return RISCV_EXCP_ILLEGAL_INST; + } + + if (env->priv == PRV_M) { + return RISCV_EXCP_NONE; + } + + if (env->priv != PRV_S) { + return RISCV_EXCP_ILLEGAL_INST; + } + + /* + * No need of separate function for rv32 as menvcfg stores both menvcfg + * menvcfgh for RV32. + */ + if (!(get_field(env->mcounteren, COUNTEREN_TM) && + get_field(env->menvcfg, MENVCFG_STCE))) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return RISCV_EXCP_NONE; +} + +static RISCVException read_stimecmp(CPURISCVState *env, int csrno, + target_ulong *val) +{ + *val = env->stimecmp; + return RISCV_EXCP_NONE; +} + +static RISCVException read_stimecmph(CPURISCVState *env, int csrno, + target_ulong *val) +{ + *val = env->stimecmp >> 32; + return RISCV_EXCP_NONE; +} + +static RISCVException write_stimecmp(CPURISCVState *env, int csrno, + target_ulong val) +{ + RISCVCPU *cpu = env_archcpu(env); + + if (riscv_cpu_mxl(env) == MXL_RV32) { + uint64_t stimecmp_hi = env->stimecmp >> 32; + env->stimecmp = (stimecmp_hi << 32) | (val & 0xFFFFFFFF); + } else { + env->stimecmp = val; + riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP); + } + + return RISCV_EXCP_NONE; +} + +static RISCVException write_stimecmph(CPURISCVState *env, int csrno, + target_ulong val) +{ + RISCVCPU *cpu = env_archcpu(env); + uint64_t timer_val = 0; + + timer_val = (uint64_t)val << 32 | (env->stimecmp & 0xFFFFFFFF); + env->stimecmp = timer_val; + riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP); + + return RISCV_EXCP_NONE; +} + /* Machine constants */ #define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP)) @@ -1515,6 +1588,12 @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno, new_val |= env->external_seip * MIP_SEIP; } + if (cpu->cfg.ext_sstc && (env->priv == PRV_M) && + get_field(env->menvcfg, MENVCFG_STCE)) { + /* sstc extension forbids STIP & VSTIP to be writeable in mip */ + mask = mask & ~(MIP_STIP | MIP_VSTIP); + } + if (mask) { old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask)); } else { @@ -3339,6 +3418,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause }, [CSR_STVAL] = { "stval", smode, read_stval, write_stval }, [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip }, + [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp, + .min_priv_ver = PRIV_VERSION_1_12_0 }, + [CSR_STIMECMPH] = { "stimecmph", sstc, read_stimecmph, write_stimecmph, + .min_priv_ver = PRIV_VERSION_1_12_0 }, /* Supervisor Protection and Translation */ [CSR_SATP] = { "satp", smode, read_satp, write_satp }, diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 14a3c1d775bc..e50d82a6085e 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -334,6 +334,7 @@ const VMStateDescription vmstate_riscv_cpu = { VMSTATE_UINTTL(env.mscratch, RISCVCPU), VMSTATE_UINT64(env.mfromhost, RISCVCPU), VMSTATE_UINT64(env.mtohost, RISCVCPU), + VMSTATE_UINT64(env.stimecmp, RISCVCPU), VMSTATE_END_OF_LIST() }, diff --git a/target/riscv/meson.build b/target/riscv/meson.build index 2c20f3dd8e9c..1243d019148e 100644 --- a/target/riscv/meson.build +++ b/target/riscv/meson.build @@ -29,7 +29,8 @@ riscv_softmmu_ss.add(files( 'pmp.c', 'debug.c', 'monitor.c', - 'machine.c' + 'machine.c', + 'time_helper.c' )) target_arch += {'riscv': riscv_ss} diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c new file mode 100644 index 000000000000..f3fb5eac7b7b --- /dev/null +++ b/target/riscv/time_helper.c @@ -0,0 +1,98 @@ +/* + * RISC-V timer helper implementation. + * + * Copyright (c) 2022 Rivos Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "cpu_bits.h" +#include "time_helper.h" +#include "hw/intc/riscv_aclint.h" + +static void riscv_stimer_cb(void *opaque) +{ + RISCVCPU *cpu = opaque; + riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1)); +} + +/* + * Called when timecmp is written to update the QEMU timer or immediately + * trigger timer interrupt if mtimecmp <= current timer value. + */ +void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer, + uint64_t timecmp, uint64_t delta, + uint32_t timer_irq) +{ + uint64_t diff, ns_diff, next; + CPURISCVState *env = &cpu->env; + RISCVAclintMTimerState *mtimer = env->rdtime_fn_arg; + uint32_t timebase_freq = mtimer->timebase_freq; + uint64_t rtc_r = env->rdtime_fn(env->rdtime_fn_arg) + delta; + + if (timecmp <= rtc_r) { + /* + * If we're setting an stimecmp value in the "past", + * immediately raise the timer interrupt + */ + riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1)); + return; + } + + /* Clear the [V]STIP bit in mip */ + riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0)); + + /* otherwise, set up the future timer interrupt */ + diff = timecmp - rtc_r; + /* back to ns (note args switched in muldiv64) */ + ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); + + /* + * check if ns_diff overflowed and check if the addition would potentially + * overflow + */ + if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) || + ns_diff > INT64_MAX) { + next = INT64_MAX; + } else { + /* + * as it is very unlikely qemu_clock_get_ns will return a value + * greater than INT64_MAX, no additional check is needed for an + * unsigned integer overflow. + */ + next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff; + /* + * if ns_diff is INT64_MAX next may still be outside the range + * of a signed integer. + */ + next = MIN(next, INT64_MAX); + } + + timer_mod(timer, next); +} + +void riscv_timer_init(RISCVCPU *cpu) +{ + CPURISCVState *env; + + if (!cpu) { + return; + } + + env = &cpu->env; + env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu); + env->stimecmp = 0; + +} diff --git a/target/riscv/time_helper.h b/target/riscv/time_helper.h new file mode 100644 index 000000000000..7b3cdcc35020 --- /dev/null +++ b/target/riscv/time_helper.h @@ -0,0 +1,30 @@ +/* + * RISC-V timer header file. + * + * Copyright (c) 2022 Rivos Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef RISCV_TIME_HELPER_H +#define RISCV_TIME_HELPER_H + +#include "cpu.h" +#include "qemu/timer.h" + +void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer, + uint64_t timecmp, uint64_t delta, + uint32_t timer_irq); +void riscv_timer_init(RISCVCPU *cpu); + +#endif From patchwork Tue Apr 26 23:08:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Kumar Patra X-Patchwork-Id: 12828064 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ACCDDC433F5 for ; Tue, 26 Apr 2022 23:18:07 +0000 (UTC) Received: from localhost ([::1]:35332 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njURa-00055I-Qk for qemu-devel@archiver.kernel.org; Tue, 26 Apr 2022 19:18:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45672) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njUIz-0005di-QH for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:13 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]:54021) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1njUIw-0000Jm-IQ for qemu-devel@nongnu.org; Tue, 26 Apr 2022 19:09:13 -0400 Received: by mail-pj1-x102b.google.com with SMTP id bx5so10233830pjb.3 for ; Tue, 26 Apr 2022 16:09:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=w2Awd7FgMhf9sRznkKZ1XajZQfx8WtTyYAHGIDlM0AY=; b=wxfqWWpvN1YxK+oRZ8wNWnMp/FcPJphlsmJv7XZxXnFzxJjB0zk6SHfpsVOeTGp9yi e4qgsfvWdDmBB3oP2QJ/AJBjZu2ySYjYs13t6RK93SFZnDTH9ESrNS4MrCBWVqkWmoNg mcDR9IUdZafcxGfs/MPAoBN5jFI/F/CFRLatI0aMGZUQe/8d5+8DG60cJU7dwepSuqL1 ehf5mTUWXzsq04+3kKQNzTC5OeqBTttZv33gqWZoXHGWzODh0CANtwI1XsqirPMFDVWk Iofa/PV+MamzG1J2nGszB/GuYTnupu/WyFc8BShsur50brysJcBquxu/HWLxwJuGOqKO M95A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=w2Awd7FgMhf9sRznkKZ1XajZQfx8WtTyYAHGIDlM0AY=; b=312KTqh3qq1MCxOpBrYC3Lux4/PkN+zbVkdIUyFjtOW6yQAgHRtTRXhJuizcDKPZrJ TVzikMeA1fa03mKbde1K6kbap7BtYNLoHXetKmYnS0/PsDBGzfGMv2Cin2l1ZhSuMsRl rb0SLBA325B4bD7kmAEPWCv7kejZ33reTkAKYAd363Z574JTObkwFlVwvWISa0NcUyAL YqV0XzMzj9Vt0bMynxl/ajT/j5P0KSmNQxcTRnghWAXA+77Ke9b47NC6LShltKEoDUD6 DikM+tClauaeFDxbLCO6gVJgJQO6e5doOiRuVeQyFLRsY9OgklICXB8rKZOnOdqLtVKv mg5w== X-Gm-Message-State: AOAM531irNPxjaA0e0k4bK/qtqNg5tkPxF1MtYexFfIbNJqYiIowI8HS tPqE9SJtkj4MrPsQuQY9zRM82C6sBVO5+Q== X-Google-Smtp-Source: ABdhPJym/DVKE+RscdnKonNozF3dsbp0LmEoxRqYj29DzORz7FwBmKQ1tqXe0X3PtOZ9I0aU/6YEPg== X-Received: by 2002:a17:902:7ec1:b0:156:17a4:a2f8 with SMTP id p1-20020a1709027ec100b0015617a4a2f8mr26351088plb.155.1651014548462; Tue, 26 Apr 2022 16:09:08 -0700 (PDT) Received: from atishp.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id t29-20020a62d15d000000b0050d42864753sm7856490pfl.49.2022.04.26.16.09.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Apr 2022 16:09:07 -0700 (PDT) From: Atish Patra To: qemu-devel@nongnu.org Subject: [PATCH v2 5/5] target/riscv: Add vstimecmp support Date: Tue, 26 Apr 2022 16:08:54 -0700 Message-Id: <20220426230855.336292-6-atishp@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220426230855.336292-1-atishp@rivosinc.com> References: <20220426230855.336292-1-atishp@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=atishp@rivosinc.com; helo=mail-pj1-x102b.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Juan Quintela , Bin Meng , Atish Patra , "Dr. David Alan Gilbert" , Alistair Francis , Palmer Dabbelt Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" vstimecmp CSR allows the guest OS or to program the next guest timer interrupt directly. Thus, hypervisor no longer need to inject the timer interrupt to the guest if vstimecmp is used. This was ratified as a part of the Sstc extension. Signed-off-by: Atish Patra --- target/riscv/cpu.h | 3 ++ target/riscv/cpu_bits.h | 4 ++ target/riscv/cpu_helper.c | 11 ++-- target/riscv/csr.c | 102 ++++++++++++++++++++++++++++++++++++- target/riscv/machine.c | 1 + target/riscv/time_helper.c | 16 ++++++ 6 files changed, 132 insertions(+), 5 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 9a5e02f217ba..29d8ab1aaca6 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -278,6 +278,7 @@ struct CPUArchState { /* Sstc CSRs */ uint64_t stimecmp; + uint64_t vstimecmp; /* physical memory protection */ pmp_table_t pmp_state; @@ -333,6 +334,8 @@ struct CPUArchState { /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ + QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */ + bool vstime_irq; hwaddr kernel_addr; hwaddr fdt_addr; diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 631b7c32b38f..ce33bf8befbb 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -269,6 +269,10 @@ #define CSR_VSIP 0x244 #define CSR_VSATP 0x280 +/* Sstc virtual CSRs */ +#define CSR_VSTIMECMP 0x24D +#define CSR_VSTIMECMPH 0x25D + #define CSR_MTINST 0x34a #define CSR_MTVAL2 0x34b diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index e1aa4f2097c1..2715021c022e 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -344,8 +344,9 @@ static uint64_t riscv_cpu_all_pending(CPURISCVState *env) { uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN); uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; + uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0; - return (env->mip | vsgein) & env->mie; + return (env->mip | vsgein | vstip) & env->mie; } int riscv_cpu_mirq_pending(CPURISCVState *env) @@ -604,7 +605,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) { CPURISCVState *env = &cpu->env; CPUState *cs = CPU(cpu); - uint64_t gein, vsgein = 0, old = env->mip; + uint64_t gein, vsgein = 0, vstip = 0, old = env->mip; bool locked = false; if (riscv_cpu_virt_enabled(env)) { @@ -612,6 +613,10 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; } + /* No need to update mip for VSTIP */ + mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask; + vstip = env->vstime_irq ? MIP_VSTIP : 0; + if (!qemu_mutex_iothread_locked()) { locked = true; qemu_mutex_lock_iothread(); @@ -619,7 +624,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) env->mip = (env->mip & ~mask) | (value & mask); - if (env->mip | vsgein) { + if (env->mip | vsgein | vstip) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); diff --git a/target/riscv/csr.c b/target/riscv/csr.c index c51c05d2ea74..c96c12a8ac74 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -567,17 +567,100 @@ static RISCVException sstc(CPURISCVState *env, int csrno) return RISCV_EXCP_NONE; } +static RISCVException sstc_hmode(CPURISCVState *env, int csrno) +{ + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + + if (!cpu->cfg.ext_sstc || !env->rdtime_fn) { + return RISCV_EXCP_ILLEGAL_INST; + } + + if (env->priv == PRV_M) { + return RISCV_EXCP_NONE; + } + + if (!(get_field(env->mcounteren, COUNTEREN_TM) & + get_field(env->menvcfg, MENVCFG_STCE))) { + return RISCV_EXCP_ILLEGAL_INST; + } + + if (!(get_field(env->hcounteren, COUNTEREN_TM) & + get_field(env->henvcfg, HENVCFG_STCE))) { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } + + return RISCV_EXCP_NONE; +} + +static RISCVException read_vstimecmp(CPURISCVState *env, int csrno, + target_ulong *val) +{ + *val = env->vstimecmp; + + return RISCV_EXCP_NONE; +} + +static RISCVException read_vstimecmph(CPURISCVState *env, int csrno, + target_ulong *val) +{ + *val = env->vstimecmp >> 32; + + return RISCV_EXCP_NONE; +} + +static RISCVException write_vstimecmp(CPURISCVState *env, int csrno, + target_ulong val) +{ + RISCVCPU *cpu = env_archcpu(env); + + if (riscv_cpu_mxl(env) == MXL_RV32) { + uint64_t vstimecmp_hi = env->vstimecmp >> 32; + env->vstimecmp = (vstimecmp_hi << 32) | (val & 0xFFFFFFFF); + } else { + env->vstimecmp = val; + riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp, + env->htimedelta, MIP_VSTIP); + } + + return RISCV_EXCP_NONE; +} + +static RISCVException write_vstimecmph(CPURISCVState *env, int csrno, + target_ulong val) +{ + RISCVCPU *cpu = env_archcpu(env); + uint64_t timer_val = 0; + + timer_val = (uint64_t)val << 32 | (env->vstimecmp & 0xFFFFFFFF); + env->vstimecmp = timer_val; + riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp, + env->htimedelta, MIP_VSTIP); + + return RISCV_EXCP_NONE; +} + static RISCVException read_stimecmp(CPURISCVState *env, int csrno, target_ulong *val) { - *val = env->stimecmp; + if (riscv_cpu_virt_enabled(env)) { + *val = env->vstimecmp; + } else { + *val = env->stimecmp; + } + return RISCV_EXCP_NONE; } static RISCVException read_stimecmph(CPURISCVState *env, int csrno, target_ulong *val) { - *val = env->stimecmp >> 32; + if (riscv_cpu_virt_enabled(env)) { + *val = env->vstimecmp >> 32; + } else { + *val = env->stimecmp >> 32; + } + return RISCV_EXCP_NONE; } @@ -586,6 +669,10 @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno, { RISCVCPU *cpu = env_archcpu(env); + if (riscv_cpu_virt_enabled(env)) { + return write_vstimecmp(env, csrno, val); + } + if (riscv_cpu_mxl(env) == MXL_RV32) { uint64_t stimecmp_hi = env->stimecmp >> 32; env->stimecmp = (stimecmp_hi << 32) | (val & 0xFFFFFFFF); @@ -603,6 +690,10 @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno, RISCVCPU *cpu = env_archcpu(env); uint64_t timer_val = 0; + if (riscv_cpu_virt_enabled(env)) { + return write_vstimecmph(env, csrno, val); + } + timer_val = (uint64_t)val << 32 | (env->stimecmp & 0xFFFFFFFF); env->stimecmp = timer_val; riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP); @@ -1603,6 +1694,7 @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno, if (csrno != CSR_HVIP) { gin = get_field(env->hstatus, HSTATUS_VGEIN); old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0; + old_mip |= env->vstime_irq ? MIP_VSTIP : 0; } if (ret_val) { @@ -3422,6 +3514,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { .min_priv_ver = PRIV_VERSION_1_12_0 }, [CSR_STIMECMPH] = { "stimecmph", sstc, read_stimecmph, write_stimecmph, .min_priv_ver = PRIV_VERSION_1_12_0 }, + [CSR_VSTIMECMP] = { "vstimecmp", sstc_hmode, read_vstimecmp, + write_vstimecmp, + .min_priv_ver = PRIV_VERSION_1_12_0 }, + [CSR_VSTIMECMPH] = { "vstimecmph", sstc_hmode, read_vstimecmph, + write_vstimecmph, + .min_priv_ver = PRIV_VERSION_1_12_0 }, /* Supervisor Protection and Translation */ [CSR_SATP] = { "satp", smode, read_satp, write_satp }, diff --git a/target/riscv/machine.c b/target/riscv/machine.c index e50d82a6085e..c3628c949640 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -92,6 +92,7 @@ static const VMStateDescription vmstate_hyper = { VMSTATE_UINTTL(env.hgeie, RISCVCPU), VMSTATE_UINTTL(env.hgeip, RISCVCPU), VMSTATE_UINT64(env.htimedelta, RISCVCPU), + VMSTATE_UINT64(env.vstimecmp, RISCVCPU), VMSTATE_UINTTL(env.hvictl, RISCVCPU), VMSTATE_UINT8_ARRAY(env.hviprio, RISCVCPU, 64), diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c index f3fb5eac7b7b..8cce667dfd47 100644 --- a/target/riscv/time_helper.c +++ b/target/riscv/time_helper.c @@ -22,6 +22,14 @@ #include "time_helper.h" #include "hw/intc/riscv_aclint.h" +static void riscv_vstimer_cb(void *opaque) +{ + RISCVCPU *cpu = opaque; + CPURISCVState *env = &cpu->env; + env->vstime_irq = 1; + riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1)); +} + static void riscv_stimer_cb(void *opaque) { RISCVCPU *cpu = opaque; @@ -47,10 +55,16 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer, * If we're setting an stimecmp value in the "past", * immediately raise the timer interrupt */ + if (timer_irq == MIP_VSTIP) { + env->vstime_irq = 1; + } riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1)); return; } + if (timer_irq == MIP_VSTIP) { + env->vstime_irq = 0; + } /* Clear the [V]STIP bit in mip */ riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0)); @@ -95,4 +109,6 @@ void riscv_timer_init(RISCVCPU *cpu) env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu); env->stimecmp = 0; + env->vstimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_vstimer_cb, cpu); + env->vstimecmp = 0; }