From patchwork Wed Feb 13 15:44:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 1041363 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.b="KBzQnP/V"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4403xt2tZMz9s3l for ; Thu, 14 Feb 2019 02:54:58 +1100 (AEDT) Received: from localhost ([127.0.0.1]:58969 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtwsC-0000R2-Bk for incoming@patchwork.ozlabs.org; Wed, 13 Feb 2019 10:54:56 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56651) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gtwjA-0002MT-R5 for qemu-devel@nongnu.org; Wed, 13 Feb 2019 10:45:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gtwj5-00076f-3l for qemu-devel@nongnu.org; Wed, 13 Feb 2019 10:45:36 -0500 Received: from mail-pl1-x643.google.com ([2607:f8b0:4864:20::643]:36472) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gtwj4-0006hF-Pk for qemu-devel@nongnu.org; Wed, 13 Feb 2019 10:45:30 -0500 Received: by mail-pl1-x643.google.com with SMTP id g9so1344005plo.3 for ; Wed, 13 Feb 2019 07:45:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=subject:date:message-id:in-reply-to:references:cc:from:to; bh=ihjYI8w/pHOrt/O0GHzxFvfptHP8KkD3SPdesRMFnZg=; b=KBzQnP/VmMzdcISHAkkStCoW2xMYpkPpyhNSff4p3GX6KmtncYMe3kTg+/+xQOZL4b MAGsrc+Cs72XXIEcY5yuj8f6uUmZNH3nOT9slFyRsZd8WHnH4ewTUtSBj4GdehZO1/5u anLQREHWB6LjOQmuyS/+yyAxaPpIG+LQliCNyDOr80uiBt6KIOQZABN87DAw1wfmy/Sd iqpi2gFkEdaQ+ylhxE9mBKSGPv5k6TI7DMUWptzo4RSwElslBp/czzLVgUMsQEMY6uUl MlP0IRw5WrrhCvTL7nWtcanFkyr3l3Jym+0AgJ6yEnkRX5M1EEsSXcQtKQEf8cuf5/hv 6STg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=ihjYI8w/pHOrt/O0GHzxFvfptHP8KkD3SPdesRMFnZg=; b=CASngBfTA1ip0hOXSFsTiXnPXJWIi/qUJFU+En38oV/SVfiZ+NnG/JAbAjJW6TF6RX KuOC3Vwd76SHPHcSVWitpspDe4PbePhz3v0wv1HTq/hhzozRNOczK7RCNbYCE0zhyDZb WoPjnOe7tprowBBduVbcOJl2eiQv2VG/6SkN0fT3RXtlv31GsRWOYjAii9LH+LtTo3Qx paAolaGTyXuSkoME2lBx1JnTE4XOx777SKP9SRHMBTreMnZZuBkTCDOmOTm/uAVyZVx1 YhhXEtdwluVqSqZ2qWHqPHG8EZdN6R9y9l95gXhQEH7LwuIVc4HqmMGgoEYLPUQItjyq zHCQ== X-Gm-Message-State: AHQUAuYJIPLvDB97ROrHurVwfJ0OsQL4M9Lk+zJVDoj3YHOt5F4aNWH+ TWccRWP5VpGlp1sTfoJFUv/N0w== X-Google-Smtp-Source: AHgI3IZiTgnVbGyC/MeKMSQzxVcXeKsb6k5l32i/8SGbEX0vQfinJfNZOkwWDzCKtnlpzNNxqm61xw== X-Received: by 2002:a17:902:9a07:: with SMTP id v7mr1079458plp.247.1550072715883; Wed, 13 Feb 2019 07:45:15 -0800 (PST) Received: from localhost ([12.206.222.5]) by smtp.gmail.com with ESMTPSA id f18sm4182108pgf.26.2019.02.13.07.45.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Feb 2019 07:45:15 -0800 (PST) Date: Wed, 13 Feb 2019 07:44:47 -0800 Message-Id: <20190213154450.14749-9-palmer@sifive.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: <20190213154450.14749-1-palmer@sifive.com> References: <20190213154450.14749-1-palmer@sifive.com> From: Palmer Dabbelt To: Peter Maydell X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::643 Subject: [Qemu-devel] [PULL 08/11] RISC-V: Add misa runtime write support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alistair Francis , Michael Clark , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Palmer Dabbelt Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Michael Clark 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. Signed-off-by: Michael Clark Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu.c | 2 +- target/riscv/cpu.h | 4 ++- target/riscv/cpu_bits.h | 11 +++++++++ target/riscv/csr.c | 54 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 28d7e5302fb1..cc3ddc0ae4b5 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -88,7 +88,7 @@ typedef struct RISCVCPUInfo { static void set_misa(CPURISCVState *env, target_ulong misa) { - env->misa = misa; + env->misa_mask = env->misa = misa; } static void set_versions(CPURISCVState *env, int user_ver, int priv_ver) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index a97435bd7b1d..5c2aebf13251 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -86,7 +86,8 @@ so a cpu features bitfield is required, likewise for optional PMP support */ enum { RISCV_FEATURE_MMU, - RISCV_FEATURE_PMP + RISCV_FEATURE_PMP, + RISCV_FEATURE_MISA }; #define USER_VERSION_2_02_0 0x00020200 @@ -118,6 +119,7 @@ struct CPURISCVState { target_ulong user_ver; target_ulong priv_ver; target_ulong misa; + target_ulong misa_mask; uint32_t features; diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 5439f4719ee5..7afcb2468d80 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -311,10 +311,21 @@ #define MSTATUS32_SD 0x80000000 #define MSTATUS64_SD 0x8000000000000000ULL +#define MISA32_MXL 0xC0000000 +#define MISA64_MXL 0xC000000000000000ULL + +#define MXL_RV32 1 +#define MXL_RV64 2 +#define MXL_RV128 3 + #if defined(TARGET_RISCV32) #define MSTATUS_SD MSTATUS32_SD +#define MISA_MXL MISA32_MXL +#define MXL_VAL MXL_RV32 #elif defined(TARGET_RISCV64) #define MSTATUS_SD MSTATUS64_SD +#define MISA_MXL MISA64_MXL +#define MXL_VAL MXL_RV64 #endif /* sstatus CSR bits */ diff --git a/target/riscv/csr.c b/target/riscv/csr.c index e2bd374f09ed..e72fcf1265d4 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -332,6 +332,58 @@ static int read_misa(CPURISCVState *env, int csrno, target_ulong *val) return 0; } +static int write_misa(CPURISCVState *env, int csrno, target_ulong val) +{ + if (!riscv_feature(env, RISCV_FEATURE_MISA)) { + /* drop write to misa */ + return 0; + } + + /* 'I' or 'E' must be present */ + if (!(val & (RVI | RVE))) { + /* It is not, drop write to misa */ + return 0; + } + + /* 'E' excludes all other extensions */ + if (val & RVE) { + /* when we support 'E' we can do "val = RVE;" however + * for now we just drop writes if 'E' is present. + */ + return 0; + } + + /* Mask extensions that are not supported by this hart */ + val &= env->misa_mask; + + /* Mask extensions that are not supported by QEMU */ + val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU); + + /* 'D' depends on 'F', so clear 'D' if 'F' is not present */ + if ((val & RVD) && !(val & RVF)) { + val &= ~RVD; + } + + /* Suppress 'C' if next instruction is not aligned + * TODO: this should check next_pc + */ + if ((val & RVC) && (GETPC() & ~3) != 0) { + val &= ~RVC; + } + + /* misa.MXL writes are not supported by QEMU */ + val = (env->misa & MISA_MXL) | (val & ~MISA_MXL); + + /* flush translation cache */ + if (val != env->misa) { + tb_flush(CPU(riscv_env_get_cpu(env))); + } + + env->misa = val; + + return 0; +} + static int read_medeleg(CPURISCVState *env, int csrno, target_ulong *val) { *val = env->medeleg; @@ -810,7 +862,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Machine Trap Setup */ [CSR_MSTATUS] = { any, read_mstatus, write_mstatus }, - [CSR_MISA] = { any, read_misa }, + [CSR_MISA] = { any, read_misa, write_misa }, [CSR_MIDELEG] = { any, read_mideleg, write_mideleg }, [CSR_MEDELEG] = { any, read_medeleg, write_medeleg }, [CSR_MIE] = { any, read_mie, write_mie },