Revision 496272a7 target-ppc/mmu-hash32.c
b/target-ppc/mmu-hash32.c | ||
---|---|---|
37 | 37 |
#define PTE_PTEM_MASK 0x7FFFFFBF |
38 | 38 |
#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B) |
39 | 39 |
|
40 |
static int ppc_hash32_pp_check(int key, int pp, int nx) |
|
41 |
{ |
|
42 |
int access; |
|
43 |
|
|
44 |
/* Compute access rights */ |
|
45 |
access = 0; |
|
46 |
if (key == 0) { |
|
47 |
switch (pp) { |
|
48 |
case 0x0: |
|
49 |
case 0x1: |
|
50 |
case 0x2: |
|
51 |
access |= PAGE_WRITE; |
|
52 |
/* No break here */ |
|
53 |
case 0x3: |
|
54 |
access |= PAGE_READ; |
|
55 |
break; |
|
56 |
} |
|
57 |
} else { |
|
58 |
switch (pp) { |
|
59 |
case 0x0: |
|
60 |
access = 0; |
|
61 |
break; |
|
62 |
case 0x1: |
|
63 |
case 0x3: |
|
64 |
access = PAGE_READ; |
|
65 |
break; |
|
66 |
case 0x2: |
|
67 |
access = PAGE_READ | PAGE_WRITE; |
|
68 |
break; |
|
69 |
} |
|
70 |
} |
|
71 |
if (nx == 0) { |
|
72 |
access |= PAGE_EXEC; |
|
73 |
} |
|
74 |
|
|
75 |
return access; |
|
76 |
} |
|
77 |
|
|
78 |
static int ppc_hash32_check_prot(int prot, int rw, int access_type) |
|
79 |
{ |
|
80 |
int ret; |
|
81 |
|
|
82 |
if (access_type == ACCESS_CODE) { |
|
83 |
if (prot & PAGE_EXEC) { |
|
84 |
ret = 0; |
|
85 |
} else { |
|
86 |
ret = -2; |
|
87 |
} |
|
88 |
} else if (rw) { |
|
89 |
if (prot & PAGE_WRITE) { |
|
90 |
ret = 0; |
|
91 |
} else { |
|
92 |
ret = -2; |
|
93 |
} |
|
94 |
} else { |
|
95 |
if (prot & PAGE_READ) { |
|
96 |
ret = 0; |
|
97 |
} else { |
|
98 |
ret = -2; |
|
99 |
} |
|
100 |
} |
|
101 |
|
|
102 |
return ret; |
|
103 |
} |
|
104 |
|
|
40 | 105 |
static inline int pte_is_valid_hash32(target_ulong pte0) |
41 | 106 |
{ |
42 | 107 |
return pte0 & 0x80000000 ? 1 : 0; |
... | ... | |
66 | 131 |
} |
67 | 132 |
} |
68 | 133 |
/* Compute access rights */ |
69 |
access = pp_check(ctx->key, pp, ctx->nx); |
|
134 |
access = ppc_hash32_pp_check(ctx->key, pp, ctx->nx);
|
|
70 | 135 |
/* Keep the matching PTE informations */ |
71 | 136 |
ctx->raddr = pte1; |
72 | 137 |
ctx->prot = access; |
73 |
ret = check_prot(ctx->prot, rw, type); |
|
138 |
ret = ppc_hash32_check_prot(ctx->prot, rw, type);
|
|
74 | 139 |
if (ret == 0) { |
75 | 140 |
/* Access granted */ |
76 | 141 |
LOG_MMU("PTE access granted !\n"); |
... | ... | |
84 | 149 |
return ret; |
85 | 150 |
} |
86 | 151 |
|
152 |
static int ppc_hash32_pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p, |
|
153 |
int ret, int rw) |
|
154 |
{ |
|
155 |
int store = 0; |
|
156 |
|
|
157 |
/* Update page flags */ |
|
158 |
if (!(*pte1p & 0x00000100)) { |
|
159 |
/* Update accessed flag */ |
|
160 |
*pte1p |= 0x00000100; |
|
161 |
store = 1; |
|
162 |
} |
|
163 |
if (!(*pte1p & 0x00000080)) { |
|
164 |
if (rw == 1 && ret == 0) { |
|
165 |
/* Update changed flag */ |
|
166 |
*pte1p |= 0x00000080; |
|
167 |
store = 1; |
|
168 |
} else { |
|
169 |
/* Force page fault for first write access */ |
|
170 |
ctx->prot &= ~PAGE_WRITE; |
|
171 |
} |
|
172 |
} |
|
173 |
|
|
174 |
return store; |
|
175 |
} |
|
176 |
|
|
87 | 177 |
/* PTE table lookup */ |
88 | 178 |
static int find_pte32(CPUPPCState *env, mmu_ctx_t *ctx, int h, |
89 | 179 |
int rw, int type, int target_page_bits) |
... | ... | |
138 | 228 |
ctx->raddr, ctx->prot, ret); |
139 | 229 |
/* Update page flags */ |
140 | 230 |
pte1 = ctx->raddr; |
141 |
if (pte_update_flags(ctx, &pte1, ret, rw) == 1) { |
|
231 |
if (ppc_hash32_pte_update_flags(ctx, &pte1, ret, rw) == 1) {
|
|
142 | 232 |
if (env->external_htab) { |
143 | 233 |
stl_p(env->external_htab + pteg_off + (good * 8) + 4, |
144 | 234 |
pte1); |
Also available in: Unified diff