master
h 105 lines 2.71 KB
Raw
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * LoongArch CPU parameters for QEMU.
4 *
5 * Copyright (c) 2025 Loongson Technology Corporation Limited
6 */
7
8 #ifndef LOONGARCH_CPU_MMU_H
9 #define LOONGARCH_CPU_MMU_H
10
11 typedef enum TLBRet {
12 TLBRET_MATCH,
13 TLBRET_BADADDR,
14 TLBRET_NOMATCH,
15 TLBRET_INVALID,
16 TLBRET_DIRTY,
17 TLBRET_RI,
18 TLBRET_XI,
19 TLBRET_PE,
20 } TLBRet;
21
22 typedef struct MMUContext {
23 vaddr addr;
24 uint64_t pte;
25 hwaddr physical;
26 int ps; /* page size shift */
27 int prot;
28 int tlb_index;
29 int mmu_index;
30 uint64_t pte_buddy[2];
31 } MMUContext;
32
33 static inline bool cpu_has_ptw(CPULoongArchState *env)
34 {
35 CPUSysState *sys = env_sys(env);
36
37 return !!FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, HPTW_EN);
38 }
39
40 static inline bool pte_present(CPULoongArchState *env, uint64_t entry)
41 {
42 uint8_t present;
43
44 if (cpu_has_ptw(env)) {
45 present = FIELD_EX64(entry, TLBENTRY, P);
46 } else {
47 present = FIELD_EX64(entry, TLBENTRY, V);
48 }
49
50 return !!present;
51 }
52
53 static inline bool pte_write(CPULoongArchState *env, uint64_t entry)
54 {
55 uint8_t writable;
56
57 if (cpu_has_ptw(env)) {
58 writable = FIELD_EX64(entry, TLBENTRY, W);
59 } else {
60 writable = FIELD_EX64(entry, TLBENTRY, D);
61 }
62
63 return !!writable;
64 }
65
66 /*
67 * The folloing functions should be called with PTW enable checked
68 * With hardware PTW enabled
69 * Bit D will be set by hardware with write access
70 * Bit A will be set by hardware with read/intruction fetch access
71 */
72 static inline uint64_t pte_mkaccess(uint64_t entry)
73 {
74 return FIELD_DP64(entry, TLBENTRY, V, 1);
75 }
76
77 static inline uint64_t pte_mkdirty(uint64_t entry)
78 {
79 return FIELD_DP64(entry, TLBENTRY, D, 1);
80 }
81
82 static inline bool pte_access(uint64_t entry)
83 {
84 return !!FIELD_EX64(entry, TLBENTRY, V);
85 }
86
87 static inline bool pte_dirty(uint64_t entry)
88 {
89 return !!FIELD_EX64(entry, TLBENTRY, D);
90 }
91
92 bool check_ps(CPULoongArchState *ent, uint8_t ps);
93 TLBRet loongarch_check_pte(CPULoongArchState *env, MMUContext *context,
94 MMUAccessType access_type, int mmu_idx);
95 TLBRet get_physical_address(CPULoongArchState *env, MMUContext *context,
96 MMUAccessType access_type, int mmu_idx,
97 int is_debug);
98 TLBRet loongarch_ptw(CPULoongArchState *env, MMUContext *context,
99 int access_type, int mmu_idx, int debug);
100 void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
101 uint64_t *dir_width, unsigned int level);
102 hwaddr loongarch_cpu_get_phys_addr_debug(CPUState *cpu, vaddr addr);
103 uint64_t loongarch_palen_mask(CPULoongArchState *env);
104
105 #endif /* LOONGARCH_CPU_MMU_H */