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 "pmu.h"
  25#include "time_helper.h"
  26#include "qemu/main-loop.h"
  27#include "exec/exec-all.h"
  28#include "sysemu/cpu-timers.h"
  29#include "qemu/guest-random.h"
  30#include "qapi/error.h"
  31
  32/* CSR function table public API */
  33void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
  34{
  35    *ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
  36}
  37
  38void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
  39{
  40    csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
  41}
  42
  43/* Predicates */
  44static RISCVException fs(CPURISCVState *env, int csrno)
  45{
  46#if !defined(CONFIG_USER_ONLY)
  47    if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
  48        !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
  49        return RISCV_EXCP_ILLEGAL_INST;
  50    }
  51#endif
  52    return RISCV_EXCP_NONE;
  53}
  54
  55static RISCVException vs(CPURISCVState *env, int csrno)
  56{
  57    CPUState *cs = env_cpu(env);
  58    RISCVCPU *cpu = RISCV_CPU(cs);
  59
  60    if (env->misa_ext & RVV ||
  61        cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
  62#if !defined(CONFIG_USER_ONLY)
  63        if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
  64            return RISCV_EXCP_ILLEGAL_INST;
  65        }
  66#endif
  67        return RISCV_EXCP_NONE;
  68    }
  69    return RISCV_EXCP_ILLEGAL_INST;
  70}
  71
  72static RISCVException ctr(CPURISCVState *env, int csrno)
  73{
  74#if !defined(CONFIG_USER_ONLY)
  75    CPUState *cs = env_cpu(env);
  76    RISCVCPU *cpu = RISCV_CPU(cs);
  77    int ctr_index;
  78    target_ulong ctr_mask;
  79    int base_csrno = CSR_CYCLE;
  80    bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
  81
  82    if (rv32 && csrno >= CSR_CYCLEH) {
  83        /* Offset for RV32 hpmcounternh counters */
  84        base_csrno += 0x80;
  85    }
  86    ctr_index = csrno - base_csrno;
  87    ctr_mask = BIT(ctr_index);
  88
  89    if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
  90        (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
  91        goto skip_ext_pmu_check;
  92    }
  93
  94    if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
  95        /* No counter is enabled in PMU or the counter is out of range */
  96        return RISCV_EXCP_ILLEGAL_INST;
  97    }
  98
  99skip_ext_pmu_check:
 100
 101    if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
 102        return RISCV_EXCP_ILLEGAL_INST;
 103    }
 104
 105    if (riscv_cpu_virt_enabled(env)) {
 106        if (!get_field(env->hcounteren, ctr_mask) ||
 107            (env->priv == PRV_U && !get_field(env->scounteren, ctr_mask))) {
 108            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 109        }
 110    }
 111
 112    if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
 113        !get_field(env->scounteren, ctr_mask)) {
 114        return RISCV_EXCP_ILLEGAL_INST;
 115    }
 116
 117#endif
 118    return RISCV_EXCP_NONE;
 119}
 120
 121static RISCVException ctr32(CPURISCVState *env, int csrno)
 122{
 123    if (riscv_cpu_mxl(env) != MXL_RV32) {
 124        return RISCV_EXCP_ILLEGAL_INST;
 125    }
 126
 127    return ctr(env, csrno);
 128}
 129
 130#if !defined(CONFIG_USER_ONLY)
 131static RISCVException mctr(CPURISCVState *env, int csrno)
 132{
 133    CPUState *cs = env_cpu(env);
 134    RISCVCPU *cpu = RISCV_CPU(cs);
 135    int ctr_index;
 136    int base_csrno = CSR_MHPMCOUNTER3;
 137
 138    if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
 139        /* Offset for RV32 mhpmcounternh counters */
 140        base_csrno += 0x80;
 141    }
 142    ctr_index = csrno - base_csrno;
 143    if (!cpu->cfg.pmu_num || ctr_index >= cpu->cfg.pmu_num) {
 144        /* The PMU is not enabled or counter is out of range*/
 145        return RISCV_EXCP_ILLEGAL_INST;
 146    }
 147
 148    return RISCV_EXCP_NONE;
 149}
 150
 151static RISCVException mctr32(CPURISCVState *env, int csrno)
 152{
 153    if (riscv_cpu_mxl(env) != MXL_RV32) {
 154        return RISCV_EXCP_ILLEGAL_INST;
 155    }
 156
 157    return mctr(env, csrno);
 158}
 159
 160static RISCVException sscofpmf(CPURISCVState *env, int csrno)
 161{
 162    CPUState *cs = env_cpu(env);
 163    RISCVCPU *cpu = RISCV_CPU(cs);
 164
 165    if (!cpu->cfg.ext_sscofpmf) {
 166        return RISCV_EXCP_ILLEGAL_INST;
 167    }
 168
 169    return RISCV_EXCP_NONE;
 170}
 171
 172static RISCVException any(CPURISCVState *env, int csrno)
 173{
 174    return RISCV_EXCP_NONE;
 175}
 176
 177static RISCVException any32(CPURISCVState *env, int csrno)
 178{
 179    if (riscv_cpu_mxl(env) != MXL_RV32) {
 180        return RISCV_EXCP_ILLEGAL_INST;
 181    }
 182
 183    return any(env, csrno);
 184
 185}
 186
 187static int aia_any(CPURISCVState *env, int csrno)
 188{
 189    RISCVCPU *cpu = env_archcpu(env);
 190
 191    if (!cpu->cfg.ext_smaia) {
 192        return RISCV_EXCP_ILLEGAL_INST;
 193    }
 194
 195    return any(env, csrno);
 196}
 197
 198static int aia_any32(CPURISCVState *env, int csrno)
 199{
 200    RISCVCPU *cpu = env_archcpu(env);
 201
 202    if (!cpu->cfg.ext_smaia) {
 203        return RISCV_EXCP_ILLEGAL_INST;
 204    }
 205
 206    return any32(env, csrno);
 207}
 208
 209static RISCVException smode(CPURISCVState *env, int csrno)
 210{
 211    if (riscv_has_ext(env, RVS)) {
 212        return RISCV_EXCP_NONE;
 213    }
 214
 215    return RISCV_EXCP_ILLEGAL_INST;
 216}
 217
 218static int smode32(CPURISCVState *env, int csrno)
 219{
 220    if (riscv_cpu_mxl(env) != MXL_RV32) {
 221        return RISCV_EXCP_ILLEGAL_INST;
 222    }
 223
 224    return smode(env, csrno);
 225}
 226
 227static int aia_smode(CPURISCVState *env, int csrno)
 228{
 229    RISCVCPU *cpu = env_archcpu(env);
 230
 231    if (!cpu->cfg.ext_ssaia) {
 232        return RISCV_EXCP_ILLEGAL_INST;
 233    }
 234
 235    return smode(env, csrno);
 236}
 237
 238static int aia_smode32(CPURISCVState *env, int csrno)
 239{
 240    RISCVCPU *cpu = env_archcpu(env);
 241
 242    if (!cpu->cfg.ext_ssaia) {
 243        return RISCV_EXCP_ILLEGAL_INST;
 244    }
 245
 246    return smode32(env, csrno);
 247}
 248
 249static RISCVException hmode(CPURISCVState *env, int csrno)
 250{
 251    if (riscv_has_ext(env, RVH)) {
 252        return RISCV_EXCP_NONE;
 253    }
 254
 255    return RISCV_EXCP_ILLEGAL_INST;
 256}
 257
 258static RISCVException hmode32(CPURISCVState *env, int csrno)
 259{
 260    if (riscv_cpu_mxl(env) != MXL_RV32) {
 261        return RISCV_EXCP_ILLEGAL_INST;
 262    }
 263
 264    return hmode(env, csrno);
 265
 266}
 267
 268static RISCVException umode(CPURISCVState *env, int csrno)
 269{
 270    if (riscv_has_ext(env, RVU)) {
 271        return RISCV_EXCP_NONE;
 272    }
 273
 274    return RISCV_EXCP_ILLEGAL_INST;
 275}
 276
 277static RISCVException umode32(CPURISCVState *env, int csrno)
 278{
 279    if (riscv_cpu_mxl(env) != MXL_RV32) {
 280        return RISCV_EXCP_ILLEGAL_INST;
 281    }
 282
 283    return umode(env, csrno);
 284}
 285
 286/* Checks if PointerMasking registers could be accessed */
 287static RISCVException pointer_masking(CPURISCVState *env, int csrno)
 288{
 289    /* Check if j-ext is present */
 290    if (riscv_has_ext(env, RVJ)) {
 291        return RISCV_EXCP_NONE;
 292    }
 293    return RISCV_EXCP_ILLEGAL_INST;
 294}
 295
 296static int aia_hmode(CPURISCVState *env, int csrno)
 297{
 298    RISCVCPU *cpu = env_archcpu(env);
 299
 300    if (!cpu->cfg.ext_ssaia) {
 301        return RISCV_EXCP_ILLEGAL_INST;
 302     }
 303
 304     return hmode(env, csrno);
 305}
 306
 307static int aia_hmode32(CPURISCVState *env, int csrno)
 308{
 309    RISCVCPU *cpu = env_archcpu(env);
 310
 311    if (!cpu->cfg.ext_ssaia) {
 312        return RISCV_EXCP_ILLEGAL_INST;
 313    }
 314
 315    return hmode32(env, csrno);
 316}
 317
 318static RISCVException pmp(CPURISCVState *env, int csrno)
 319{
 320    if (riscv_feature(env, RISCV_FEATURE_PMP)) {
 321        return RISCV_EXCP_NONE;
 322    }
 323
 324    return RISCV_EXCP_ILLEGAL_INST;
 325}
 326
 327static RISCVException epmp(CPURISCVState *env, int csrno)
 328{
 329    if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
 330        return RISCV_EXCP_NONE;
 331    }
 332
 333    return RISCV_EXCP_ILLEGAL_INST;
 334}
 335
 336static RISCVException debug(CPURISCVState *env, int csrno)
 337{
 338    if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
 339        return RISCV_EXCP_NONE;
 340    }
 341
 342    return RISCV_EXCP_ILLEGAL_INST;
 343}
 344#endif
 345
 346static RISCVException seed(CPURISCVState *env, int csrno)
 347{
 348    RISCVCPU *cpu = env_archcpu(env);
 349
 350    if (!cpu->cfg.ext_zkr) {
 351        return RISCV_EXCP_ILLEGAL_INST;
 352    }
 353
 354#if !defined(CONFIG_USER_ONLY)
 355    /*
 356     * With a CSR read-write instruction:
 357     * 1) The seed CSR is always available in machine mode as normal.
 358     * 2) Attempted access to seed from virtual modes VS and VU always raises
 359     * an exception(virtual instruction exception only if mseccfg.sseed=1).
 360     * 3) Without the corresponding access control bit set to 1, any attempted
 361     * access to seed from U, S or HS modes will raise an illegal instruction
 362     * exception.
 363     */
 364    if (env->priv == PRV_M) {
 365        return RISCV_EXCP_NONE;
 366    } else if (riscv_cpu_virt_enabled(env)) {
 367        if (env->mseccfg & MSECCFG_SSEED) {
 368            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 369        } else {
 370            return RISCV_EXCP_ILLEGAL_INST;
 371        }
 372    } else {
 373        if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) {
 374            return RISCV_EXCP_NONE;
 375        } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) {
 376            return RISCV_EXCP_NONE;
 377        } else {
 378            return RISCV_EXCP_ILLEGAL_INST;
 379        }
 380    }
 381#else
 382    return RISCV_EXCP_NONE;
 383#endif
 384}
 385
 386/* User Floating-Point CSRs */
 387static RISCVException read_fflags(CPURISCVState *env, int csrno,
 388                                  target_ulong *val)
 389{
 390    *val = riscv_cpu_get_fflags(env);
 391    return RISCV_EXCP_NONE;
 392}
 393
 394static RISCVException write_fflags(CPURISCVState *env, int csrno,
 395                                   target_ulong val)
 396{
 397#if !defined(CONFIG_USER_ONLY)
 398    if (riscv_has_ext(env, RVF)) {
 399        env->mstatus |= MSTATUS_FS;
 400    }
 401#endif
 402    riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
 403    return RISCV_EXCP_NONE;
 404}
 405
 406static RISCVException read_frm(CPURISCVState *env, int csrno,
 407                               target_ulong *val)
 408{
 409    *val = env->frm;
 410    return RISCV_EXCP_NONE;
 411}
 412
 413static RISCVException write_frm(CPURISCVState *env, int csrno,
 414                                target_ulong val)
 415{
 416#if !defined(CONFIG_USER_ONLY)
 417    if (riscv_has_ext(env, RVF)) {
 418        env->mstatus |= MSTATUS_FS;
 419    }
 420#endif
 421    env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
 422    return RISCV_EXCP_NONE;
 423}
 424
 425static RISCVException read_fcsr(CPURISCVState *env, int csrno,
 426                                target_ulong *val)
 427{
 428    *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
 429        | (env->frm << FSR_RD_SHIFT);
 430    return RISCV_EXCP_NONE;
 431}
 432
 433static RISCVException write_fcsr(CPURISCVState *env, int csrno,
 434                                 target_ulong val)
 435{
 436#if !defined(CONFIG_USER_ONLY)
 437    if (riscv_has_ext(env, RVF)) {
 438        env->mstatus |= MSTATUS_FS;
 439    }
 440#endif
 441    env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
 442    riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
 443    return RISCV_EXCP_NONE;
 444}
 445
 446static RISCVException read_vtype(CPURISCVState *env, int csrno,
 447                                 target_ulong *val)
 448{
 449    uint64_t vill;
 450    switch (env->xl) {
 451    case MXL_RV32:
 452        vill = (uint32_t)env->vill << 31;
 453        break;
 454    case MXL_RV64:
 455        vill = (uint64_t)env->vill << 63;
 456        break;
 457    default:
 458        g_assert_not_reached();
 459    }
 460    *val = (target_ulong)vill | env->vtype;
 461    return RISCV_EXCP_NONE;
 462}
 463
 464static RISCVException read_vl(CPURISCVState *env, int csrno,
 465                              target_ulong *val)
 466{
 467    *val = env->vl;
 468    return RISCV_EXCP_NONE;
 469}
 470
 471static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
 472{
 473    *val = env_archcpu(env)->cfg.vlen >> 3;
 474    return RISCV_EXCP_NONE;
 475}
 476
 477static RISCVException read_vxrm(CPURISCVState *env, int csrno,
 478                                target_ulong *val)
 479{
 480    *val = env->vxrm;
 481    return RISCV_EXCP_NONE;
 482}
 483
 484static RISCVException write_vxrm(CPURISCVState *env, int csrno,
 485                                 target_ulong val)
 486{
 487#if !defined(CONFIG_USER_ONLY)
 488    env->mstatus |= MSTATUS_VS;
 489#endif
 490    env->vxrm = val;
 491    return RISCV_EXCP_NONE;
 492}
 493
 494static RISCVException read_vxsat(CPURISCVState *env, int csrno,
 495                                 target_ulong *val)
 496{
 497    *val = env->vxsat;
 498    return RISCV_EXCP_NONE;
 499}
 500
 501static RISCVException write_vxsat(CPURISCVState *env, int csrno,
 502                                  target_ulong val)
 503{
 504#if !defined(CONFIG_USER_ONLY)
 505    env->mstatus |= MSTATUS_VS;
 506#endif
 507    env->vxsat = val;
 508    return RISCV_EXCP_NONE;
 509}
 510
 511static RISCVException read_vstart(CPURISCVState *env, int csrno,
 512                                  target_ulong *val)
 513{
 514    *val = env->vstart;
 515    return RISCV_EXCP_NONE;
 516}
 517
 518static RISCVException write_vstart(CPURISCVState *env, int csrno,
 519                                   target_ulong val)
 520{
 521#if !defined(CONFIG_USER_ONLY)
 522    env->mstatus |= MSTATUS_VS;
 523#endif
 524    /*
 525     * The vstart CSR is defined to have only enough writable bits
 526     * to hold the largest element index, i.e. lg2(VLEN) bits.
 527     */
 528    env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen));
 529    return RISCV_EXCP_NONE;
 530}
 531
 532static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
 533{
 534    *val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
 535    return RISCV_EXCP_NONE;
 536}
 537
 538static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
 539{
 540#if !defined(CONFIG_USER_ONLY)
 541    env->mstatus |= MSTATUS_VS;
 542#endif
 543    env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
 544    env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
 545    return RISCV_EXCP_NONE;
 546}
 547
 548/* User Timers and Counters */
 549static target_ulong get_ticks(bool shift)
 550{
 551    int64_t val;
 552    target_ulong result;
 553
 554#if !defined(CONFIG_USER_ONLY)
 555    if (icount_enabled()) {
 556        val = icount_get();
 557    } else {
 558        val = cpu_get_host_ticks();
 559    }
 560#else
 561    val = cpu_get_host_ticks();
 562#endif
 563
 564    if (shift) {
 565        result = val >> 32;
 566    } else {
 567        result = val;
 568    }
 569
 570    return result;
 571}
 572
 573#if defined(CONFIG_USER_ONLY)
 574static RISCVException read_time(CPURISCVState *env, int csrno,
 575                                target_ulong *val)
 576{
 577    *val = cpu_get_host_ticks();
 578    return RISCV_EXCP_NONE;
 579}
 580
 581static RISCVException read_timeh(CPURISCVState *env, int csrno,
 582                                 target_ulong *val)
 583{
 584    *val = cpu_get_host_ticks() >> 32;
 585    return RISCV_EXCP_NONE;
 586}
 587
 588static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
 589{
 590    *val = get_ticks(false);
 591    return RISCV_EXCP_NONE;
 592}
 593
 594static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
 595{
 596    *val = get_ticks(true);
 597    return RISCV_EXCP_NONE;
 598}
 599
 600#else /* CONFIG_USER_ONLY */
 601
 602static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
 603{
 604    int evt_index = csrno - CSR_MCOUNTINHIBIT;
 605
 606    *val = env->mhpmevent_val[evt_index];
 607
 608    return RISCV_EXCP_NONE;
 609}
 610
 611static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
 612{
 613    int evt_index = csrno - CSR_MCOUNTINHIBIT;
 614    uint64_t mhpmevt_val = val;
 615
 616    env->mhpmevent_val[evt_index] = val;
 617
 618    if (riscv_cpu_mxl(env) == MXL_RV32) {
 619        mhpmevt_val = mhpmevt_val |
 620                      ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
 621    }
 622    riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
 623
 624    return RISCV_EXCP_NONE;
 625}
 626
 627static int read_mhpmeventh(CPURISCVState *env, int csrno, target_ulong *val)
 628{
 629    int evt_index = csrno - CSR_MHPMEVENT3H + 3;
 630
 631    *val = env->mhpmeventh_val[evt_index];
 632
 633    return RISCV_EXCP_NONE;
 634}
 635
 636static int write_mhpmeventh(CPURISCVState *env, int csrno, target_ulong val)
 637{
 638    int evt_index = csrno - CSR_MHPMEVENT3H + 3;
 639    uint64_t mhpmevth_val = val;
 640    uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
 641
 642    mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
 643    env->mhpmeventh_val[evt_index] = val;
 644
 645    riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
 646
 647    return RISCV_EXCP_NONE;
 648}
 649
 650static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
 651{
 652    int ctr_idx = csrno - CSR_MCYCLE;
 653    PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
 654    uint64_t mhpmctr_val = val;
 655
 656    counter->mhpmcounter_val = val;
 657    if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
 658        riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
 659        counter->mhpmcounter_prev = get_ticks(false);
 660        if (ctr_idx > 2) {
 661            if (riscv_cpu_mxl(env) == MXL_RV32) {
 662                mhpmctr_val = mhpmctr_val |
 663                              ((uint64_t)counter->mhpmcounterh_val << 32);
 664            }
 665            riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
 666        }
 667     } else {
 668        /* Other counters can keep incrementing from the given value */
 669        counter->mhpmcounter_prev = val;
 670    }
 671
 672    return RISCV_EXCP_NONE;
 673}
 674
 675static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
 676{
 677    int ctr_idx = csrno - CSR_MCYCLEH;
 678    PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
 679    uint64_t mhpmctr_val = counter->mhpmcounter_val;
 680    uint64_t mhpmctrh_val = val;
 681
 682    counter->mhpmcounterh_val = val;
 683    mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
 684    if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
 685        riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
 686        counter->mhpmcounterh_prev = get_ticks(true);
 687        if (ctr_idx > 2) {
 688            riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
 689        }
 690    } else {
 691        counter->mhpmcounterh_prev = val;
 692    }
 693
 694    return RISCV_EXCP_NONE;
 695}
 696
 697static RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
 698                                         bool upper_half, uint32_t ctr_idx)
 699{
 700    PMUCTRState counter = env->pmu_ctrs[ctr_idx];
 701    target_ulong ctr_prev = upper_half ? counter.mhpmcounterh_prev :
 702                                         counter.mhpmcounter_prev;
 703    target_ulong ctr_val = upper_half ? counter.mhpmcounterh_val :
 704                                        counter.mhpmcounter_val;
 705
 706    if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
 707        /**
 708         * Counter should not increment if inhibit bit is set. We can't really
 709         * stop the icount counting. Just return the counter value written by
 710         * the supervisor to indicate that counter was not incremented.
 711         */
 712        if (!counter.started) {
 713            *val = ctr_val;
 714            return RISCV_EXCP_NONE;
 715        } else {
 716            /* Mark that the counter has been stopped */
 717            counter.started = false;
 718        }
 719    }
 720
 721    /**
 722     * The kernel computes the perf delta by subtracting the current value from
 723     * the value it initialized previously (ctr_val).
 724     */
 725    if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
 726        riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
 727        *val = get_ticks(upper_half) - ctr_prev + ctr_val;
 728    } else {
 729        *val = ctr_val;
 730    }
 731
 732    return RISCV_EXCP_NONE;
 733}
 734
 735static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
 736{
 737    uint16_t ctr_index;
 738
 739    if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
 740        ctr_index = csrno - CSR_MCYCLE;
 741    } else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
 742        ctr_index = csrno - CSR_CYCLE;
 743    } else {
 744        return RISCV_EXCP_ILLEGAL_INST;
 745    }
 746
 747    return riscv_pmu_read_ctr(env, val, false, ctr_index);
 748}
 749
 750static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
 751{
 752    uint16_t ctr_index;
 753
 754    if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
 755        ctr_index = csrno - CSR_MCYCLEH;
 756    } else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
 757        ctr_index = csrno - CSR_CYCLEH;
 758    } else {
 759        return RISCV_EXCP_ILLEGAL_INST;
 760    }
 761
 762    return riscv_pmu_read_ctr(env, val, true, ctr_index);
 763}
 764
 765static int read_scountovf(CPURISCVState *env, int csrno, target_ulong *val)
 766{
 767    int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
 768    int i;
 769    *val = 0;
 770    target_ulong *mhpm_evt_val;
 771    uint64_t of_bit_mask;
 772
 773    if (riscv_cpu_mxl(env) == MXL_RV32) {
 774        mhpm_evt_val = env->mhpmeventh_val;
 775        of_bit_mask = MHPMEVENTH_BIT_OF;
 776    } else {
 777        mhpm_evt_val = env->mhpmevent_val;
 778        of_bit_mask = MHPMEVENT_BIT_OF;
 779    }
 780
 781    for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) {
 782        if ((get_field(env->mcounteren, BIT(i))) &&
 783            (mhpm_evt_val[i] & of_bit_mask)) {
 784                    *val |= BIT(i);
 785            }
 786    }
 787
 788    return RISCV_EXCP_NONE;
 789}
 790
 791static RISCVException read_time(CPURISCVState *env, int csrno,
 792                                target_ulong *val)
 793{
 794    uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
 795
 796    if (!env->rdtime_fn) {
 797        return RISCV_EXCP_ILLEGAL_INST;
 798    }
 799
 800    *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
 801    return RISCV_EXCP_NONE;
 802}
 803
 804static RISCVException read_timeh(CPURISCVState *env, int csrno,
 805                                 target_ulong *val)
 806{
 807    uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
 808
 809    if (!env->rdtime_fn) {
 810        return RISCV_EXCP_ILLEGAL_INST;
 811    }
 812
 813    *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
 814    return RISCV_EXCP_NONE;
 815}
 816
 817static RISCVException sstc(CPURISCVState *env, int csrno)
 818{
 819    CPUState *cs = env_cpu(env);
 820    RISCVCPU *cpu = RISCV_CPU(cs);
 821    bool hmode_check = false;
 822
 823    if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
 824        return RISCV_EXCP_ILLEGAL_INST;
 825    }
 826
 827    if (env->priv == PRV_M) {
 828        return RISCV_EXCP_NONE;
 829    }
 830
 831    /*
 832     * No need of separate function for rv32 as menvcfg stores both menvcfg
 833     * menvcfgh for RV32.
 834     */
 835    if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
 836          get_field(env->menvcfg, MENVCFG_STCE))) {
 837        return RISCV_EXCP_ILLEGAL_INST;
 838    }
 839
 840    if (riscv_cpu_virt_enabled(env)) {
 841        if (!(get_field(env->hcounteren, COUNTEREN_TM) &
 842              get_field(env->henvcfg, HENVCFG_STCE))) {
 843            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 844        }
 845    }
 846
 847    if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
 848        hmode_check = true;
 849    }
 850
 851    return hmode_check ? hmode(env, csrno) : smode(env, csrno);
 852}
 853
 854static RISCVException sstc_32(CPURISCVState *env, int csrno)
 855{
 856    if (riscv_cpu_mxl(env) != MXL_RV32) {
 857        return RISCV_EXCP_ILLEGAL_INST;
 858    }
 859
 860    return sstc(env, csrno);
 861}
 862
 863static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
 864                                    target_ulong *val)
 865{
 866    *val = env->vstimecmp;
 867
 868    return RISCV_EXCP_NONE;
 869}
 870
 871static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
 872                                    target_ulong *val)
 873{
 874    *val = env->vstimecmp >> 32;
 875
 876    return RISCV_EXCP_NONE;
 877}
 878
 879static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
 880                                    target_ulong val)
 881{
 882    RISCVCPU *cpu = env_archcpu(env);
 883
 884    if (riscv_cpu_mxl(env) == MXL_RV32) {
 885        env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
 886    } else {
 887        env->vstimecmp = val;
 888    }
 889
 890    riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
 891                              env->htimedelta, MIP_VSTIP);
 892
 893    return RISCV_EXCP_NONE;
 894}
 895
 896static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
 897                                    target_ulong val)
 898{
 899    RISCVCPU *cpu = env_archcpu(env);
 900
 901    env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
 902    riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
 903                              env->htimedelta, MIP_VSTIP);
 904
 905    return RISCV_EXCP_NONE;
 906}
 907
 908static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
 909                                    target_ulong *val)
 910{
 911    if (riscv_cpu_virt_enabled(env)) {
 912        *val = env->vstimecmp;
 913    } else {
 914        *val = env->stimecmp;
 915    }
 916
 917    return RISCV_EXCP_NONE;
 918}
 919
 920static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
 921                                    target_ulong *val)
 922{
 923    if (riscv_cpu_virt_enabled(env)) {
 924        *val = env->vstimecmp >> 32;
 925    } else {
 926        *val = env->stimecmp >> 32;
 927    }
 928
 929    return RISCV_EXCP_NONE;
 930}
 931
 932static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
 933                                    target_ulong val)
 934{
 935    RISCVCPU *cpu = env_archcpu(env);
 936
 937    if (riscv_cpu_virt_enabled(env)) {
 938        return write_vstimecmp(env, csrno, val);
 939    }
 940
 941    if (riscv_cpu_mxl(env) == MXL_RV32) {
 942        env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val);
 943    } else {
 944        env->stimecmp = val;
 945    }
 946
 947    riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
 948
 949    return RISCV_EXCP_NONE;
 950}
 951
 952static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
 953                                    target_ulong val)
 954{
 955    RISCVCPU *cpu = env_archcpu(env);
 956
 957    if (riscv_cpu_virt_enabled(env)) {
 958        return write_vstimecmph(env, csrno, val);
 959    }
 960
 961    env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
 962    riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
 963
 964    return RISCV_EXCP_NONE;
 965}
 966
 967/* Machine constants */
 968
 969#define M_MODE_INTERRUPTS  ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
 970#define S_MODE_INTERRUPTS  ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP | \
 971                                      MIP_LCOFIP))
 972#define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
 973#define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
 974
 975#define VSTOPI_NUM_SRCS 5
 976
 977static const uint64_t delegable_ints = S_MODE_INTERRUPTS |
 978                                           VS_MODE_INTERRUPTS;
 979static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS;
 980static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS |
 981                                     HS_MODE_INTERRUPTS;
 982#define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
 983                         (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
 984                         (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
 985                         (1ULL << (RISCV_EXCP_BREAKPOINT)) | \
 986                         (1ULL << (RISCV_EXCP_LOAD_ADDR_MIS)) | \
 987                         (1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT)) | \
 988                         (1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS)) | \
 989                         (1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT)) | \
 990                         (1ULL << (RISCV_EXCP_U_ECALL)) | \
 991                         (1ULL << (RISCV_EXCP_S_ECALL)) | \
 992                         (1ULL << (RISCV_EXCP_VS_ECALL)) | \
 993                         (1ULL << (RISCV_EXCP_M_ECALL)) | \
 994                         (1ULL << (RISCV_EXCP_INST_PAGE_FAULT)) | \
 995                         (1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT)) | \
 996                         (1ULL << (RISCV_EXCP_STORE_PAGE_FAULT)) | \
 997                         (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | \
 998                         (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | \
 999                         (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) | \
1000                         (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)))
1001static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
1002    ~((1ULL << (RISCV_EXCP_S_ECALL)) |
1003      (1ULL << (RISCV_EXCP_VS_ECALL)) |
1004      (1ULL << (RISCV_EXCP_M_ECALL)) |
1005      (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) |
1006      (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) |
1007      (1ULL << (RISCV_EXCP_VIRT_INSTRUCTION_FAULT)) |
1008      (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
1009static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
1010    SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
1011    SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
1012static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP |
1013                                              SIP_LCOFIP;
1014static const target_ulong hip_writable_mask = MIP_VSSIP;
1015static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
1016static const target_ulong vsip_writable_mask = MIP_VSSIP;
1017
1018static const char valid_vm_1_10_32[16] = {
1019    [VM_1_10_MBARE] = 1,
1020    [VM_1_10_SV32] = 1
1021};
1022
1023static const char valid_vm_1_10_64[16] = {
1024    [VM_1_10_MBARE] = 1,
1025    [VM_1_10_SV39] = 1,
1026    [VM_1_10_SV48] = 1,
1027    [VM_1_10_SV57] = 1
1028};
1029
1030/* Machine Information Registers */
1031static RISCVException read_zero(CPURISCVState *env, int csrno,
1032                                target_ulong *val)
1033{
1034    *val = 0;
1035    return RISCV_EXCP_NONE;
1036}
1037
1038static RISCVException write_ignore(CPURISCVState *env, int csrno,
1039                                   target_ulong val)
1040{
1041    return RISCV_EXCP_NONE;
1042}
1043
1044static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
1045                                     target_ulong *val)
1046{
1047    CPUState *cs = env_cpu(env);
1048    RISCVCPU *cpu = RISCV_CPU(cs);
1049
1050    *val = cpu->cfg.mvendorid;
1051    return RISCV_EXCP_NONE;
1052}
1053
1054static RISCVException read_marchid(CPURISCVState *env, int csrno,
1055                                   target_ulong *val)
1056{
1057    CPUState *cs = env_cpu(env);
1058    RISCVCPU *cpu = RISCV_CPU(cs);
1059
1060    *val = cpu->cfg.marchid;
1061    return RISCV_EXCP_NONE;
1062}
1063
1064static RISCVException read_mimpid(CPURISCVState *env, int csrno,
1065                                  target_ulong *val)
1066{
1067    CPUState *cs = env_cpu(env);
1068    RISCVCPU *cpu = RISCV_CPU(cs);
1069
1070    *val = cpu->cfg.mimpid;
1071    return RISCV_EXCP_NONE;
1072}
1073
1074static RISCVException read_mhartid(CPURISCVState *env, int csrno,
1075                                   target_ulong *val)
1076{
1077    *val = env->mhartid;
1078    return RISCV_EXCP_NONE;
1079}
1080
1081/* Machine Trap Setup */
1082
1083/* We do not store SD explicitly, only compute it on demand. */
1084static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
1085{
1086    if ((status & MSTATUS_FS) == MSTATUS_FS ||
1087        (status & MSTATUS_VS) == MSTATUS_VS ||
1088        (status & MSTATUS_XS) == MSTATUS_XS) {
1089        switch (xl) {
1090        case MXL_RV32:
1091            return status | MSTATUS32_SD;
1092        case MXL_RV64:
1093            return status | MSTATUS64_SD;
1094        case MXL_RV128:
1095            return MSTATUSH128_SD;
1096        default:
1097            g_assert_not_reached();
1098        }
1099    }
1100    return status;
1101}
1102
1103static RISCVException read_mstatus(CPURISCVState *env, int csrno,
1104                                   target_ulong *val)
1105{
1106    *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
1107    return RISCV_EXCP_NONE;
1108}
1109
1110static int validate_vm(CPURISCVState *env, target_ulong vm)
1111{
1112    if (riscv_cpu_mxl(env) == MXL_RV32) {
1113        return valid_vm_1_10_32[vm & 0xf];
1114    } else {
1115        return valid_vm_1_10_64[vm & 0xf];
1116    }
1117}
1118
1119static RISCVException write_mstatus(CPURISCVState *env, int csrno,
1120                                    target_ulong val)
1121{
1122    uint64_t mstatus = env->mstatus;
1123    uint64_t mask = 0;
1124    RISCVMXL xl = riscv_cpu_mxl(env);
1125
1126    /* flush tlb on mstatus fields that affect VM */
1127    if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
1128            MSTATUS_MPRV | MSTATUS_SUM)) {
1129        tlb_flush(env_cpu(env));
1130    }
1131    mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
1132        MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM |
1133        MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
1134        MSTATUS_TW | MSTATUS_VS;
1135
1136    if (riscv_has_ext(env, RVF)) {
1137        mask |= MSTATUS_FS;
1138    }
1139
1140    if (xl != MXL_RV32 || env->debugger) {
1141        /*
1142         * RV32: MPV and GVA are not in mstatus. The current plan is to
1143         * add them to mstatush. For now, we just don't support it.
1144         */
1145        mask |= MSTATUS_MPV | MSTATUS_GVA;
1146        if ((val & MSTATUS64_UXL) != 0) {
1147            mask |= MSTATUS64_UXL;
1148        }
1149    }
1150
1151    mstatus = (mstatus & ~mask) | (val & mask);
1152
1153    if (xl > MXL_RV32) {
1154        /* SXL field is for now read only */
1155        mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
1156    }
1157    env->mstatus = mstatus;
1158    env->xl = cpu_recompute_xl(env);
1159
1160    return RISCV_EXCP_NONE;
1161}
1162
1163static RISCVException read_mstatush(CPURISCVState *env, int csrno,
1164                                    target_ulong *val)
1165{
1166    *val = env->mstatus >> 32;
1167    return RISCV_EXCP_NONE;
1168}
1169
1170static RISCVException write_mstatush(CPURISCVState *env, int csrno,
1171                                     target_ulong val)
1172{
1173    uint64_t valh = (uint64_t)val << 32;
1174    uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
1175
1176    if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
1177        tlb_flush(env_cpu(env));
1178    }
1179
1180    env->mstatus = (env->mstatus & ~mask) | (valh & mask);
1181
1182    return RISCV_EXCP_NONE;
1183}
1184
1185static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
1186                                        Int128 *val)
1187{
1188    *val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, env->mstatus));
1189    return RISCV_EXCP_NONE;
1190}
1191
1192static RISCVException read_misa_i128(CPURISCVState *env, int csrno,
1193                                     Int128 *val)
1194{
1195    *val = int128_make128(env->misa_ext, (uint64_t)MXL_RV128 << 62);
1196    return RISCV_EXCP_NONE;
1197}
1198
1199static RISCVException read_misa(CPURISCVState *env, int csrno,
1200                                target_ulong *val)
1201{
1202    target_ulong misa;
1203
1204    switch (env->misa_mxl) {
1205    case MXL_RV32:
1206        misa = (target_ulong)MXL_RV32 << 30;
1207        break;
1208#ifdef TARGET_RISCV64
1209    case MXL_RV64:
1210        misa = (target_ulong)MXL_RV64 << 62;
1211        break;
1212#endif
1213    default:
1214        g_assert_not_reached();
1215    }
1216
1217    *val = misa | env->misa_ext;
1218    return RISCV_EXCP_NONE;
1219}
1220
1221static RISCVException write_misa(CPURISCVState *env, int csrno,
1222                                 target_ulong val)
1223{
1224    if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
1225        /* drop write to misa */
1226        return RISCV_EXCP_NONE;
1227    }
1228
1229    /* 'I' or 'E' must be present */
1230    if (!(val & (RVI | RVE))) {
1231        /* It is not, drop write to misa */
1232        return RISCV_EXCP_NONE;
1233    }
1234
1235    /* 'E' excludes all other extensions */
1236    if (val & RVE) {
1237        /* when we support 'E' we can do "val = RVE;" however
1238         * for now we just drop writes if 'E' is present.
1239         */
1240        return RISCV_EXCP_NONE;
1241    }
1242
1243    /*
1244     * misa.MXL writes are not supported by QEMU.
1245     * Drop writes to those bits.
1246     */
1247
1248    /* Mask extensions that are not supported by this hart */
1249    val &= env->misa_ext_mask;
1250
1251    /* Mask extensions that are not supported by QEMU */
1252    val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
1253
1254    /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
1255    if ((val & RVD) && !(val & RVF)) {
1256        val &= ~RVD;
1257    }
1258
1259    /* Suppress 'C' if next instruction is not aligned
1260     * TODO: this should check next_pc
1261     */
1262    if ((val & RVC) && (GETPC() & ~3) != 0) {
1263        val &= ~RVC;
1264    }
1265
1266    /* If nothing changed, do nothing. */
1267    if (val == env->misa_ext) {
1268        return RISCV_EXCP_NONE;
1269    }
1270
1271    if (!(val & RVF)) {
1272        env->mstatus &= ~MSTATUS_FS;
1273    }
1274
1275    /* flush translation cache */
1276    tb_flush(env_cpu(env));
1277    env->misa_ext = val;
1278    env->xl = riscv_cpu_mxl(env);
1279    return RISCV_EXCP_NONE;
1280}
1281
1282static RISCVException read_medeleg(CPURISCVState *env, int csrno,
1283                                   target_ulong *val)
1284{
1285    *val = env->medeleg;
1286    return RISCV_EXCP_NONE;
1287}
1288
1289static RISCVException write_medeleg(CPURISCVState *env, int csrno,
1290                                    target_ulong val)
1291{
1292    env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
1293    return RISCV_EXCP_NONE;
1294}
1295
1296static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno,
1297                                    uint64_t *ret_val,
1298                                    uint64_t new_val, uint64_t wr_mask)
1299{
1300    uint64_t mask = wr_mask & delegable_ints;
1301
1302    if (ret_val) {
1303        *ret_val = env->mideleg;
1304    }
1305
1306    env->mideleg = (env->mideleg & ~mask) | (new_val & mask);
1307
1308    if (riscv_has_ext(env, RVH)) {
1309        env->mideleg |= HS_MODE_INTERRUPTS;
1310    }
1311
1312    return RISCV_EXCP_NONE;
1313}
1314
1315static RISCVException rmw_mideleg(CPURISCVState *env, int csrno,
1316                                  target_ulong *ret_val,
1317                                  target_ulong new_val, target_ulong wr_mask)
1318{
1319    uint64_t rval;
1320    RISCVException ret;
1321
1322    ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask);
1323    if (ret_val) {
1324        *ret_val = rval;
1325    }
1326
1327    return ret;
1328}
1329
1330static RISCVException rmw_midelegh(CPURISCVState *env, int csrno,
1331                                   target_ulong *ret_val,
1332                                   target_ulong new_val,
1333                                   target_ulong wr_mask)
1334{
1335    uint64_t rval;
1336    RISCVException ret;
1337
1338    ret = rmw_mideleg64(env, csrno, &rval,
1339        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1340    if (ret_val) {
1341        *ret_val = rval >> 32;
1342    }
1343
1344    return ret;
1345}
1346
1347static RISCVException rmw_mie64(CPURISCVState *env, int csrno,
1348                                uint64_t *ret_val,
1349                                uint64_t new_val, uint64_t wr_mask)
1350{
1351    uint64_t mask = wr_mask & all_ints;
1352
1353    if (ret_val) {
1354        *ret_val = env->mie;
1355    }
1356
1357    env->mie = (env->mie & ~mask) | (new_val & mask);
1358
1359    if (!riscv_has_ext(env, RVH)) {
1360        env->mie &= ~((uint64_t)MIP_SGEIP);
1361    }
1362
1363    return RISCV_EXCP_NONE;
1364}
1365
1366static RISCVException rmw_mie(CPURISCVState *env, int csrno,
1367                              target_ulong *ret_val,
1368                              target_ulong new_val, target_ulong wr_mask)
1369{
1370    uint64_t rval;
1371    RISCVException ret;
1372
1373    ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask);
1374    if (ret_val) {
1375        *ret_val = rval;
1376    }
1377
1378    return ret;
1379}
1380
1381static RISCVException rmw_mieh(CPURISCVState *env, int csrno,
1382                               target_ulong *ret_val,
1383                               target_ulong new_val, target_ulong wr_mask)
1384{
1385    uint64_t rval;
1386    RISCVException ret;
1387
1388    ret = rmw_mie64(env, csrno, &rval,
1389        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1390    if (ret_val) {
1391        *ret_val = rval >> 32;
1392    }
1393
1394    return ret;
1395}
1396
1397static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val)
1398{
1399    int irq;
1400    uint8_t iprio;
1401
1402    irq = riscv_cpu_mirq_pending(env);
1403    if (irq <= 0 || irq > 63) {
1404        *val = 0;
1405    } else {
1406        iprio = env->miprio[irq];
1407        if (!iprio) {
1408            if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) {
1409                iprio = IPRIO_MMAXIPRIO;
1410            }
1411        }
1412        *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
1413        *val |= iprio;
1414    }
1415
1416    return RISCV_EXCP_NONE;
1417}
1418
1419static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
1420{
1421    if (!riscv_cpu_virt_enabled(env)) {
1422        return csrno;
1423    }
1424
1425    switch (csrno) {
1426    case CSR_SISELECT:
1427        return CSR_VSISELECT;
1428    case CSR_SIREG:
1429        return CSR_VSIREG;
1430    case CSR_STOPEI:
1431        return CSR_VSTOPEI;
1432    default:
1433        return csrno;
1434    };
1435}
1436
1437static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val,
1438                        target_ulong new_val, target_ulong wr_mask)
1439{
1440    target_ulong *iselect;
1441
1442    /* Translate CSR number for VS-mode */
1443    csrno = aia_xlate_vs_csrno(env, csrno);
1444
1445    /* Find the iselect CSR based on CSR number */
1446    switch (csrno) {
1447    case CSR_MISELECT:
1448        iselect = &env->miselect;
1449        break;
1450    case CSR_SISELECT:
1451        iselect = &env->siselect;
1452        break;
1453    case CSR_VSISELECT:
1454        iselect = &env->vsiselect;
1455        break;
1456    default:
1457         return RISCV_EXCP_ILLEGAL_INST;
1458    };
1459
1460    if (val) {
1461        *val = *iselect;
1462    }
1463
1464    wr_mask &= ISELECT_MASK;
1465    if (wr_mask) {
1466        *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
1467    }
1468
1469    return RISCV_EXCP_NONE;
1470}
1471
1472static int rmw_iprio(target_ulong xlen,
1473                     target_ulong iselect, uint8_t *iprio,
1474                     target_ulong *val, target_ulong new_val,
1475                     target_ulong wr_mask, int ext_irq_no)
1476{
1477    int i, firq, nirqs;
1478    target_ulong old_val;
1479
1480    if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) {
1481        return -EINVAL;
1482    }
1483    if (xlen != 32 && iselect & 0x1) {
1484        return -EINVAL;
1485    }
1486
1487    nirqs = 4 * (xlen / 32);
1488    firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs);
1489
1490    old_val = 0;
1491    for (i = 0; i < nirqs; i++) {
1492        old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i);
1493    }
1494
1495    if (val) {
1496        *val = old_val;
1497    }
1498
1499    if (wr_mask) {
1500        new_val = (old_val & ~wr_mask) | (new_val & wr_mask);
1501        for (i = 0; i < nirqs; i++) {
1502            /*
1503             * M-level and S-level external IRQ priority always read-only
1504             * zero. This means default priority order is always preferred
1505             * for M-level and S-level external IRQs.
1506             */
1507            if ((firq + i) == ext_irq_no) {
1508                continue;
1509            }
1510            iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff;
1511        }
1512    }
1513
1514    return 0;
1515}
1516
1517static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
1518                     target_ulong new_val, target_ulong wr_mask)
1519{
1520    bool virt;
1521    uint8_t *iprio;
1522    int ret = -EINVAL;
1523    target_ulong priv, isel, vgein;
1524
1525    /* Translate CSR number for VS-mode */
1526    csrno = aia_xlate_vs_csrno(env, csrno);
1527
1528    /* Decode register details from CSR number */
1529    virt = false;
1530    switch (csrno) {
1531    case CSR_MIREG:
1532        iprio = env->miprio;
1533        isel = env->miselect;
1534        priv = PRV_M;
1535        break;
1536    case CSR_SIREG:
1537        iprio = env->siprio;
1538        isel = env->siselect;
1539        priv = PRV_S;
1540        break;
1541    case CSR_VSIREG:
1542        iprio = env->hviprio;
1543        isel = env->vsiselect;
1544        priv = PRV_S;
1545        virt = true;
1546        break;
1547    default:
1548         goto done;
1549    };
1550
1551    /* Find the selected guest interrupt file */
1552    vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1553
1554    if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
1555        /* Local interrupt priority registers not available for VS-mode */
1556        if (!virt) {
1557            ret = rmw_iprio(riscv_cpu_mxl_bits(env),
1558                            isel, iprio, val, new_val, wr_mask,
1559                            (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
1560        }
1561    } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) {
1562        /* IMSIC registers only available when machine implements it. */
1563        if (env->aia_ireg_rmw_fn[priv]) {
1564            /* Selected guest interrupt file should not be zero */
1565            if (virt && (!vgein || env->geilen < vgein)) {
1566                goto done;
1567            }
1568            /* Call machine specific IMSIC register emulation */
1569            ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1570                                    AIA_MAKE_IREG(isel, priv, virt, vgein,
1571                                                  riscv_cpu_mxl_bits(env)),
1572                                    val, new_val, wr_mask);
1573        }
1574    }
1575
1576done:
1577    if (ret) {
1578        return (riscv_cpu_virt_enabled(env) && virt) ?
1579               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1580    }
1581    return RISCV_EXCP_NONE;
1582}
1583
1584static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
1585                      target_ulong new_val, target_ulong wr_mask)
1586{
1587    bool virt;
1588    int ret = -EINVAL;
1589    target_ulong priv, vgein;
1590
1591    /* Translate CSR number for VS-mode */
1592    csrno = aia_xlate_vs_csrno(env, csrno);
1593
1594    /* Decode register details from CSR number */
1595    virt = false;
1596    switch (csrno) {
1597    case CSR_MTOPEI:
1598        priv = PRV_M;
1599        break;
1600    case CSR_STOPEI:
1601        priv = PRV_S;
1602        break;
1603    case CSR_VSTOPEI:
1604        priv = PRV_S;
1605        virt = true;
1606        break;
1607    default:
1608        goto done;
1609    };
1610
1611    /* IMSIC CSRs only available when machine implements IMSIC. */
1612    if (!env->aia_ireg_rmw_fn[priv]) {
1613        goto done;
1614    }
1615
1616    /* Find the selected guest interrupt file */
1617    vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
1618
1619    /* Selected guest interrupt file should be valid */
1620    if (virt && (!vgein || env->geilen < vgein)) {
1621        goto done;
1622    }
1623
1624    /* Call machine specific IMSIC register emulation for TOPEI */
1625    ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
1626                    AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein,
1627                                  riscv_cpu_mxl_bits(env)),
1628                    val, new_val, wr_mask);
1629
1630done:
1631    if (ret) {
1632        return (riscv_cpu_virt_enabled(env) && virt) ?
1633               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
1634    }
1635    return RISCV_EXCP_NONE;
1636}
1637
1638static RISCVException read_mtvec(CPURISCVState *env, int csrno,
1639                                 target_ulong *val)
1640{
1641    *val = env->mtvec;
1642    return RISCV_EXCP_NONE;
1643}
1644
1645static RISCVException write_mtvec(CPURISCVState *env, int csrno,
1646                                  target_ulong val)
1647{
1648    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
1649    if ((val & 3) < 2) {
1650        env->mtvec = val;
1651    } else {
1652        qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
1653    }
1654    return RISCV_EXCP_NONE;
1655}
1656
1657static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
1658                                         target_ulong *val)
1659{
1660    *val = env->mcountinhibit;
1661    return RISCV_EXCP_NONE;
1662}
1663
1664static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
1665                                          target_ulong val)
1666{
1667    int cidx;
1668    PMUCTRState *counter;
1669
1670    env->mcountinhibit = val;
1671
1672    /* Check if any other counter is also monitoring cycles/instructions */
1673    for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
1674        if (!get_field(env->mcountinhibit, BIT(cidx))) {
1675            counter = &env->pmu_ctrs[cidx];
1676            counter->started = true;
1677        }
1678    }
1679
1680    return RISCV_EXCP_NONE;
1681}
1682
1683static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
1684                                      target_ulong *val)
1685{
1686    *val = env->mcounteren;
1687    return RISCV_EXCP_NONE;
1688}
1689
1690static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
1691                                       target_ulong val)
1692{
1693    env->mcounteren = val;
1694    return RISCV_EXCP_NONE;
1695}
1696
1697/* Machine Trap Handling */
1698static RISCVException read_mscratch_i128(CPURISCVState *env, int csrno,
1699                                         Int128 *val)
1700{
1701    *val = int128_make128(env->mscratch, env->mscratchh);
1702    return RISCV_EXCP_NONE;
1703}
1704
1705static RISCVException write_mscratch_i128(CPURISCVState *env, int csrno,
1706                                          Int128 val)
1707{
1708    env->mscratch = int128_getlo(val);
1709    env->mscratchh = int128_gethi(val);
1710    return RISCV_EXCP_NONE;
1711}
1712
1713static RISCVException read_mscratch(CPURISCVState *env, int csrno,
1714                                    target_ulong *val)
1715{
1716    *val = env->mscratch;
1717    return RISCV_EXCP_NONE;
1718}
1719
1720static RISCVException write_mscratch(CPURISCVState *env, int csrno,
1721                                     target_ulong val)
1722{
1723    env->mscratch = val;
1724    return RISCV_EXCP_NONE;
1725}
1726
1727static RISCVException read_mepc(CPURISCVState *env, int csrno,
1728                                     target_ulong *val)
1729{
1730    *val = env->mepc;
1731    return RISCV_EXCP_NONE;
1732}
1733
1734static RISCVException write_mepc(CPURISCVState *env, int csrno,
1735                                     target_ulong val)
1736{
1737    env->mepc = val;
1738    return RISCV_EXCP_NONE;
1739}
1740
1741static RISCVException read_mcause(CPURISCVState *env, int csrno,
1742                                     target_ulong *val)
1743{
1744    *val = env->mcause;
1745    return RISCV_EXCP_NONE;
1746}
1747
1748static RISCVException write_mcause(CPURISCVState *env, int csrno,
1749                                     target_ulong val)
1750{
1751    env->mcause = val;
1752    return RISCV_EXCP_NONE;
1753}
1754
1755static RISCVException read_mtval(CPURISCVState *env, int csrno,
1756                                 target_ulong *val)
1757{
1758    *val = env->mtval;
1759    return RISCV_EXCP_NONE;
1760}
1761
1762static RISCVException write_mtval(CPURISCVState *env, int csrno,
1763                                  target_ulong val)
1764{
1765    env->mtval = val;
1766    return RISCV_EXCP_NONE;
1767}
1768
1769/* Execution environment configuration setup */
1770static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
1771                                 target_ulong *val)
1772{
1773    *val = env->menvcfg;
1774    return RISCV_EXCP_NONE;
1775}
1776
1777static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
1778                                  target_ulong val)
1779{
1780    uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
1781
1782    if (riscv_cpu_mxl(env) == MXL_RV64) {
1783        mask |= MENVCFG_PBMTE | MENVCFG_STCE;
1784    }
1785    env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
1786
1787    return RISCV_EXCP_NONE;
1788}
1789
1790static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
1791                                 target_ulong *val)
1792{
1793    *val = env->menvcfg >> 32;
1794    return RISCV_EXCP_NONE;
1795}
1796
1797static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
1798                                  target_ulong val)
1799{
1800    uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE;
1801    uint64_t valh = (uint64_t)val << 32;
1802
1803    env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
1804
1805    return RISCV_EXCP_NONE;
1806}
1807
1808static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
1809                                 target_ulong *val)
1810{
1811    *val = env->senvcfg;
1812    return RISCV_EXCP_NONE;
1813}
1814
1815static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
1816                                  target_ulong val)
1817{
1818    uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
1819
1820    env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
1821
1822    return RISCV_EXCP_NONE;
1823}
1824
1825static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
1826                                 target_ulong *val)
1827{
1828    *val = env->henvcfg;
1829    return RISCV_EXCP_NONE;
1830}
1831
1832static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
1833                                  target_ulong val)
1834{
1835    uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
1836
1837    if (riscv_cpu_mxl(env) == MXL_RV64) {
1838        mask |= HENVCFG_PBMTE | HENVCFG_STCE;
1839    }
1840
1841    env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
1842
1843    return RISCV_EXCP_NONE;
1844}
1845
1846static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
1847                                 target_ulong *val)
1848{
1849    *val = env->henvcfg >> 32;
1850    return RISCV_EXCP_NONE;
1851}
1852
1853static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
1854                                  target_ulong val)
1855{
1856    uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
1857    uint64_t valh = (uint64_t)val << 32;
1858
1859    env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
1860
1861    return RISCV_EXCP_NONE;
1862}
1863
1864static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
1865                                uint64_t *ret_val,
1866                                uint64_t new_val, uint64_t wr_mask)
1867{
1868    RISCVCPU *cpu = env_archcpu(env);
1869    uint64_t old_mip, mask = wr_mask & delegable_ints;
1870    uint32_t gin;
1871
1872    if (mask & MIP_SEIP) {
1873        env->software_seip = new_val & MIP_SEIP;
1874        new_val |= env->external_seip * MIP_SEIP;
1875    }
1876
1877    if (cpu->cfg.ext_sstc && (env->priv == PRV_M) &&
1878        get_field(env->menvcfg, MENVCFG_STCE)) {
1879        /* sstc extension forbids STIP & VSTIP to be writeable in mip */
1880        mask = mask & ~(MIP_STIP | MIP_VSTIP);
1881    }
1882
1883    if (mask) {
1884        old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
1885    } else {
1886        old_mip = env->mip;
1887    }
1888
1889    if (csrno != CSR_HVIP) {
1890        gin = get_field(env->hstatus, HSTATUS_VGEIN);
1891        old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
1892        old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
1893    }
1894
1895    if (ret_val) {
1896        *ret_val = old_mip;
1897    }
1898
1899    return RISCV_EXCP_NONE;
1900}
1901
1902static RISCVException rmw_mip(CPURISCVState *env, int csrno,
1903                              target_ulong *ret_val,
1904                              target_ulong new_val, target_ulong wr_mask)
1905{
1906    uint64_t rval;
1907    RISCVException ret;
1908
1909    ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask);
1910    if (ret_val) {
1911        *ret_val = rval;
1912    }
1913
1914    return ret;
1915}
1916
1917static RISCVException rmw_miph(CPURISCVState *env, int csrno,
1918                               target_ulong *ret_val,
1919                               target_ulong new_val, target_ulong wr_mask)
1920{
1921    uint64_t rval;
1922    RISCVException ret;
1923
1924    ret = rmw_mip64(env, csrno, &rval,
1925        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
1926    if (ret_val) {
1927        *ret_val = rval >> 32;
1928    }
1929
1930    return ret;
1931}
1932
1933/* Supervisor Trap Setup */
1934static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
1935                                        Int128 *val)
1936{
1937    uint64_t mask = sstatus_v1_10_mask;
1938    uint64_t sstatus = env->mstatus & mask;
1939    if (env->xl != MXL_RV32 || env->debugger) {
1940        mask |= SSTATUS64_UXL;
1941    }
1942
1943    *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
1944    return RISCV_EXCP_NONE;
1945}
1946
1947static RISCVException read_sstatus(CPURISCVState *env, int csrno,
1948                                   target_ulong *val)
1949{
1950    target_ulong mask = (sstatus_v1_10_mask);
1951    if (env->xl != MXL_RV32 || env->debugger) {
1952        mask |= SSTATUS64_UXL;
1953    }
1954    /* TODO: Use SXL not MXL. */
1955    *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
1956    return RISCV_EXCP_NONE;
1957}
1958
1959static RISCVException write_sstatus(CPURISCVState *env, int csrno,
1960                                    target_ulong val)
1961{
1962    target_ulong mask = (sstatus_v1_10_mask);
1963
1964    if (env->xl != MXL_RV32 || env->debugger) {
1965        if ((val & SSTATUS64_UXL) != 0) {
1966            mask |= SSTATUS64_UXL;
1967        }
1968    }
1969    target_ulong newval = (env->mstatus & ~mask) | (val & mask);
1970    return write_mstatus(env, CSR_MSTATUS, newval);
1971}
1972
1973static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
1974                                 uint64_t *ret_val,
1975                                 uint64_t new_val, uint64_t wr_mask)
1976{
1977    RISCVException ret;
1978    uint64_t rval, vsbits, mask = env->hideleg & VS_MODE_INTERRUPTS;
1979
1980    /* Bring VS-level bits to correct position */
1981    vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
1982    new_val &= ~(VS_MODE_INTERRUPTS >> 1);
1983    new_val |= vsbits << 1;
1984    vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
1985    wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
1986    wr_mask |= vsbits << 1;
1987
1988    ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
1989    if (ret_val) {
1990        rval &= mask;
1991        vsbits = rval & VS_MODE_INTERRUPTS;
1992        rval &= ~VS_MODE_INTERRUPTS;
1993        *ret_val = rval | (vsbits >> 1);
1994    }
1995
1996    return ret;
1997}
1998
1999static RISCVException rmw_vsie(CPURISCVState *env, int csrno,
2000                               target_ulong *ret_val,
2001                               target_ulong new_val, target_ulong wr_mask)
2002{
2003    uint64_t rval;
2004    RISCVException ret;
2005
2006    ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask);
2007    if (ret_val) {
2008        *ret_val = rval;
2009    }
2010
2011    return ret;
2012}
2013
2014static RISCVException rmw_vsieh(CPURISCVState *env, int csrno,
2015                                target_ulong *ret_val,
2016                                target_ulong new_val, target_ulong wr_mask)
2017{
2018    uint64_t rval;
2019    RISCVException ret;
2020
2021    ret = rmw_vsie64(env, csrno, &rval,
2022        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2023    if (ret_val) {
2024        *ret_val = rval >> 32;
2025    }
2026
2027    return ret;
2028}
2029
2030static RISCVException rmw_sie64(CPURISCVState *env, int csrno,
2031                                uint64_t *ret_val,
2032                                uint64_t new_val, uint64_t wr_mask)
2033{
2034    RISCVException ret;
2035    uint64_t mask = env->mideleg & S_MODE_INTERRUPTS;
2036
2037    if (riscv_cpu_virt_enabled(env)) {
2038        if (env->hvictl & HVICTL_VTI) {
2039            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
2040        }
2041        ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask);
2042    } else {
2043        ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask);
2044    }
2045
2046    if (ret_val) {
2047        *ret_val &= mask;
2048    }
2049
2050    return ret;
2051}
2052
2053static RISCVException rmw_sie(CPURISCVState *env, int csrno,
2054                              target_ulong *ret_val,
2055                              target_ulong new_val, target_ulong wr_mask)
2056{
2057    uint64_t rval;
2058    RISCVException ret;
2059
2060    ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask);
2061    if (ret == RISCV_EXCP_NONE && ret_val) {
2062        *ret_val = rval;
2063    }
2064
2065    return ret;
2066}
2067
2068static RISCVException rmw_sieh(CPURISCVState *env, int csrno,
2069                               target_ulong *ret_val,
2070                               target_ulong new_val, target_ulong wr_mask)
2071{
2072    uint64_t rval;
2073    RISCVException ret;
2074
2075    ret = rmw_sie64(env, csrno, &rval,
2076        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2077    if (ret_val) {
2078        *ret_val = rval >> 32;
2079    }
2080
2081    return ret;
2082}
2083
2084static RISCVException read_stvec(CPURISCVState *env, int csrno,
2085                                 target_ulong *val)
2086{
2087    *val = env->stvec;
2088    return RISCV_EXCP_NONE;
2089}
2090
2091static RISCVException write_stvec(CPURISCVState *env, int csrno,
2092                                  target_ulong val)
2093{
2094    /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
2095    if ((val & 3) < 2) {
2096        env->stvec = val;
2097    } else {
2098        qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
2099    }
2100    return RISCV_EXCP_NONE;
2101}
2102
2103static RISCVException read_scounteren(CPURISCVState *env, int csrno,
2104                                      target_ulong *val)
2105{
2106    *val = env->scounteren;
2107    return RISCV_EXCP_NONE;
2108}
2109
2110static RISCVException write_scounteren(CPURISCVState *env, int csrno,
2111                                       target_ulong val)
2112{
2113    env->scounteren = val;
2114    return RISCV_EXCP_NONE;
2115}
2116
2117/* Supervisor Trap Handling */
2118static RISCVException read_sscratch_i128(CPURISCVState *env, int csrno,
2119                                         Int128 *val)
2120{
2121    *val = int128_make128(env->sscratch, env->sscratchh);
2122    return RISCV_EXCP_NONE;
2123}
2124
2125static RISCVException write_sscratch_i128(CPURISCVState *env, int csrno,
2126                                          Int128 val)
2127{
2128    env->sscratch = int128_getlo(val);
2129    env->sscratchh = int128_gethi(val);
2130    return RISCV_EXCP_NONE;
2131}
2132
2133static RISCVException read_sscratch(CPURISCVState *env, int csrno,
2134                                    target_ulong *val)
2135{
2136    *val = env->sscratch;
2137    return RISCV_EXCP_NONE;
2138}
2139
2140static RISCVException write_sscratch(CPURISCVState *env, int csrno,
2141                                     target_ulong val)
2142{
2143    env->sscratch = val;
2144    return RISCV_EXCP_NONE;
2145}
2146
2147static RISCVException read_sepc(CPURISCVState *env, int csrno,
2148                                target_ulong *val)
2149{
2150    *val = env->sepc;
2151    return RISCV_EXCP_NONE;
2152}
2153
2154static RISCVException write_sepc(CPURISCVState *env, int csrno,
2155                                 target_ulong val)
2156{
2157    env->sepc = val;
2158    return RISCV_EXCP_NONE;
2159}
2160
2161static RISCVException read_scause(CPURISCVState *env, int csrno,
2162                                  target_ulong *val)
2163{
2164    *val = env->scause;
2165    return RISCV_EXCP_NONE;
2166}
2167
2168static RISCVException write_scause(CPURISCVState *env, int csrno,
2169                                   target_ulong val)
2170{
2171    env->scause = val;
2172    return RISCV_EXCP_NONE;
2173}
2174
2175static RISCVException read_stval(CPURISCVState *env, int csrno,
2176                                 target_ulong *val)
2177{
2178    *val = env->stval;
2179    return RISCV_EXCP_NONE;
2180}
2181
2182static RISCVException write_stval(CPURISCVState *env, int csrno,
2183                                  target_ulong val)
2184{
2185    env->stval = val;
2186    return RISCV_EXCP_NONE;
2187}
2188
2189static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
2190                                 uint64_t *ret_val,
2191                                 uint64_t new_val, uint64_t wr_mask)
2192{
2193    RISCVException ret;
2194    uint64_t rval, vsbits, mask = env->hideleg & vsip_writable_mask;
2195
2196    /* Bring VS-level bits to correct position */
2197    vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
2198    new_val &= ~(VS_MODE_INTERRUPTS >> 1);
2199    new_val |= vsbits << 1;
2200    vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
2201    wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
2202    wr_mask |= vsbits << 1;
2203
2204    ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask & mask);
2205    if (ret_val) {
2206        rval &= mask;
2207        vsbits = rval & VS_MODE_INTERRUPTS;
2208        rval &= ~VS_MODE_INTERRUPTS;
2209        *ret_val = rval | (vsbits >> 1);
2210    }
2211
2212    return ret;
2213}
2214
2215static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
2216                               target_ulong *ret_val,
2217                               target_ulong new_val, target_ulong wr_mask)
2218{
2219    uint64_t rval;
2220    RISCVException ret;
2221
2222    ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask);
2223    if (ret_val) {
2224        *ret_val = rval;
2225    }
2226
2227    return ret;
2228}
2229
2230static RISCVException rmw_vsiph(CPURISCVState *env, int csrno,
2231                                target_ulong *ret_val,
2232                                target_ulong new_val, target_ulong wr_mask)
2233{
2234    uint64_t rval;
2235    RISCVException ret;
2236
2237    ret = rmw_vsip64(env, csrno, &rval,
2238        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2239    if (ret_val) {
2240        *ret_val = rval >> 32;
2241    }
2242
2243    return ret;
2244}
2245
2246static RISCVException rmw_sip64(CPURISCVState *env, int csrno,
2247                                uint64_t *ret_val,
2248                                uint64_t new_val, uint64_t wr_mask)
2249{
2250    RISCVException ret;
2251    uint64_t mask = env->mideleg & sip_writable_mask;
2252
2253    if (riscv_cpu_virt_enabled(env)) {
2254        if (env->hvictl & HVICTL_VTI) {
2255            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
2256        }
2257        ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask);
2258    } else {
2259        ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask);
2260    }
2261
2262    if (ret_val) {
2263        *ret_val &= env->mideleg & S_MODE_INTERRUPTS;
2264    }
2265
2266    return ret;
2267}
2268
2269static RISCVException rmw_sip(CPURISCVState *env, int csrno,
2270                              target_ulong *ret_val,
2271                              target_ulong new_val, target_ulong wr_mask)
2272{
2273    uint64_t rval;
2274    RISCVException ret;
2275
2276    ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask);
2277    if (ret_val) {
2278        *ret_val = rval;
2279    }
2280
2281    return ret;
2282}
2283
2284static RISCVException rmw_siph(CPURISCVState *env, int csrno,
2285                               target_ulong *ret_val,
2286                               target_ulong new_val, target_ulong wr_mask)
2287{
2288    uint64_t rval;
2289    RISCVException ret;
2290
2291    ret = rmw_sip64(env, csrno, &rval,
2292        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2293    if (ret_val) {
2294        *ret_val = rval >> 32;
2295    }
2296
2297    return ret;
2298}
2299
2300/* Supervisor Protection and Translation */
2301static RISCVException read_satp(CPURISCVState *env, int csrno,
2302                                target_ulong *val)
2303{
2304    if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
2305        *val = 0;
2306        return RISCV_EXCP_NONE;
2307    }
2308
2309    if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
2310        return RISCV_EXCP_ILLEGAL_INST;
2311    } else {
2312        *val = env->satp;
2313    }
2314
2315    return RISCV_EXCP_NONE;
2316}
2317
2318static RISCVException write_satp(CPURISCVState *env, int csrno,
2319                                 target_ulong val)
2320{
2321    target_ulong vm, mask;
2322
2323    if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
2324        return RISCV_EXCP_NONE;
2325    }
2326
2327    if (riscv_cpu_mxl(env) == MXL_RV32) {
2328        vm = validate_vm(env, get_field(val, SATP32_MODE));
2329        mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
2330    } else {
2331        vm = validate_vm(env, get_field(val, SATP64_MODE));
2332        mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN);
2333    }
2334
2335    if (vm && mask) {
2336        if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
2337            return RISCV_EXCP_ILLEGAL_INST;
2338        } else {
2339            /*
2340             * The ISA defines SATP.MODE=Bare as "no translation", but we still
2341             * pass these through QEMU's TLB emulation as it improves
2342             * performance.  Flushing the TLB on SATP writes with paging
2343             * enabled avoids leaking those invalid cached mappings.
2344             */
2345            tlb_flush(env_cpu(env));
2346            env->satp = val;
2347        }
2348    }
2349    return RISCV_EXCP_NONE;
2350}
2351
2352static int read_vstopi(CPURISCVState *env, int csrno, target_ulong *val)
2353{
2354    int irq, ret;
2355    target_ulong topei;
2356    uint64_t vseip, vsgein;
2357    uint32_t iid, iprio, hviid, hviprio, gein;
2358    uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS];
2359
2360    gein = get_field(env->hstatus, HSTATUS_VGEIN);
2361    hviid = get_field(env->hvictl, HVICTL_IID);
2362    hviprio = get_field(env->hvictl, HVICTL_IPRIO);
2363
2364    if (gein) {
2365        vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
2366        vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP;
2367        if (gein <= env->geilen && vseip) {
2368            siid[scount] = IRQ_S_EXT;
2369            siprio[scount] = IPRIO_MMAXIPRIO + 1;
2370            if (env->aia_ireg_rmw_fn[PRV_S]) {
2371                /*
2372                 * Call machine specific IMSIC register emulation for
2373                 * reading TOPEI.
2374                 */
2375                ret = env->aia_ireg_rmw_fn[PRV_S](
2376                        env->aia_ireg_rmw_fn_arg[PRV_S],
2377                        AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein,
2378                                      riscv_cpu_mxl_bits(env)),
2379                        &topei, 0, 0);
2380                if (!ret && topei) {
2381                    siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK;
2382                }
2383            }
2384            scount++;
2385        }
2386    } else {
2387        if (hviid == IRQ_S_EXT && hviprio) {
2388            siid[scount] = IRQ_S_EXT;
2389            siprio[scount] = hviprio;
2390            scount++;
2391        }
2392    }
2393
2394    if (env->hvictl & HVICTL_VTI) {
2395        if (hviid != IRQ_S_EXT) {
2396            siid[scount] = hviid;
2397            siprio[scount] = hviprio;
2398            scount++;
2399        }
2400    } else {
2401        irq = riscv_cpu_vsirq_pending(env);
2402        if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) {
2403            siid[scount] = irq;
2404            siprio[scount] = env->hviprio[irq];
2405            scount++;
2406        }
2407    }
2408
2409    iid = 0;
2410    iprio = UINT_MAX;
2411    for (s = 0; s < scount; s++) {
2412        if (siprio[s] < iprio) {
2413            iid = siid[s];
2414            iprio = siprio[s];
2415        }
2416    }
2417
2418    if (iid) {
2419        if (env->hvictl & HVICTL_IPRIOM) {
2420            if (iprio > IPRIO_MMAXIPRIO) {
2421                iprio = IPRIO_MMAXIPRIO;
2422            }
2423            if (!iprio) {
2424                if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) {
2425                    iprio = IPRIO_MMAXIPRIO;
2426                }
2427            }
2428        } else {
2429            iprio = 1;
2430        }
2431    } else {
2432        iprio = 0;
2433    }
2434
2435    *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2436    *val |= iprio;
2437    return RISCV_EXCP_NONE;
2438}
2439
2440static int read_stopi(CPURISCVState *env, int csrno, target_ulong *val)
2441{
2442    int irq;
2443    uint8_t iprio;
2444
2445    if (riscv_cpu_virt_enabled(env)) {
2446        return read_vstopi(env, CSR_VSTOPI, val);
2447    }
2448
2449    irq = riscv_cpu_sirq_pending(env);
2450    if (irq <= 0 || irq > 63) {
2451        *val = 0;
2452    } else {
2453        iprio = env->siprio[irq];
2454        if (!iprio) {
2455            if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) {
2456                iprio = IPRIO_MMAXIPRIO;
2457           }
2458        }
2459        *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT;
2460        *val |= iprio;
2461    }
2462
2463    return RISCV_EXCP_NONE;
2464}
2465
2466/* Hypervisor Extensions */
2467static RISCVException read_hstatus(CPURISCVState *env, int csrno,
2468                                   target_ulong *val)
2469{
2470    *val = env->hstatus;
2471    if (riscv_cpu_mxl(env) != MXL_RV32) {
2472        /* We only support 64-bit VSXL */
2473        *val = set_field(*val, HSTATUS_VSXL, 2);
2474    }
2475    /* We only support little endian */
2476    *val = set_field(*val, HSTATUS_VSBE, 0);
2477    return RISCV_EXCP_NONE;
2478}
2479
2480static RISCVException write_hstatus(CPURISCVState *env, int csrno,
2481                                    target_ulong val)
2482{
2483    env->hstatus = val;
2484    if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
2485        qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
2486    }
2487    if (get_field(val, HSTATUS_VSBE) != 0) {
2488        qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
2489    }
2490    return RISCV_EXCP_NONE;
2491}
2492
2493static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
2494                                   target_ulong *val)
2495{
2496    *val = env->hedeleg;
2497    return RISCV_EXCP_NONE;
2498}
2499
2500static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
2501                                    target_ulong val)
2502{
2503    env->hedeleg = val & vs_delegable_excps;
2504    return RISCV_EXCP_NONE;
2505}
2506
2507static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno,
2508                                    uint64_t *ret_val,
2509                                    uint64_t new_val, uint64_t wr_mask)
2510{
2511    uint64_t mask = wr_mask & vs_delegable_ints;
2512
2513    if (ret_val) {
2514        *ret_val = env->hideleg & vs_delegable_ints;
2515    }
2516
2517    env->hideleg = (env->hideleg & ~mask) | (new_val & mask);
2518    return RISCV_EXCP_NONE;
2519}
2520
2521static RISCVException rmw_hideleg(CPURISCVState *env, int csrno,
2522                                  target_ulong *ret_val,
2523                                  target_ulong new_val, target_ulong wr_mask)
2524{
2525    uint64_t rval;
2526    RISCVException ret;
2527
2528    ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask);
2529    if (ret_val) {
2530        *ret_val = rval;
2531    }
2532
2533    return ret;
2534}
2535
2536static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno,
2537                                   target_ulong *ret_val,
2538                                   target_ulong new_val, target_ulong wr_mask)
2539{
2540    uint64_t rval;
2541    RISCVException ret;
2542
2543    ret = rmw_hideleg64(env, csrno, &rval,
2544        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2545    if (ret_val) {
2546        *ret_val = rval >> 32;
2547    }
2548
2549    return ret;
2550}
2551
2552static RISCVException rmw_hvip64(CPURISCVState *env, int csrno,
2553                                 uint64_t *ret_val,
2554                                 uint64_t new_val, uint64_t wr_mask)
2555{
2556    RISCVException ret;
2557
2558    ret = rmw_mip64(env, csrno, ret_val, new_val,
2559                    wr_mask & hvip_writable_mask);
2560    if (ret_val) {
2561        *ret_val &= VS_MODE_INTERRUPTS;
2562    }
2563
2564    return ret;
2565}
2566
2567static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
2568                               target_ulong *ret_val,
2569                               target_ulong new_val, target_ulong wr_mask)
2570{
2571    uint64_t rval;
2572    RISCVException ret;
2573
2574    ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask);
2575    if (ret_val) {
2576        *ret_val = rval;
2577    }
2578
2579    return ret;
2580}
2581
2582static RISCVException rmw_hviph(CPURISCVState *env, int csrno,
2583                                target_ulong *ret_val,
2584                                target_ulong new_val, target_ulong wr_mask)
2585{
2586    uint64_t rval;
2587    RISCVException ret;
2588
2589    ret = rmw_hvip64(env, csrno, &rval,
2590        ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32);
2591    if (ret_val) {
2592        *ret_val = rval >> 32;
2593    }
2594
2595    return ret;
2596}
2597
2598static RISCVException rmw_hip(CPURISCVState *env, int csrno,
2599                              target_ulong *ret_value,
2600                              target_ulong new_value, target_ulong write_mask)
2601{
2602    int ret = rmw_mip(env, csrno, ret_value, new_value,
2603                      write_mask & hip_writable_mask);
2604
2605    if (ret_value) {
2606        *ret_value &= HS_MODE_INTERRUPTS;
2607    }
2608    return ret;
2609}
2610
2611static RISCVException rmw_hie(CPURISCVState *env, int csrno,
2612                              target_ulong *ret_val,
2613                              target_ulong new_val, target_ulong wr_mask)
2614{
2615    uint64_t rval;
2616    RISCVException ret;
2617
2618    ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS);
2619    if (ret_val) {
2620        *ret_val = rval & HS_MODE_INTERRUPTS;
2621    }
2622
2623    return ret;
2624}
2625
2626static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
2627                                      target_ulong *val)
2628{
2629    *val = env->hcounteren;
2630    return RISCV_EXCP_NONE;
2631}
2632
2633static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
2634                                       target_ulong val)
2635{
2636    env->hcounteren = val;
2637    return RISCV_EXCP_NONE;
2638}
2639
2640static RISCVException read_hgeie(CPURISCVState *env, int csrno,
2641                                 target_ulong *val)
2642{
2643    if (val) {
2644        *val = env->hgeie;
2645    }
2646    return RISCV_EXCP_NONE;
2647}
2648
2649static RISCVException write_hgeie(CPURISCVState *env, int csrno,
2650                                  target_ulong val)
2651{
2652    /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
2653    val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
2654    env->hgeie = val;
2655    /* Update mip.SGEIP bit */
2656    riscv_cpu_update_mip(env_archcpu(env), MIP_SGEIP,
2657                         BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
2658    return RISCV_EXCP_NONE;
2659}
2660
2661static RISCVException read_htval(CPURISCVState *env, int csrno,
2662                                 target_ulong *val)
2663{
2664    *val = env->htval;
2665    return RISCV_EXCP_NONE;
2666}
2667
2668static RISCVException write_htval(CPURISCVState *env, int csrno,
2669                                  target_ulong val)
2670{
2671    env->htval = val;
2672    return RISCV_EXCP_NONE;
2673}
2674
2675static RISCVException read_htinst(CPURISCVState *env, int csrno,
2676                                  target_ulong *val)
2677{
2678    *val = env->htinst;
2679    return RISCV_EXCP_NONE;
2680}
2681
2682static RISCVException write_htinst(CPURISCVState *env, int csrno,
2683                                   target_ulong val)
2684{
2685    return RISCV_EXCP_NONE;
2686}
2687
2688static RISCVException read_hgeip(CPURISCVState *env, int csrno,
2689                                 target_ulong *val)
2690{
2691    if (val) {
2692        *val = env->hgeip;
2693    }
2694    return RISCV_EXCP_NONE;
2695}
2696
2697static RISCVException read_hgatp(CPURISCVState *env, int csrno,
2698                                 target_ulong *val)
2699{
2700    *val = env->hgatp;
2701    return RISCV_EXCP_NONE;
2702}
2703
2704static RISCVException write_hgatp(CPURISCVState *env, int csrno,
2705                                  target_ulong val)
2706{
2707    env->hgatp = val;
2708    return RISCV_EXCP_NONE;
2709}
2710
2711static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
2712                                      target_ulong *val)
2713{
2714    if (!env->rdtime_fn) {
2715        return RISCV_EXCP_ILLEGAL_INST;
2716    }
2717
2718    *val = env->htimedelta;
2719    return RISCV_EXCP_NONE;
2720}
2721
2722static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
2723                                       target_ulong val)
2724{
2725    if (!env->rdtime_fn) {
2726        return RISCV_EXCP_ILLEGAL_INST;
2727    }
2728
2729    if (riscv_cpu_mxl(env) == MXL_RV32) {
2730        env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
2731    } else {
2732        env->htimedelta = val;
2733    }
2734    return RISCV_EXCP_NONE;
2735}
2736
2737static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
2738                                       target_ulong *val)
2739{
2740    if (!env->rdtime_fn) {
2741        return RISCV_EXCP_ILLEGAL_INST;
2742    }
2743
2744    *val = env->htimedelta >> 32;
2745    return RISCV_EXCP_NONE;
2746}
2747
2748static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
2749                                        target_ulong val)
2750{
2751    if (!env->rdtime_fn) {
2752        return RISCV_EXCP_ILLEGAL_INST;
2753    }
2754
2755    env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
2756    return RISCV_EXCP_NONE;
2757}
2758
2759static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
2760{
2761    *val = env->hvictl;
2762    return RISCV_EXCP_NONE;
2763}
2764
2765static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
2766{
2767    env->hvictl = val & HVICTL_VALID_MASK;
2768    return RISCV_EXCP_NONE;
2769}
2770
2771static int read_hvipriox(CPURISCVState *env, int first_index,
2772                         uint8_t *iprio, target_ulong *val)
2773{
2774    int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
2775
2776    /* First index has to be a multiple of number of irqs per register */
2777    if (first_index % num_irqs) {
2778        return (riscv_cpu_virt_enabled(env)) ?
2779               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2780    }
2781
2782    /* Fill-up return value */
2783    *val = 0;
2784    for (i = 0; i < num_irqs; i++) {
2785        if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
2786            continue;
2787        }
2788        if (rdzero) {
2789            continue;
2790        }
2791        *val |= ((target_ulong)iprio[irq]) << (i * 8);
2792    }
2793
2794    return RISCV_EXCP_NONE;
2795}
2796
2797static int write_hvipriox(CPURISCVState *env, int first_index,
2798                          uint8_t *iprio, target_ulong val)
2799{
2800    int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32);
2801
2802    /* First index has to be a multiple of number of irqs per register */
2803    if (first_index % num_irqs) {
2804        return (riscv_cpu_virt_enabled(env)) ?
2805               RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
2806    }
2807
2808    /* Fill-up priority arrary */
2809    for (i = 0; i < num_irqs; i++) {
2810        if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) {
2811            continue;
2812        }
2813        if (rdzero) {
2814            iprio[irq] = 0;
2815        } else {
2816            iprio[irq] = (val >> (i * 8)) & 0xff;
2817        }
2818    }
2819
2820    return RISCV_EXCP_NONE;
2821}
2822
2823static int read_hviprio1(CPURISCVState *env, int csrno, target_ulong *val)
2824{
2825    return read_hvipriox(env, 0, env->hviprio, val);
2826}
2827
2828static int write_hviprio1(CPURISCVState *env, int csrno, target_ulong val)
2829{
2830    return write_hvipriox(env, 0, env->hviprio, val);
2831}
2832
2833static int read_hviprio1h(CPURISCVState *env, int csrno, target_ulong *val)
2834{
2835    return read_hvipriox(env, 4, env->hviprio, val);
2836}
2837
2838static int write_hviprio1h(CPURISCVState *env, int csrno, target_ulong val)
2839{
2840    return write_hvipriox(env, 4, env->hviprio, val);
2841}
2842
2843static int read_hviprio2(CPURISCVState *env, int csrno, target_ulong *val)
2844{
2845    return read_hvipriox(env, 8, env->hviprio, val);
2846}
2847
2848static int write_hviprio2(CPURISCVState *env, int csrno, target_ulong val)
2849{
2850    return write_hvipriox(env, 8, env->hviprio, val);
2851}
2852
2853static int read_hviprio2h(CPURISCVState *env, int csrno, target_ulong *val)
2854{
2855    return read_hvipriox(env, 12, env->hviprio, val);
2856}
2857
2858static int write_hviprio2h(CPURISCVState *env, int csrno, target_ulong val)
2859{
2860    return write_hvipriox(env, 12, env->hviprio, val);
2861}
2862
2863/* Virtual CSR Registers */
2864static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
2865                                    target_ulong *val)
2866{
2867    *val = env->vsstatus;
2868    return RISCV_EXCP_NONE;
2869}
2870
2871static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
2872                                     target_ulong val)
2873{
2874    uint64_t mask = (target_ulong)-1;
2875    if ((val & VSSTATUS64_UXL) == 0) {
2876        mask &= ~VSSTATUS64_UXL;
2877    }
2878    env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
2879    return RISCV_EXCP_NONE;
2880}
2881
2882static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
2883{
2884    *val = env->vstvec;
2885    return RISCV_EXCP_NONE;
2886}
2887
2888static RISCVException write_vstvec(CPURISCVState *env, int csrno,
2889                                   target_ulong val)
2890{
2891    env->vstvec = val;
2892    return RISCV_EXCP_NONE;
2893}
2894
2895static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
2896                                     target_ulong *val)
2897{
2898    *val = env->vsscratch;
2899    return RISCV_EXCP_NONE;
2900}
2901
2902static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
2903                                      target_ulong val)
2904{
2905    env->vsscratch = val;
2906    return RISCV_EXCP_NONE;
2907}
2908
2909static RISCVException read_vsepc(CPURISCVState *env, int csrno,
2910                                 target_ulong *val)
2911{
2912    *val = env->vsepc;
2913    return RISCV_EXCP_NONE;
2914}
2915
2916static RISCVException write_vsepc(CPURISCVState *env, int csrno,
2917                                  target_ulong val)
2918{
2919    env->vsepc = val;
2920    return RISCV_EXCP_NONE;
2921}
2922
2923static RISCVException read_vscause(CPURISCVState *env, int csrno,
2924                                   target_ulong *val)
2925{
2926    *val = env->vscause;
2927    return RISCV_EXCP_NONE;
2928}
2929
2930static RISCVException write_vscause(CPURISCVState *env, int csrno,
2931                                    target_ulong val)
2932{
2933    env->vscause = val;
2934    return RISCV_EXCP_NONE;
2935}
2936
2937static RISCVException read_vstval(CPURISCVState *env, int csrno,
2938                                  target_ulong *val)
2939{
2940    *val = env->vstval;
2941    return RISCV_EXCP_NONE;
2942}
2943
2944static RISCVException write_vstval(CPURISCVState *env, int csrno,
2945                                   target_ulong val)
2946{
2947    env->vstval = val;
2948    return RISCV_EXCP_NONE;
2949}
2950
2951static RISCVException read_vsatp(CPURISCVState *env, int csrno,
2952                                 target_ulong *val)
2953{
2954    *val = env->vsatp;
2955    return RISCV_EXCP_NONE;
2956}
2957
2958static RISCVException write_vsatp(CPURISCVState *env, int csrno,
2959                                  target_ulong val)
2960{
2961    env->vsatp = val;
2962    return RISCV_EXCP_NONE;
2963}
2964
2965static RISCVException read_mtval2(CPURISCVState *env, int csrno,
2966                                  target_ulong *val)
2967{
2968    *val = env->mtval2;
2969    return RISCV_EXCP_NONE;
2970}
2971
2972static RISCVException write_mtval2(CPURISCVState *env, int csrno,
2973                                   target_ulong val)
2974{
2975    env->mtval2 = val;
2976    return RISCV_EXCP_NONE;
2977}
2978
2979static RISCVException read_mtinst(CPURISCVState *env, int csrno,
2980                                  target_ulong *val)
2981{
2982    *val = env->mtinst;
2983    return RISCV_EXCP_NONE;
2984}
2985
2986static RISCVException write_mtinst(CPURISCVState *env, int csrno,
2987                                   target_ulong val)
2988{
2989    env->mtinst = val;
2990    return RISCV_EXCP_NONE;
2991}
2992
2993/* Physical Memory Protection */
2994static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
2995                                   target_ulong *val)
2996{
2997    *val = mseccfg_csr_read(env);
2998    return RISCV_EXCP_NONE;
2999}
3000
3001static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
3002                         target_ulong val)
3003{
3004    mseccfg_csr_write(env, val);
3005    return RISCV_EXCP_NONE;
3006}
3007
3008static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
3009{
3010    /* TODO: RV128 restriction check */
3011    if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
3012        return false;
3013    }
3014    return true;
3015}
3016
3017static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
3018                                  target_ulong *val)
3019{
3020    uint32_t reg_index = csrno - CSR_PMPCFG0;
3021
3022    if (!check_pmp_reg_index(env, reg_index)) {
3023        return RISCV_EXCP_ILLEGAL_INST;
3024    }
3025    *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
3026    return RISCV_EXCP_NONE;
3027}
3028
3029static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
3030                                   target_ulong val)
3031{
3032    uint32_t reg_index = csrno - CSR_PMPCFG0;
3033
3034    if (!check_pmp_reg_index(env, reg_index)) {
3035        return RISCV_EXCP_ILLEGAL_INST;
3036    }
3037    pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
3038    return RISCV_EXCP_NONE;
3039}
3040
3041static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
3042                                   target_ulong *val)
3043{
3044    *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
3045    return RISCV_EXCP_NONE;
3046}
3047
3048static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
3049                                    target_ulong val)
3050{
3051    pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
3052    return RISCV_EXCP_NONE;
3053}
3054
3055static RISCVException read_tselect(CPURISCVState *env, int csrno,
3056                                   target_ulong *val)
3057{
3058    *val = tselect_csr_read(env);
3059    return RISCV_EXCP_NONE;
3060}
3061
3062static RISCVException write_tselect(CPURISCVState *env, int csrno,
3063                                    target_ulong val)
3064{
3065    tselect_csr_write(env, val);
3066    return RISCV_EXCP_NONE;
3067}
3068
3069static RISCVException read_tdata(CPURISCVState *env, int csrno,
3070                                 target_ulong *val)
3071{
3072    /* return 0 in tdata1 to end the trigger enumeration */
3073    if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
3074        *val = 0;
3075        return RISCV_EXCP_NONE;
3076    }
3077
3078    if (!tdata_available(env, csrno - CSR_TDATA1)) {
3079        return RISCV_EXCP_ILLEGAL_INST;
3080    }
3081
3082    *val = tdata_csr_read(env, csrno - CSR_TDATA1);
3083    return RISCV_EXCP_NONE;
3084}
3085
3086static RISCVException write_tdata(CPURISCVState *env, int csrno,
3087                                  target_ulong val)
3088{
3089    if (!tdata_available(env, csrno - CSR_TDATA1)) {
3090        return RISCV_EXCP_ILLEGAL_INST;
3091    }
3092
3093    tdata_csr_write(env, csrno - CSR_TDATA1, val);
3094    return RISCV_EXCP_NONE;
3095}
3096
3097static RISCVException read_tinfo(CPURISCVState *env, int csrno,
3098                                 target_ulong *val)
3099{
3100    *val = tinfo_csr_read(env);
3101    return RISCV_EXCP_NONE;
3102}
3103
3104/*
3105 * Functions to access Pointer Masking feature registers
3106 * We have to check if current priv lvl could modify
3107 * csr in given mode
3108 */
3109static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
3110{
3111    int csr_priv = get_field(csrno, 0x300);
3112    int pm_current;
3113
3114    if (env->debugger) {
3115        return false;
3116    }
3117    /*
3118     * If priv lvls differ that means we're accessing csr from higher priv lvl,
3119     * so allow the access
3120     */
3121    if (env->priv != csr_priv) {
3122        return false;
3123    }
3124    switch (env->priv) {
3125    case PRV_M:
3126        pm_current = get_field(env->mmte, M_PM_CURRENT);
3127        break;
3128    case PRV_S:
3129        pm_current = get_field(env->mmte, S_PM_CURRENT);
3130        break;
3131    case PRV_U:
3132        pm_current = get_field(env->mmte, U_PM_CURRENT);
3133        break;
3134    default:
3135        g_assert_not_reached();
3136    }
3137    /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
3138    return !pm_current;
3139}
3140
3141static RISCVException read_mmte(CPURISCVState *env, int csrno,
3142                                target_ulong *val)
3143{
3144    *val = env->mmte & MMTE_MASK;
3145    return RISCV_EXCP_NONE;
3146}
3147
3148static RISCVException write_mmte(CPURISCVState *env, int csrno,
3149                                 target_ulong val)
3150{
3151    uint64_t mstatus;
3152    target_ulong wpri_val = val & MMTE_MASK;
3153
3154    if (val != wpri_val) {
3155        qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
3156                      "MMTE: WPRI violation written 0x", val,
3157                      "vs expected 0x", wpri_val);
3158    }
3159    /* for machine mode pm.current is hardwired to 1 */
3160    wpri_val |= MMTE_M_PM_CURRENT;
3161
3162    /* hardwiring pm.instruction bit to 0, since it's not supported yet */
3163    wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
3164    env->mmte = wpri_val | PM_EXT_DIRTY;
3165    riscv_cpu_update_mask(env);
3166
3167    /* Set XS and SD bits, since PM CSRs are dirty */
3168    mstatus = env->mstatus | MSTATUS_XS;
3169    write_mstatus(env, csrno, mstatus);
3170    return RISCV_EXCP_NONE;
3171}
3172
3173static RISCVException read_smte(CPURISCVState *env, int csrno,
3174                                target_ulong *val)
3175{
3176    *val = env->mmte & SMTE_MASK;
3177    return RISCV_EXCP_NONE;
3178}
3179
3180static RISCVException write_smte(CPURISCVState *env, int csrno,
3181                                 target_ulong val)
3182{
3183    target_ulong wpri_val = val & SMTE_MASK;
3184
3185    if (val != wpri_val) {
3186        qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
3187                      "SMTE: WPRI violation written 0x", val,
3188                      "vs expected 0x", wpri_val);
3189    }
3190
3191    /* if pm.current==0 we can't modify current PM CSRs */
3192    if (check_pm_current_disabled(env, csrno)) {
3193        return RISCV_EXCP_NONE;
3194    }
3195
3196    wpri_val |= (env->mmte & ~SMTE_MASK);
3197    write_mmte(env, csrno, wpri_val);
3198    return RISCV_EXCP_NONE;
3199}
3200
3201static RISCVException read_umte(CPURISCVState *env, int csrno,
3202                                target_ulong *val)
3203{
3204    *val = env->mmte & UMTE_MASK;
3205    return RISCV_EXCP_NONE;
3206}
3207
3208static RISCVException write_umte(CPURISCVState *env, int csrno,
3209                                 target_ulong val)
3210{
3211    target_ulong wpri_val = val & UMTE_MASK;
3212
3213    if (val != wpri_val) {
3214        qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx "\n",
3215                      "UMTE: WPRI violation written 0x", val,
3216                      "vs expected 0x", wpri_val);
3217    }
3218
3219    if (check_pm_current_disabled(env, csrno)) {
3220        return RISCV_EXCP_NONE;
3221    }
3222
3223    wpri_val |= (env->mmte & ~UMTE_MASK);
3224    write_mmte(env, csrno, wpri_val);
3225    return RISCV_EXCP_NONE;
3226}
3227
3228static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
3229                                   target_ulong *val)
3230{
3231    *val = env->mpmmask;
3232    return RISCV_EXCP_NONE;
3233}
3234
3235static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
3236                                    target_ulong val)
3237{
3238    uint64_t mstatus;
3239
3240    env->mpmmask = val;
3241    if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
3242        env->cur_pmmask = val;
3243    }
3244    env->mmte |= PM_EXT_DIRTY;
3245
3246    /* Set XS and SD bits, since PM CSRs are dirty */
3247    mstatus = env->mstatus | MSTATUS_XS;
3248    write_mstatus(env, csrno, mstatus);
3249    return RISCV_EXCP_NONE;
3250}
3251
3252static RISCVException read_spmmask(CPURISCVState *env, int csrno,
3253                                   target_ulong *val)
3254{
3255    *val = env->spmmask;
3256    return RISCV_EXCP_NONE;
3257}
3258
3259static RISCVException write_spmmask(CPURISCVState *env, int csrno,
3260                                    target_ulong val)
3261{
3262    uint64_t mstatus;
3263
3264    /* if pm.current==0 we can't modify current PM CSRs */
3265    if (check_pm_current_disabled(env, csrno)) {
3266        return RISCV_EXCP_NONE;
3267    }
3268    env->spmmask = val;
3269    if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
3270        env->cur_pmmask = val;
3271    }
3272    env->mmte |= PM_EXT_DIRTY;
3273
3274    /* Set XS and SD bits, since PM CSRs are dirty */
3275    mstatus = env->mstatus | MSTATUS_XS;
3276    write_mstatus(env, csrno, mstatus);
3277    return RISCV_EXCP_NONE;
3278}
3279
3280static RISCVException read_upmmask(CPURISCVState *env, int csrno,
3281                                   target_ulong *val)
3282{
3283    *val = env->upmmask;
3284    return RISCV_EXCP_NONE;
3285}
3286
3287static RISCVException write_upmmask(CPURISCVState *env, int csrno,
3288                                    target_ulong val)
3289{
3290    uint64_t mstatus;
3291
3292    /* if pm.current==0 we can't modify current PM CSRs */
3293    if (check_pm_current_disabled(env, csrno)) {
3294        return RISCV_EXCP_NONE;
3295    }
3296    env->upmmask = val;
3297    if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
3298        env->cur_pmmask = val;
3299    }
3300    env->mmte |= PM_EXT_DIRTY;
3301
3302    /* Set XS and SD bits, since PM CSRs are dirty */
3303    mstatus = env->mstatus | MSTATUS_XS;
3304    write_mstatus(env, csrno, mstatus);
3305    return RISCV_EXCP_NONE;
3306}
3307
3308static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
3309                                   target_ulong *val)
3310{
3311    *val = env->mpmbase;
3312    return RISCV_EXCP_NONE;
3313}
3314
3315static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
3316                                    target_ulong val)
3317{
3318    uint64_t mstatus;
3319
3320    env->mpmbase = val;
3321    if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
3322        env->cur_pmbase = val;
3323    }
3324    env->mmte |= PM_EXT_DIRTY;
3325
3326    /* Set XS and SD bits, since PM CSRs are dirty */
3327    mstatus = env->mstatus | MSTATUS_XS;
3328    write_mstatus(env, csrno, mstatus);
3329    return RISCV_EXCP_NONE;
3330}
3331
3332static RISCVException read_spmbase(CPURISCVState *env, int csrno,
3333                                   target_ulong *val)
3334{
3335    *val = env->spmbase;
3336    return RISCV_EXCP_NONE;
3337}
3338
3339static RISCVException write_spmbase(CPURISCVState *env, int csrno,
3340                                    target_ulong val)
3341{
3342    uint64_t mstatus;
3343
3344    /* if pm.current==0 we can't modify current PM CSRs */
3345    if (check_pm_current_disabled(env, csrno)) {
3346        return RISCV_EXCP_NONE;
3347    }
3348    env->spmbase = val;
3349    if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
3350        env->cur_pmbase = val;
3351    }
3352    env->mmte |= PM_EXT_DIRTY;
3353
3354    /* Set XS and SD bits, since PM CSRs are dirty */
3355    mstatus = env->mstatus | MSTATUS_XS;
3356    write_mstatus(env, csrno, mstatus);
3357    return RISCV_EXCP_NONE;
3358}
3359
3360static RISCVException read_upmbase(CPURISCVState *env, int csrno,
3361                                   target_ulong *val)
3362{
3363    *val = env->upmbase;
3364    return RISCV_EXCP_NONE;
3365}
3366
3367static RISCVException write_upmbase(CPURISCVState *env, int csrno,
3368                                    target_ulong val)
3369{
3370    uint64_t mstatus;
3371
3372    /* if pm.current==0 we can't modify current PM CSRs */
3373    if (check_pm_current_disabled(env, csrno)) {
3374        return RISCV_EXCP_NONE;
3375    }
3376    env->upmbase = val;
3377    if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
3378        env->cur_pmbase = val;
3379    }
3380    env->mmte |= PM_EXT_DIRTY;
3381
3382    /* Set XS and SD bits, since PM CSRs are dirty */
3383    mstatus = env->mstatus | MSTATUS_XS;
3384    write_mstatus(env, csrno, mstatus);
3385    return RISCV_EXCP_NONE;
3386}
3387
3388#endif
3389
3390/* Crypto Extension */
3391static RISCVException rmw_seed(CPURISCVState *env, int csrno,
3392                               target_ulong *ret_value,
3393                               target_ulong new_value,
3394                               target_ulong write_mask)
3395{
3396    uint16_t random_v;
3397    Error *random_e = NULL;
3398    int random_r;
3399    target_ulong rval;
3400
3401    random_r = qemu_guest_getrandom(&random_v, 2, &random_e);
3402    if (unlikely(random_r < 0)) {
3403        /*
3404         * Failed, for unknown reasons in the crypto subsystem.
3405         * The best we can do is log the reason and return a
3406         * failure indication to the guest.  There is no reason
3407         * we know to expect the failure to be transitory, so
3408         * indicate DEAD to avoid having the guest spin on WAIT.
3409         */
3410        qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
3411                      __func__, error_get_pretty(random_e));
3412        error_free(random_e);
3413        rval = SEED_OPST_DEAD;
3414    } else {
3415        rval = random_v | SEED_OPST_ES16;
3416    }
3417
3418    if (ret_value) {
3419        *ret_value = rval;
3420    }
3421
3422    return RISCV_EXCP_NONE;
3423}
3424
3425/*
3426 * riscv_csrrw - read and/or update control and status register
3427 *
3428 * csrr   <->  riscv_csrrw(env, csrno, ret_value, 0, 0);
3429 * csrrw  <->  riscv_csrrw(env, csrno, ret_value, value, -1);
3430 * csrrs  <->  riscv_csrrw(env, csrno, ret_value, -1, value);
3431 * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
3432 */
3433
3434static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
3435                                               int csrno,
3436                                               bool write_mask,
3437                                               RISCVCPU *cpu)
3438{
3439    /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
3440    int read_only = get_field(csrno, 0xC00) == 3;
3441    int csr_min_priv = csr_ops[csrno].min_priv_ver;
3442
3443    /* ensure the CSR extension is enabled. */
3444    if (!cpu->cfg.ext_icsr) {
3445        return RISCV_EXCP_ILLEGAL_INST;
3446    }
3447
3448    if (env->priv_ver < csr_min_priv) {
3449        return RISCV_EXCP_ILLEGAL_INST;
3450    }
3451
3452    /* check predicate */
3453    if (!csr_ops[csrno].predicate) {
3454        return RISCV_EXCP_ILLEGAL_INST;
3455    }
3456
3457    if (write_mask && read_only) {
3458        return RISCV_EXCP_ILLEGAL_INST;
3459    }
3460
3461    RISCVException ret = csr_ops[csrno].predicate(env, csrno);
3462    if (ret != RISCV_EXCP_NONE) {
3463        return ret;
3464    }
3465
3466#if !defined(CONFIG_USER_ONLY)
3467    int csr_priv, effective_priv = env->priv;
3468
3469    if (riscv_has_ext(env, RVH) && env->priv == PRV_S &&
3470        !riscv_cpu_virt_enabled(env)) {
3471        /*
3472         * We are in HS mode. Add 1 to the effective privledge level to
3473         * allow us to access the Hypervisor CSRs.
3474         */
3475        effective_priv++;
3476    }
3477
3478    csr_priv = get_field(csrno, 0x300);
3479    if (!env->debugger && (effective_priv < csr_priv)) {
3480        if (csr_priv == (PRV_S + 1) && riscv_cpu_virt_enabled(env)) {
3481            return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
3482        }
3483        return RISCV_EXCP_ILLEGAL_INST;
3484    }
3485#endif
3486    return RISCV_EXCP_NONE;
3487}
3488
3489static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
3490                                       target_ulong *ret_value,
3491                                       target_ulong new_value,
3492                                       target_ulong write_mask)
3493{
3494    RISCVException ret;
3495    target_ulong old_value;
3496
3497    /* execute combined read/write operation if it exists */
3498    if (csr_ops[csrno].op) {
3499        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
3500    }
3501
3502    /* if no accessor exists then return failure */
3503    if (!csr_ops[csrno].read) {
3504        return RISCV_EXCP_ILLEGAL_INST;
3505    }
3506    /* read old value */
3507    ret = csr_ops[csrno].read(env, csrno, &old_value);
3508    if (ret != RISCV_EXCP_NONE) {
3509        return ret;
3510    }
3511
3512    /* write value if writable and write mask set, otherwise drop writes */
3513    if (write_mask) {
3514        new_value = (old_value & ~write_mask) | (new_value & write_mask);
3515        if (csr_ops[csrno].write) {
3516            ret = csr_ops[csrno].write(env, csrno, new_value);
3517            if (ret != RISCV_EXCP_NONE) {
3518                return ret;
3519            }
3520        }
3521    }
3522
3523    /* return old value */
3524    if (ret_value) {
3525        *ret_value = old_value;
3526    }
3527
3528    return RISCV_EXCP_NONE;
3529}
3530
3531RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
3532                           target_ulong *ret_value,
3533                           target_ulong new_value, target_ulong write_mask)
3534{
3535    RISCVCPU *cpu = env_archcpu(env);
3536
3537    RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu);
3538    if (ret != RISCV_EXCP_NONE) {
3539        return ret;
3540    }
3541
3542    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
3543}
3544
3545static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
3546                                        Int128 *ret_value,
3547                                        Int128 new_value,
3548                                        Int128 write_mask)
3549{
3550    RISCVException ret;
3551    Int128 old_value;
3552
3553    /* read old value */
3554    ret = csr_ops[csrno].read128(env, csrno, &old_value);
3555    if (ret != RISCV_EXCP_NONE) {
3556        return ret;
3557    }
3558
3559    /* write value if writable and write mask set, otherwise drop writes */
3560    if (int128_nz(write_mask)) {
3561        new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
3562                              int128_and(new_value, write_mask));
3563        if (csr_ops[csrno].write128) {
3564            ret = csr_ops[csrno].write128(env, csrno, new_value);
3565            if (ret != RISCV_EXCP_NONE) {
3566                return ret;
3567            }
3568        } else if (csr_ops[csrno].write) {
3569            /* avoids having to write wrappers for all registers */
3570            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
3571            if (ret != RISCV_EXCP_NONE) {
3572                return ret;
3573            }
3574        }
3575    }
3576
3577    /* return old value */
3578    if (ret_value) {
3579        *ret_value = old_value;
3580    }
3581
3582    return RISCV_EXCP_NONE;
3583}
3584
3585RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
3586                                Int128 *ret_value,
3587                                Int128 new_value, Int128 write_mask)
3588{
3589    RISCVException ret;
3590    RISCVCPU *cpu = env_archcpu(env);
3591
3592    ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu);
3593    if (ret != RISCV_EXCP_NONE) {
3594        return ret;
3595    }
3596
3597    if (csr_ops[csrno].read128) {
3598        return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
3599    }
3600
3601    /*
3602     * Fall back to 64-bit version for now, if the 128-bit alternative isn't
3603     * at all defined.
3604     * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
3605     * significant), for those, this fallback is correctly handling the accesses
3606     */
3607    target_ulong old_value;
3608    ret = riscv_csrrw_do64(env, csrno, &old_value,
3609                           int128_getlo(new_value),
3610                           int128_getlo(write_mask));
3611    if (ret == RISCV_EXCP_NONE && ret_value) {
3612        *ret_value = int128_make64(old_value);
3613    }
3614    return ret;
3615}
3616
3617/*
3618 * Debugger support.  If not in user mode, set env->debugger before the
3619 * riscv_csrrw call and clear it after the call.
3620 */
3621RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
3622                                 target_ulong *ret_value,
3623                                 target_ulong new_value,
3624                                 target_ulong write_mask)
3625{
3626    RISCVException ret;
3627#if !defined(CONFIG_USER_ONLY)
3628    env->debugger = true;
3629#endif
3630    ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
3631#if !defined(CONFIG_USER_ONLY)
3632    env->debugger = false;
3633#endif
3634    return ret;
3635}
3636
3637/* Control and Status Register function table */
3638riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
3639    /* User Floating-Point CSRs */
3640    [CSR_FFLAGS]   = { "fflags",   fs,     read_fflags,  write_fflags },
3641    [CSR_FRM]      = { "frm",      fs,     read_frm,     write_frm    },
3642    [CSR_FCSR]     = { "fcsr",     fs,     read_fcsr,    write_fcsr   },
3643    /* Vector CSRs */
3644    [CSR_VSTART]   = { "vstart",   vs,     read_vstart,  write_vstart,
3645                       .min_priv_ver = PRIV_VERSION_1_12_0            },
3646    [CSR_VXSAT]    = { "vxsat",    vs,     read_vxsat,   write_vxsat,
3647                       .min_priv_ver = PRIV_VERSION_1_12_0            },
3648    [CSR_VXRM]     = { "vxrm",     vs,     read_vxrm,    write_vxrm,
3649                       .min_priv_ver = PRIV_VERSION_1_12_0            },
3650    [CSR_VCSR]     = { "vcsr",     vs,     read_vcsr,    write_vcsr,
3651                       .min_priv_ver = PRIV_VERSION_1_12_0            },
3652    [CSR_VL]       = { "vl",       vs,     read_vl,
3653                       .min_priv_ver = PRIV_VERSION_1_12_0            },
3654    [CSR_VTYPE]    = { "vtype",    vs,     read_vtype,
3655                       .min_priv_ver = PRIV_VERSION_1_12_0            },
3656    [CSR_VLENB]    = { "vlenb",    vs,     read_vlenb,
3657                       .min_priv_ver = PRIV_VERSION_1_12_0            },
3658    /* User Timers and Counters */
3659    [CSR_CYCLE]    = { "cycle",    ctr,    read_hpmcounter  },
3660    [CSR_INSTRET]  = { "instret",  ctr,    read_hpmcounter  },
3661    [CSR_CYCLEH]   = { "cycleh",   ctr32,  read_hpmcounterh },
3662    [CSR_INSTRETH] = { "instreth", ctr32,  read_hpmcounterh },
3663
3664    /*
3665     * In privileged mode, the monitor will have to emulate TIME CSRs only if
3666     * rdtime callback is not provided by machine/platform emulation.
3667     */
3668    [CSR_TIME]  = { "time",  ctr,   read_time  },
3669    [CSR_TIMEH] = { "timeh", ctr32, read_timeh },
3670
3671    /* Crypto Extension */
3672    [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
3673
3674#if !defined(CONFIG_USER_ONLY)
3675    /* Machine Timers and Counters */
3676    [CSR_MCYCLE]    = { "mcycle",    any,   read_hpmcounter,
3677                        write_mhpmcounter                    },
3678    [CSR_MINSTRET]  = { "minstret",  any,   read_hpmcounter,
3679                        write_mhpmcounter                    },
3680    [CSR_MCYCLEH]   = { "mcycleh",   any32, read_hpmcounterh,
3681                        write_mhpmcounterh                   },
3682    [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh,
3683                        write_mhpmcounterh                   },
3684
3685    /* Machine Information Registers */
3686    [CSR_MVENDORID] = { "mvendorid", any,   read_mvendorid },
3687    [CSR_MARCHID]   = { "marchid",   any,   read_marchid   },
3688    [CSR_MIMPID]    = { "mimpid",    any,   read_mimpid    },
3689    [CSR_MHARTID]   = { "mhartid",   any,   read_mhartid   },
3690
3691    [CSR_MCONFIGPTR]  = { "mconfigptr", any,   read_zero,
3692                          .min_priv_ver = PRIV_VERSION_1_12_0 },
3693    /* Machine Trap Setup */
3694    [CSR_MSTATUS]     = { "mstatus",    any,   read_mstatus, write_mstatus,
3695                          NULL,                read_mstatus_i128           },
3696    [CSR_MISA]        = { "misa",       any,   read_misa,    write_misa,
3697                          NULL,                read_misa_i128              },
3698    [CSR_MIDELEG]     = { "mideleg",    any,   NULL, NULL,   rmw_mideleg   },
3699    [CSR_MEDELEG]     = { "medeleg",    any,   read_medeleg, write_medeleg },
3700    [CSR_MIE]         = { "mie",        any,   NULL, NULL,   rmw_mie       },
3701    [CSR_MTVEC]       = { "mtvec",      any,   read_mtvec,   write_mtvec   },
3702    [CSR_MCOUNTEREN]  = { "mcounteren", umode, read_mcounteren,
3703                          write_mcounteren                                 },
3704
3705    [CSR_MSTATUSH]    = { "mstatush",   any32, read_mstatush,
3706                          write_mstatush                                   },
3707
3708    /* Machine Trap Handling */
3709    [CSR_MSCRATCH] = { "mscratch", any,  read_mscratch, write_mscratch,
3710                       NULL, read_mscratch_i128, write_mscratch_i128   },
3711    [CSR_MEPC]     = { "mepc",     any,  read_mepc,     write_mepc     },
3712    [CSR_MCAUSE]   = { "mcause",   any,  read_mcause,   write_mcause   },
3713    [CSR_MTVAL]    = { "mtval",    any,  read_mtval,    write_mtval    },
3714    [CSR_MIP]      = { "mip",      any,  NULL,    NULL, rmw_mip        },
3715
3716    /* Machine-Level Window to Indirectly Accessed Registers (AIA) */
3717    [CSR_MISELECT] = { "miselect", aia_any,   NULL, NULL,    rmw_xiselect },
3718    [CSR_MIREG]    = { "mireg",    aia_any,   NULL, NULL,    rmw_xireg },
3719
3720    /* Machine-Level Interrupts (AIA) */
3721    [CSR_MTOPEI]   = { "mtopei",   aia_any, NULL, NULL, rmw_xtopei },
3722    [CSR_MTOPI]    = { "mtopi",    aia_any, read_mtopi },
3723
3724    /* Virtual Interrupts for Supervisor Level (AIA) */
3725    [CSR_MVIEN]    = { "mvien",    aia_any, read_zero, write_ignore },
3726    [CSR_MVIP]     = { "mvip",     aia_any, read_zero, write_ignore },
3727
3728    /* Machine-Level High-Half CSRs (AIA) */
3729    [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh },
3730    [CSR_MIEH]     = { "mieh",     aia_any32, NULL, NULL, rmw_mieh     },
3731    [CSR_MVIENH]   = { "mvienh",   aia_any32, read_zero,  write_ignore },
3732    [CSR_MVIPH]    = { "mviph",    aia_any32, read_zero,  write_ignore },
3733    [CSR_MIPH]     = { "miph",     aia_any32, NULL, NULL, rmw_miph     },
3734
3735    /* Execution environment configuration */
3736    [CSR_MENVCFG]  = { "menvcfg",  umode, read_menvcfg,  write_menvcfg,
3737                       .min_priv_ver = PRIV_VERSION_1_12_0              },
3738    [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
3739                       .min_priv_ver = PRIV_VERSION_1_12_0              },
3740    [CSR_SENVCFG]  = { "senvcfg",  smode, read_senvcfg,  write_senvcfg,
3741                       .min_priv_ver = PRIV_VERSION_1_12_0              },
3742    [CSR_HENVCFG]  = { "henvcfg",  hmode, read_henvcfg, write_henvcfg,
3743                       .min_priv_ver = PRIV_VERSION_1_12_0              },
3744    [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
3745                       .min_priv_ver = PRIV_VERSION_1_12_0              },
3746
3747    /* Supervisor Trap Setup */
3748    [CSR_SSTATUS]    = { "sstatus",    smode, read_sstatus,    write_sstatus,
3749                         NULL,                read_sstatus_i128               },
3750    [CSR_SIE]        = { "sie",        smode, NULL,   NULL,    rmw_sie        },
3751    [CSR_STVEC]      = { "stvec",      smode, read_stvec,      write_stvec    },
3752    [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren,
3753                         write_scounteren                                     },
3754
3755    /* Supervisor Trap Handling */
3756    [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch,
3757                       NULL, read_sscratch_i128, write_sscratch_i128    },
3758    [CSR_SEPC]     = { "sepc",     smode, read_sepc,     write_sepc     },
3759    [CSR_SCAUSE]   = { "scause",   smode, read_scause,   write_scause   },
3760    [CSR_STVAL]    = { "stval",    smode, read_stval,    write_stval    },
3761    [CSR_SIP]      = { "sip",      smode, NULL,    NULL, rmw_sip        },
3762    [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
3763                       .min_priv_ver = PRIV_VERSION_1_12_0 },
3764    [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph,
3765                        .min_priv_ver = PRIV_VERSION_1_12_0 },
3766    [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp,
3767                        write_vstimecmp,
3768                        .min_priv_ver = PRIV_VERSION_1_12_0 },
3769    [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph,
3770                         write_vstimecmph,
3771                         .min_priv_ver = PRIV_VERSION_1_12_0 },
3772
3773    /* Supervisor Protection and Translation */
3774    [CSR_SATP]     = { "satp",     smode, read_satp,     write_satp     },
3775
3776    /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
3777    [CSR_SISELECT]   = { "siselect",   aia_smode, NULL, NULL, rmw_xiselect },
3778    [CSR_SIREG]      = { "sireg",      aia_smode, NULL, NULL, rmw_xireg },
3779
3780    /* Supervisor-Level Interrupts (AIA) */
3781    [CSR_STOPEI]     = { "stopei",     aia_smode, NULL, NULL, rmw_xtopei },
3782    [CSR_STOPI]      = { "stopi",      aia_smode, read_stopi },
3783
3784    /* Supervisor-Level High-Half CSRs (AIA) */
3785    [CSR_SIEH]       = { "sieh",   aia_smode32, NULL, NULL, rmw_sieh },
3786    [CSR_SIPH]       = { "siph",   aia_smode32, NULL, NULL, rmw_siph },
3787
3788    [CSR_HSTATUS]     = { "hstatus",     hmode,   read_hstatus, write_hstatus,
3789                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3790    [CSR_HEDELEG]     = { "hedeleg",     hmode,   read_hedeleg, write_hedeleg,
3791                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3792    [CSR_HIDELEG]     = { "hideleg",     hmode,   NULL,   NULL, rmw_hideleg,
3793                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3794    [CSR_HVIP]        = { "hvip",        hmode,   NULL,   NULL, rmw_hvip,
3795                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3796    [CSR_HIP]         = { "hip",         hmode,   NULL,   NULL, rmw_hip,
3797                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3798    [CSR_HIE]         = { "hie",         hmode,   NULL,   NULL, rmw_hie,
3799                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3800    [CSR_HCOUNTEREN]  = { "hcounteren",  hmode,   read_hcounteren,
3801                          write_hcounteren,
3802                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3803    [CSR_HGEIE]       = { "hgeie",       hmode,   read_hgeie,   write_hgeie,
3804                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3805    [CSR_HTVAL]       = { "htval",       hmode,   read_htval,   write_htval,
3806                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3807    [CSR_HTINST]      = { "htinst",      hmode,   read_htinst,  write_htinst,
3808                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3809    [CSR_HGEIP]       = { "hgeip",       hmode,   read_hgeip,
3810                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3811    [CSR_HGATP]       = { "hgatp",       hmode,   read_hgatp,   write_hgatp,
3812                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3813    [CSR_HTIMEDELTA]  = { "htimedelta",  hmode,   read_htimedelta,
3814                          write_htimedelta,
3815                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3816    [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah,
3817                          write_htimedeltah,
3818                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3819
3820    [CSR_VSSTATUS]    = { "vsstatus",    hmode,   read_vsstatus,
3821                          write_vsstatus,
3822                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3823    [CSR_VSIP]        = { "vsip",        hmode,   NULL,    NULL, rmw_vsip,
3824                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3825    [CSR_VSIE]        = { "vsie",        hmode,   NULL,    NULL, rmw_vsie ,
3826                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3827    [CSR_VSTVEC]      = { "vstvec",      hmode,   read_vstvec,   write_vstvec,
3828                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3829    [CSR_VSSCRATCH]   = { "vsscratch",   hmode,   read_vsscratch,
3830                          write_vsscratch,
3831                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3832    [CSR_VSEPC]       = { "vsepc",       hmode,   read_vsepc,    write_vsepc,
3833                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3834    [CSR_VSCAUSE]     = { "vscause",     hmode,   read_vscause,  write_vscause,
3835                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3836    [CSR_VSTVAL]      = { "vstval",      hmode,   read_vstval,   write_vstval,
3837                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3838    [CSR_VSATP]       = { "vsatp",       hmode,   read_vsatp,    write_vsatp,
3839                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3840
3841    [CSR_MTVAL2]      = { "mtval2",      hmode,   read_mtval2,   write_mtval2,
3842                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3843    [CSR_MTINST]      = { "mtinst",      hmode,   read_mtinst,   write_mtinst,
3844                          .min_priv_ver = PRIV_VERSION_1_12_0                },
3845
3846    /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
3847    [CSR_HVIEN]       = { "hvien",       aia_hmode, read_zero, write_ignore },
3848    [CSR_HVICTL]      = { "hvictl",      aia_hmode, read_hvictl,
3849                          write_hvictl                                      },
3850    [CSR_HVIPRIO1]    = { "hviprio1",    aia_hmode, read_hviprio1,
3851                          write_hviprio1                                    },
3852    [CSR_HVIPRIO2]    = { "hviprio2",    aia_hmode, read_hviprio2,
3853                          write_hviprio2                                    },
3854
3855    /*
3856     * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
3857     */
3858    [CSR_VSISELECT]   = { "vsiselect",   aia_hmode, NULL, NULL,
3859                          rmw_xiselect                                     },
3860    [CSR_VSIREG]      = { "vsireg",      aia_hmode, NULL, NULL, rmw_xireg  },
3861
3862    /* VS-Level Interrupts (H-extension with AIA) */
3863    [CSR_VSTOPEI]     = { "vstopei",     aia_hmode, NULL, NULL, rmw_xtopei },
3864    [CSR_VSTOPI]      = { "vstopi",      aia_hmode, read_vstopi },
3865
3866    /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
3867    [CSR_HIDELEGH]    = { "hidelegh",    aia_hmode32, NULL, NULL,
3868                          rmw_hidelegh                                      },
3869    [CSR_HVIENH]      = { "hvienh",      aia_hmode32, read_zero,
3870                          write_ignore                                      },
3871    [CSR_HVIPH]       = { "hviph",       aia_hmode32, NULL, NULL, rmw_hviph },
3872    [CSR_HVIPRIO1H]   = { "hviprio1h",   aia_hmode32, read_hviprio1h,
3873                          write_hviprio1h                                   },
3874    [CSR_HVIPRIO2H]   = { "hviprio2h",   aia_hmode32, read_hviprio2h,
3875                          write_hviprio2h                                   },
3876    [CSR_VSIEH]       = { "vsieh",       aia_hmode32, NULL, NULL, rmw_vsieh },
3877    [CSR_VSIPH]       = { "vsiph",       aia_hmode32, NULL, NULL, rmw_vsiph },
3878
3879    /* Physical Memory Protection */
3880    [CSR_MSECCFG]    = { "mseccfg",  epmp, read_mseccfg, write_mseccfg,
3881                         .min_priv_ver = PRIV_VERSION_1_11_0           },
3882    [CSR_PMPCFG0]    = { "pmpcfg0",   pmp, read_pmpcfg,  write_pmpcfg  },
3883    [CSR_PMPCFG1]    = { "pmpcfg1",   pmp, read_pmpcfg,  write_pmpcfg  },
3884    [CSR_PMPCFG2]    = { "pmpcfg2",   pmp, read_pmpcfg,  write_pmpcfg  },
3885    [CSR_PMPCFG3]    = { "pmpcfg3",   pmp, read_pmpcfg,  write_pmpcfg  },
3886    [CSR_PMPADDR0]   = { "pmpaddr0",  pmp, read_pmpaddr, write_pmpaddr },
3887    [CSR_PMPADDR1]   = { "pmpaddr1",  pmp, read_pmpaddr, write_pmpaddr },
3888    [CSR_PMPADDR2]   = { "pmpaddr2",  pmp, read_pmpaddr, write_pmpaddr },
3889    [CSR_PMPADDR3]   = { "pmpaddr3",  pmp, read_pmpaddr, write_pmpaddr },
3890    [CSR_PMPADDR4]   = { "pmpaddr4",  pmp, read_pmpaddr, write_pmpaddr },
3891    [CSR_PMPADDR5]   = { "pmpaddr5",  pmp, read_pmpaddr, write_pmpaddr },
3892    [CSR_PMPADDR6]   = { "pmpaddr6",  pmp, read_pmpaddr, write_pmpaddr },
3893    [CSR_PMPADDR7]   = { "pmpaddr7",  pmp, read_pmpaddr, write_pmpaddr },
3894    [CSR_PMPADDR8]   = { "pmpaddr8",  pmp, read_pmpaddr, write_pmpaddr },
3895    [CSR_PMPADDR9]   = { "pmpaddr9",  pmp, read_pmpaddr, write_pmpaddr },
3896    [CSR_PMPADDR10]  = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr },
3897    [CSR_PMPADDR11]  = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr },
3898    [CSR_PMPADDR12]  = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr },
3899    [CSR_PMPADDR13]  = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr },
3900    [CSR_PMPADDR14] =  { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
3901    [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
3902
3903    /* Debug CSRs */
3904    [CSR_TSELECT]   =  { "tselect", debug, read_tselect, write_tselect },
3905    [CSR_TDATA1]    =  { "tdata1",  debug, read_tdata,   write_tdata   },
3906    [CSR_TDATA2]    =  { "tdata2",  debug, read_tdata,   write_tdata   },
3907    [CSR_TDATA3]    =  { "tdata3",  debug, read_tdata,   write_tdata   },
3908    [CSR_TINFO]     =  { "tinfo",   debug, read_tinfo,   write_ignore  },
3909
3910    /* User Pointer Masking */
3911    [CSR_UMTE]    =    { "umte",    pointer_masking, read_umte,  write_umte },
3912    [CSR_UPMMASK] =    { "upmmask", pointer_masking, read_upmmask,
3913                         write_upmmask                                      },
3914    [CSR_UPMBASE] =    { "upmbase", pointer_masking, read_upmbase,
3915                         write_upmbase                                      },
3916    /* Machine Pointer Masking */
3917    [CSR_MMTE]    =    { "mmte",    pointer_masking, read_mmte,  write_mmte },
3918    [CSR_MPMMASK] =    { "mpmmask", pointer_masking, read_mpmmask,
3919                         write_mpmmask                                      },
3920    [CSR_MPMBASE] =    { "mpmbase", pointer_masking, read_mpmbase,
3921                         write_mpmbase                                      },
3922    /* Supervisor Pointer Masking */
3923    [CSR_SMTE]    =    { "smte",    pointer_masking, read_smte,  write_smte },
3924    [CSR_SPMMASK] =    { "spmmask", pointer_masking, read_spmmask,
3925                         write_spmmask                                      },
3926    [CSR_SPMBASE] =    { "spmbase", pointer_masking, read_spmbase,
3927                         write_spmbase                                      },
3928
3929    /* Performance Counters */
3930    [CSR_HPMCOUNTER3]    = { "hpmcounter3",    ctr,    read_hpmcounter },
3931    [CSR_HPMCOUNTER4]    = { "hpmcounter4",    ctr,    read_hpmcounter },
3932    [CSR_HPMCOUNTER5]    = { "hpmcounter5",    ctr,    read_hpmcounter },
3933    [CSR_HPMCOUNTER6]    = { "hpmcounter6",    ctr,    read_hpmcounter },
3934    [CSR_HPMCOUNTER7]    = { "hpmcounter7",    ctr,    read_hpmcounter },
3935    [CSR_HPMCOUNTER8]    = { "hpmcounter8",    ctr,    read_hpmcounter },
3936    [CSR_HPMCOUNTER9]    = { "hpmcounter9",    ctr,    read_hpmcounter },
3937    [CSR_HPMCOUNTER10]   = { "hpmcounter10",   ctr,    read_hpmcounter },
3938    [CSR_HPMCOUNTER11]   = { "hpmcounter11",   ctr,    read_hpmcounter },
3939    [CSR_HPMCOUNTER12]   = { "hpmcounter12",   ctr,    read_hpmcounter },
3940    [CSR_HPMCOUNTER13]   = { "hpmcounter13",   ctr,    read_hpmcounter },
3941    [CSR_HPMCOUNTER14]   = { "hpmcounter14",   ctr,    read_hpmcounter },
3942    [CSR_HPMCOUNTER15]   = { "hpmcounter15",   ctr,    read_hpmcounter },
3943    [CSR_HPMCOUNTER16]   = { "hpmcounter16",   ctr,    read_hpmcounter },
3944    [CSR_HPMCOUNTER17]   = { "hpmcounter17",   ctr,    read_hpmcounter },
3945    [CSR_HPMCOUNTER18]   = { "hpmcounter18",   ctr,    read_hpmcounter },
3946    [CSR_HPMCOUNTER19]   = { "hpmcounter19",   ctr,    read_hpmcounter },
3947    [CSR_HPMCOUNTER20]   = { "hpmcounter20",   ctr,    read_hpmcounter },
3948    [CSR_HPMCOUNTER21]   = { "hpmcounter21",   ctr,    read_hpmcounter },
3949    [CSR_HPMCOUNTER22]   = { "hpmcounter22",   ctr,    read_hpmcounter },
3950    [CSR_HPMCOUNTER23]   = { "hpmcounter23",   ctr,    read_hpmcounter },
3951    [CSR_HPMCOUNTER24]   = { "hpmcounter24",   ctr,    read_hpmcounter },
3952    [CSR_HPMCOUNTER25]   = { "hpmcounter25",   ctr,    read_hpmcounter },
3953    [CSR_HPMCOUNTER26]   = { "hpmcounter26",   ctr,    read_hpmcounter },
3954    [CSR_HPMCOUNTER27]   = { "hpmcounter27",   ctr,    read_hpmcounter },
3955    [CSR_HPMCOUNTER28]   = { "hpmcounter28",   ctr,    read_hpmcounter },
3956    [CSR_HPMCOUNTER29]   = { "hpmcounter29",   ctr,    read_hpmcounter },
3957    [CSR_HPMCOUNTER30]   = { "hpmcounter30",   ctr,    read_hpmcounter },
3958    [CSR_HPMCOUNTER31]   = { "hpmcounter31",   ctr,    read_hpmcounter },
3959
3960    [CSR_MHPMCOUNTER3]   = { "mhpmcounter3",   mctr,    read_hpmcounter,
3961                             write_mhpmcounter                         },
3962    [CSR_MHPMCOUNTER4]   = { "mhpmcounter4",   mctr,    read_hpmcounter,
3963                             write_mhpmcounter                         },
3964    [CSR_MHPMCOUNTER5]   = { "mhpmcounter5",   mctr,    read_hpmcounter,
3965                             write_mhpmcounter                         },
3966    [CSR_MHPMCOUNTER6]   = { "mhpmcounter6",   mctr,    read_hpmcounter,
3967                             write_mhpmcounter                         },
3968    [CSR_MHPMCOUNTER7]   = { "mhpmcounter7",   mctr,    read_hpmcounter,
3969                             write_mhpmcounter                         },
3970    [CSR_MHPMCOUNTER8]   = { "mhpmcounter8",   mctr,    read_hpmcounter,
3971                             write_mhpmcounter                         },
3972    [CSR_MHPMCOUNTER9]   = { "mhpmcounter9",   mctr,    read_hpmcounter,
3973                             write_mhpmcounter                         },
3974    [CSR_MHPMCOUNTER10]  = { "mhpmcounter10",  mctr,    read_hpmcounter,
3975                             write_mhpmcounter                         },
3976    [CSR_MHPMCOUNTER11]  = { "mhpmcounter11",  mctr,    read_hpmcounter,
3977                             write_mhpmcounter                         },
3978    [CSR_MHPMCOUNTER12]  = { "mhpmcounter12",  mctr,    read_hpmcounter,
3979                             write_mhpmcounter                         },
3980    [CSR_MHPMCOUNTER13]  = { "mhpmcounter13",  mctr,    read_hpmcounter,
3981                             write_mhpmcounter                         },
3982    [CSR_MHPMCOUNTER14]  = { "mhpmcounter14",  mctr,    read_hpmcounter,
3983                             write_mhpmcounter                         },
3984    [CSR_MHPMCOUNTER15]  = { "mhpmcounter15",  mctr,    read_hpmcounter,
3985                             write_mhpmcounter                         },
3986    [CSR_MHPMCOUNTER16]  = { "mhpmcounter16",  mctr,    read_hpmcounter,
3987                             write_mhpmcounter                         },
3988    [CSR_MHPMCOUNTER17]  = { "mhpmcounter17",  mctr,    read_hpmcounter,
3989                             write_mhpmcounter                         },
3990    [CSR_MHPMCOUNTER18]  = { "mhpmcounter18",  mctr,    read_hpmcounter,
3991                             write_mhpmcounter                         },
3992    [CSR_MHPMCOUNTER19]  = { "mhpmcounter19",  mctr,    read_hpmcounter,
3993                             write_mhpmcounter                         },
3994    [CSR_MHPMCOUNTER20]  = { "mhpmcounter20",  mctr,    read_hpmcounter,
3995                             write_mhpmcounter                         },
3996    [CSR_MHPMCOUNTER21]  = { "mhpmcounter21",  mctr,    read_hpmcounter,
3997                             write_mhpmcounter                         },
3998    [CSR_MHPMCOUNTER22]  = { "mhpmcounter22",  mctr,    read_hpmcounter,
3999                             write_mhpmcounter                         },
4000    [CSR_MHPMCOUNTER23]  = { "mhpmcounter23",  mctr,    read_hpmcounter,
4001                             write_mhpmcounter                         },
4002    [CSR_MHPMCOUNTER24]  = { "mhpmcounter24",  mctr,    read_hpmcounter,
4003                             write_mhpmcounter                         },
4004    [CSR_MHPMCOUNTER25]  = { "mhpmcounter25",  mctr,    read_hpmcounter,
4005                             write_mhpmcounter                         },
4006    [CSR_MHPMCOUNTER26]  = { "mhpmcounter26",  mctr,    read_hpmcounter,
4007                             write_mhpmcounter                         },
4008    [CSR_MHPMCOUNTER27]  = { "mhpmcounter27",  mctr,    read_hpmcounter,
4009                             write_mhpmcounter                         },
4010    [CSR_MHPMCOUNTER28]  = { "mhpmcounter28",  mctr,    read_hpmcounter,
4011                             write_mhpmcounter                         },
4012    [CSR_MHPMCOUNTER29]  = { "mhpmcounter29",  mctr,    read_hpmcounter,
4013                             write_mhpmcounter                         },
4014    [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  mctr,    read_hpmcounter,
4015                             write_mhpmcounter                         },
4016    [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  mctr,    read_hpmcounter,
4017                             write_mhpmcounter                         },
4018
4019    [CSR_MCOUNTINHIBIT]  = { "mcountinhibit",  any, read_mcountinhibit,
4020                             write_mcountinhibit,
4021                             .min_priv_ver = PRIV_VERSION_1_11_0       },
4022
4023    [CSR_MHPMEVENT3]     = { "mhpmevent3",     any,    read_mhpmevent,
4024                             write_mhpmevent                           },
4025    [CSR_MHPMEVENT4]     = { "mhpmevent4",     any,    read_mhpmevent,
4026                             write_mhpmevent                           },
4027    [CSR_MHPMEVENT5]     = { "mhpmevent5",     any,    read_mhpmevent,
4028                             write_mhpmevent                           },
4029    [CSR_MHPMEVENT6]     = { "mhpmevent6",     any,    read_mhpmevent,
4030                             write_mhpmevent                           },
4031    [CSR_MHPMEVENT7]     = { "mhpmevent7",     any,    read_mhpmevent,
4032                             write_mhpmevent                           },
4033    [CSR_MHPMEVENT8]     = { "mhpmevent8",     any,    read_mhpmevent,
4034                             write_mhpmevent                           },
4035    [CSR_MHPMEVENT9]     = { "mhpmevent9",     any,    read_mhpmevent,
4036                             write_mhpmevent                           },
4037    [CSR_MHPMEVENT10]    = { "mhpmevent10",    any,    read_mhpmevent,
4038                             write_mhpmevent                           },
4039    [CSR_MHPMEVENT11]    = { "mhpmevent11",    any,    read_mhpmevent,
4040                             write_mhpmevent                           },
4041    [CSR_MHPMEVENT12]    = { "mhpmevent12",    any,    read_mhpmevent,
4042                             write_mhpmevent                           },
4043    [CSR_MHPMEVENT13]    = { "mhpmevent13",    any,    read_mhpmevent,
4044                             write_mhpmevent                           },
4045    [CSR_MHPMEVENT14]    = { "mhpmevent14",    any,    read_mhpmevent,
4046                             write_mhpmevent                           },
4047    [CSR_MHPMEVENT15]    = { "mhpmevent15",    any,    read_mhpmevent,
4048                             write_mhpmevent                           },
4049    [CSR_MHPMEVENT16]    = { "mhpmevent16",    any,    read_mhpmevent,
4050                             write_mhpmevent                           },
4051    [CSR_MHPMEVENT17]    = { "mhpmevent17",    any,    read_mhpmevent,
4052                             write_mhpmevent                           },
4053    [CSR_MHPMEVENT18]    = { "mhpmevent18",    any,    read_mhpmevent,
4054                             write_mhpmevent                           },
4055    [CSR_MHPMEVENT19]    = { "mhpmevent19",    any,    read_mhpmevent,
4056                             write_mhpmevent                           },
4057    [CSR_MHPMEVENT20]    = { "mhpmevent20",    any,    read_mhpmevent,
4058                             write_mhpmevent                           },
4059    [CSR_MHPMEVENT21]    = { "mhpmevent21",    any,    read_mhpmevent,
4060                             write_mhpmevent                           },
4061    [CSR_MHPMEVENT22]    = { "mhpmevent22",    any,    read_mhpmevent,
4062                             write_mhpmevent                           },
4063    [CSR_MHPMEVENT23]    = { "mhpmevent23",    any,    read_mhpmevent,
4064                             write_mhpmevent                           },
4065    [CSR_MHPMEVENT24]    = { "mhpmevent24",    any,    read_mhpmevent,
4066                             write_mhpmevent                           },
4067    [CSR_MHPMEVENT25]    = { "mhpmevent25",    any,    read_mhpmevent,
4068                             write_mhpmevent                           },
4069    [CSR_MHPMEVENT26]    = { "mhpmevent26",    any,    read_mhpmevent,
4070                             write_mhpmevent                           },
4071    [CSR_MHPMEVENT27]    = { "mhpmevent27",    any,    read_mhpmevent,
4072                             write_mhpmevent                           },
4073    [CSR_MHPMEVENT28]    = { "mhpmevent28",    any,    read_mhpmevent,
4074                             write_mhpmevent                           },
4075    [CSR_MHPMEVENT29]    = { "mhpmevent29",    any,    read_mhpmevent,
4076                             write_mhpmevent                           },
4077    [CSR_MHPMEVENT30]    = { "mhpmevent30",    any,    read_mhpmevent,
4078                             write_mhpmevent                           },
4079    [CSR_MHPMEVENT31]    = { "mhpmevent31",    any,    read_mhpmevent,
4080                             write_mhpmevent                           },
4081
4082    [CSR_MHPMEVENT3H]    = { "mhpmevent3h",    sscofpmf,  read_mhpmeventh,
4083                             write_mhpmeventh,
4084                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4085    [CSR_MHPMEVENT4H]    = { "mhpmevent4h",    sscofpmf,  read_mhpmeventh,
4086                             write_mhpmeventh,
4087                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4088    [CSR_MHPMEVENT5H]    = { "mhpmevent5h",    sscofpmf,  read_mhpmeventh,
4089                             write_mhpmeventh,
4090                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4091    [CSR_MHPMEVENT6H]    = { "mhpmevent6h",    sscofpmf,  read_mhpmeventh,
4092                             write_mhpmeventh,
4093                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4094    [CSR_MHPMEVENT7H]    = { "mhpmevent7h",    sscofpmf,  read_mhpmeventh,
4095                             write_mhpmeventh,
4096                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4097    [CSR_MHPMEVENT8H]    = { "mhpmevent8h",    sscofpmf,  read_mhpmeventh,
4098                             write_mhpmeventh,
4099                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4100    [CSR_MHPMEVENT9H]    = { "mhpmevent9h",    sscofpmf,  read_mhpmeventh,
4101                             write_mhpmeventh,
4102                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4103    [CSR_MHPMEVENT10H]   = { "mhpmevent10h",    sscofpmf,  read_mhpmeventh,
4104                             write_mhpmeventh,
4105                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4106    [CSR_MHPMEVENT11H]   = { "mhpmevent11h",    sscofpmf,  read_mhpmeventh,
4107                             write_mhpmeventh,
4108                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4109    [CSR_MHPMEVENT12H]   = { "mhpmevent12h",    sscofpmf,  read_mhpmeventh,
4110                             write_mhpmeventh,
4111                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4112    [CSR_MHPMEVENT13H]   = { "mhpmevent13h",    sscofpmf,  read_mhpmeventh,
4113                             write_mhpmeventh,
4114                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4115    [CSR_MHPMEVENT14H]   = { "mhpmevent14h",    sscofpmf,  read_mhpmeventh,
4116                             write_mhpmeventh,
4117                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4118    [CSR_MHPMEVENT15H]   = { "mhpmevent15h",    sscofpmf,  read_mhpmeventh,
4119                             write_mhpmeventh,
4120                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4121    [CSR_MHPMEVENT16H]   = { "mhpmevent16h",    sscofpmf,  read_mhpmeventh,
4122                             write_mhpmeventh,
4123                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4124    [CSR_MHPMEVENT17H]   = { "mhpmevent17h",    sscofpmf,  read_mhpmeventh,
4125                             write_mhpmeventh,
4126                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4127    [CSR_MHPMEVENT18H]   = { "mhpmevent18h",    sscofpmf,  read_mhpmeventh,
4128                             write_mhpmeventh,
4129                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4130    [CSR_MHPMEVENT19H]   = { "mhpmevent19h",    sscofpmf,  read_mhpmeventh,
4131                             write_mhpmeventh,
4132                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4133    [CSR_MHPMEVENT20H]   = { "mhpmevent20h",    sscofpmf,  read_mhpmeventh,
4134                             write_mhpmeventh,
4135                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4136    [CSR_MHPMEVENT21H]   = { "mhpmevent21h",    sscofpmf,  read_mhpmeventh,
4137                             write_mhpmeventh,
4138                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4139    [CSR_MHPMEVENT22H]   = { "mhpmevent22h",    sscofpmf,  read_mhpmeventh,
4140                             write_mhpmeventh,
4141                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4142    [CSR_MHPMEVENT23H]   = { "mhpmevent23h",    sscofpmf,  read_mhpmeventh,
4143                             write_mhpmeventh,
4144                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4145    [CSR_MHPMEVENT24H]   = { "mhpmevent24h",    sscofpmf,  read_mhpmeventh,
4146                             write_mhpmeventh,
4147                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4148    [CSR_MHPMEVENT25H]   = { "mhpmevent25h",    sscofpmf,  read_mhpmeventh,
4149                             write_mhpmeventh,
4150                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4151    [CSR_MHPMEVENT26H]   = { "mhpmevent26h",    sscofpmf,  read_mhpmeventh,
4152                             write_mhpmeventh,
4153                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4154    [CSR_MHPMEVENT27H]   = { "mhpmevent27h",    sscofpmf,  read_mhpmeventh,
4155                             write_mhpmeventh,
4156                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4157    [CSR_MHPMEVENT28H]   = { "mhpmevent28h",    sscofpmf,  read_mhpmeventh,
4158                             write_mhpmeventh,
4159                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4160    [CSR_MHPMEVENT29H]   = { "mhpmevent29h",    sscofpmf,  read_mhpmeventh,
4161                             write_mhpmeventh,
4162                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4163    [CSR_MHPMEVENT30H]   = { "mhpmevent30h",    sscofpmf,  read_mhpmeventh,
4164                             write_mhpmeventh,
4165                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4166    [CSR_MHPMEVENT31H]   = { "mhpmevent31h",    sscofpmf,  read_mhpmeventh,
4167                             write_mhpmeventh,
4168                             .min_priv_ver = PRIV_VERSION_1_12_0        },
4169
4170    [CSR_HPMCOUNTER3H]   = { "hpmcounter3h",   ctr32,  read_hpmcounterh },
4171    [CSR_HPMCOUNTER4H]   = { "hpmcounter4h",   ctr32,  read_hpmcounterh },
4172    [CSR_HPMCOUNTER5H]   = { "hpmcounter5h",   ctr32,  read_hpmcounterh },
4173    [CSR_HPMCOUNTER6H]   = { "hpmcounter6h",   ctr32,  read_hpmcounterh },
4174    [CSR_HPMCOUNTER7H]   = { "hpmcounter7h",   ctr32,  read_hpmcounterh },
4175    [CSR_HPMCOUNTER8H]   = { "hpmcounter8h",   ctr32,  read_hpmcounterh },
4176    [CSR_HPMCOUNTER9H]   = { "hpmcounter9h",   ctr32,  read_hpmcounterh },
4177    [CSR_HPMCOUNTER10H]  = { "hpmcounter10h",  ctr32,  read_hpmcounterh },
4178    [CSR_HPMCOUNTER11H]  = { "hpmcounter11h",  ctr32,  read_hpmcounterh },
4179    [CSR_HPMCOUNTER12H]  = { "hpmcounter12h",  ctr32,  read_hpmcounterh },
4180    [CSR_HPMCOUNTER13H]  = { "hpmcounter13h",  ctr32,  read_hpmcounterh },
4181    [CSR_HPMCOUNTER14H]  = { "hpmcounter14h",  ctr32,  read_hpmcounterh },
4182    [CSR_HPMCOUNTER15H]  = { "hpmcounter15h",  ctr32,  read_hpmcounterh },
4183    [CSR_HPMCOUNTER16H]  = { "hpmcounter16h",  ctr32,  read_hpmcounterh },
4184    [CSR_HPMCOUNTER17H]  = { "hpmcounter17h",  ctr32,  read_hpmcounterh },
4185    [CSR_HPMCOUNTER18H]  = { "hpmcounter18h",  ctr32,  read_hpmcounterh },
4186    [CSR_HPMCOUNTER19H]  = { "hpmcounter19h",  ctr32,  read_hpmcounterh },
4187    [CSR_HPMCOUNTER20H]  = { "hpmcounter20h",  ctr32,  read_hpmcounterh },
4188    [CSR_HPMCOUNTER21H]  = { "hpmcounter21h",  ctr32,  read_hpmcounterh },
4189    [CSR_HPMCOUNTER22H]  = { "hpmcounter22h",  ctr32,  read_hpmcounterh },
4190    [CSR_HPMCOUNTER23H]  = { "hpmcounter23h",  ctr32,  read_hpmcounterh },
4191    [CSR_HPMCOUNTER24H]  = { "hpmcounter24h",  ctr32,  read_hpmcounterh },
4192    [CSR_HPMCOUNTER25H]  = { "hpmcounter25h",  ctr32,  read_hpmcounterh },
4193    [CSR_HPMCOUNTER26H]  = { "hpmcounter26h",  ctr32,  read_hpmcounterh },
4194    [CSR_HPMCOUNTER27H]  = { "hpmcounter27h",  ctr32,  read_hpmcounterh },
4195    [CSR_HPMCOUNTER28H]  = { "hpmcounter28h",  ctr32,  read_hpmcounterh },
4196    [CSR_HPMCOUNTER29H]  = { "hpmcounter29h",  ctr32,  read_hpmcounterh },
4197    [CSR_HPMCOUNTER30H]  = { "hpmcounter30h",  ctr32,  read_hpmcounterh },
4198    [CSR_HPMCOUNTER31H]  = { "hpmcounter31h",  ctr32,  read_hpmcounterh },
4199
4200    [CSR_MHPMCOUNTER3H]  = { "mhpmcounter3h",  mctr32,  read_hpmcounterh,
4201                             write_mhpmcounterh                         },
4202    [CSR_MHPMCOUNTER4H]  = { "mhpmcounter4h",  mctr32,  read_hpmcounterh,
4203                             write_mhpmcounterh                         },
4204    [CSR_MHPMCOUNTER5H]  = { "mhpmcounter5h",  mctr32,  read_hpmcounterh,
4205                             write_mhpmcounterh                         },
4206    [CSR_MHPMCOUNTER6H]  = { "mhpmcounter6h",  mctr32,  read_hpmcounterh,
4207                             write_mhpmcounterh                         },
4208    [CSR_MHPMCOUNTER7H]  = { "mhpmcounter7h",  mctr32,  read_hpmcounterh,
4209                             write_mhpmcounterh                         },
4210    [CSR_MHPMCOUNTER8H]  = { "mhpmcounter8h",  mctr32,  read_hpmcounterh,
4211                             write_mhpmcounterh                         },
4212    [CSR_MHPMCOUNTER9H]  = { "mhpmcounter9h",  mctr32,  read_hpmcounterh,
4213                             write_mhpmcounterh                         },
4214    [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32,  read_hpmcounterh,
4215                             write_mhpmcounterh                         },
4216    [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32,  read_hpmcounterh,
4217                             write_mhpmcounterh                         },
4218    [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32,  read_hpmcounterh,
4219                             write_mhpmcounterh                         },
4220    [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32,  read_hpmcounterh,
4221                             write_mhpmcounterh                         },
4222    [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32,  read_hpmcounterh,
4223                             write_mhpmcounterh                         },
4224    [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32,  read_hpmcounterh,
4225                             write_mhpmcounterh                         },
4226    [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32,  read_hpmcounterh,
4227                             write_mhpmcounterh                         },
4228    [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32,  read_hpmcounterh,
4229                             write_mhpmcounterh                         },
4230    [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32,  read_hpmcounterh,
4231                             write_mhpmcounterh                         },
4232    [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32,  read_hpmcounterh,
4233                             write_mhpmcounterh                         },
4234    [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32,  read_hpmcounterh,
4235                             write_mhpmcounterh                         },
4236    [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32,  read_hpmcounterh,
4237                             write_mhpmcounterh                         },
4238    [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32,  read_hpmcounterh,
4239                             write_mhpmcounterh                         },
4240    [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32,  read_hpmcounterh,
4241                             write_mhpmcounterh                         },
4242    [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32,  read_hpmcounterh,
4243                             write_mhpmcounterh                         },
4244    [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32,  read_hpmcounterh,
4245                             write_mhpmcounterh                         },
4246    [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32,  read_hpmcounterh,
4247                             write_mhpmcounterh                         },
4248    [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32,  read_hpmcounterh,
4249                             write_mhpmcounterh                         },
4250    [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32,  read_hpmcounterh,
4251                             write_mhpmcounterh                         },
4252    [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32,  read_hpmcounterh,
4253                             write_mhpmcounterh                         },
4254    [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32,  read_hpmcounterh,
4255                             write_mhpmcounterh                         },
4256    [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32,  read_hpmcounterh,
4257                             write_mhpmcounterh                         },
4258    [CSR_SCOUNTOVF]      = { "scountovf", sscofpmf,  read_scountovf,
4259                             .min_priv_ver = PRIV_VERSION_1_12_0 },
4260
4261#endif /* !CONFIG_USER_ONLY */
4262};
4263