qemu/target/riscv/csr.c
<<
>>
Prefs
   1/*
   2 * RISC-V Control and Status Registers.
   3 *
   4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
   5 * Copyright (c) 2017-2018 SiFive, Inc.
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms and conditions of the GNU General Public License,
   9 * version 2 or later, as published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "qemu/log.h"
  22#include "qemu/timer.h"
  23#include "cpu.h"
  24#include "qemu/main-loop.h"
  25#include "exec/exec-all.h"
  26#include "sysemu/cpu-timers.h"
  27
  28/* CSR function table public API */
  29void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
  30{
  31    *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
  32}
  33
  34void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
  35{
  36    csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
  37}
  38
  39/* Predicates */
  40static RISCVException fs(CPURISCVState *env, int csrno)
  41{
  42#if !defined(CONFIG_USER_ONLY)
  43    if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
  44        !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
  45        return RISCV_EXCP_ILLEGAL_INST;
  46    }
  47#endif
  48    return RISCV_EXCP_NONE;
  49}
  50
  51static RISCVException vs(CPURISCVState *env, int csrno)
  52{
  53    CPUState *cs = env_cpu(env);
  54    RISCVCPU *cpu = RISCV_CPU(cs);
  55
  56    if (env->misa_ext & RVV ||
  57        cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
  58#if !defined(CONFIG_USER_ONLY)
  59        if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
  60            return RISCV_EXCP_ILLEGAL_INST;
  61        }
  62#endif
  63        return RISCV_EXCP_NONE;
  64    }
  65    return RISCV_EXCP_ILLEGAL_INST;
  66}
  67
  68static RISCVException ctr(CPURISCVState *env, int csrno)
  69{
  70#if !defined(CONFIG_USER_ONLY)
  71    CPUState *cs = env_cpu(env);
  72    RISCVCPU *cpu = RISCV_CPU(cs);
  73
  74    if (!cpu->cfg.ext_counters) {
  75        /* The Counters extensions is not enabled */
  76        return RISCV_EXCP_ILLEGAL_INST;
  77    }
  78
  79    if (riscv_cpu_virt_enabled(env)) {
  80        switch (csrno) {
  81        case CSR_CYCLE:
  82            if (!get_field(env->hcounteren, COUNTEREN_CY) &&
  83                get_field(env->mcounteren, COUNTEREN_CY)) {
  84                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
  85            }
  86            break;
  87        case CSR_TIME:
  88            if (!get_field(env->hcounteren, COUNTEREN_TM) &&
  89                get_field(env->mcounteren, COUNTEREN_TM)) {
  90                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
  91            }
  92            break;
  93        case CSR_INSTRET:
  94            if (!get_field(env->hcounteren, COUNTEREN_IR) &&
  95                get_field(env->mcounteren, COUNTEREN_IR)) {
  96                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
  97            }
  98            break;
  99        case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
 100            if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
 101                get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
 102                return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 103            }
 104            break;
 105        }
 106        if (riscv_cpu_mxl(env) == MXL_RV32) {
 107            switch (csrno) {
 108            case CSR_CYCLEH:
 109                if (!get_field(env->hcounteren, COUNTEREN_CY) &&
 110                    get_field(env->mcounteren, COUNTEREN_CY)) {
 111                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 112                }
 113                break;
 114            case CSR_TIMEH:
 115                if (!get_field(env->hcounteren, COUNTEREN_TM) &&
 116                    get_field(env->mcounteren, COUNTEREN_TM)) {
 117                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 118                }
 119                break;
 120            case CSR_INSTRETH:
 121                if (!get_field(env->hcounteren, COUNTEREN_IR) &&
 122                    get_field(env->mcounteren, COUNTEREN_IR)) {
 123                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 124                }
 125                break;
 126            case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
 127                if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
 128                    get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
 129                    return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 130                }
 131                break;
 132            }
 133        }
 134    }
 135#endif
 136    return RISCV_EXCP_NONE;
 137}
 138
 139static RISCVException ctr32(CPURISCVState *env, int csrno)
 140{
 141    if (riscv_cpu_mxl(env) != MXL_RV32) {
 142        return RISCV_EXCP_ILLEGAL_INST;
 143    }
 144
 145    return ctr(env, csrno);
 146}
 147
 148#if !defined(CONFIG_USER_ONLY)
 149static RISCVException any(CPURISCVState *env, int csrno)
 150{
 151    return RISCV_EXCP_NONE;
 152}
 153
 154static RISCVException any32(CPURISCVState *env, int csrno)
 155{
 156    if (riscv_cpu_mxl(env) != MXL_RV32) {
 157        return RISCV_EXCP_ILLEGAL_INST;
 158    }
 159
 160    return any(env, csrno);
 161
 162}
 163
 164static int aia_any(CPURISCVState *env, int csrno)
 165{
 166    if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
 167        return RISCV_EXCP_ILLEGAL_INST;
 168    }
 169
 170    return any(env, csrno);
 171}
 172
 173static int aia_any32(CPURISCVState *env, int csrno)
 174{
 175    if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
 176        return RISCV_EXCP_ILLEGAL_INST;
 177    }
 178
 179    return any32(env, csrno);
 180}
 181
 182static RISCVException smode(CPURISCVState *env, int csrno)
 183{
 184    if (riscv_has_ext(env, RVS)) {
 185        return RISCV_EXCP_NONE;
 186    }
 187
 188    return RISCV_EXCP_ILLEGAL_INST;
 189}
 190
 191static int smode32(CPURISCVState *env, int csrno)
 192{
 193    if (riscv_cpu_mxl(env) != MXL_RV32) {
 194        return RISCV_EXCP_ILLEGAL_INST;
 195    }
 196
 197    return smode(env, csrno);
 198}
 199
 200static int aia_smode(CPURISCVState *env, int csrno)
 201{
 202    if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
 203        return RISCV_EXCP_ILLEGAL_INST;
 204    }
 205
 206    return smode(env, csrno);
 207}
 208
 209static int aia_smode32(CPURISCVState *env, int csrno)
 210{
 211    if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
 212        return RISCV_EXCP_ILLEGAL_INST;
 213    }
 214
 215    return smode32(env, csrno);
 216}
 217
 218static RISCVException hmode(CPURISCVState *env, int csrno)
 219{
 220    if (riscv_has_ext(env, RVS) &&
 221        riscv_has_ext(env, RVH)) {
 222        /* Hypervisor extension is supported */
 223        if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
 224            env->priv == PRV_M) {
 225            return RISCV_EXCP_NONE;
 226        } else {
 227            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 228        }
 229    }
 230
 231    return RISCV_EXCP_ILLEGAL_INST;
 232}
 233
 234static RISCVException hmode32(CPURISCVState *env, int csrno)
 235{
 236    if (riscv_cpu_mxl(env) != MXL_RV32) {
 237        if (!riscv_cpu_virt_enabled(env)) {
 238            return RISCV_EXCP_ILLEGAL_INST;
 239        } else {
 240            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 241        }
 242    }
 243
 244    return hmode(env, csrno);
 245
 246}
 247
 248/* Checks if PointerMasking registers could be accessed */
 249static RISCVException pointer_masking(CPURISCVState *env, int csrno)
 250{
 251    /* Check if j-ext is present */
 252    if (riscv_has_ext(env, RVJ)) {
 253        return RISCV_EXCP_NONE;
 254    }
 255    return RISCV_EXCP_ILLEGAL_INST;
 256}
 257
 258static int aia_hmode(CPURISCVState *env, int csrno)
 259{
 260    if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
 261        return RISCV_EXCP_ILLEGAL_INST;
 262     }
 263
 264     return hmode(env, csrno);
 265}
 266
 267static int aia_hmode32(CPURISCVState *env, int csrno)
 268{
 269    if (!riscv_feature(env, RISCV_FEATURE_AIA)) {
 270        return RISCV_EXCP_ILLEGAL_INST;
 271    }
 272
 273    return hmode32(env, csrno);
 274}
 275
 276static RISCVException pmp(CPURISCVState *env, int csrno)
 277{
 278    if (riscv_feature(env, RISCV_FEATURE_PMP)) {
 279        return RISCV_EXCP_NONE;
 280    }
 281
 282    return RISCV_EXCP_ILLEGAL_INST;
 283}
 284
 285static RISCVException epmp(CPURISCVState *env, int csrno)
 286{
 287    if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
 288        return RISCV_EXCP_NONE;
 289    }
 290
 291    return RISCV_EXCP_ILLEGAL_INST;
 292}
 293#endif
 294
 295/* User Floating-Point CSRs */
 296static RISCVException read_fflags(CPURISCVState *env, int csrno,
 297                                  target_ulong *val)
 298{
 299    *val = riscv_cpu_get_fflags(env);
 300    return RISCV_EXCP_NONE;
 301}
 302
 303static RISCVException write_fflags(CPURISCVState *env, int csrno,
 304                                   target_ulong val)
 305{
 306#if !defined(CONFIG_USER_ONLY)
 307    if (riscv_has_ext(env, RVF)) {
 308        env->mstatus |= MSTATUS_FS;
 309    }
 310#endif
 311    riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
 312    return RISCV_EXCP_NONE;
 313}
 314
 315static RISCVException read_frm(CPURISCVState *env, int csrno,
 316                               target_ulong *val)
 317{
 318    *val = env->frm;
 319    return RISCV_EXCP_NONE;
 320}
 321
 322static RISCVException write_frm(CPURISCVState *env, int csrno,
 323                                target_ulong val)
 324{
 325#if !defined(CONFIG_USER_ONLY)
 326    if (riscv_has_ext(env, RVF)) {
 327        env->mstatus |= MSTATUS_FS;
 328    }
 329#endif
 330    env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
 331    return RISCV_EXCP_NONE;
 332}
 333
 334static RISCVException read_fcsr(CPURISCVState *env, int csrno,
 335                                target_ulong *val)
 336{
 337    *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
 338        | (env->frm << FSR_RD_SHIFT);
 339    return RISCV_EXCP_NONE;
 340}
 341
 342static RISCVException write_fcsr(CPURISCVState *env, int csrno,
 343                                 target_ulong val)
 344{
 345#if !defined(CONFIG_USER_ONLY)
 346    if (riscv_has_ext(env, RVF)) {
 347        env->mstatus |= MSTATUS_FS;
 348    }
 349#endif
 350    env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
 351    riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
 352    return RISCV_EXCP_NONE;
 353}
 354
 355static RISCVException read_vtype(CPURISCVState *env, int csrno,
 356                                 target_ulong *val)
 357{
 358    uint64_t vill;
 359    switch (env->xl) {
 360    case MXL_RV32:
 361        vill = (uint32_t)env->vill << 31;
 362        break;
 363    case MXL_RV64:
 364        vill = (uint64_t)env->vill << 63;
 365        break;
 366    default:
 367        g_assert_not_reached();
 368    }
 369    *val = (target_ulong)vill | env->vtype;
 370    return RISCV_EXCP_NONE;
 371}
 372
 373static RISCVException read_vl(CPURISCVState *env, int csrno,
 374                              target_ulong *val)
 375{
 376    *val = env->vl;
 377    return RISCV_EXCP_NONE;
 378}
 379
 380static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
 381{
 382    *val = env_archcpu(env)->cfg.vlen >> 3;
 383    return RISCV_EXCP_NONE;
 384}
 385
 386static RISCVException read_vxrm(CPURISCVState *env, int csrno,
 387                                target_ulong *val)
 388{
 389    *val = env->vxrm;
 390    return RISCV_EXCP_NONE;
 391}
 392
 393static RISCVException write_vxrm(CPURISCVState *env, int csrno,
 394                                 target_ulong val)
 395{
 396#if !defined(CONFIG_USER_ONLY)
 397    env->mstatus |= MSTATUS_VS;
 398#endif
 399    env->vxrm = val;
 400    return RISCV_EXCP_NONE;
 401}
 402
 403static RISCVException read_vxsat(CPURISCVState *env, int csrno,
 404                                 target_ulong *val)
 405{
 406    *val = env->vxsat;
 407    return RISCV_EXCP_NONE;
 408}
 409
 410static RISCVException write_vxsat(CPURISCVState *env, int csrno,
 411                                  target_ulong val)
 412{
 413#if !defined(CONFIG_USER_ONLY)
 414    env->mstatus |= MSTATUS_VS;
 415#endif
 416    env->vxsat = val;
 417    return RISCV_EXCP_NONE;
 418}
 419
 420static RISCVException read_vstart(CPURISCVState *env, int csrno,
 421                                  target_ulong *val)
 422{
 423    *val = env->vstart;
 424    return RISCV_EXCP_NONE;
 425}
 426
 427static RISCVException write_vstart(CPURISCVState *env, int csrno,
 428                                   target_ulong val)
 429{
 430#if !defined(CONFIG_USER_ONLY)
 431    env->mstatus |= MSTATUS_VS;
 432#endif
 433    /*
 434     * The vstart CSR is defined to have only enough writable bits
 435     * to hold the largest element index, i.e. lg2(VLEN) bits.
 436     */
 437    env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen));
 438    return RISCV_EXCP_NONE;
 439}
 440
 441static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
 442{
 443    *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
 444    return RISCV_EXCP_NONE;
 445}
 446
 447static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
 448{
 449#if !defined(CONFIG_USER_ONLY)
 450    env->mstatus |= MSTATUS_VS;
 451#endif
 452    env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
 453    env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
 454    return RISCV_EXCP_NONE;
 455}
 456
 457/* User Timers and Counters */
 458static RISCVException read_instret(CPURISCVState *env, int csrno,
 459                                   target_ulong *val)
 460{
 461#if !defined(CONFIG_USER_ONLY)
 462    if (icount_enabled()) {
 463        *val = icount_get();
 464    } else {
 465        *val = cpu_get_host_ticks();
 466    }
 467#else
 468    *val = cpu_get_host_ticks();
 469#endif
 470    return RISCV_EXCP_NONE;
 471}
 472
 473static RISCVException read_instreth(CPURISCVState *env, int csrno,
 474                                    target_ulong *val)
 475{
 476#if !defined(CONFIG_USER_ONLY)
 477    if (icount_enabled()) {
 478        *val = icount_get() >> 32;
 479    } else {
 480        *val = cpu_get_host_ticks() >> 32;
 481    }
 482#else
 483    *val = cpu_get_host_ticks() >> 32;
 484#endif
 485    return RISCV_EXCP_NONE;
 486}
 487
 488#if defined(CONFIG_USER_ONLY)
 489static RISCVException read_time(CPURISCVState *env, int csrno,
 490                                target_ulong *val)
 491{
 492    *val = cpu_get_host_ticks();
 493    return RISCV_EXCP_NONE;
 494}
 495
 496static RISCVException read_timeh(CPURISCVState *env, int csrno,
 497                                 target_ulong *val)
 498{
 499    *val = cpu_get_host_ticks() >> 32;
 500    return RISCV_EXCP_NONE;
 501}
 502
 503#else /* CONFIG_USER_ONLY */
 504
 505static RISCVException read_time(CPURISCVState *env, int csrno,
 506                                target_ulong *val)
 507{
 508    uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
 509
 510    if (!env->rdtime_fn) {
 511        return RISCV_EXCP_ILLEGAL_INST;
 512    }
 513
 514    *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
 515    return RISCV_EXCP_NONE;
 516}
 517
 518static RISCVException read_timeh(CPURISCVState *env, int csrno,
 519                                 target_ulong *val)
 520{
 521    uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
 522
 523    if (!env->rdtime_fn) {
 524        return RISCV_EXCP_ILLEGAL_INST;
 525    }
 526
 527    *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
 528    return RISCV_EXCP_NONE;
 529}
 530
 531/* Machine constants */
 532
 533#define M_MODE_INTERRUPTS  ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
 534#define S_MODE_INTERRUPTS  ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP))
 535#define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
 536#define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
 537
 538#define VSTOPI_NUM_SRCS 5
 539
 540static const uint64_t delegable_ints = S_MODE_INTERRUPTS |
 541                                           VS_MODE_INTERRUPTS;
 542static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS;
 543static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
 544                                     HS_MODE_INTERRUPTS;
 545#define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
 546                         (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
 547                         (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
 548                         (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
 549                         (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
 550                         (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
 551                         (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
 552                         (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
 553                         (1ULL << (RISCV_EXCP_U_ECALL)) | \
 554                         (1ULL << (RISCV_EXCP_S_ECALL)) | \
 555                         (1ULL << (RISCV_EXCP_VS_ECALL)) | \
 556                         (1ULL << (RISCV_EXCP_M_ECALL)) | \
 557                         (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
 558                         (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
 559                         (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
 560                         (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
 561                         (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
 562                         (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
 563                         (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
 564static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
 565    ~((1ULL << (RISCV_EXCP_S_ECALL)) |
 566      (1ULL << (RISCV_EXCP_VS_ECALL)) |
 567      (1ULL << (RISCV_EXCP_M_ECALL)) |
 568      (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
 569      (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
 570      (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
 571      (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
 572static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
 573    SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
 574    SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
 575static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
 576static const target_ulong hip_writable_mask = MIP_VSSIP;
 577static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
 578static const target_ulong vsip_writable_mask = MIP_VSSIP;
 579
 580static const char valid_vm_1_10_32[16] = {
 581    [VM_1_10_MBARE] = 1,
 582    [VM_1_10_SV32] = 1
 583};
 584
 585static const char valid_vm_1_10_64[16] = {
 586    [VM_1_10_MBARE] = 1,
 587    [VM_1_10_SV39] = 1,
 588    [VM_1_10_SV48] = 1,
 589    [VM_1_10_SV57] = 1
 590};
 591
 592/* Machine Information Registers */
 593static RISCVException read_zero(CPURISCVState *env, int csrno,
 594                                target_ulong *val)
 595{
 596    *val = 0;
 597    return RISCV_EXCP_NONE;
 598}
 599
 600static RISCVException write_ignore(CPURISCVState *env, int csrno,
 601                                   target_ulong val)
 602{
 603    return RISCV_EXCP_NONE;
 604}
 605
 606static RISCVException read_mhartid(CPURISCVState *env, int csrno,
 607                                   target_ulong *val)
 608{
 609    *val = env->mhartid;
 610    return RISCV_EXCP_NONE;
 611}
 612
 613/* Machine Trap Setup */
 614
 615/* We do not store SD explicitly, only compute it on demand. */
 616static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
 617{
 618    if ((status & MSTATUS_FS) == MSTATUS_FS ||
 619        (status & MSTATUS_VS) == MSTATUS_VS ||
 620        (status & MSTATUS_XS) == MSTATUS_XS) {
 621        switch (xl) {
 622        case MXL_RV32:
 623            return status | MSTATUS32_SD;
 624        case MXL_RV64:
 625            return status | MSTATUS64_SD;
 626        case MXL_RV128:
 627            return MSTATUSH128_SD;
 628        default:
 629            g_assert_not_reached();
 630        }
 631    }
 632    return status;
 633}
 634
 635static RISCVException read_mstatus(CPURISCVState *env, int csrno,
 636                                   target_ulong *val)
 637{
 638    *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
 639    return RISCV_EXCP_NONE;
 640}
 641
 642static int validate_vm(CPURISCVState *env, target_ulong vm)
 643{
 644    if (riscv_cpu_mxl(env) == MXL_RV32) {
 645        return valid_vm_1_10_32[vm & 0xf];
 646    } else {
 647        return valid_vm_1_10_64[vm & 0xf];
 648    }
 649}
 650
 651static RISCVException write_mstatus(CPURISCVState *env, int csrno,
 652                                    target_ulong val)
 653{
 654    uint64_t mstatus = env->mstatus;
 655    uint64_t mask = 0;
 656    RISCVMXL xl = riscv_cpu_mxl(env);
 657
 658    /* flush tlb on mstatus fields that affect VM */
 659    if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
 660            MSTATUS_MPRV | MSTATUS_SUM)) {
 661        tlb_flush(env_cpu(env));
 662    }
 663    mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
 664        MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
 665        MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
 666        MSTATUS_TW | MSTATUS_VS;
 667
 668    if (riscv_has_ext(env, RVF)) {
 669        mask |= MSTATUS_FS;
 670    }
 671
 672    if (xl != MXL_RV32 || env->debugger) {
 673        /*
 674         * RV32: MPV and GVA are not in mstatus. The current plan is to
 675         * add them to mstatush. For now, we just don't support it.
 676         */
 677        mask |= MSTATUS_MPV | MSTATUS_GVA;
 678        if ((val & MSTATUS64_UXL) != 0) {
 679            mask |= MSTATUS64_UXL;
 680        }
 681    }
 682
 683    mstatus = (mstatus & ~mask) | (val & mask);
 684
 685    if (xl > MXL_RV32) {
 686        /* SXL field is for now read only */
 687        mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
 688    }
 689    env->mstatus = mstatus;
 690    env->xl = cpu_recompute_xl(env);
 691
 692    return RISCV_EXCP_NONE;
 693}
 694
 695static RISCVException read_mstatush(CPURISCVState *env, int csrno,
 696                                    target_ulong *val)
 697{
 698    *val = env->mstatus >> 32;
 699    return RISCV_EXCP_NONE;
 700}
 701
 702static RISCVException write_mstatush(CPURISCVState *env, int csrno,
 703                                     target_ulong val)
 704{
 705    uint64_t valh = (uint64_t)val << 32;
 706    uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
 707
 708    if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
 709        tlb_flush(env_cpu(env));
 710    }
 711
 712    env->mstatus = (env->mstatus & ~mask) | (valh & mask);
 713
 714    return RISCV_EXCP_NONE;
 715}
 716
 717static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
 718                                        Int128 *val)
 719{
 720    *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, env->mstatus));
 721    return RISCV_EXCP_NONE;
 722}
 723
 724static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
 725                                     Int128 *val)
 726{
 727    *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
 728    return RISCV_EXCP_NONE;
 729}
 730
 731static RISCVException read_misa(CPURISCVState *env, int csrno,
 732                                target_ulong *val)
 733{
 734    target_ulong misa;
 735
 736    switch (env->misa_mxl) {
 737    case MXL_RV32:
 738        misa = (target_ulong)MXL_RV32 << 30;
 739        break;
 740#ifdef TARGET_RISCV64
 741    case MXL_RV64:
 742        misa = (target_ulong)MXL_RV64 << 62;
 743        break;
 744#endif
 745    default:
 746        g_assert_not_reached();
 747    }
 748
 749    *val = misa | env->misa_ext;
 750    return RISCV_EXCP_NONE;
 751}
 752
 753static RISCVException write_misa(CPURISCVState *env, int csrno,
 754                                 target_ulong val)
 755{
 756    if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
 757        /* drop write to misa */
 758        return RISCV_EXCP_NONE;
 759    }
 760
 761    /* 'I' or 'E' must be present */
 762    if (!(val & (RVI | RVE))) {
 763        /* It is not, drop write to misa */
 764        return RISCV_EXCP_NONE;
 765    }
 766
 767    /* 'E' excludes all other extensions */
 768    if (val & RVE) {
 769        /* when we support 'E' we can do "val = RVE;" however
 770         * for now we just drop writes if 'E' is present.
 771         */
 772        return RISCV_EXCP_NONE;
 773    }
 774
 775    /*
 776     * misa.MXL writes are not supported by QEMU.
 777     * Drop writes to those bits.
 778     */
 779
 780    /* Mask extensions that are not supported by this hart */
 781    val &= env->misa_ext_mask;
 782
 783    /* Mask extensions that are not supported by QEMU */
 784    val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
 785
 786    /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
 787    if ((val & RVD) && !(val & RVF)) {
 788        val &= ~RVD;
 789    }
 790
 791    /* Suppress 'C' if next instruction is not aligned
 792     * TODO: this should check next_pc
 793     */
 794    if ((val & RVC) && (GETPC() & ~3) != 0) {
 795        val &= ~RVC;
 796    }
 797
 798    /* If nothing changed, do nothing. */
 799    if (val == env->misa_ext) {
 800        return RISCV_EXCP_NONE;
 801    }
 802
 803    if (!(val & RVF)) {
 804        env->mstatus &= ~MSTATUS_FS;
 805    }
 806
 807    /* flush translation cache */
 808    tb_flush(env_cpu(env));
 809    env->misa_ext = val;
 810    env->xl = riscv_cpu_mxl(env);
 811    return RISCV_EXCP_NONE;
 812}
 813
 814static RISCVException read_medeleg(CPURISCVState *env, int csrno,
 815                                   target_ulong *val)
 816{
 817    *val = env->medeleg;
 818    return RISCV_EXCP_NONE;
 819}
 820
 821static RISCVException write_medeleg(CPURISCVState *env, int csrno,
 822                                    target_ulong val)
 823{
 824    env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
 825    return RISCV_EXCP_NONE;
 826}
 827
 828static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
 829                                    uint64_t *ret_val,
 830                                    uint64_t new_val, uint64_t wr_mask)
 831{
 832    uint64_t mask = wr_mask & delegable_ints;
 833
 834    if (ret_val) {
 835        *ret_val = env->mideleg;
 836    }
 837
 838    env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
 839
 840    if (riscv_has_ext(env, RVH)) {
 841        env->mideleg |= HS_MODE_INTERRUPTS;
 842    }
 843
 844    return RISCV_EXCP_NONE;
 845}
 846
 847static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
 848                                  target_ulong *ret_val,
 849                                  target_ulong new_val, target_ulong wr_mask)
 850{
 851    uint64_t rval;
 852    RISCVException ret;
 853
 854    ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
 855    if (ret_val) {
 856        *ret_val = rval;
 857    }
 858
 859    return ret;
 860}
 861
 862static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
 863                                   target_ulong *ret_val,
 864                                   target_ulong new_val,
 865                                   target_ulong wr_mask)
 866{
 867    uint64_t rval;
 868    RISCVException ret;
 869
 870    ret = rmw_mideleg64(env, csrno, &rval,
 871        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
 872    if (ret_val) {
 873        *ret_val = rval >> 32;
 874    }
 875
 876    return ret;
 877}
 878
 879static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
 880                                uint64_t *ret_val,
 881                                uint64_t new_val, uint64_t wr_mask)
 882{
 883    uint64_t mask = wr_mask & all_ints;
 884
 885    if (ret_val) {
 886        *ret_val = env->mie;
 887    }
 888
 889    env->mie = (env->mie & ~mask) | (new_val & mask);
 890
 891    if (!riscv_has_ext(env, RVH)) {
 892        env->mie &= ~((uint64_t)MIP_SGEIP);
 893    }
 894
 895    return RISCV_EXCP_NONE;
 896}
 897
 898static RISCVException rmw_mie(CPURISCVState *env, int csrno,
 899                              target_ulong *ret_val,
 900                              target_ulong new_val, target_ulong wr_mask)
 901{
 902    uint64_t rval;
 903    RISCVException ret;
 904
 905    ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
 906    if (ret_val) {
 907        *ret_val = rval;
 908    }
 909
 910    return ret;
 911}
 912
 913static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
 914                               target_ulong *ret_val,
 915                               target_ulong new_val, target_ulong wr_mask)
 916{
 917    uint64_t rval;
 918    RISCVException ret;
 919
 920    ret = rmw_mie64(env, csrno, &rval,
 921        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
 922    if (ret_val) {
 923        *ret_val = rval >> 32;
 924    }
 925
 926    return ret;
 927}
 928
 929static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val)
 930{
 931    int irq;
 932    uint8_t iprio;
 933
 934    irq = riscv_cpu_mirq_pending(env);
 935    if (irq <= 0 || irq > 63) {
 936        *val = 0;
 937    } else {
 938        iprio = env->miprio[irq];
 939        if (!iprio) {
 940            if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
 941                iprio = IPRIO_MMAXIPRIO;
 942            }
 943        }
 944        *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
 945        *val |= iprio;
 946    }
 947
 948    return RISCV_EXCP_NONE;
 949}
 950
 951static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
 952{
 953    if (!riscv_cpu_virt_enabled(env)) {
 954        return csrno;
 955    }
 956
 957    switch (csrno) {
 958    case CSR_SISELECT:
 959        return CSR_VSISELECT;
 960    case CSR_SIREG:
 961        return CSR_VSIREG;
 962    case CSR_SSETEIPNUM:
 963        return CSR_VSSETEIPNUM;
 964    case CSR_SCLREIPNUM:
 965        return CSR_VSCLREIPNUM;
 966    case CSR_SSETEIENUM:
 967        return CSR_VSSETEIENUM;
 968    case CSR_SCLREIENUM:
 969        return CSR_VSCLREIENUM;
 970    case CSR_STOPEI:
 971        return CSR_VSTOPEI;
 972    default:
 973        return csrno;
 974    };
 975}
 976
 977static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
 978                        target_ulong new_val, target_ulong wr_mask)
 979{
 980    target_ulong *iselect;
 981
 982    /* Translate CSR number for VS-mode */
 983    csrno = aia_xlate_vs_csrno(env, csrno);
 984
 985    /* Find the iselect CSR based on CSR number */
 986    switch (csrno) {
 987    case CSR_MISELECT:
 988        iselect = &env->miselect;
 989        break;
 990    case CSR_SISELECT:
 991        iselect = &env->siselect;
 992        break;
 993    case CSR_VSISELECT:
 994        iselect = &env->vsiselect;
 995        break;
 996    default:
 997         return RISCV_EXCP_ILLEGAL_INST;
 998    };
 999
1000    if (val) {
1001        *val = *iselect;
1002    }
1003
1004    wr_mask &= ISELECT_MASK;
1005    if (wr_mask) {
1006        *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
1007    }
1008
1009    return RISCV_EXCP_NONE;
1010}
1011
1012static int rmw_iprio(target_ulong xlen,
1013                     target_ulong iselect, uint8_t *iprio,
1014                     target_ulong *val, target_ulong new_val,
1015                     target_ulong wr_mask, int ext_irq_no)
1016{
1017    int i, firq, nirqs;
1018    target_ulong old_val;
1019
1020    if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
1021        return -EINVAL;
1022    }
1023    if (xlen != 32 && iselect & 0x1) {
1024        return -EINVAL;
1025    }
1026
1027    nirqs = 4 * (xlen / 32);
1028    firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
1029
1030    old_val = 0;
1031    for (i = 0; i < nirqs; i++) {
1032        old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
1033    }
1034
1035    if (val) {
1036        *val = old_val;
1037    }
1038
1039    if (wr_mask) {
1040        new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
1041        for (i = 0; i < nirqs; i++) {
1042            /*
1043             * M-level and S-level external IRQ priority always read-only
1044             * zero. This means default priority order is always preferred
1045             * for M-level and S-level external IRQs.
1046             */
1047            if ((firq + i) == ext_irq_no) {
1048                continue;
1049            }
1050            iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
1051        }
1052    }
1053
1054    return 0;
1055}
1056
1057static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
1058                     target_ulong new_val, target_ulong wr_mask)
1059{
1060    bool virt;
1061    uint8_t *iprio;
1062    int ret = -EINVAL;
1063    target_ulong priv, isel, vgein;
1064
1065    /* Translate CSR number for VS-mode */
1066    csrno = aia_xlate_vs_csrno(env, csrno);
1067
1068    /* Decode register details from CSR number */
1069    virt = false;
1070    switch (csrno) {
1071    case CSR_MIREG:
1072        iprio = env->miprio;
1073        isel = env->miselect;
1074        priv = PRV_M;
1075        break;
1076    case CSR_SIREG:
1077        iprio = env->siprio;
1078        isel = env->siselect;
1079        priv = PRV_S;
1080        break;
1081    case CSR_VSIREG:
1082        iprio = env->hviprio;
1083        isel = env->vsiselect;
1084        priv = PRV_S;
1085        virt = true;
1086        break;
1087    default:
1088         goto done;
1089    };
1090
1091    /* Find the selected guest interrupt file */
1092    vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1093
1094    if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
1095        /* Local interrupt priority registers not available for VS-mode */
1096        if (!virt) {
1097            ret = rmw_iprio(riscv_cpu_mxl_bits(env),
1098                            isel, iprio, val, new_val, wr_mask,
1099                            (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
1100        }
1101    } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
1102        /* IMSIC registers only available when machine implements it. */
1103        if (env->aia_ireg_rmw_fn[priv]) {
1104            /* Selected guest interrupt file should not be zero */
1105            if (virt && (!vgein || env->geilen < vgein)) {
1106                goto done;
1107            }
1108            /* Call machine specific IMSIC register emulation */
1109            ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1110                                    AIA_MAKE_IREG(isel, priv, virt, vgein,
1111                                                  riscv_cpu_mxl_bits(env)),
1112                                    val, new_val, wr_mask);
1113        }
1114    }
1115
1116done:
1117    if (ret) {
1118        return (riscv_cpu_virt_enabled(env) && virt) ?
1119               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1120    }
1121    return RISCV_EXCP_NONE;
1122}
1123
1124static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong *val,
1125                            target_ulong new_val, target_ulong wr_mask)
1126{
1127    int ret = -EINVAL;
1128    bool set, pend, virt;
1129    target_ulong priv, isel, vgein, xlen, nval, wmask;
1130
1131    /* Translate CSR number for VS-mode */
1132    csrno = aia_xlate_vs_csrno(env, csrno);
1133
1134    /* Decode register details from CSR number */
1135    virt = set = pend = false;
1136    switch (csrno) {
1137    case CSR_MSETEIPNUM:
1138        priv = PRV_M;
1139        set = true;
1140        pend = true;
1141        break;
1142    case CSR_MCLREIPNUM:
1143        priv = PRV_M;
1144        pend = true;
1145        break;
1146    case CSR_MSETEIENUM:
1147        priv = PRV_M;
1148        set = true;
1149        break;
1150    case CSR_MCLREIENUM:
1151        priv = PRV_M;
1152        break;
1153    case CSR_SSETEIPNUM:
1154        priv = PRV_S;
1155        set = true;
1156        pend = true;
1157        break;
1158    case CSR_SCLREIPNUM:
1159        priv = PRV_S;
1160        pend = true;
1161        break;
1162    case CSR_SSETEIENUM:
1163        priv = PRV_S;
1164        set = true;
1165        break;
1166    case CSR_SCLREIENUM:
1167        priv = PRV_S;
1168        break;
1169    case CSR_VSSETEIPNUM:
1170        priv = PRV_S;
1171        virt = true;
1172        set = true;
1173        pend = true;
1174        break;
1175    case CSR_VSCLREIPNUM:
1176        priv = PRV_S;
1177        virt = true;
1178        pend = true;
1179        break;
1180    case CSR_VSSETEIENUM:
1181        priv = PRV_S;
1182        virt = true;
1183        set = true;
1184        break;
1185    case CSR_VSCLREIENUM:
1186        priv = PRV_S;
1187        virt = true;
1188        break;
1189    default:
1190         goto done;
1191    };
1192
1193    /* IMSIC CSRs only available when machine implements IMSIC. */
1194    if (!env->aia_ireg_rmw_fn[priv]) {
1195        goto done;
1196    }
1197
1198    /* Find the selected guest interrupt file */
1199    vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1200
1201    /* Selected guest interrupt file should be valid */
1202    if (virt && (!vgein || env->geilen < vgein)) {
1203        goto done;
1204    }
1205
1206    /* Set/Clear CSRs always read zero */
1207    if (val) {
1208        *val = 0;
1209    }
1210
1211    if (wr_mask) {
1212        /* Get interrupt number */
1213        new_val &= wr_mask;
1214
1215        /* Find target interrupt pending/enable register */
1216        xlen = riscv_cpu_mxl_bits(env);
1217        isel = (new_val / xlen);
1218        isel *= (xlen / IMSIC_EIPx_BITS);
1219        isel += (pend) ? ISELECT_IMSIC_EIP0 : ISELECT_IMSIC_EIE0;
1220
1221        /* Find the interrupt bit to be set/clear */
1222        wmask = ((target_ulong)1) << (new_val % xlen);
1223        nval = (set) ? wmask : 0;
1224
1225        /* Call machine specific IMSIC register emulation */
1226        ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1227                                         AIA_MAKE_IREG(isel, priv, virt,
1228                                                       vgein, xlen),
1229                                         NULL, nval, wmask);
1230    } else {
1231        ret = 0;
1232    }
1233
1234done:
1235    if (ret) {
1236        return (riscv_cpu_virt_enabled(env) && virt) ?
1237               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1238    }
1239    return RISCV_EXCP_NONE;
1240}
1241
1242static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
1243                      target_ulong new_val, target_ulong wr_mask)
1244{
1245    bool virt;
1246    int ret = -EINVAL;
1247    target_ulong priv, vgein;
1248
1249    /* Translate CSR number for VS-mode */
1250    csrno = aia_xlate_vs_csrno(env, csrno);
1251
1252    /* Decode register details from CSR number */
1253    virt = false;
1254    switch (csrno) {
1255    case CSR_MTOPEI:
1256        priv = PRV_M;
1257        break;
1258    case CSR_STOPEI:
1259        priv = PRV_S;
1260        break;
1261    case CSR_VSTOPEI:
1262        priv = PRV_S;
1263        virt = true;
1264        break;
1265    default:
1266        goto done;
1267    };
1268
1269    /* IMSIC CSRs only available when machine implements IMSIC. */
1270    if (!env->aia_ireg_rmw_fn[priv]) {
1271        goto done;
1272    }
1273
1274    /* Find the selected guest interrupt file */
1275    vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1276
1277    /* Selected guest interrupt file should be valid */
1278    if (virt && (!vgein || env->geilen < vgein)) {
1279        goto done;
1280    }
1281
1282    /* Call machine specific IMSIC register emulation for TOPEI */
1283    ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1284                    AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
1285                                  riscv_cpu_mxl_bits(env)),
1286                    val, new_val, wr_mask);
1287
1288done:
1289    if (ret) {
1290        return (riscv_cpu_virt_enabled(env) && virt) ?
1291               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1292    }
1293    return RISCV_EXCP_NONE;
1294}
1295
1296static RISCVException read_mtvec(CPURISCVState *env, int csrno,
1297                                 target_ulong *val)
1298{
1299    *val = env->mtvec;
1300    return RISCV_EXCP_NONE;
1301}
1302
1303static RISCVException write_mtvec(CPURISCVState *env, int csrno,
1304                                  target_ulong val)
1305{
1306    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
1307    if ((val & 3) < 2) {
1308        env->mtvec = val;
1309    } else {
1310        qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
1311    }
1312    return RISCV_EXCP_NONE;
1313}
1314
1315static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
1316                                      target_ulong *val)
1317{
1318    *val = env->mcounteren;
1319    return RISCV_EXCP_NONE;
1320}
1321
1322static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
1323                                       target_ulong val)
1324{
1325    env->mcounteren = val;
1326    return RISCV_EXCP_NONE;
1327}
1328
1329/* Machine Trap Handling */
1330static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
1331                                         Int128 *val)
1332{
1333    *val = int128_make128(env->mscratch, env->mscratchh);
1334    return RISCV_EXCP_NONE;
1335}
1336
1337static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
1338                                          Int128 val)
1339{
1340    env->mscratch = int128_getlo(val);
1341    env->mscratchh = int128_gethi(val);
1342    return RISCV_EXCP_NONE;
1343}
1344
1345static RISCVException read_mscratch(CPURISCVState *env, int csrno,
1346                                    target_ulong *val)
1347{
1348    *val = env->mscratch;
1349    return RISCV_EXCP_NONE;
1350}
1351
1352static RISCVException write_mscratch(CPURISCVState *env, int csrno,
1353                                     target_ulong val)
1354{
1355    env->mscratch = val;
1356    return RISCV_EXCP_NONE;
1357}
1358
1359static RISCVException read_mepc(CPURISCVState *env, int csrno,
1360                                     target_ulong *val)
1361{
1362    *val = env->mepc;
1363    return RISCV_EXCP_NONE;
1364}
1365
1366static RISCVException write_mepc(CPURISCVState *env, int csrno,
1367                                     target_ulong val)
1368{
1369    env->mepc = val;
1370    return RISCV_EXCP_NONE;
1371}
1372
1373static RISCVException read_mcause(CPURISCVState *env, int csrno,
1374                                     target_ulong *val)
1375{
1376    *val = env->mcause;
1377    return RISCV_EXCP_NONE;
1378}
1379
1380static RISCVException write_mcause(CPURISCVState *env, int csrno,
1381                                     target_ulong val)
1382{
1383    env->mcause = val;
1384    return RISCV_EXCP_NONE;
1385}
1386
1387static RISCVException read_mtval(CPURISCVState *env, int csrno,
1388                                 target_ulong *val)
1389{
1390    *val = env->mtval;
1391    return RISCV_EXCP_NONE;
1392}
1393
1394static RISCVException write_mtval(CPURISCVState *env, int csrno,
1395                                  target_ulong val)
1396{
1397    env->mtval = val;
1398    return RISCV_EXCP_NONE;
1399}
1400
1401static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
1402                                uint64_t *ret_val,
1403                                uint64_t new_val, uint64_t wr_mask)
1404{
1405    RISCVCPU *cpu = env_archcpu(env);
1406    /* Allow software control of delegable interrupts not claimed by hardware */
1407    uint64_t old_mip, mask = wr_mask & delegable_ints & ~env->miclaim;
1408    uint32_t gin;
1409
1410    if (mask) {
1411        old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
1412    } else {
1413        old_mip = env->mip;
1414    }
1415
1416    if (csrno != CSR_HVIP) {
1417        gin = get_field(env->hstatus, HSTATUS_VGEIN);
1418        old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
1419    }
1420
1421    if (ret_val) {
1422        *ret_val = old_mip;
1423    }
1424
1425    return RISCV_EXCP_NONE;
1426}
1427
1428static RISCVException rmw_mip(CPURISCVState *env, int csrno,
1429                              target_ulong *ret_val,
1430                              target_ulong new_val, target_ulong wr_mask)
1431{
1432    uint64_t rval;
1433    RISCVException ret;
1434
1435    ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
1436    if (ret_val) {
1437        *ret_val = rval;
1438    }
1439
1440    return ret;
1441}
1442
1443static RISCVException rmw_miph(CPURISCVState *env, int csrno,
1444                               target_ulong *ret_val,
1445                               target_ulong new_val, target_ulong wr_mask)
1446{
1447    uint64_t rval;
1448    RISCVException ret;
1449
1450    ret = rmw_mip64(env, csrno, &rval,
1451        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1452    if (ret_val) {
1453        *ret_val = rval >> 32;
1454    }
1455
1456    return ret;
1457}
1458
1459/* Supervisor Trap Setup */
1460static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
1461                                        Int128 *val)
1462{
1463    uint64_t mask = sstatus_v1_10_mask;
1464    uint64_t sstatus = env->mstatus & mask;
1465    if (env->xl != MXL_RV32 || env->debugger) {
1466        mask |= SSTATUS64_UXL;
1467    }
1468
1469    *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
1470    return RISCV_EXCP_NONE;
1471}
1472
1473static RISCVException read_sstatus(CPURISCVState *env, int csrno,
1474                                   target_ulong *val)
1475{
1476    target_ulong mask = (sstatus_v1_10_mask);
1477    if (env->xl != MXL_RV32 || env->debugger) {
1478        mask |= SSTATUS64_UXL;
1479    }
1480    /* TODO: Use SXL not MXL. */
1481    *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
1482    return RISCV_EXCP_NONE;
1483}
1484
1485static RISCVException write_sstatus(CPURISCVState *env, int csrno,
1486                                    target_ulong val)
1487{
1488    target_ulong mask = (sstatus_v1_10_mask);
1489
1490    if (env->xl != MXL_RV32 || env->debugger) {
1491        if ((val & SSTATUS64_UXL) != 0) {
1492            mask |= SSTATUS64_UXL;
1493        }
1494    }
1495    target_ulong newval = (env->mstatus & ~mask) | (val & mask);
1496    return write_mstatus(env, CSR_MSTATUS, newval);
1497}
1498
1499static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
1500                                 uint64_t *ret_val,
1501                                 uint64_t new_val, uint64_t wr_mask)
1502{
1503    RISCVException ret;
1504    uint64_t rval, vsbits, mask = env->hideleg & VS_MODE_INTERRUPTS;
1505
1506    /* Bring VS-level bits to correct position */
1507    vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1508    new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1509    new_val |= vsbits << 1;
1510    vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1511    wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1512    wr_mask |= vsbits << 1;
1513
1514    ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
1515    if (ret_val) {
1516        rval &= mask;
1517        vsbits = rval & VS_MODE_INTERRUPTS;
1518        rval &= ~VS_MODE_INTERRUPTS;
1519        *ret_val = rval | (vsbits >> 1);
1520    }
1521
1522    return ret;
1523}
1524
1525static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
1526                               target_ulong *ret_val,
1527                               target_ulong new_val, target_ulong wr_mask)
1528{
1529    uint64_t rval;
1530    RISCVException ret;
1531
1532    ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
1533    if (ret_val) {
1534        *ret_val = rval;
1535    }
1536
1537    return ret;
1538}
1539
1540static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
1541                                target_ulong *ret_val,
1542                                target_ulong new_val, target_ulong wr_mask)
1543{
1544    uint64_t rval;
1545    RISCVException ret;
1546
1547    ret = rmw_vsie64(env, csrno, &rval,
1548        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1549    if (ret_val) {
1550        *ret_val = rval >> 32;
1551    }
1552
1553    return ret;
1554}
1555
1556static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
1557                                uint64_t *ret_val,
1558                                uint64_t new_val, uint64_t wr_mask)
1559{
1560    RISCVException ret;
1561    uint64_t mask = env->mideleg & S_MODE_INTERRUPTS;
1562
1563    if (riscv_cpu_virt_enabled(env)) {
1564        if (env->hvictl & HVICTL_VTI) {
1565            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1566        }
1567        ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
1568    } else {
1569        ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask);
1570    }
1571
1572    if (ret_val) {
1573        *ret_val &= mask;
1574    }
1575
1576    return ret;
1577}
1578
1579static RISCVException rmw_sie(CPURISCVState *env, int csrno,
1580                              target_ulong *ret_val,
1581                              target_ulong new_val, target_ulong wr_mask)
1582{
1583    uint64_t rval;
1584    RISCVException ret;
1585
1586    ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
1587    if (ret == RISCV_EXCP_NONE && ret_val) {
1588        *ret_val = rval;
1589    }
1590
1591    return ret;
1592}
1593
1594static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
1595                               target_ulong *ret_val,
1596                               target_ulong new_val, target_ulong wr_mask)
1597{
1598    uint64_t rval;
1599    RISCVException ret;
1600
1601    ret = rmw_sie64(env, csrno, &rval,
1602        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1603    if (ret_val) {
1604        *ret_val = rval >> 32;
1605    }
1606
1607    return ret;
1608}
1609
1610static RISCVException read_stvec(CPURISCVState *env, int csrno,
1611                                 target_ulong *val)
1612{
1613    *val = env->stvec;
1614    return RISCV_EXCP_NONE;
1615}
1616
1617static RISCVException write_stvec(CPURISCVState *env, int csrno,
1618                                  target_ulong val)
1619{
1620    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
1621    if ((val & 3) < 2) {
1622        env->stvec = val;
1623    } else {
1624        qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
1625    }
1626    return RISCV_EXCP_NONE;
1627}
1628
1629static RISCVException read_scounteren(CPURISCVState *env, int csrno,
1630                                      target_ulong *val)
1631{
1632    *val = env->scounteren;
1633    return RISCV_EXCP_NONE;
1634}
1635
1636static RISCVException write_scounteren(CPURISCVState *env, int csrno,
1637                                       target_ulong val)
1638{
1639    env->scounteren = val;
1640    return RISCV_EXCP_NONE;
1641}
1642
1643/* Supervisor Trap Handling */
1644static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
1645                                         Int128 *val)
1646{
1647    *val = int128_make128(env->sscratch, env->sscratchh);
1648    return RISCV_EXCP_NONE;
1649}
1650
1651static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
1652                                          Int128 val)
1653{
1654    env->sscratch = int128_getlo(val);
1655    env->sscratchh = int128_gethi(val);
1656    return RISCV_EXCP_NONE;
1657}
1658
1659static RISCVException read_sscratch(CPURISCVState *env, int csrno,
1660                                    target_ulong *val)
1661{
1662    *val = env->sscratch;
1663    return RISCV_EXCP_NONE;
1664}
1665
1666static RISCVException write_sscratch(CPURISCVState *env, int csrno,
1667                                     target_ulong val)
1668{
1669    env->sscratch = val;
1670    return RISCV_EXCP_NONE;
1671}
1672
1673static RISCVException read_sepc(CPURISCVState *env, int csrno,
1674                                target_ulong *val)
1675{
1676    *val = env->sepc;
1677    return RISCV_EXCP_NONE;
1678}
1679
1680static RISCVException write_sepc(CPURISCVState *env, int csrno,
1681                                 target_ulong val)
1682{
1683    env->sepc = val;
1684    return RISCV_EXCP_NONE;
1685}
1686
1687static RISCVException read_scause(CPURISCVState *env, int csrno,
1688                                  target_ulong *val)
1689{
1690    *val = env->scause;
1691    return RISCV_EXCP_NONE;
1692}
1693
1694static RISCVException write_scause(CPURISCVState *env, int csrno,
1695                                   target_ulong val)
1696{
1697    env->scause = val;
1698    return RISCV_EXCP_NONE;
1699}
1700
1701static RISCVException read_stval(CPURISCVState *env, int csrno,
1702                                 target_ulong *val)
1703{
1704    *val = env->stval;
1705    return RISCV_EXCP_NONE;
1706}
1707
1708static RISCVException write_stval(CPURISCVState *env, int csrno,
1709                                  target_ulong val)
1710{
1711    env->stval = val;
1712    return RISCV_EXCP_NONE;
1713}
1714
1715static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
1716                                 uint64_t *ret_val,
1717                                 uint64_t new_val, uint64_t wr_mask)
1718{
1719    RISCVException ret;
1720    uint64_t rval, vsbits, mask = env->hideleg & vsip_writable_mask;
1721
1722    /* Bring VS-level bits to correct position */
1723    vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1724    new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1725    new_val |= vsbits << 1;
1726    vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1727    wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1728    wr_mask |= vsbits << 1;
1729
1730    ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask & mask);
1731    if (ret_val) {
1732        rval &= mask;
1733        vsbits = rval & VS_MODE_INTERRUPTS;
1734        rval &= ~VS_MODE_INTERRUPTS;
1735        *ret_val = rval | (vsbits >> 1);
1736    }
1737
1738    return ret;
1739}
1740
1741static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
1742                               target_ulong *ret_val,
1743                               target_ulong new_val, target_ulong wr_mask)
1744{
1745    uint64_t rval;
1746    RISCVException ret;
1747
1748    ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
1749    if (ret_val) {
1750        *ret_val = rval;
1751    }
1752
1753    return ret;
1754}
1755
1756static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
1757                                target_ulong *ret_val,
1758                                target_ulong new_val, target_ulong wr_mask)
1759{
1760    uint64_t rval;
1761    RISCVException ret;
1762
1763    ret = rmw_vsip64(env, csrno, &rval,
1764        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1765    if (ret_val) {
1766        *ret_val = rval >> 32;
1767    }
1768
1769    return ret;
1770}
1771
1772static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
1773                                uint64_t *ret_val,
1774                                uint64_t new_val, uint64_t wr_mask)
1775{
1776    RISCVException ret;
1777    uint64_t mask = env->mideleg & sip_writable_mask;
1778
1779    if (riscv_cpu_virt_enabled(env)) {
1780        if (env->hvictl & HVICTL_VTI) {
1781            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
1782        }
1783        ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
1784    } else {
1785        ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask);
1786    }
1787
1788    if (ret_val) {
1789        *ret_val &= env->mideleg & S_MODE_INTERRUPTS;
1790    }
1791
1792    return ret;
1793}
1794
1795static RISCVException rmw_sip(CPURISCVState *env, int csrno,
1796                              target_ulong *ret_val,
1797                              target_ulong new_val, target_ulong wr_mask)
1798{
1799    uint64_t rval;
1800    RISCVException ret;
1801
1802    ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
1803    if (ret_val) {
1804        *ret_val = rval;
1805    }
1806
1807    return ret;
1808}
1809
1810static RISCVException rmw_siph(CPURISCVState *env, int csrno,
1811                               target_ulong *ret_val,
1812                               target_ulong new_val, target_ulong wr_mask)
1813{
1814    uint64_t rval;
1815    RISCVException ret;
1816
1817    ret = rmw_sip64(env, csrno, &rval,
1818        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1819    if (ret_val) {
1820        *ret_val = rval >> 32;
1821    }
1822
1823    return ret;
1824}
1825
1826/* Supervisor Protection and Translation */
1827static RISCVException read_satp(CPURISCVState *env, int csrno,
1828                                target_ulong *val)
1829{
1830    if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
1831        *val = 0;
1832        return RISCV_EXCP_NONE;
1833    }
1834
1835    if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
1836        return RISCV_EXCP_ILLEGAL_INST;
1837    } else {
1838        *val = env->satp;
1839    }
1840
1841    return RISCV_EXCP_NONE;
1842}
1843
1844static RISCVException write_satp(CPURISCVState *env, int csrno,
1845                                 target_ulong val)
1846{
1847    target_ulong vm, mask;
1848
1849    if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
1850        return RISCV_EXCP_NONE;
1851    }
1852
1853    if (riscv_cpu_mxl(env) == MXL_RV32) {
1854        vm = validate_vm(env, get_field(val, SATP32_MODE));
1855        mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
1856    } else {
1857        vm = validate_vm(env, get_field(val, SATP64_MODE));
1858        mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
1859    }
1860
1861    if (vm && mask) {
1862        if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
1863            return RISCV_EXCP_ILLEGAL_INST;
1864        } else {
1865            /*
1866             * The ISA defines SATP.MODE=Bare as "no translation", but we still
1867             * pass these through QEMU's TLB emulation as it improves
1868             * performance.  Flushing the TLB on SATP writes with paging
1869             * enabled avoids leaking those invalid cached mappings.
1870             */
1871            tlb_flush(env_cpu(env));
1872            env->satp = val;
1873        }
1874    }
1875    return RISCV_EXCP_NONE;
1876}
1877
1878static int read_vstopi(CPURISCVState *env, int csrno, target_ulong *val)
1879{
1880    int irq, ret;
1881    target_ulong topei;
1882    uint64_t vseip, vsgein;
1883    uint32_t iid, iprio, hviid, hviprio, gein;
1884    uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
1885
1886    gein = get_field(env->hstatus, HSTATUS_VGEIN);
1887    hviid = get_field(env->hvictl, HVICTL_IID);
1888    hviprio = get_field(env->hvictl, HVICTL_IPRIO);
1889
1890    if (gein) {
1891        vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
1892        vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
1893        if (gein <= env->geilen && vseip) {
1894            siid[scount] = IRQ_S_EXT;
1895            siprio[scount] = IPRIO_MMAXIPRIO + 1;
1896            if (env->aia_ireg_rmw_fn[PRV_S]) {
1897                /*
1898                 * Call machine specific IMSIC register emulation for
1899                 * reading TOPEI.
1900                 */
1901                ret = env->aia_ireg_rmw_fn[PRV_S](
1902                        env->aia_ireg_rmw_fn_arg[PRV_S],
1903                        AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
1904                                      riscv_cpu_mxl_bits(env)),
1905                        &topei, 0, 0);
1906                if (!ret && topei) {
1907                    siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
1908                }
1909            }
1910            scount++;
1911        }
1912    } else {
1913        if (hviid == IRQ_S_EXT && hviprio) {
1914            siid[scount] = IRQ_S_EXT;
1915            siprio[scount] = hviprio;
1916            scount++;
1917        }
1918    }
1919
1920    if (env->hvictl & HVICTL_VTI) {
1921        if (hviid != IRQ_S_EXT) {
1922            siid[scount] = hviid;
1923            siprio[scount] = hviprio;
1924            scount++;
1925        }
1926    } else {
1927        irq = riscv_cpu_vsirq_pending(env);
1928        if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
1929            siid[scount] = irq;
1930            siprio[scount] = env->hviprio[irq];
1931            scount++;
1932        }
1933    }
1934
1935    iid = 0;
1936    iprio = UINT_MAX;
1937    for (s = 0; s < scount; s++) {
1938        if (siprio[s] < iprio) {
1939            iid = siid[s];
1940            iprio = siprio[s];
1941        }
1942    }
1943
1944    if (iid) {
1945        if (env->hvictl & HVICTL_IPRIOM) {
1946            if (iprio > IPRIO_MMAXIPRIO) {
1947                iprio = IPRIO_MMAXIPRIO;
1948            }
1949            if (!iprio) {
1950                if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
1951                    iprio = IPRIO_MMAXIPRIO;
1952                }
1953            }
1954        } else {
1955            iprio = 1;
1956        }
1957    } else {
1958        iprio = 0;
1959    }
1960
1961    *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
1962    *val |= iprio;
1963    return RISCV_EXCP_NONE;
1964}
1965
1966static int read_stopi(CPURISCVState *env, int csrno, target_ulong *val)
1967{
1968    int irq;
1969    uint8_t iprio;
1970
1971    if (riscv_cpu_virt_enabled(env)) {
1972        return read_vstopi(env, CSR_VSTOPI, val);
1973    }
1974
1975    irq = riscv_cpu_sirq_pending(env);
1976    if (irq <= 0 || irq > 63) {
1977        *val = 0;
1978    } else {
1979        iprio = env->siprio[irq];
1980        if (!iprio) {
1981            if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
1982                iprio = IPRIO_MMAXIPRIO;
1983           }
1984        }
1985        *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
1986        *val |= iprio;
1987    }
1988
1989    return RISCV_EXCP_NONE;
1990}
1991
1992/* Hypervisor Extensions */
1993static RISCVException read_hstatus(CPURISCVState *env, int csrno,
1994                                   target_ulong *val)
1995{
1996    *val = env->hstatus;
1997    if (riscv_cpu_mxl(env) != MXL_RV32) {
1998        /* We only support 64-bit VSXL */
1999        *val = set_field(*val, HSTATUS_VSXL, 2);
2000    }
2001    /* We only support little endian */
2002    *val = set_field(*val, HSTATUS_VSBE, 0);
2003    return RISCV_EXCP_NONE;
2004}
2005
2006static RISCVException write_hstatus(CPURISCVState *env, int csrno,
2007                                    target_ulong val)
2008{
2009    env->hstatus = val;
2010    if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
2011        qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
2012    }
2013    if (get_field(val, HSTATUS_VSBE) != 0) {
2014        qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
2015    }
2016    return RISCV_EXCP_NONE;
2017}
2018
2019static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
2020                                   target_ulong *val)
2021{
2022    *val = env->hedeleg;
2023    return RISCV_EXCP_NONE;
2024}
2025
2026static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
2027                                    target_ulong val)
2028{
2029    env->hedeleg = val & vs_delegable_excps;
2030    return RISCV_EXCP_NONE;
2031}
2032
2033static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
2034                                    uint64_t *ret_val,
2035                                    uint64_t new_val, uint64_t wr_mask)
2036{
2037    uint64_t mask = wr_mask & vs_delegable_ints;
2038
2039    if (ret_val) {
2040        *ret_val = env->hideleg & vs_delegable_ints;
2041    }
2042
2043    env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
2044    return RISCV_EXCP_NONE;
2045}
2046
2047static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
2048                                  target_ulong *ret_val,
2049                                  target_ulong new_val, target_ulong wr_mask)
2050{
2051    uint64_t rval;
2052    RISCVException ret;
2053
2054    ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
2055    if (ret_val) {
2056        *ret_val = rval;
2057    }
2058
2059    return ret;
2060}
2061
2062static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
2063                                   target_ulong *ret_val,
2064                                   target_ulong new_val, target_ulong wr_mask)
2065{
2066    uint64_t rval;
2067    RISCVException ret;
2068
2069    ret = rmw_hideleg64(env, csrno, &rval,
2070        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2071    if (ret_val) {
2072        *ret_val = rval >> 32;
2073    }
2074
2075    return ret;
2076}
2077
2078static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
2079                                 uint64_t *ret_val,
2080                                 uint64_t new_val, uint64_t wr_mask)
2081{
2082    RISCVException ret;
2083
2084    ret = rmw_mip64(env, csrno, ret_val, new_val,
2085                    wr_mask & hvip_writable_mask);
2086    if (ret_val) {
2087        *ret_val &= VS_MODE_INTERRUPTS;
2088    }
2089
2090    return ret;
2091}
2092
2093static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
2094                               target_ulong *ret_val,
2095                               target_ulong new_val, target_ulong wr_mask)
2096{
2097    uint64_t rval;
2098    RISCVException ret;
2099
2100    ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
2101    if (ret_val) {
2102        *ret_val = rval;
2103    }
2104
2105    return ret;
2106}
2107
2108static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
2109                                target_ulong *ret_val,
2110                                target_ulong new_val, target_ulong wr_mask)
2111{
2112    uint64_t rval;
2113    RISCVException ret;
2114
2115    ret = rmw_hvip64(env, csrno, &rval,
2116        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2117    if (ret_val) {
2118        *ret_val = rval >> 32;
2119    }
2120
2121    return ret;
2122}
2123
2124static RISCVException rmw_hip(CPURISCVState *env, int csrno,
2125                              target_ulong *ret_value,
2126                              target_ulong new_value, target_ulong write_mask)
2127{
2128    int ret = rmw_mip(env, csrno, ret_value, new_value,
2129                      write_mask & hip_writable_mask);
2130
2131    if (ret_value) {
2132        *ret_value &= HS_MODE_INTERRUPTS;
2133    }
2134    return ret;
2135}
2136
2137static RISCVException rmw_hie(CPURISCVState *env, int csrno,
2138                              target_ulong *ret_val,
2139                              target_ulong new_val, target_ulong wr_mask)
2140{
2141    uint64_t rval;
2142    RISCVException ret;
2143
2144    ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
2145    if (ret_val) {
2146        *ret_val = rval & HS_MODE_INTERRUPTS;
2147    }
2148
2149    return ret;
2150}
2151
2152static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
2153                                      target_ulong *val)
2154{
2155    *val = env->hcounteren;
2156    return RISCV_EXCP_NONE;
2157}
2158
2159static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
2160                                       target_ulong val)
2161{
2162    env->hcounteren = val;
2163    return RISCV_EXCP_NONE;
2164}
2165
2166static RISCVException read_hgeie(CPURISCVState *env, int csrno,
2167                                 target_ulong *val)
2168{
2169    if (val) {
2170        *val = env->hgeie;
2171    }
2172    return RISCV_EXCP_NONE;
2173}
2174
2175static RISCVException write_hgeie(CPURISCVState *env, int csrno,
2176                                  target_ulong val)
2177{
2178    /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
2179    val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
2180    env->hgeie = val;
2181    /* Update mip.SGEIP bit */
2182    riscv_cpu_update_mip(env_archcpu(env), MIP_SGEIP,
2183                         BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
2184    return RISCV_EXCP_NONE;
2185}
2186
2187static RISCVException read_htval(CPURISCVState *env, int csrno,
2188                                 target_ulong *val)
2189{
2190    *val = env->htval;
2191    return RISCV_EXCP_NONE;
2192}
2193
2194static RISCVException write_htval(CPURISCVState *env, int csrno,
2195                                  target_ulong val)
2196{
2197    env->htval = val;
2198    return RISCV_EXCP_NONE;
2199}
2200
2201static RISCVException read_htinst(CPURISCVState *env, int csrno,
2202                                  target_ulong *val)
2203{
2204    *val = env->htinst;
2205    return RISCV_EXCP_NONE;
2206}
2207
2208static RISCVException write_htinst(CPURISCVState *env, int csrno,
2209                                   target_ulong val)
2210{
2211    return RISCV_EXCP_NONE;
2212}
2213
2214static RISCVException read_hgeip(CPURISCVState *env, int csrno,
2215                                 target_ulong *val)
2216{
2217    if (val) {
2218        *val = env->hgeip;
2219    }
2220    return RISCV_EXCP_NONE;
2221}
2222
2223static RISCVException read_hgatp(CPURISCVState *env, int csrno,
2224                                 target_ulong *val)
2225{
2226    *val = env->hgatp;
2227    return RISCV_EXCP_NONE;
2228}
2229
2230static RISCVException write_hgatp(CPURISCVState *env, int csrno,
2231                                  target_ulong val)
2232{
2233    env->hgatp = val;
2234    return RISCV_EXCP_NONE;
2235}
2236
2237static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
2238                                      target_ulong *val)
2239{
2240    if (!env->rdtime_fn) {
2241        return RISCV_EXCP_ILLEGAL_INST;
2242    }
2243
2244    *val = env->htimedelta;
2245    return RISCV_EXCP_NONE;
2246}
2247
2248static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
2249                                       target_ulong val)
2250{
2251    if (!env->rdtime_fn) {
2252        return RISCV_EXCP_ILLEGAL_INST;
2253    }
2254
2255    if (riscv_cpu_mxl(env) == MXL_RV32) {
2256        env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
2257    } else {
2258        env->htimedelta = val;
2259    }
2260    return RISCV_EXCP_NONE;
2261}
2262
2263static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
2264                                       target_ulong *val)
2265{
2266    if (!env->rdtime_fn) {
2267        return RISCV_EXCP_ILLEGAL_INST;
2268    }
2269
2270    *val = env->htimedelta >> 32;
2271    return RISCV_EXCP_NONE;
2272}
2273
2274static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
2275                                        target_ulong val)
2276{
2277    if (!env->rdtime_fn) {
2278        return RISCV_EXCP_ILLEGAL_INST;
2279    }
2280
2281    env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
2282    return RISCV_EXCP_NONE;
2283}
2284
2285static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
2286{
2287    *val = env->hvictl;
2288    return RISCV_EXCP_NONE;
2289}
2290
2291static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
2292{
2293    env->hvictl = val & HVICTL_VALID_MASK;
2294    return RISCV_EXCP_NONE;
2295}
2296
2297static int read_hvipriox(CPURISCVState *env, int first_index,
2298                         uint8_t *iprio, target_ulong *val)
2299{
2300    int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
2301
2302    /* First index has to be a multiple of number of irqs per register */
2303    if (first_index % num_irqs) {
2304        return (riscv_cpu_virt_enabled(env)) ?
2305               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2306    }
2307
2308    /* Fill-up return value */
2309    *val = 0;
2310    for (i = 0; i < num_irqs; i++) {
2311        if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
2312            continue;
2313        }
2314        if (rdzero) {
2315            continue;
2316        }
2317        *val |= ((target_ulong)iprio[irq]) << (i * 8);
2318    }
2319
2320    return RISCV_EXCP_NONE;
2321}
2322
2323static int write_hvipriox(CPURISCVState *env, int first_index,
2324                          uint8_t *iprio, target_ulong val)
2325{
2326    int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
2327
2328    /* First index has to be a multiple of number of irqs per register */
2329    if (first_index % num_irqs) {
2330        return (riscv_cpu_virt_enabled(env)) ?
2331               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2332    }
2333
2334    /* Fill-up priority arrary */
2335    for (i = 0; i < num_irqs; i++) {
2336        if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
2337            continue;
2338        }
2339        if (rdzero) {
2340            iprio[irq] = 0;
2341        } else {
2342            iprio[irq] = (val >> (i * 8)) & 0xff;
2343        }
2344    }
2345
2346    return RISCV_EXCP_NONE;
2347}
2348
2349static int read_hviprio1(CPURISCVState *env, int csrno, target_ulong *val)
2350{
2351    return read_hvipriox(env, 0, env->hviprio, val);
2352}
2353
2354static int write_hviprio1(CPURISCVState *env, int csrno, target_ulong val)
2355{
2356    return write_hvipriox(env, 0, env->hviprio, val);
2357}
2358
2359static int read_hviprio1h(CPURISCVState *env, int csrno, target_ulong *val)
2360{
2361    return read_hvipriox(env, 4, env->hviprio, val);
2362}
2363
2364static int write_hviprio1h(CPURISCVState *env, int csrno, target_ulong val)
2365{
2366    return write_hvipriox(env, 4, env->hviprio, val);
2367}
2368
2369static int read_hviprio2(CPURISCVState *env, int csrno, target_ulong *val)
2370{
2371    return read_hvipriox(env, 8, env->hviprio, val);
2372}
2373
2374static int write_hviprio2(CPURISCVState *env, int csrno, target_ulong val)
2375{
2376    return write_hvipriox(env, 8, env->hviprio, val);
2377}
2378
2379static int read_hviprio2h(CPURISCVState *env, int csrno, target_ulong *val)
2380{
2381    return read_hvipriox(env, 12, env->hviprio, val);
2382}
2383
2384static int write_hviprio2h(CPURISCVState *env, int csrno, target_ulong val)
2385{
2386    return write_hvipriox(env, 12, env->hviprio, val);
2387}
2388
2389/* Virtual CSR Registers */
2390static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
2391                                    target_ulong *val)
2392{
2393    *val = env->vsstatus;
2394    return RISCV_EXCP_NONE;
2395}
2396
2397static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
2398                                     target_ulong val)
2399{
2400    uint64_t mask = (target_ulong)-1;
2401    if ((val & VSSTATUS64_UXL) == 0) {
2402        mask &= ~VSSTATUS64_UXL;
2403    }
2404    env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
2405    return RISCV_EXCP_NONE;
2406}
2407
2408static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
2409{
2410    *val = env->vstvec;
2411    return RISCV_EXCP_NONE;
2412}
2413
2414static RISCVException write_vstvec(CPURISCVState *env, int csrno,
2415                                   target_ulong val)
2416{
2417    env->vstvec = val;
2418    return RISCV_EXCP_NONE;
2419}
2420
2421static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
2422                                     target_ulong *val)
2423{
2424    *val = env->vsscratch;
2425    return RISCV_EXCP_NONE;
2426}
2427
2428static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
2429                                      target_ulong val)
2430{
2431    env->vsscratch = val;
2432    return RISCV_EXCP_NONE;
2433}
2434
2435static RISCVException read_vsepc(CPURISCVState *env, int csrno,
2436                                 target_ulong *val)
2437{
2438    *val = env->vsepc;
2439    return RISCV_EXCP_NONE;
2440}
2441
2442static RISCVException write_vsepc(CPURISCVState *env, int csrno,
2443                                  target_ulong val)
2444{
2445    env->vsepc = val;
2446    return RISCV_EXCP_NONE;
2447}
2448
2449static RISCVException read_vscause(CPURISCVState *env, int csrno,
2450                                   target_ulong *val)
2451{
2452    *val = env->vscause;
2453    return RISCV_EXCP_NONE;
2454}
2455
2456static RISCVException write_vscause(CPURISCVState *env, int csrno,
2457                                    target_ulong val)
2458{
2459    env->vscause = val;
2460    return RISCV_EXCP_NONE;
2461}
2462
2463static RISCVException read_vstval(CPURISCVState *env, int csrno,
2464                                  target_ulong *val)
2465{
2466    *val = env->vstval;
2467    return RISCV_EXCP_NONE;
2468}
2469
2470static RISCVException write_vstval(CPURISCVState *env, int csrno,
2471                                   target_ulong val)
2472{
2473    env->vstval = val;
2474    return RISCV_EXCP_NONE;
2475}
2476
2477static RISCVException read_vsatp(CPURISCVState *env, int csrno,
2478                                 target_ulong *val)
2479{
2480    *val = env->vsatp;
2481    return RISCV_EXCP_NONE;
2482}
2483
2484static RISCVException write_vsatp(CPURISCVState *env, int csrno,
2485                                  target_ulong val)
2486{
2487    env->vsatp = val;
2488    return RISCV_EXCP_NONE;
2489}
2490
2491static RISCVException read_mtval2(CPURISCVState *env, int csrno,
2492                                  target_ulong *val)
2493{
2494    *val = env->mtval2;
2495    return RISCV_EXCP_NONE;
2496}
2497
2498static RISCVException write_mtval2(CPURISCVState *env, int csrno,
2499                                   target_ulong val)
2500{
2501    env->mtval2 = val;
2502    return RISCV_EXCP_NONE;
2503}
2504
2505static RISCVException read_mtinst(CPURISCVState *env, int csrno,
2506                                  target_ulong *val)
2507{
2508    *val = env->mtinst;
2509    return RISCV_EXCP_NONE;
2510}
2511
2512static RISCVException write_mtinst(CPURISCVState *env, int csrno,
2513                                   target_ulong val)
2514{
2515    env->mtinst = val;
2516    return RISCV_EXCP_NONE;
2517}
2518
2519/* Physical Memory Protection */
2520static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
2521                                   target_ulong *val)
2522{
2523    *val = mseccfg_csr_read(env);
2524    return RISCV_EXCP_NONE;
2525}
2526
2527static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
2528                         target_ulong val)
2529{
2530    mseccfg_csr_write(env, val);
2531    return RISCV_EXCP_NONE;
2532}
2533
2534static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
2535{
2536    /* TODO: RV128 restriction check */
2537    if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
2538        return false;
2539    }
2540    return true;
2541}
2542
2543static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
2544                                  target_ulong *val)
2545{
2546    uint32_t reg_index = csrno - CSR_PMPCFG0;
2547
2548    if (!check_pmp_reg_index(env, reg_index)) {
2549        return RISCV_EXCP_ILLEGAL_INST;
2550    }
2551    *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
2552    return RISCV_EXCP_NONE;
2553}
2554
2555static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
2556                                   target_ulong val)
2557{
2558    uint32_t reg_index = csrno - CSR_PMPCFG0;
2559
2560    if (!check_pmp_reg_index(env, reg_index)) {
2561        return RISCV_EXCP_ILLEGAL_INST;
2562    }
2563    pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
2564    return RISCV_EXCP_NONE;
2565}
2566
2567static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
2568                                   target_ulong *val)
2569{
2570    *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
2571    return RISCV_EXCP_NONE;
2572}
2573
2574static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
2575                                    target_ulong val)
2576{
2577    pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
2578    return RISCV_EXCP_NONE;
2579}
2580
2581/*
2582 * Functions to access Pointer Masking feature registers
2583 * We have to check if current priv lvl could modify
2584 * csr in given mode
2585 */
2586static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
2587{
2588    int csr_priv = get_field(csrno, 0x300);
2589    int pm_current;
2590
2591    if (env->debugger) {
2592        return false;
2593    }
2594    /*
2595     * If priv lvls differ that means we're accessing csr from higher priv lvl,
2596     * so allow the access
2597     */
2598    if (env->priv != csr_priv) {
2599        return false;
2600    }
2601    switch (env->priv) {
2602    case PRV_M:
2603        pm_current = get_field(env->mmte, M_PM_CURRENT);
2604        break;
2605    case PRV_S:
2606        pm_current = get_field(env->mmte, S_PM_CURRENT);
2607        break;
2608    case PRV_U:
2609        pm_current = get_field(env->mmte, U_PM_CURRENT);
2610        break;
2611    default:
2612        g_assert_not_reached();
2613    }
2614    /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
2615    return !pm_current;
2616}
2617
2618static RISCVException read_mmte(CPURISCVState *env, int csrno,
2619                                target_ulong *val)
2620{
2621    *val = env->mmte & MMTE_MASK;
2622    return RISCV_EXCP_NONE;
2623}
2624
2625static RISCVException write_mmte(CPURISCVState *env, int csrno,
2626                                 target_ulong val)
2627{
2628    uint64_t mstatus;
2629    target_ulong wpri_val = val & MMTE_MASK;
2630
2631    if (val != wpri_val) {
2632        qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2633                      "MMTE: WPRI violation written 0x", val,
2634                      "vs expected 0x", wpri_val);
2635    }
2636    /* for machine mode pm.current is hardwired to 1 */
2637    wpri_val |= MMTE_M_PM_CURRENT;
2638
2639    /* hardwiring pm.instruction bit to 0, since it's not supported yet */
2640    wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
2641    env->mmte = wpri_val | PM_EXT_DIRTY;
2642    riscv_cpu_update_mask(env);
2643
2644    /* Set XS and SD bits, since PM CSRs are dirty */
2645    mstatus = env->mstatus | MSTATUS_XS;
2646    write_mstatus(env, csrno, mstatus);
2647    return RISCV_EXCP_NONE;
2648}
2649
2650static RISCVException read_smte(CPURISCVState *env, int csrno,
2651                                target_ulong *val)
2652{
2653    *val = env->mmte & SMTE_MASK;
2654    return RISCV_EXCP_NONE;
2655}
2656
2657static RISCVException write_smte(CPURISCVState *env, int csrno,
2658                                 target_ulong val)
2659{
2660    target_ulong wpri_val = val & SMTE_MASK;
2661
2662    if (val != wpri_val) {
2663        qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2664                      "SMTE: WPRI violation written 0x", val,
2665                      "vs expected 0x", wpri_val);
2666    }
2667
2668    /* if pm.current==0 we can't modify current PM CSRs */
2669    if (check_pm_current_disabled(env, csrno)) {
2670        return RISCV_EXCP_NONE;
2671    }
2672
2673    wpri_val |= (env->mmte & ~SMTE_MASK);
2674    write_mmte(env, csrno, wpri_val);
2675    return RISCV_EXCP_NONE;
2676}
2677
2678static RISCVException read_umte(CPURISCVState *env, int csrno,
2679                                target_ulong *val)
2680{
2681    *val = env->mmte & UMTE_MASK;
2682    return RISCV_EXCP_NONE;
2683}
2684
2685static RISCVException write_umte(CPURISCVState *env, int csrno,
2686                                 target_ulong val)
2687{
2688    target_ulong wpri_val = val & UMTE_MASK;
2689
2690    if (val != wpri_val) {
2691        qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
2692                      "UMTE: WPRI violation written 0x", val,
2693                      "vs expected 0x", wpri_val);
2694    }
2695
2696    if (check_pm_current_disabled(env, csrno)) {
2697        return RISCV_EXCP_NONE;
2698    }
2699
2700    wpri_val |= (env->mmte & ~UMTE_MASK);
2701    write_mmte(env, csrno, wpri_val);
2702    return RISCV_EXCP_NONE;
2703}
2704
2705static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
2706                                   target_ulong *val)
2707{
2708    *val = env->mpmmask;
2709    return RISCV_EXCP_NONE;
2710}
2711
2712static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
2713                                    target_ulong val)
2714{
2715    uint64_t mstatus;
2716
2717    env->mpmmask = val;
2718    if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
2719        env->cur_pmmask = val;
2720    }
2721    env->mmte |= PM_EXT_DIRTY;
2722
2723    /* Set XS and SD bits, since PM CSRs are dirty */
2724    mstatus = env->mstatus | MSTATUS_XS;
2725    write_mstatus(env, csrno, mstatus);
2726    return RISCV_EXCP_NONE;
2727}
2728
2729static RISCVException read_spmmask(CPURISCVState *env, int csrno,
2730                                   target_ulong *val)
2731{
2732    *val = env->spmmask;
2733    return RISCV_EXCP_NONE;
2734}
2735
2736static RISCVException write_spmmask(CPURISCVState *env, int csrno,
2737                                    target_ulong val)
2738{
2739    uint64_t mstatus;
2740
2741    /* if pm.current==0 we can't modify current PM CSRs */
2742    if (check_pm_current_disabled(env, csrno)) {
2743        return RISCV_EXCP_NONE;
2744    }
2745    env->spmmask = val;
2746    if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
2747        env->cur_pmmask = val;
2748    }
2749    env->mmte |= PM_EXT_DIRTY;
2750
2751    /* Set XS and SD bits, since PM CSRs are dirty */
2752    mstatus = env->mstatus | MSTATUS_XS;
2753    write_mstatus(env, csrno, mstatus);
2754    return RISCV_EXCP_NONE;
2755}
2756
2757static RISCVException read_upmmask(CPURISCVState *env, int csrno,
2758                                   target_ulong *val)
2759{
2760    *val = env->upmmask;
2761    return RISCV_EXCP_NONE;
2762}
2763
2764static RISCVException write_upmmask(CPURISCVState *env, int csrno,
2765                                    target_ulong val)
2766{
2767    uint64_t mstatus;
2768
2769    /* if pm.current==0 we can't modify current PM CSRs */
2770    if (check_pm_current_disabled(env, csrno)) {
2771        return RISCV_EXCP_NONE;
2772    }
2773    env->upmmask = val;
2774    if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
2775        env->cur_pmmask = val;
2776    }
2777    env->mmte |= PM_EXT_DIRTY;
2778
2779    /* Set XS and SD bits, since PM CSRs are dirty */
2780    mstatus = env->mstatus | MSTATUS_XS;
2781    write_mstatus(env, csrno, mstatus);
2782    return RISCV_EXCP_NONE;
2783}
2784
2785static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
2786                                   target_ulong *val)
2787{
2788    *val = env->mpmbase;
2789    return RISCV_EXCP_NONE;
2790}
2791
2792static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
2793                                    target_ulong val)
2794{
2795    uint64_t mstatus;
2796
2797    env->mpmbase = val;
2798    if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
2799        env->cur_pmbase = val;
2800    }
2801    env->mmte |= PM_EXT_DIRTY;
2802
2803    /* Set XS and SD bits, since PM CSRs are dirty */
2804    mstatus = env->mstatus | MSTATUS_XS;
2805    write_mstatus(env, csrno, mstatus);
2806    return RISCV_EXCP_NONE;
2807}
2808
2809static RISCVException read_spmbase(CPURISCVState *env, int csrno,
2810                                   target_ulong *val)
2811{
2812    *val = env->spmbase;
2813    return RISCV_EXCP_NONE;
2814}
2815
2816static RISCVException write_spmbase(CPURISCVState *env, int csrno,
2817                                    target_ulong val)
2818{
2819    uint64_t mstatus;
2820
2821    /* if pm.current==0 we can't modify current PM CSRs */
2822    if (check_pm_current_disabled(env, csrno)) {
2823        return RISCV_EXCP_NONE;
2824    }
2825    env->spmbase = val;
2826    if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
2827        env->cur_pmbase = val;
2828    }
2829    env->mmte |= PM_EXT_DIRTY;
2830
2831    /* Set XS and SD bits, since PM CSRs are dirty */
2832    mstatus = env->mstatus | MSTATUS_XS;
2833    write_mstatus(env, csrno, mstatus);
2834    return RISCV_EXCP_NONE;
2835}
2836
2837static RISCVException read_upmbase(CPURISCVState *env, int csrno,
2838                                   target_ulong *val)
2839{
2840    *val = env->upmbase;
2841    return RISCV_EXCP_NONE;
2842}
2843
2844static RISCVException write_upmbase(CPURISCVState *env, int csrno,
2845                                    target_ulong val)
2846{
2847    uint64_t mstatus;
2848
2849    /* if pm.current==0 we can't modify current PM CSRs */
2850    if (check_pm_current_disabled(env, csrno)) {
2851        return RISCV_EXCP_NONE;
2852    }
2853    env->upmbase = val;
2854    if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
2855        env->cur_pmbase = val;
2856    }
2857    env->mmte |= PM_EXT_DIRTY;
2858
2859    /* Set XS and SD bits, since PM CSRs are dirty */
2860    mstatus = env->mstatus | MSTATUS_XS;
2861    write_mstatus(env, csrno, mstatus);
2862    return RISCV_EXCP_NONE;
2863}
2864
2865#endif
2866
2867/*
2868 * riscv_csrrw - read and/or update control and status register
2869 *
2870 * csrr   <->  riscv_csrrw(env, csrno, ret_value, 0, 0);
2871 * csrrw  <->  riscv_csrrw(env, csrno, ret_value, value, -1);
2872 * csrrs  <->  riscv_csrrw(env, csrno, ret_value, -1, value);
2873 * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
2874 */
2875
2876static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
2877                                               int csrno,
2878                                               bool write_mask,
2879                                               RISCVCPU *cpu)
2880{
2881    /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
2882    int read_only = get_field(csrno, 0xC00) == 3;
2883#if !defined(CONFIG_USER_ONLY)
2884    int effective_priv = env->priv;
2885
2886    if (riscv_has_ext(env, RVH) &&
2887        env->priv == PRV_S &&
2888        !riscv_cpu_virt_enabled(env)) {
2889        /*
2890         * We are in S mode without virtualisation, therefore we are in HS Mode.
2891         * Add 1 to the effective privledge level to allow us to access the
2892         * Hypervisor CSRs.
2893         */
2894        effective_priv++;
2895    }
2896
2897    if (!env->debugger && (effective_priv < get_field(csrno, 0x300))) {
2898        return RISCV_EXCP_ILLEGAL_INST;
2899    }
2900#endif
2901    if (write_mask && read_only) {
2902        return RISCV_EXCP_ILLEGAL_INST;
2903    }
2904
2905    /* ensure the CSR extension is enabled. */
2906    if (!cpu->cfg.ext_icsr) {
2907        return RISCV_EXCP_ILLEGAL_INST;
2908    }
2909
2910    /* check predicate */
2911    if (!csr_ops[csrno].predicate) {
2912        return RISCV_EXCP_ILLEGAL_INST;
2913    }
2914
2915    return csr_ops[csrno].predicate(env, csrno);
2916}
2917
2918static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
2919                                       target_ulong *ret_value,
2920                                       target_ulong new_value,
2921                                       target_ulong write_mask)
2922{
2923    RISCVException ret;
2924    target_ulong old_value;
2925
2926    /* execute combined read/write operation if it exists */
2927    if (csr_ops[csrno].op) {
2928        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
2929    }
2930
2931    /* if no accessor exists then return failure */
2932    if (!csr_ops[csrno].read) {
2933        return RISCV_EXCP_ILLEGAL_INST;
2934    }
2935    /* read old value */
2936    ret = csr_ops[csrno].read(env, csrno, &old_value);
2937    if (ret != RISCV_EXCP_NONE) {
2938        return ret;
2939    }
2940
2941    /* write value if writable and write mask set, otherwise drop writes */
2942    if (write_mask) {
2943        new_value = (old_value & ~write_mask) | (new_value & write_mask);
2944        if (csr_ops[csrno].write) {
2945            ret = csr_ops[csrno].write(env, csrno, new_value);
2946            if (ret != RISCV_EXCP_NONE) {
2947                return ret;
2948            }
2949        }
2950    }
2951
2952    /* return old value */
2953    if (ret_value) {
2954        *ret_value = old_value;
2955    }
2956
2957    return RISCV_EXCP_NONE;
2958}
2959
2960RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
2961                           target_ulong *ret_value,
2962                           target_ulong new_value, target_ulong write_mask)
2963{
2964    RISCVCPU *cpu = env_archcpu(env);
2965
2966    RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu);
2967    if (ret != RISCV_EXCP_NONE) {
2968        return ret;
2969    }
2970
2971    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
2972}
2973
2974static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
2975                                        Int128 *ret_value,
2976                                        Int128 new_value,
2977                                        Int128 write_mask)
2978{
2979    RISCVException ret;
2980    Int128 old_value;
2981
2982    /* read old value */
2983    ret = csr_ops[csrno].read128(env, csrno, &old_value);
2984    if (ret != RISCV_EXCP_NONE) {
2985        return ret;
2986    }
2987
2988    /* write value if writable and write mask set, otherwise drop writes */
2989    if (int128_nz(write_mask)) {
2990        new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
2991                              int128_and(new_value, write_mask));
2992        if (csr_ops[csrno].write128) {
2993            ret = csr_ops[csrno].write128(env, csrno, new_value);
2994            if (ret != RISCV_EXCP_NONE) {
2995                return ret;
2996            }
2997        } else if (csr_ops[csrno].write) {
2998            /* avoids having to write wrappers for all registers */
2999            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
3000            if (ret != RISCV_EXCP_NONE) {
3001                return ret;
3002            }
3003        }
3004    }
3005
3006    /* return old value */
3007    if (ret_value) {
3008        *ret_value = old_value;
3009    }
3010
3011    return RISCV_EXCP_NONE;
3012}
3013
3014RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
3015                                Int128 *ret_value,
3016                                Int128 new_value, Int128 write_mask)
3017{
3018    RISCVException ret;
3019    RISCVCPU *cpu = env_archcpu(env);
3020
3021    ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu);
3022    if (ret != RISCV_EXCP_NONE) {
3023        return ret;
3024    }
3025
3026    if (csr_ops[csrno].read128) {
3027        return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
3028    }
3029
3030    /*
3031     * Fall back to 64-bit version for now, if the 128-bit alternative isn't
3032     * at all defined.
3033     * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
3034     * significant), for those, this fallback is correctly handling the accesses
3035     */
3036    target_ulong old_value;
3037    ret = riscv_csrrw_do64(env, csrno, &old_value,
3038                           int128_getlo(new_value),
3039                           int128_getlo(write_mask));
3040    if (ret == RISCV_EXCP_NONE && ret_value) {
3041        *ret_value = int128_make64(old_value);
3042    }
3043    return ret;
3044}
3045
3046/*
3047 * Debugger support.  If not in user mode, set env->debugger before the
3048 * riscv_csrrw call and clear it after the call.
3049 */
3050RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
3051                                 target_ulong *ret_value,
3052                                 target_ulong new_value,
3053                                 target_ulong write_mask)
3054{
3055    RISCVException ret;
3056#if !defined(CONFIG_USER_ONLY)
3057    env->debugger = true;
3058#endif
3059    ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
3060#if !defined(CONFIG_USER_ONLY)
3061    env->debugger = false;
3062#endif
3063    return ret;
3064}
3065
3066/* Control and Status Register function table */
3067riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
3068    /* User Floating-Point CSRs */
3069    [CSR_FFLAGS]   = { "fflags",   fs,     read_fflags,  write_fflags },
3070    [CSR_FRM]      = { "frm",      fs,     read_frm,     write_frm    },
3071    [CSR_FCSR]     = { "fcsr",     fs,     read_fcsr,    write_fcsr   },
3072    /* Vector CSRs */
3073    [CSR_VSTART]   = { "vstart",   vs,     read_vstart,  write_vstart },
3074    [CSR_VXSAT]    = { "vxsat",    vs,     read_vxsat,   write_vxsat  },
3075    [CSR_VXRM]     = { "vxrm",     vs,     read_vxrm,    write_vxrm   },
3076    [CSR_VCSR]     = { "vcsr",     vs,     read_vcsr,    write_vcsr   },
3077    [CSR_VL]       = { "vl",       vs,     read_vl                    },
3078    [CSR_VTYPE]    = { "vtype",    vs,     read_vtype                 },
3079    [CSR_VLENB]    = { "vlenb",    vs,     read_vlenb                 },
3080    /* User Timers and Counters */
3081    [CSR_CYCLE]    = { "cycle",    ctr,    read_instret  },
3082    [CSR_INSTRET]  = { "instret",  ctr,    read_instret  },
3083    [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_instreth },
3084    [CSR_INSTRETH] = { "instreth", ctr32,  read_instreth },
3085
3086    /*
3087     * In privileged mode, the monitor will have to emulate TIME CSRs only if
3088     * rdtime callback is not provided by machine/platform emulation.
3089     */
3090    [CSR_TIME]  = { "time",  ctr,   read_time  },
3091    [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
3092
3093#if !defined(CONFIG_USER_ONLY)
3094    /* Machine Timers and Counters */
3095    [CSR_MCYCLE]    = { "mcycle",    any,   read_instret  },
3096    [CSR_MINSTRET]  = { "minstret",  any,   read_instret  },
3097    [CSR_MCYCLEH]   = { "mcycleh",   any32, read_instreth },
3098    [CSR_MINSTRETH] = { "minstreth", any32, read_instreth },
3099
3100    /* Machine Information Registers */
3101    [CSR_MVENDORID] = { "mvendorid", any,   read_zero    },
3102    [CSR_MARCHID]   = { "marchid",   any,   read_zero    },
3103    [CSR_MIMPID]    = { "mimpid",    any,   read_zero    },
3104    [CSR_MHARTID]   = { "mhartid",   any,   read_mhartid },
3105
3106    /* Machine Trap Setup */
3107    [CSR_MSTATUS]     = { "mstatus",    any,   read_mstatus,     write_mstatus, NULL,
3108                                               read_mstatus_i128                   },
3109    [CSR_MISA]        = { "misa",       any,   read_misa,        write_misa, NULL,
3110                                               read_misa_i128                      },
3111    [CSR_MIDELEG]     = { "mideleg",    any,   NULL,    NULL,    rmw_mideleg       },
3112    [CSR_MEDELEG]     = { "medeleg",    any,   read_medeleg,     write_medeleg     },
3113    [CSR_MIE]         = { "mie",        any,   NULL,    NULL,    rmw_mie           },
3114    [CSR_MTVEC]       = { "mtvec",      any,   read_mtvec,       write_mtvec       },
3115    [CSR_MCOUNTEREN]  = { "mcounteren", any,   read_mcounteren,  write_mcounteren  },
3116
3117    [CSR_MSTATUSH]    = { "mstatush",   any32, read_mstatush,    write_mstatush    },
3118
3119    /* Machine Trap Handling */
3120    [CSR_MSCRATCH] = { "mscratch", any,  read_mscratch,      write_mscratch, NULL,
3121                                         read_mscratch_i128, write_mscratch_i128   },
3122    [CSR_MEPC]     = { "mepc",     any,  read_mepc,     write_mepc     },
3123    [CSR_MCAUSE]   = { "mcause",   any,  read_mcause,   write_mcause   },
3124    [CSR_MTVAL]    = { "mtval",    any,  read_mtval,    write_mtval    },
3125    [CSR_MIP]      = { "mip",      any,  NULL,    NULL, rmw_mip        },
3126
3127    /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
3128    [CSR_MISELECT] = { "miselect", aia_any,   NULL, NULL,    rmw_xiselect },
3129    [CSR_MIREG]    = { "mireg",    aia_any,   NULL, NULL,    rmw_xireg },
3130
3131    /* Machine-Level Interrupts (AIA) */
3132    [CSR_MTOPI]    = { "mtopi",    aia_any,   read_mtopi },
3133
3134    /* Machine-Level IMSIC Interface (AIA) */
3135    [CSR_MSETEIPNUM] = { "mseteipnum", aia_any, NULL, NULL, rmw_xsetclreinum },
3136    [CSR_MCLREIPNUM] = { "mclreipnum", aia_any, NULL, NULL, rmw_xsetclreinum },
3137    [CSR_MSETEIENUM] = { "mseteienum", aia_any, NULL, NULL, rmw_xsetclreinum },
3138    [CSR_MCLREIENUM] = { "mclreienum", aia_any, NULL, NULL, rmw_xsetclreinum },
3139    [CSR_MTOPEI]     = { "mtopei",     aia_any, NULL, NULL, rmw_xtopei },
3140
3141    /* Virtual Interrupts for Supervisor Level (AIA) */
3142    [CSR_MVIEN]      = { "mvien", aia_any, read_zero, write_ignore },
3143    [CSR_MVIP]       = { "mvip",  aia_any, read_zero, write_ignore },
3144
3145    /* Machine-Level High-Half CSRs (AIA) */
3146    [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
3147    [CSR_MIEH]     = { "mieh",     aia_any32, NULL, NULL, rmw_mieh     },
3148    [CSR_MVIENH]   = { "mvienh",   aia_any32, read_zero,  write_ignore },
3149    [CSR_MVIPH]    = { "mviph",    aia_any32, read_zero,  write_ignore },
3150    [CSR_MIPH]     = { "miph",     aia_any32, NULL, NULL, rmw_miph     },
3151
3152    /* Supervisor Trap Setup */
3153    [CSR_SSTATUS]    = { "sstatus",    smode, read_sstatus,    write_sstatus, NULL,
3154                                              read_sstatus_i128                 },
3155    [CSR_SIE]        = { "sie",        smode, NULL,   NULL,    rmw_sie          },
3156    [CSR_STVEC]      = { "stvec",      smode, read_stvec,      write_stvec      },
3157    [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren },
3158
3159    /* Supervisor Trap Handling */
3160    [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL,
3161                                          read_sscratch_i128, write_sscratch_i128  },
3162    [CSR_SEPC]     = { "sepc",     smode, read_sepc,     write_sepc     },
3163    [CSR_SCAUSE]   = { "scause",   smode, read_scause,   write_scause   },
3164    [CSR_STVAL]    = { "stval",    smode, read_stval,   write_stval   },
3165    [CSR_SIP]      = { "sip",      smode, NULL,    NULL, rmw_sip        },
3166
3167    /* Supervisor Protection and Translation */
3168    [CSR_SATP]     = { "satp",     smode, read_satp,    write_satp      },
3169
3170    /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
3171    [CSR_SISELECT]   = { "siselect",   aia_smode, NULL, NULL, rmw_xiselect },
3172    [CSR_SIREG]      = { "sireg",      aia_smode, NULL, NULL, rmw_xireg },
3173
3174    /* Supervisor-Level Interrupts (AIA) */
3175    [CSR_STOPI]      = { "stopi",      aia_smode, read_stopi },
3176
3177    /* Supervisor-Level IMSIC Interface (AIA) */
3178    [CSR_SSETEIPNUM] = { "sseteipnum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3179    [CSR_SCLREIPNUM] = { "sclreipnum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3180    [CSR_SSETEIENUM] = { "sseteienum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3181    [CSR_SCLREIENUM] = { "sclreienum", aia_smode, NULL, NULL, rmw_xsetclreinum },
3182    [CSR_STOPEI]     = { "stopei",     aia_smode, NULL, NULL, rmw_xtopei },
3183
3184    /* Supervisor-Level High-Half CSRs (AIA) */
3185    [CSR_SIEH]       = { "sieh",   aia_smode32, NULL, NULL, rmw_sieh },
3186    [CSR_SIPH]       = { "siph",   aia_smode32, NULL, NULL, rmw_siph },
3187
3188    [CSR_HSTATUS]     = { "hstatus",     hmode,   read_hstatus,     write_hstatus     },
3189    [CSR_HEDELEG]     = { "hedeleg",     hmode,   read_hedeleg,     write_hedeleg     },
3190    [CSR_HIDELEG]     = { "hideleg",     hmode,   NULL,   NULL,     rmw_hideleg       },
3191    [CSR_HVIP]        = { "hvip",        hmode,   NULL,   NULL,     rmw_hvip          },
3192    [CSR_HIP]         = { "hip",         hmode,   NULL,   NULL,     rmw_hip           },
3193    [CSR_HIE]         = { "hie",         hmode,   NULL,   NULL,     rmw_hie           },
3194    [CSR_HCOUNTEREN]  = { "hcounteren",  hmode,   read_hcounteren,  write_hcounteren  },
3195    [CSR_HGEIE]       = { "hgeie",       hmode,   read_hgeie,       write_hgeie       },
3196    [CSR_HTVAL]       = { "htval",       hmode,   read_htval,       write_htval       },
3197    [CSR_HTINST]      = { "htinst",      hmode,   read_htinst,      write_htinst      },
3198    [CSR_HGEIP]       = { "hgeip",       hmode,   read_hgeip,       NULL              },
3199    [CSR_HGATP]       = { "hgatp",       hmode,   read_hgatp,       write_hgatp       },
3200    [CSR_HTIMEDELTA]  = { "htimedelta",  hmode,   read_htimedelta,  write_htimedelta  },
3201    [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah },
3202
3203    [CSR_VSSTATUS]    = { "vsstatus",    hmode,   read_vsstatus,    write_vsstatus    },
3204    [CSR_VSIP]        = { "vsip",        hmode,   NULL,    NULL,    rmw_vsip          },
3205    [CSR_VSIE]        = { "vsie",        hmode,   NULL,    NULL,    rmw_vsie          },
3206    [CSR_VSTVEC]      = { "vstvec",      hmode,   read_vstvec,      write_vstvec      },
3207    [CSR_VSSCRATCH]   = { "vsscratch",   hmode,   read_vsscratch,   write_vsscratch   },
3208    [CSR_VSEPC]       = { "vsepc",       hmode,   read_vsepc,       write_vsepc       },
3209    [CSR_VSCAUSE]     = { "vscause",     hmode,   read_vscause,     write_vscause     },
3210    [CSR_VSTVAL]      = { "vstval",      hmode,   read_vstval,      write_vstval      },
3211    [CSR_VSATP]       = { "vsatp",       hmode,   read_vsatp,       write_vsatp       },
3212
3213    [CSR_MTVAL2]      = { "mtval2",      hmode,   read_mtval2,      write_mtval2      },
3214    [CSR_MTINST]      = { "mtinst",      hmode,   read_mtinst,      write_mtinst      },
3215
3216    /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
3217    [CSR_HVIEN]       = { "hvien",       aia_hmode, read_zero, write_ignore },
3218    [CSR_HVICTL]      = { "hvictl",      aia_hmode, read_hvictl, write_hvictl },
3219    [CSR_HVIPRIO1]    = { "hviprio1",    aia_hmode, read_hviprio1,   write_hviprio1 },
3220    [CSR_HVIPRIO2]    = { "hviprio2",    aia_hmode, read_hviprio2,   write_hviprio2 },
3221
3222    /*
3223     * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
3224     */
3225    [CSR_VSISELECT]   = { "vsiselect",   aia_hmode, NULL, NULL,      rmw_xiselect },
3226    [CSR_VSIREG]      = { "vsireg",      aia_hmode, NULL, NULL,      rmw_xireg },
3227
3228    /* VS-Level Interrupts (H-extension with AIA) */
3229    [CSR_VSTOPI]      = { "vstopi",      aia_hmode, read_vstopi },
3230
3231    /* VS-Level IMSIC Interface (H-extension with AIA) */
3232    [CSR_VSSETEIPNUM] = { "vsseteipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3233    [CSR_VSCLREIPNUM] = { "vsclreipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3234    [CSR_VSSETEIENUM] = { "vsseteienum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3235    [CSR_VSCLREIENUM] = { "vsclreienum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
3236    [CSR_VSTOPEI]     = { "vstopei",     aia_hmode, NULL, NULL, rmw_xtopei },
3237
3238    /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
3239    [CSR_HIDELEGH]    = { "hidelegh",    aia_hmode32, NULL, NULL, rmw_hidelegh },
3240    [CSR_HVIENH]      = { "hvienh",      aia_hmode32, read_zero, write_ignore },
3241    [CSR_HVIPH]       = { "hviph",       aia_hmode32, NULL, NULL, rmw_hviph },
3242    [CSR_HVIPRIO1H]   = { "hviprio1h",   aia_hmode32, read_hviprio1h, write_hviprio1h },
3243    [CSR_HVIPRIO2H]   = { "hviprio2h",   aia_hmode32, read_hviprio2h, write_hviprio2h },
3244    [CSR_VSIEH]       = { "vsieh",       aia_hmode32, NULL, NULL, rmw_vsieh },
3245    [CSR_VSIPH]       = { "vsiph",       aia_hmode32, NULL, NULL, rmw_vsiph },
3246
3247    /* Physical Memory Protection */
3248    [CSR_MSECCFG]    = { "mseccfg",  epmp, read_mseccfg, write_mseccfg },
3249    [CSR_PMPCFG0]    = { "pmpcfg0",   pmp, read_pmpcfg,  write_pmpcfg  },
3250    [CSR_PMPCFG1]    = { "pmpcfg1",   pmp, read_pmpcfg,  write_pmpcfg  },
3251    [CSR_PMPCFG2]    = { "pmpcfg2",   pmp, read_pmpcfg,  write_pmpcfg  },
3252    [CSR_PMPCFG3]    = { "pmpcfg3",   pmp, read_pmpcfg,  write_pmpcfg  },
3253    [CSR_PMPADDR0]   = { "pmpaddr0",  pmp, read_pmpaddr, write_pmpaddr },
3254    [CSR_PMPADDR1]   = { "pmpaddr1",  pmp, read_pmpaddr, write_pmpaddr },
3255    [CSR_PMPADDR2]   = { "pmpaddr2",  pmp, read_pmpaddr, write_pmpaddr },
3256    [CSR_PMPADDR3]   = { "pmpaddr3",  pmp, read_pmpaddr, write_pmpaddr },
3257    [CSR_PMPADDR4]   = { "pmpaddr4",  pmp, read_pmpaddr, write_pmpaddr },
3258    [CSR_PMPADDR5]   = { "pmpaddr5",  pmp, read_pmpaddr, write_pmpaddr },
3259    [CSR_PMPADDR6]   = { "pmpaddr6",  pmp, read_pmpaddr, write_pmpaddr },
3260    [CSR_PMPADDR7]   = { "pmpaddr7",  pmp, read_pmpaddr, write_pmpaddr },
3261    [CSR_PMPADDR8]   = { "pmpaddr8",  pmp, read_pmpaddr, write_pmpaddr },
3262    [CSR_PMPADDR9]   = { "pmpaddr9",  pmp, read_pmpaddr, write_pmpaddr },
3263    [CSR_PMPADDR10]  = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
3264    [CSR_PMPADDR11]  = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
3265    [CSR_PMPADDR12]  = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
3266    [CSR_PMPADDR13]  = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
3267    [CSR_PMPADDR14] =  { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
3268    [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
3269
3270    /* User Pointer Masking */
3271    [CSR_UMTE]    =    { "umte",    pointer_masking, read_umte,    write_umte    },
3272    [CSR_UPMMASK] =    { "upmmask", pointer_masking, read_upmmask, write_upmmask },
3273    [CSR_UPMBASE] =    { "upmbase", pointer_masking, read_upmbase, write_upmbase },
3274    /* Machine Pointer Masking */
3275    [CSR_MMTE]    =    { "mmte",    pointer_masking, read_mmte,    write_mmte    },
3276    [CSR_MPMMASK] =    { "mpmmask", pointer_masking, read_mpmmask, write_mpmmask },
3277    [CSR_MPMBASE] =    { "mpmbase", pointer_masking, read_mpmbase, write_mpmbase },
3278    /* Supervisor Pointer Masking */
3279    [CSR_SMTE]    =    { "smte",    pointer_masking, read_smte,    write_smte    },
3280    [CSR_SPMMASK] =    { "spmmask", pointer_masking, read_spmmask, write_spmmask },
3281    [CSR_SPMBASE] =    { "spmbase", pointer_masking, read_spmbase, write_spmbase },
3282
3283    /* Performance Counters */
3284    [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_zero },
3285    [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_zero },
3286    [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_zero },
3287    [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_zero },
3288    [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_zero },
3289    [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_zero },
3290    [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_zero },
3291    [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_zero },
3292    [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_zero },
3293    [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_zero },
3294    [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_zero },
3295    [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_zero },
3296    [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_zero },
3297    [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_zero },
3298    [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_zero },
3299    [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_zero },
3300    [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_zero },
3301    [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_zero },
3302    [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_zero },
3303    [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_zero },
3304    [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_zero },
3305    [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_zero },
3306    [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_zero },
3307    [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_zero },
3308    [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_zero },
3309    [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_zero },
3310    [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_zero },
3311    [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_zero },
3312    [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_zero },
3313
3314    [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   any,    read_zero },
3315    [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   any,    read_zero },
3316    [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   any,    read_zero },
3317    [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   any,    read_zero },
3318    [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   any,    read_zero },
3319    [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   any,    read_zero },
3320    [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   any,    read_zero },
3321    [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  any,    read_zero },
3322    [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  any,    read_zero },
3323    [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  any,    read_zero },
3324    [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  any,    read_zero },
3325    [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  any,    read_zero },
3326    [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  any,    read_zero },
3327    [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  any,    read_zero },
3328    [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  any,    read_zero },
3329    [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  any,    read_zero },
3330    [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  any,    read_zero },
3331    [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  any,    read_zero },
3332    [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  any,    read_zero },
3333    [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  any,    read_zero },
3334    [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  any,    read_zero },
3335    [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  any,    read_zero },
3336    [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  any,    read_zero },
3337    [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  any,    read_zero },
3338    [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  any,    read_zero },
3339    [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  any,    read_zero },
3340    [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  any,    read_zero },
3341    [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  any,    read_zero },
3342    [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  any,    read_zero },
3343
3344    [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_zero },
3345    [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_zero },
3346    [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_zero },
3347    [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_zero },
3348    [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_zero },
3349    [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_zero },
3350    [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_zero },
3351    [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_zero },
3352    [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_zero },
3353    [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_zero },
3354    [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_zero },
3355    [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_zero },
3356    [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_zero },
3357    [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_zero },
3358    [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_zero },
3359    [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_zero },
3360    [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_zero },
3361    [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_zero },
3362    [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_zero },
3363    [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_zero },
3364    [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_zero },
3365    [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_zero },
3366    [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_zero },
3367    [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_zero },
3368    [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_zero },
3369    [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_zero },
3370    [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_zero },
3371    [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_zero },
3372    [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_zero },
3373
3374    [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_zero },
3375    [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_zero },
3376    [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_zero },
3377    [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_zero },
3378    [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_zero },
3379    [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_zero },
3380    [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_zero },
3381    [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_zero },
3382    [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_zero },
3383    [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_zero },
3384    [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_zero },
3385    [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_zero },
3386    [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_zero },
3387    [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_zero },
3388    [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_zero },
3389    [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_zero },
3390    [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_zero },
3391    [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_zero },
3392    [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_zero },
3393    [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_zero },
3394    [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_zero },
3395    [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_zero },
3396    [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_zero },
3397    [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_zero },
3398    [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_zero },
3399    [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_zero },
3400    [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_zero },
3401    [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_zero },
3402    [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_zero },
3403
3404    [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  any32,  read_zero },
3405    [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  any32,  read_zero },
3406    [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  any32,  read_zero },
3407    [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  any32,  read_zero },
3408    [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  any32,  read_zero },
3409    [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  any32,  read_zero },
3410    [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  any32,  read_zero },
3411    [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32,  read_zero },
3412    [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32,  read_zero },
3413    [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32,  read_zero },
3414    [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32,  read_zero },
3415    [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32,  read_zero },
3416    [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32,  read_zero },
3417    [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32,  read_zero },
3418    [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32,  read_zero },
3419    [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32,  read_zero },
3420    [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32,  read_zero },
3421    [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32,  read_zero },
3422    [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32,  read_zero },
3423    [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32,  read_zero },
3424    [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32,  read_zero },
3425    [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32,  read_zero },
3426    [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32,  read_zero },
3427    [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32,  read_zero },
3428    [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32,  read_zero },
3429    [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32,  read_zero },
3430    [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32,  read_zero },
3431    [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32,  read_zero },
3432    [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32,  read_zero },
3433#endif /* !CONFIG_USER_ONLY */
3434};
3435