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