Commit 461c0471af05cf29ac416afdbc9480e4732e4252
1 parent
9c3ad574
a20 support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@440 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
33 additions
and
5 deletions
target-i386/cpu.h
@@ -389,6 +389,9 @@ void cpu_x86_init_mmu(CPUX86State *env); | @@ -389,6 +389,9 @@ void cpu_x86_init_mmu(CPUX86State *env); | ||
389 | extern int phys_ram_size; | 389 | extern int phys_ram_size; |
390 | extern int phys_ram_fd; | 390 | extern int phys_ram_fd; |
391 | extern uint8_t *phys_ram_base; | 391 | extern uint8_t *phys_ram_base; |
392 | +extern int a20_enabled; | ||
393 | + | ||
394 | +void cpu_x86_set_a20(CPUX86State *env, int a20_state); | ||
392 | 395 | ||
393 | /* used to debug */ | 396 | /* used to debug */ |
394 | #define X86_DUMP_FPU 0x0001 /* dump FPU state too */ | 397 | #define X86_DUMP_FPU 0x0001 /* dump FPU state too */ |
target-i386/helper2.c
@@ -158,10 +158,29 @@ void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags) | @@ -158,10 +158,29 @@ void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags) | ||
158 | /* called when cr3 or PG bit are modified */ | 158 | /* called when cr3 or PG bit are modified */ |
159 | static int last_pg_state = -1; | 159 | static int last_pg_state = -1; |
160 | static int last_pe_state = 0; | 160 | static int last_pe_state = 0; |
161 | +static uint32_t a20_mask; | ||
162 | +int a20_enabled; | ||
163 | + | ||
161 | int phys_ram_size; | 164 | int phys_ram_size; |
162 | int phys_ram_fd; | 165 | int phys_ram_fd; |
163 | uint8_t *phys_ram_base; | 166 | uint8_t *phys_ram_base; |
164 | 167 | ||
168 | +void cpu_x86_set_a20(CPUX86State *env, int a20_state) | ||
169 | +{ | ||
170 | + a20_state = (a20_state != 0); | ||
171 | + if (a20_state != a20_enabled) { | ||
172 | + /* when a20 is changed, all the MMU mappings are invalid, so | ||
173 | + we must flush everything */ | ||
174 | + page_unmap(); | ||
175 | + tlb_flush(env); | ||
176 | + a20_enabled = a20_state; | ||
177 | + if (a20_enabled) | ||
178 | + a20_mask = 0xffffffff; | ||
179 | + else | ||
180 | + a20_mask = 0xffefffff; | ||
181 | + } | ||
182 | +} | ||
183 | + | ||
165 | void cpu_x86_update_cr0(CPUX86State *env) | 184 | void cpu_x86_update_cr0(CPUX86State *env) |
166 | { | 185 | { |
167 | int pg_state, pe_state; | 186 | int pg_state, pe_state; |
@@ -195,6 +214,9 @@ void cpu_x86_update_cr3(CPUX86State *env) | @@ -195,6 +214,9 @@ void cpu_x86_update_cr3(CPUX86State *env) | ||
195 | 214 | ||
196 | void cpu_x86_init_mmu(CPUX86State *env) | 215 | void cpu_x86_init_mmu(CPUX86State *env) |
197 | { | 216 | { |
217 | + a20_enabled = 1; | ||
218 | + a20_mask = 0xffffffff; | ||
219 | + | ||
198 | last_pg_state = -1; | 220 | last_pg_state = -1; |
199 | cpu_x86_update_cr0(env); | 221 | cpu_x86_update_cr0(env); |
200 | } | 222 | } |
@@ -244,14 +266,15 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, | @@ -244,14 +266,15 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, | ||
244 | 266 | ||
245 | if (!(env->cr[0] & CR0_PG_MASK)) { | 267 | if (!(env->cr[0] & CR0_PG_MASK)) { |
246 | pte = addr; | 268 | pte = addr; |
247 | - virt_addr = addr & ~0xfff; | 269 | + virt_addr = addr & TARGET_PAGE_MASK; |
248 | prot = PROT_READ | PROT_WRITE; | 270 | prot = PROT_READ | PROT_WRITE; |
249 | page_size = 4096; | 271 | page_size = 4096; |
250 | goto do_mapping; | 272 | goto do_mapping; |
251 | } | 273 | } |
252 | 274 | ||
253 | /* page directory entry */ | 275 | /* page directory entry */ |
254 | - pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)); | 276 | + pde_ptr = phys_ram_base + |
277 | + (((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & a20_mask); | ||
255 | pde = ldl_raw(pde_ptr); | 278 | pde = ldl_raw(pde_ptr); |
256 | if (!(pde & PG_PRESENT_MASK)) { | 279 | if (!(pde & PG_PRESENT_MASK)) { |
257 | error_code = 0; | 280 | error_code = 0; |
@@ -287,7 +310,8 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, | @@ -287,7 +310,8 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, | ||
287 | } | 310 | } |
288 | 311 | ||
289 | /* page directory entry */ | 312 | /* page directory entry */ |
290 | - pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc)); | 313 | + pte_ptr = phys_ram_base + |
314 | + (((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask); | ||
291 | pte = ldl_raw(pte_ptr); | 315 | pte = ldl_raw(pte_ptr); |
292 | if (!(pte & PG_PRESENT_MASK)) { | 316 | if (!(pte & PG_PRESENT_MASK)) { |
293 | error_code = 0; | 317 | error_code = 0; |
@@ -325,6 +349,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, | @@ -325,6 +349,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, | ||
325 | } | 349 | } |
326 | 350 | ||
327 | do_mapping: | 351 | do_mapping: |
352 | + pte = pte & a20_mask; | ||
328 | #if !defined(CONFIG_SOFTMMU) | 353 | #if !defined(CONFIG_SOFTMMU) |
329 | if (is_softmmu) | 354 | if (is_softmmu) |
330 | #endif | 355 | #endif |
@@ -334,8 +359,8 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, | @@ -334,8 +359,8 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, | ||
334 | 359 | ||
335 | /* software MMU case. Even if 4MB pages, we map only one 4KB | 360 | /* software MMU case. Even if 4MB pages, we map only one 4KB |
336 | page in the cache to avoid filling it too fast */ | 361 | page in the cache to avoid filling it too fast */ |
337 | - page_offset = (addr & ~0xfff) & (page_size - 1); | ||
338 | - paddr = (pte & ~0xfff) + page_offset; | 362 | + page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1); |
363 | + paddr = (pte & TARGET_PAGE_MASK) + page_offset; | ||
339 | vaddr = virt_addr + page_offset; | 364 | vaddr = virt_addr + page_offset; |
340 | index = (addr >> 12) & (CPU_TLB_SIZE - 1); | 365 | index = (addr >> 12) & (CPU_TLB_SIZE - 1); |
341 | pd = physpage_find(paddr); | 366 | pd = physpage_find(paddr); |