xref: /qemu/target/ppc/mmu-hash32.h (revision fc524567087c2537b5103cdfc1d41e4f442892b6)
1 #ifndef MMU_HASH32_H
2 #define MMU_HASH32_H
3 
4 #ifndef CONFIG_USER_ONLY
5 
6 #include "system/memory.h"
7 
8 bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
9                       hwaddr *raddrp, int *psizep, int *protp, int mmu_idx,
10                       bool guest_visible);
11 
12 /*
13  * Segment register definitions
14  */
15 
16 #define SR32_T                  0x80000000
17 #define SR32_KS                 0x40000000
18 #define SR32_KP                 0x20000000
19 #define SR32_NX                 0x10000000
20 #define SR32_VSID               0x00ffffff
21 
22 /*
23  * Block Address Translation (BAT) definitions
24  */
25 
26 #define BATU32_BEPIU            0xf0000000
27 #define BATU32_BEPIL            0x0ffe0000
28 #define BATU32_BEPI             0xfffe0000
29 #define BATU32_BL               0x00001ffc
30 #define BATU32_VS               0x00000002
31 #define BATU32_VP               0x00000001
32 
33 
34 #define BATL32_BRPN             0xfffe0000
35 #define BATL32_WIMG             0x00000078
36 #define BATL32_PP               0x00000003
37 
38 /*
39  * Hash page table definitions
40  */
41 #define SDR_32_HTABORG         0xFFFF0000UL
42 #define SDR_32_HTABMASK        0x000001FFUL
43 
44 #define HPTES_PER_GROUP         8
45 #define HASH_PTE_SIZE_32        8
46 #define HASH_PTEG_SIZE_32       (HASH_PTE_SIZE_32 * HPTES_PER_GROUP)
47 
48 #define HPTE32_V_VALID          0x80000000
49 #define HPTE32_V_VSID           0x7fffff80
50 #define HPTE32_V_SECONDARY      0x00000040
51 #define HPTE32_V_API            0x0000003f
52 #define HPTE32_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0x7fffffbf))
53 
54 #define HPTE32_R_RPN            0xfffff000
55 #define HPTE32_R_R              0x00000100
56 #define HPTE32_R_C              0x00000080
57 #define HPTE32_R_W              0x00000040
58 #define HPTE32_R_I              0x00000020
59 #define HPTE32_R_M              0x00000010
60 #define HPTE32_R_G              0x00000008
61 #define HPTE32_R_WIMG           0x00000078
62 #define HPTE32_R_PP             0x00000003
63 
ppc_hash32_hpt_base(PowerPCCPU * cpu)64 static inline hwaddr ppc_hash32_hpt_base(PowerPCCPU *cpu)
65 {
66     return cpu->env.spr[SPR_SDR1] & SDR_32_HTABORG;
67 }
68 
ppc_hash32_hpt_mask(PowerPCCPU * cpu)69 static inline hwaddr ppc_hash32_hpt_mask(PowerPCCPU *cpu)
70 {
71     return ((cpu->env.spr[SPR_SDR1] & SDR_32_HTABMASK) << 16) | 0xFFFF;
72 }
73 
ppc_hash32_load_hpte0(PowerPCCPU * cpu,hwaddr pte_offset)74 static inline target_ulong ppc_hash32_load_hpte0(PowerPCCPU *cpu,
75                                                  hwaddr pte_offset)
76 {
77     target_ulong base = ppc_hash32_hpt_base(cpu);
78 
79     return ldl_phys(CPU(cpu)->as, base + pte_offset);
80 }
81 
ppc_hash32_load_hpte1(PowerPCCPU * cpu,hwaddr pte_offset)82 static inline target_ulong ppc_hash32_load_hpte1(PowerPCCPU *cpu,
83                                                  hwaddr pte_offset)
84 {
85     target_ulong base = ppc_hash32_hpt_base(cpu);
86 
87     return ldl_phys(CPU(cpu)->as, base + pte_offset + HASH_PTE_SIZE_32 / 2);
88 }
89 
ppc_hash32_store_hpte0(PowerPCCPU * cpu,hwaddr pte_offset,target_ulong pte0)90 static inline void ppc_hash32_store_hpte0(PowerPCCPU *cpu,
91                                           hwaddr pte_offset, target_ulong pte0)
92 {
93     target_ulong base = ppc_hash32_hpt_base(cpu);
94 
95     stl_phys(CPU(cpu)->as, base + pte_offset, pte0);
96 }
97 
ppc_hash32_store_hpte1(PowerPCCPU * cpu,hwaddr pte_offset,target_ulong pte1)98 static inline void ppc_hash32_store_hpte1(PowerPCCPU *cpu,
99                                           hwaddr pte_offset, target_ulong pte1)
100 {
101     target_ulong base = ppc_hash32_hpt_base(cpu);
102 
103     stl_phys(CPU(cpu)->as, base + pte_offset + HASH_PTE_SIZE_32 / 2, pte1);
104 }
105 
get_pteg_offset32(PowerPCCPU * cpu,hwaddr hash)106 static inline hwaddr get_pteg_offset32(PowerPCCPU *cpu, hwaddr hash)
107 {
108     return (hash * HASH_PTEG_SIZE_32) & ppc_hash32_hpt_mask(cpu);
109 }
110 
ppc_hash32_key(bool pr,target_ulong sr)111 static inline bool ppc_hash32_key(bool pr, target_ulong sr)
112 {
113     return pr ? (sr & SR32_KP) : (sr & SR32_KS);
114 }
115 
ppc_hash32_prot(bool key,int pp,bool nx)116 static inline int ppc_hash32_prot(bool key, int pp, bool nx)
117 {
118     int prot;
119 
120     if (key) {
121         switch (pp) {
122         case 0x0:
123             prot = 0;
124             break;
125         case 0x1:
126         case 0x3:
127             prot = PAGE_READ;
128             break;
129         case 0x2:
130             prot = PAGE_READ | PAGE_WRITE;
131             break;
132         default:
133             g_assert_not_reached();
134         }
135     } else {
136         switch (pp) {
137         case 0x0:
138         case 0x1:
139         case 0x2:
140             prot = PAGE_READ | PAGE_WRITE;
141             break;
142         case 0x3:
143             prot = PAGE_READ;
144             break;
145         default:
146             g_assert_not_reached();
147         }
148     }
149     return nx ? prot : prot | PAGE_EXEC;
150 }
151 
ppc_hash32_bat_prot(target_ulong batu,target_ulong batl)152 static inline int ppc_hash32_bat_prot(target_ulong batu, target_ulong batl)
153 {
154     int prot = 0;
155     int pp = batl & BATL32_PP;
156 
157     if (pp) {
158         prot = PAGE_READ | PAGE_EXEC;
159         if (pp == 0x2) {
160             prot |= PAGE_WRITE;
161         }
162     }
163     return prot;
164 }
165 
166 typedef struct {
167     uint32_t pte0, pte1;
168 } ppc_hash_pte32_t;
169 
170 #endif /* CONFIG_USER_ONLY */
171 
172 #endif /* MMU_HASH32_H */
173