Commit 461c0471af05cf29ac416afdbc9480e4732e4252

Authored by bellard
1 parent 9c3ad574

a20 support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@440 c046a42c-6fe2-441c-8c8c-71466251a162
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);