xref: /qemu/target/riscv/pmp.h (revision 2582a95c3c46d2e9d7fbe4a6ff01cfe6b4875339)
165c5b75cSMichael Clark /*
265c5b75cSMichael Clark  * QEMU RISC-V PMP (Physical Memory Protection)
365c5b75cSMichael Clark  *
465c5b75cSMichael Clark  * Author: Daire McNamara, daire.mcnamara@emdalo.com
565c5b75cSMichael Clark  *         Ivan Griffin, ivan.griffin@emdalo.com
665c5b75cSMichael Clark  *
765c5b75cSMichael Clark  * This provides a RISC-V Physical Memory Protection interface
865c5b75cSMichael Clark  *
965c5b75cSMichael Clark  * This program is free software; you can redistribute it and/or modify it
1065c5b75cSMichael Clark  * under the terms and conditions of the GNU General Public License,
1165c5b75cSMichael Clark  * version 2 or later, as published by the Free Software Foundation.
1265c5b75cSMichael Clark  *
1365c5b75cSMichael Clark  * This program is distributed in the hope it will be useful, but WITHOUT
1465c5b75cSMichael Clark  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1565c5b75cSMichael Clark  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1665c5b75cSMichael Clark  * more details.
1765c5b75cSMichael Clark  *
1865c5b75cSMichael Clark  * You should have received a copy of the GNU General Public License along with
1965c5b75cSMichael Clark  * this program.  If not, see <http://www.gnu.org/licenses/>.
2065c5b75cSMichael Clark  */
2165c5b75cSMichael Clark 
22a8b991b5SMarkus Armbruster #ifndef RISCV_PMP_H
23a8b991b5SMarkus Armbruster #define RISCV_PMP_H
2465c5b75cSMichael Clark 
2565c5b75cSMichael Clark typedef enum {
2665c5b75cSMichael Clark     PMP_READ  = 1 << 0,
2765c5b75cSMichael Clark     PMP_WRITE = 1 << 1,
2865c5b75cSMichael Clark     PMP_EXEC  = 1 << 2,
2965c5b75cSMichael Clark     PMP_LOCK  = 1 << 7
3065c5b75cSMichael Clark } pmp_priv_t;
3165c5b75cSMichael Clark 
3265c5b75cSMichael Clark typedef enum {
3365c5b75cSMichael Clark     PMP_AMATCH_OFF,  /* Null (off)                            */
3465c5b75cSMichael Clark     PMP_AMATCH_TOR,  /* Top of Range                          */
3565c5b75cSMichael Clark     PMP_AMATCH_NA4,  /* Naturally aligned four-byte region    */
3665c5b75cSMichael Clark     PMP_AMATCH_NAPOT /* Naturally aligned power-of-two region */
3765c5b75cSMichael Clark } pmp_am_t;
3865c5b75cSMichael Clark 
39*2582a95cSHou Weiying typedef enum {
40*2582a95cSHou Weiying     MSECCFG_MML  = 1 << 0,
41*2582a95cSHou Weiying     MSECCFG_MMWP = 1 << 1,
42*2582a95cSHou Weiying     MSECCFG_RLB  = 1 << 2
43*2582a95cSHou Weiying } mseccfg_field_t;
44*2582a95cSHou Weiying 
4565c5b75cSMichael Clark typedef struct {
4665c5b75cSMichael Clark     target_ulong addr_reg;
4765c5b75cSMichael Clark     uint8_t  cfg_reg;
4865c5b75cSMichael Clark } pmp_entry_t;
4965c5b75cSMichael Clark 
5065c5b75cSMichael Clark typedef struct {
5165c5b75cSMichael Clark     target_ulong sa;
5265c5b75cSMichael Clark     target_ulong ea;
5365c5b75cSMichael Clark } pmp_addr_t;
5465c5b75cSMichael Clark 
5565c5b75cSMichael Clark typedef struct {
5665c5b75cSMichael Clark     pmp_entry_t pmp[MAX_RISCV_PMPS];
5765c5b75cSMichael Clark     pmp_addr_t  addr[MAX_RISCV_PMPS];
5865c5b75cSMichael Clark     uint32_t num_rules;
5965c5b75cSMichael Clark } pmp_table_t;
6065c5b75cSMichael Clark 
6165c5b75cSMichael Clark void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
6265c5b75cSMichael Clark     target_ulong val);
6365c5b75cSMichael Clark target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index);
64*2582a95cSHou Weiying 
65*2582a95cSHou Weiying void mseccfg_csr_write(CPURISCVState *env, target_ulong val);
66*2582a95cSHou Weiying target_ulong mseccfg_csr_read(CPURISCVState *env);
67*2582a95cSHou Weiying 
6865c5b75cSMichael Clark void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
6965c5b75cSMichael Clark     target_ulong val);
7065c5b75cSMichael Clark target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
7165c5b75cSMichael Clark bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
72b297129aSJim Shu     target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
73b297129aSJim Shu     target_ulong mode);
74af3fc195SZong Li bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
75af3fc195SZong Li                          target_ulong *tlb_size);
7624beb03eSYifei Jiang void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
7724beb03eSYifei Jiang void pmp_update_rule_nums(CPURISCVState *env);
78d102f19aSAtish Patra uint32_t pmp_get_num_rules(CPURISCVState *env);
79b297129aSJim Shu int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
8065c5b75cSMichael Clark 
81*2582a95cSHou Weiying #define MSECCFG_MML_ISSET(env) get_field(env->mseccfg, MSECCFG_MML)
82*2582a95cSHou Weiying #define MSECCFG_MMWP_ISSET(env) get_field(env->mseccfg, MSECCFG_MMWP)
83*2582a95cSHou Weiying #define MSECCFG_RLB_ISSET(env) get_field(env->mseccfg, MSECCFG_RLB)
84*2582a95cSHou Weiying 
8565c5b75cSMichael Clark #endif
86