diff options
author | Damien Zammit <damien@zamaudio.com> | 2023-02-03 10:01:49 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-02-03 20:07:10 +0100 |
commit | e09a4974ddc43ec10f0a940c08cc79e4778dfc49 (patch) | |
tree | 3aa1fdfcd014491adea993b4bc845fc3435a679f | |
parent | ebb783b68d13012e7e44fb47055f2ab2dee7f186 (diff) | |
download | gnumach-e09a4974ddc43ec10f0a940c08cc79e4778dfc49.tar.gz gnumach-e09a4974ddc43ec10f0a940c08cc79e4778dfc49.tar.bz2 gnumach-e09a4974ddc43ec10f0a940c08cc79e4778dfc49.zip |
pmap: Refactor temporary mapping functions
Message-Id: <20230203100133.835589-1-damien@zamaudio.com>
-rw-r--r-- | i386/i386at/model_dep.c | 73 | ||||
-rw-r--r-- | i386/intel/pmap.c | 93 | ||||
-rw-r--r-- | i386/intel/pmap.h | 6 |
3 files changed, 101 insertions, 71 deletions
diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c index fe11bffc..98408c06 100644 --- a/i386/i386at/model_dep.c +++ b/i386/i386at/model_dep.c @@ -359,10 +359,6 @@ register_boot_data(const struct multiboot_raw_info *mbi) static void i386at_init(void) { - /* XXX move to intel/pmap.h */ - extern pt_entry_t *kernel_page_dir; - int i; - /* * Initialize the PIC prior to any possible call to an spl. */ @@ -448,47 +444,8 @@ i386at_init(void) */ biosmem_setup(); - /* - * We'll have to temporarily install a direct mapping - * between physical memory and low linear memory, - * until we start using our new kernel segment descriptors. - */ -#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS - vm_offset_t delta = INIT_VM_MIN_KERNEL_ADDRESS - LINEAR_MIN_KERNEL_ADDRESS; - if ((vm_offset_t)(-delta) < delta) - delta = (vm_offset_t)(-delta); - int nb_direct = delta >> PDESHIFT; - for (i = 0; i < nb_direct; i++) - kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + i] = - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS) + i]; -#endif - /* We need BIOS memory mapped at 0xc0000 & co for BIOS accesses */ -#if VM_MIN_KERNEL_ADDRESS != 0 - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)] = - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)]; -#endif + pmap_make_temporary_mapping(); -#ifdef MACH_PV_PAGETABLES - for (i = 0; i < PDPNUM; i++) - pmap_set_page_readonly_init((void*) kernel_page_dir + i * INTEL_PGBYTES); -#if PAE - pmap_set_page_readonly_init(kernel_pmap->pdpbase); -#endif /* PAE */ -#endif /* MACH_PV_PAGETABLES */ -#if PAE -#ifdef __x86_64__ - set_cr3((unsigned long)_kvtophys(kernel_pmap->l4base)); -#else - set_cr3((unsigned long)_kvtophys(kernel_pmap->pdpbase)); -#endif -#ifndef MACH_HYP - if (!CPU_HAS_FEATURE(CPU_FEATURE_PAE)) - panic("CPU doesn't have support for PAE."); - set_cr4(get_cr4() | CR4_PAE); -#endif /* MACH_HYP */ -#else - set_cr3((unsigned long)_kvtophys(kernel_page_dir)); -#endif /* PAE */ #ifndef MACH_HYP /* Turn paging on. * Also set the WP bit so that on 486 or better processors @@ -520,33 +477,7 @@ i386at_init(void) mp_desc_init(0); #endif // NCPUS -#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS - /* Get rid of the temporary direct mapping and flush it out of the TLB. */ - for (i = 0 ; i < nb_direct; i++) { -#ifdef MACH_XEN -#ifdef MACH_PSEUDO_PHYS - if (!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum_cont(VM_MIN_KERNEL_ADDRESS) + i]), 0)) -#else /* MACH_PSEUDO_PHYS */ - if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS + i * INTEL_PGBYTES, 0, UVMF_INVLPG | UVMF_ALL)) -#endif /* MACH_PSEUDO_PHYS */ - printf("couldn't unmap frame %d\n", i); -#else /* MACH_XEN */ - kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + i] = 0; -#endif /* MACH_XEN */ - } -#endif - /* Keep BIOS memory mapped */ -#if VM_MIN_KERNEL_ADDRESS != 0 - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)] = - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)]; -#endif - - /* Not used after boot, better give it back. */ -#ifdef MACH_XEN - hyp_free_page(0, (void*) VM_MIN_KERNEL_ADDRESS); -#endif /* MACH_XEN */ - - flush_tlb(); + pmap_remove_temporary_mapping(); #ifdef MACH_XEN hyp_p2m_init(); diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c index 0505cfa2..3c57d732 100644 --- a/i386/intel/pmap.c +++ b/i386/intel/pmap.c @@ -3009,3 +3009,96 @@ pmap_unmap_page_zero (void) #endif /* MACH_PV_PAGETABLES */ } #endif /* __i386__ */ + +void +pmap_make_temporary_mapping(void) +{ + int i; + + /* + * We'll have to temporarily install a direct mapping + * between physical memory and low linear memory, + * until we start using our new kernel segment descriptors. + */ +#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS + vm_offset_t delta = INIT_VM_MIN_KERNEL_ADDRESS - LINEAR_MIN_KERNEL_ADDRESS; + if ((vm_offset_t)(-delta) < delta) + delta = (vm_offset_t)(-delta); + int nb_direct = delta >> PDESHIFT; + for (i = 0; i < nb_direct; i++) + kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + i] = + kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS) + i]; +#endif + /* We need BIOS memory mapped at 0xc0000 & co for BIOS accesses */ +#if VM_MIN_KERNEL_ADDRESS != 0 + kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)] = + kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)]; +#endif + +#ifdef MACH_PV_PAGETABLES + for (i = 0; i < PDPNUM; i++) + pmap_set_page_readonly_init((void*) kernel_page_dir + i * INTEL_PGBYTES); +#if PAE + pmap_set_page_readonly_init(kernel_pmap->pdpbase); +#endif /* PAE */ +#endif /* MACH_PV_PAGETABLES */ + + pmap_set_page_dir(); +} + +void +pmap_set_page_dir(void) +{ +#if PAE +#ifdef __x86_64__ + set_cr3((unsigned long)_kvtophys(kernel_pmap->l4base)); +#else + set_cr3((unsigned long)_kvtophys(kernel_pmap->pdpbase)); +#endif +#ifndef MACH_HYP + if (!CPU_HAS_FEATURE(CPU_FEATURE_PAE)) + panic("CPU doesn't have support for PAE."); + set_cr4(get_cr4() | CR4_PAE); +#endif /* MACH_HYP */ +#else + set_cr3((unsigned long)_kvtophys(kernel_page_dir)); +#endif /* PAE */ +} + +void +pmap_remove_temporary_mapping(void) +{ + int i; + +#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS + vm_offset_t delta = INIT_VM_MIN_KERNEL_ADDRESS - LINEAR_MIN_KERNEL_ADDRESS; + if ((vm_offset_t)(-delta) < delta) + delta = (vm_offset_t)(-delta); + int nb_direct = delta >> PDESHIFT; + /* Get rid of the temporary direct mapping and flush it out of the TLB. */ + for (i = 0 ; i < nb_direct; i++) { +#ifdef MACH_XEN +#ifdef MACH_PSEUDO_PHYS + if (!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum_cont(VM_MIN_KERNEL_ADDRESS) + i]), 0)) +#else /* MACH_PSEUDO_PHYS */ + if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS + i * INTEL_PGBYTES, 0, UVMF_INVLPG | UVMF_ALL)) +#endif /* MACH_PSEUDO_PHYS */ + printf("couldn't unmap frame %d\n", i); +#else /* MACH_XEN */ + kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + i] = 0; +#endif /* MACH_XEN */ + } +#endif + /* Keep BIOS memory mapped */ +#if VM_MIN_KERNEL_ADDRESS != 0 + kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS)] = + kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)]; +#endif + + /* Not used after boot, better give it back. */ +#ifdef MACH_XEN + hyp_free_page(0, (void*) VM_MIN_KERNEL_ADDRESS); +#endif /* MACH_XEN */ + + flush_tlb(); +} diff --git a/i386/intel/pmap.h b/i386/intel/pmap.h index d6bf85fb..92247faa 100644 --- a/i386/intel/pmap.h +++ b/i386/intel/pmap.h @@ -475,6 +475,8 @@ pt_entry_t *pmap_pte(const pmap_t pmap, vm_offset_t addr); #define pmap_attribute(pmap,addr,size,attr,value) \ (KERN_INVALID_ADDRESS) +extern pt_entry_t *kernel_page_dir; + /* * Bootstrap the system enough to run with virtual memory. * Allocate the kernel page directory and page tables, @@ -483,6 +485,10 @@ pt_entry_t *pmap_pte(const pmap_t pmap, vm_offset_t addr); */ extern void pmap_bootstrap(void); +extern void pmap_set_page_dir(void); +extern void pmap_make_temporary_mapping(void); +extern void pmap_remove_temporary_mapping(void); + extern void pmap_unmap_page_zero (void); /* |