Re: [Milkymist port] virtual memory management
Le 18/02/14 13:48, Joerg Sonnenberger a écrit : On Tue, Feb 18, 2014 at 12:54:05PM +0100, Yann Sionneau wrote: Is there somewhere a function like vaddr_t map_paddr(paddr_t, prot)? uvm_km_alloc with UVM_KMF_VAONLY can be used to allocate the VA, pmap_kenter_pa to map a given physical address. Don't forget to call pmap_update(pmap_kernel()) afterwards. A simple example is arch/x86/x86/mpbios.c, mpbios_map. Joerg Thank you Matt and Joerg for your very quick answer, for now I implemented as Joerg said, but I imagine that the clean way is to use bus_space(9), right? Anyway, it works very well now :) From now on I need to debug an infinite loop, it seems that since cold = 0 (after configure2() ran), any printf (which calls kprintf then putchar then logputchar) will end up in a dead lock: logputchar() is calling mutex_spin_exit(), the latter is calling turnstile_exit() which in turn is calling mutex_spin_exit() as well, then it goes on and on. I didn't figure out yet what's going on. Cheers, -- Yann Sionneau
Re: [Milkymist port] virtual memory management
Le 10/02/14 23:00, Yann Sionneau a écrit : Thanks for all your explanations, if everything I said here is correct (which would mean I understood correctly your answer) then I think I'm ready to implement all this :) Hi, I have made good progress on the NetBSD port, it is now booting up to enabling interrupts and cpu_initclocks() call, see the boot log [0]. But then I am wondering how I can map the memory mapped registers of the timer0 of Milkymist SoC in order to use it as the main ticking clock. Basically, I need to map physical address 0xe000.1000 somewhere in kernel virtual memory. Is there somewhere a function like vaddr_t map_paddr(paddr_t, prot)? I could indeed walk the kernel page table and insert somewhere in a free PTE (a NULL one) a reference to the 0xe000.1000 physical address, but then how to be sure that the vm subsystem will not allocate this virtual address twice? Is there an iomapping mechanism? Thank you for your help :) [0] -- http://pastebin.com/MYitt9L4 Best regards, -- Yann Sionneau
Re: [Milkymist port] virtual memory management
On Tue, Feb 18, 2014 at 12:54:05PM +0100, Yann Sionneau wrote: Is there somewhere a function like vaddr_t map_paddr(paddr_t, prot)? uvm_km_alloc with UVM_KMF_VAONLY can be used to allocate the VA, pmap_kenter_pa to map a given physical address. Don't forget to call pmap_update(pmap_kernel()) afterwards. A simple example is arch/x86/x86/mpbios.c, mpbios_map. Joerg
Re: [Milkymist port] virtual memory management
On Feb 18, 2014, at 3:54 AM, Yann Sionneau yann.sionn...@gmail.com wrote: Le 10/02/14 23:00, Yann Sionneau a écrit : Thanks for all your explanations, if everything I said here is correct (which would mean I understood correctly your answer) then I think I'm ready to implement all this :) Hi, I have made good progress on the NetBSD port, it is now booting up to enabling interrupts and cpu_initclocks() call, see the boot log [0]. But then I am wondering how I can map the memory mapped registers of the timer0 of Milkymist SoC in order to use it as the main ticking clock. Basically, I need to map physical address 0xe000.1000 somewhere in kernel virtual memory. Is there somewhere a function like vaddr_t map_paddr(paddr_t, prot)? I could indeed walk the kernel page table and insert somewhere in a free PTE (a NULL one) a reference to the 0xe000.1000 physical address, but then how to be sure that the vm subsystem will not allocate this virtual address twice? Is there an iomapping mechanism? Thank you for your help :) [0] -- http://pastebin.com/MYitt9L4 see bus_space(9), specifically bus_space_map. internally, it allocates some KVA via uvm and uses pmap_kenter_pa to map the I/O address via the allocated KVA.
Re: [Milkymist port] virtual memory management
On Sun, 9 Feb 2014, Yann Sionneau wrote: Thank you for your answer Matt, Le 09/02/14 19:49, Matt Thomas a écrit : On Feb 9, 2014, at 10:07 AM, Yann Sionneau yann.sionn...@gmail.com wrote: Since the kernel runs with MMU on, using virtual addresses, it cannot dereference physical pointers then it cannot add/modify/remove PTEs, right? Wrong. See above. You mean that the TLB contains entries which map a physical address to itself? like 0xabcd. is mapped to 0xabcd.? Or you mean all RAM is always mapped but to the (0xa000.000+physical_pframe) kind of virtual address you mention later in your reply? What I did for BookE is reserve the low half of the kernel address space for VA=PA mappings. The kernel resides in the high half of the address space. I did this because the existing PPC port did strange things with BAT registers to access physical memory and copyin/copyout operations and I couldn't come up with a better way to do something compatible with the BookE MMU. It did limit the machine to 2GB RAM, which wasn't a problem for the 405GP. Also, the user address space is not shared with the kernel address space as on most machines. Instead, user processes get access to their own 4GB address space, and the kernel has 2GB to play with when you deduct the 2GB VA==PA region. (It's the same sort of thing I did for sparc64 way back when it was running 32-bit userland. But it doesn't need VA==PA mappings and can access physical and userland addresses while the kernel address space is active. Much nicer design.) When a BookE machine takes an MMU miss fault, the fault handler examines the faulting address if the high bit is zero, it synthesizes a TLB entry where the physical address is the same as the virtual address. If the high bit is set, it walks the page tables to find the TLB entry. This did make the copyin/copyout operations a bit complicated since it requires flipping the MMU between two contexts while doing the copy operation. Also, is it possible to make sure that everything (in kernel space) is mapped so that virtual_addr = physical_addr - RAM_START_ADDR + virtual_offset In my case RAM_START_ADDR is 0x4000 and I am trying to use virtual_offset of 0xc000 (everything in my kernel ELF binary is mapped at virtual address starting at 0xc000) If I can ensure that this formula is always correct I can then use a very simple macro to translate statically a physical address to a virtual address. Not knowing how much ram you have, I can only speak in generalities. I have 128 MB of RAM. But in general you reserve a part of the address space for direct mapped memory and then place the kernel about that. For instance, you might have 512MB of RAM which you map at 0xa000. and then have the kernel's mapped va space start at 0xc000.. So if I understand correctly, the first page of physical ram (0x4000.) is mapped at virtual address 0xa000. *and* at 0xc000. ? Isn't it a problem that a physical address is mapped twice in the same process (here the kernel)? My caches are VIPT, couldn't it generate cache aliases issues? If the MMU is always on while the kernel is running, and covers all of the KVA, then you could relocate the kernel text and data segments wherever you want them to be. If you want to put the kernel text and data segments in the direct-mapped range, you can easily do that. If you want it elsewhere, that should work too. The cache aliasing issues in VIPT caches only occur if the cache way size is larger than the page size. If you're designing your own hardware, don't do that. Otherwise, remember to only access a page through a single mapping and you won't have aliasing issues. And flush the page from the cache wenever establishing a new mapping. Eduardo
Re: [Milkymist port] virtual memory management
Le 10/02/14 18:10, Eduardo Horvath a écrit : On Sun, 9 Feb 2014, Yann Sionneau wrote: Thank you for your answer Matt, Le 09/02/14 19:49, Matt Thomas a écrit : On Feb 9, 2014, at 10:07 AM, Yann Sionneau yann.sionn...@gmail.com wrote: Since the kernel runs with MMU on, using virtual addresses, it cannot dereference physical pointers then it cannot add/modify/remove PTEs, right? Wrong. See above. You mean that the TLB contains entries which map a physical address to itself? like 0xabcd. is mapped to 0xabcd.? Or you mean all RAM is always mapped but to the (0xa000.000+physical_pframe) kind of virtual address you mention later in your reply? What I did for BookE is reserve the low half of the kernel address space for VA=PA mappings. The kernel resides in the high half of the address space. I did this because the existing PPC port did strange things with BAT registers to access physical memory and copyin/copyout operations and I couldn't come up with a better way to do something compatible with the BookE MMU. It did limit the machine to 2GB RAM, which wasn't a problem for the 405GP. Also, the user address space is not shared with the kernel address space as on most machines. Instead, user processes get access to their own 4GB address space, and the kernel has 2GB to play with when you deduct the 2GB VA==PA region. (It's the same sort of thing I did for sparc64 way back when it was running 32-bit userland. But it doesn't need VA==PA mappings and can access physical and userland addresses while the kernel address space is active. Much nicer design.) When a BookE machine takes an MMU miss fault, the fault handler examines the faulting address if the high bit is zero, it synthesizes a TLB entry where the physical address is the same as the virtual address. If the high bit is set, it walks the page tables to find the TLB entry. This did make the copyin/copyout operations a bit complicated since it requires flipping the MMU between two contexts while doing the copy operation. Also, is it possible to make sure that everything (in kernel space) is mapped so that virtual_addr = physical_addr - RAM_START_ADDR + virtual_offset In my case RAM_START_ADDR is 0x4000 and I am trying to use virtual_offset of 0xc000 (everything in my kernel ELF binary is mapped at virtual address starting at 0xc000) If I can ensure that this formula is always correct I can then use a very simple macro to translate statically a physical address to a virtual address. Not knowing how much ram you have, I can only speak in generalities. I have 128 MB of RAM. But in general you reserve a part of the address space for direct mapped memory and then place the kernel about that. For instance, you might have 512MB of RAM which you map at 0xa000. and then have the kernel's mapped va space start at 0xc000.. So if I understand correctly, the first page of physical ram (0x4000.) is mapped at virtual address 0xa000. *and* at 0xc000. ? Isn't it a problem that a physical address is mapped twice in the same process (here the kernel)? My caches are VIPT, couldn't it generate cache aliases issues? If the MMU is always on while the kernel is running, and covers all of the KVA, then you could relocate the kernel text and data segments wherever you want them to be. If you want to put the kernel text and data segments in the direct-mapped range, you can easily do that. If you want it elsewhere, that should work too. So if I understand correctly I could implement the following scheme: Let my linker put the kernel ELF virtual addresses to 0xc000.. Load the kernel at base of RAM (0x4000.) Then reserve this memory region as a window over physical ram : 0xc000.-0xc800. (ram size is 128 MB) by doing something like physseg[0].avail_start = 0xc800.; in pmap_bootstrap() Then in my tlb miss handlers I could do: if (fault happened in kernel mode) /* we don't want user space to access all ram through the kernel window */ { if ( (miss_vaddr 0xc800) (miss_vaddr = 0xc000) ) /* = this would be kind of like your test of the high bit of the faulty vaddr */ { reload_tlb_with(atop(miss_vaddr), atop(miss_vaddr - 0xc000 + 0x4000) | some_flags); /* = create the mapping for accessing the window */ return_from_exception; } } else { - access the page table to reload tlb - page table contains only physical addresses - but I can dereference those using the 0xc000.-0xc800. window knowing that a nested tlb miss can happen } Does this sound reasonable ? The cache aliasing issues in VIPT caches only occur if the cache way size is larger than the page size. If you're designing your own hardware, don't do that. Otherwise, remember to only access a page through a single mapping and you won't have aliasing issues. And flush the page from the cache wenever establishing a new mapping. Well, lm32 caches are configurable but
Re: [Milkymist port] virtual memory management
On Feb 10, 2014, at 9:10 AM, Eduardo Horvath e...@netbsd.org wrote: On Sun, 9 Feb 2014, Yann Sionneau wrote: Thank you for your answer Matt, Le 09/02/14 19:49, Matt Thomas a écrit : On Feb 9, 2014, at 10:07 AM, Yann Sionneau yann.sionn...@gmail.com wrote: Since the kernel runs with MMU on, using virtual addresses, it cannot dereference physical pointers then it cannot add/modify/remove PTEs, right? Wrong. See above. You mean that the TLB contains entries which map a physical address to itself? like 0xabcd. is mapped to 0xabcd.? Or you mean all RAM is always mapped but to the (0xa000.000+physical_pframe) kind of virtual address you mention later in your reply? What I did for BookE is reserve the low half of the kernel address space for VA=PA mappings. The kernel resides in the high half of the address space. I did this because the existing PPC port did strange things with BAT registers to access physical memory and copyin/copyout operations and I couldn't come up with a better way to do something compatible with the BookE MMU. It did limit the machine to 2GB RAM, which wasn't a problem for the 405GP. For the MPC85xx, I did something similar but I used fixed TLB1 entries to map the physical ram 1:1 with VA=PA mappings. Also, the user address space is not shared with the kernel address space as on most machines. Instead, user processes get access to their own 4GB address space, and the kernel has 2GB to play with when you deduct the 2GB VA==PA region. (It's the same sort of thing I did for sparc64 way back when it was running 32-bit userland. But it doesn't need VA==PA mappings and can access physical and userland addresses while the kernel address space is active. Much nicer design.) BookE could have avoided the VA==PA mappings but it simplifies a lot of things. When a BookE machine takes an MMU miss fault, the fault handler examines the faulting address if the high bit is zero, it synthesizes a TLB entry where the physical address is the same as the virtual address. If the high bit is set, it walks the page tables to find the TLB entry. Not true for the MPC85xx BookE. Then a trap happens, the PSL[PR] bit gets reset along with the PSL[DS] and PSL[IS] bits. This forces the MMU to only match the match TLB entries with a MAS1[TS] == 0 (e.g. kernel TLB entries). This did make the copyin/copyout operations a bit complicated since it requires flipping the MMU between two contexts while doing the copy operation. Well, for the MPC85xx, I only set the PSL[DS] bit so I can access the user address space, load/store stuff to/from register, and then reset it back. It's not as fast as I'd like but it works. Also, is it possible to make sure that everything (in kernel space) is mapped so that virtual_addr = physical_addr - RAM_START_ADDR + virtual_offset In my case RAM_START_ADDR is 0x4000 and I am trying to use virtual_offset of 0xc000 (everything in my kernel ELF binary is mapped at virtual address starting at 0xc000) If I can ensure that this formula is always correct I can then use a very simple macro to translate statically a physical address to a virtual address. Not knowing how much ram you have, I can only speak in generalities. I have 128 MB of RAM. But in general you reserve a part of the address space for direct mapped memory and then place the kernel about that. For instance, you might have 512MB of RAM which you map at 0xa000. and then have the kernel's mapped va space start at 0xc000.. So if I understand correctly, the first page of physical ram (0x4000.) is mapped at virtual address 0xa000. *and* at 0xc000. ? Isn't it a problem that a physical address is mapped twice in the same process (here the kernel)? My caches are VIPT, couldn't it generate cache aliases issues? If the MMU is always on while the kernel is running, and covers all of the KVA, then you could relocate the kernel text and data segments wherever you want them to be. If you want to put the kernel text and data segments in the direct-mapped range, you can easily do that. If you want it elsewhere, that should work too. In fast, I'd recommend doing that. Leaving the mapped KVA space for those things that need to dynamically mapped. The cache aliasing issues in VIPT caches only occur if the cache way size is larger than the page size. If you're designing your own hardware, don't do that. Otherwise, remember to only access a page through a single mapping and you won't have aliasing issues. And flush the page from the cache wenever establishing a new mapping. I agree. You can play other games with VIPT but it becomes complex quickly.
Re: [Milkymist port] virtual memory management
On Feb 10, 2014, at 2:00 PM, Yann Sionneau yann.sionn...@gmail.com wrote: So if I understand correctly I could implement the following scheme: Let my linker put the kernel ELF virtual addresses to 0xc000.. Load the kernel at base of RAM (0x4000.) Then reserve this memory region as a window over physical ram : 0xc000.-0xc800. (ram size is 128 MB) by doing something like physseg[0].avail_start = 0xc800.; in pmap_bootstrap() Then in my tlb miss handlers I could do: if (fault happened in kernel mode) /* we don't want user space to access all ram through the kernel window */ { if ( (miss_vaddr 0xc800) (miss_vaddr = 0xc000) ) /* = this would be kind of like your test of the high bit of the faulty vaddr */ { reload_tlb_with(atop(miss_vaddr), atop(miss_vaddr - 0xc000 + 0x4000) | some_flags); /* = create the mapping for accessing the window */ atop(miss_vaddr ^ 0x800) :) return_from_exception; } } else { - access the page table to reload tlb - page table contains only physical addresses - but I can dereference those using the 0xc000.-0xc800. window knowing that a nested tlb miss can happen } I'd leave the page_table using virtual addresses but since they will all be direct mapped, simply convert to them to physical before using them. That way, when the kernel is running with the TLB enabled (which is most of the time), it can traverse the page tables normally. Does this sound reasonable ? The cache aliasing issues in VIPT caches only occur if the cache way size is larger than the page size. If you're designing your own hardware, don't do that. Otherwise, remember to only access a page through a single mapping and you won't have aliasing issues. And flush the page from the cache wenever establishing a new mapping. Well, lm32 caches are configurable but for the Milkymist SoC they are not configured too big such that there is no alias problem. In order to handle all cases of lm32 cache sizes I guess I need to add a macro that the machine headers will define if there are cache alias issues possible. But then if I am using the 0xc000.-0xc800. window during my tlb miss handler I guess I will have no choice but to invalidate the cache because any fault while reading this window will then add a tlb entry to this window which would possibly cause a physical page to be mapped twice and then could cause alias issues (in the scenario where caches are too big). Hopefully, if they make the caches larger they increase the number of ways. I wouldn't add code to flush. Just add a panic if you detect you can have aliases and deal with it if it ever happens.
Re: [Milkymist port] virtual memory management
On Mon, Feb 10, 2014 at 02:38:27PM -0800, Matt Thomas wrote: Hopefully, if they make the caches larger they increase the number of ways. I wouldn't add code to flush. Just add a panic if you detect you can have aliases and deal with it if it ever happens. IIRC A lot of sparc systems have VIPT caches where the cache size (divided by the ways) is much larger than a page size (IIRC at least 64k). If memory has to be mapped at different VA (eg in different processes) then it is best to pick VA so that the data hits the correct part of the cache. Otherwise it has to be mapped uncached. I guess another solution is to use logical pages that are the right size. David -- David Laight: da...@l8s.co.uk
Re: [Milkymist port] virtual memory management
Hello Eduardo, Le 30/05/13 22:45, Eduardo Horvath a écrit : On Wed, 29 May 2013, Yann Sionneau wrote: Hello NetBSD fellows, As I mentioned in my previous e-mail, I may need from time to time a little bit of help since this is my first full featured OS port. I am wondering how I can manage virtual memory (especially how to avoid tlb miss, or deal with them) in exception handlers. There are essentially three ways to do this. Which one you chose depends on the hardware. 1) Turn off the MMU on exception 2) Keep parts of the address space untranslated 3) Lock important pages into the TLB Turning off the MMU is pretty straight-forward. ISTR the PowerPC Book E processors do this. Just look up the TLB entry in the table and return from exception. You just have to make sure that the kernel manages page tables using physical addresses. This seems like the easiest thing to do (because I won't have to think about recursive faults) but then if I put physical addresses in my 1st level page table, how does the kernel manage the page table entries? Since the kernel runs with MMU on, using virtual addresses, it cannot dereference physical pointers then it cannot add/modify/remove PTEs, right? I'm sure there is some kernel internal mechanism that I don't know about which could help me getting the virtual address from the physical one, do you know which mechanism it would be? Also, is it possible to make sure that everything (in kernel space) is mapped so that virtual_addr = physical_addr - RAM_START_ADDR + virtual_offset In my case RAM_START_ADDR is 0x4000 and I am trying to use virtual_offset of 0xc000 (everything in my kernel ELF binary is mapped at virtual address starting at 0xc000) If I can ensure that this formula is always correct I can then use a very simple macro to translate statically a physical address to a virtual address. Then I have another question, who is supposed to build the kernel's page table? pmap_bootstrap()? If so, then how do I allocate pages for that purpose? using pmap_pte_pagealloc() and pmap_segtab_init() ? FYI I am using those files for my pmap: uvm/pmap/pmap.c uvm/pmap/pmap_segtab.c uvm/pmap/pmap_tlb.c I am taking inspiration from the PPC Book-E (mpc85xx) code. Thanks ! Regards, -- Yann
Re: [Milkymist port] virtual memory management
On Feb 9, 2014, at 10:07 AM, Yann Sionneau yann.sionn...@gmail.com wrote: This seems like the easiest thing to do (because I won't have to think about recursive faults) but then if I put physical addresses in my 1st level page table, how does the kernel manage the page table entries? BookE always has the MMU on and contains fixed TLB entries to make sure all of physical ram is always mapped. Since the kernel runs with MMU on, using virtual addresses, it cannot dereference physical pointers then it cannot add/modify/remove PTEs, right? Wrong. See above. Note that on BookE, PTEs are purely a software construction and the H/W never reads them directly. I'm sure there is some kernel internal mechanism that I don't know about which could help me getting the virtual address from the physical one, do you know which mechanism it would be? Look at __HAVE_MM_MD_DIRECT_MAPPED_PHYS and/or PMAP_{MAP,UNMAP}_POOLPAGE. Also, is it possible to make sure that everything (in kernel space) is mapped so that virtual_addr = physical_addr - RAM_START_ADDR + virtual_offset In my case RAM_START_ADDR is 0x4000 and I am trying to use virtual_offset of 0xc000 (everything in my kernel ELF binary is mapped at virtual address starting at 0xc000) If I can ensure that this formula is always correct I can then use a very simple macro to translate statically a physical address to a virtual address. Not knowing how much ram you have, I can only speak in generalities. But in general you reserve a part of the address space for direct mapped memory and then place the kernel about that. For instance, you might have 512MB of RAM which you map at 0xa000. and then have the kernel's mapped va space start at 0xc000.. Then conversion to from PA to VA is just adding a constant while getting the PA from a direct mapped VA is just subtraction. Then I have another question, who is supposed to build the kernel's page table? pmap_bootstrap()? Some part of MD code. pmap_bootstrap() could be that. If so, then how do I allocate pages for that purpose? using pmap_pte_pagealloc() and pmap_segtab_init() ? usually you use pmap_steal_memory to do that. But for mpc85xx I just allocate the kernel initial segmap in the .bss. But the page tables were from allocated using uvm can do prebootstrap allocations. FYI I am using those files for my pmap: uvm/pmap/pmap.c uvm/pmap/pmap_segtab.c uvm/pmap/pmap_tlb.c I am taking inspiration from the PPC Book-E (mpc85xx) code.
Re: [Milkymist port] virtual memory management
Thank you for your answer Matt, Le 09/02/14 19:49, Matt Thomas a écrit : On Feb 9, 2014, at 10:07 AM, Yann Sionneau yann.sionn...@gmail.com wrote: This seems like the easiest thing to do (because I won't have to think about recursive faults) but then if I put physical addresses in my 1st level page table, how does the kernel manage the page table entries? BookE always has the MMU on and contains fixed TLB entries to make sure all of physical ram is always mapped. My TLB hardware is very simple and does not give me the option to fix a TLB entry so I won't be able to do that. the lm32 MMU is turned off upon exception (tlb miss for instance) automatically, then I can enable it back if I want. In the end the MMU is enabled back upon return from exception. Since the kernel runs with MMU on, using virtual addresses, it cannot dereference physical pointers then it cannot add/modify/remove PTEs, right? Wrong. See above. You mean that the TLB contains entries which map a physical address to itself? like 0xabcd. is mapped to 0xabcd.? Or you mean all RAM is always mapped but to the (0xa000.000+physical_pframe) kind of virtual address you mention later in your reply? Note that on BookE, PTEs are purely a software construction and the H/W never reads them directly. Here my HW is like BookE, I don't have hardware page tree walker, PTEs are only for the software to reload the TLB when there is an exception (tlb miss), TLB will never read memory to find PTE in my lm32 MMU implementation. I'm sure there is some kernel internal mechanism that I don't know about which could help me getting the virtual address from the physical one, do you know which mechanism it would be? Look at __HAVE_MM_MD_DIRECT_MAPPED_PHYS and/or PMAP_{MAP,UNMAP}_POOLPAGE. For now I have something like that: vaddr_t pmap_md_map_poolpage(paddr_t pa, vsize_t size) { const vaddr_t sva = (vaddr_t) pa - 0x4000 + 0xc000; return sva; } But I guess it only works to access the content of kernel ELF (text and data) but not to access dynamic runtime kernel allocations, right? Also, is it possible to make sure that everything (in kernel space) is mapped so that virtual_addr = physical_addr - RAM_START_ADDR + virtual_offset In my case RAM_START_ADDR is 0x4000 and I am trying to use virtual_offset of 0xc000 (everything in my kernel ELF binary is mapped at virtual address starting at 0xc000) If I can ensure that this formula is always correct I can then use a very simple macro to translate statically a physical address to a virtual address. Not knowing how much ram you have, I can only speak in generalities. I have 128 MB of RAM. But in general you reserve a part of the address space for direct mapped memory and then place the kernel about that. For instance, you might have 512MB of RAM which you map at 0xa000. and then have the kernel's mapped va space start at 0xc000.. So if I understand correctly, the first page of physical ram (0x4000.) is mapped at virtual address 0xa000. *and* at 0xc000. ? Isn't it a problem that a physical address is mapped twice in the same process (here the kernel)? My caches are VIPT, couldn't it generate cache aliases issues? Then conversion to from PA to VA is just adding a constant while getting the PA from a direct mapped VA is just subtraction. Then I have another question, who is supposed to build the kernel's page table? pmap_bootstrap()? Some part of MD code. pmap_bootstrap() could be that. If so, then how do I allocate pages for that purpose? using pmap_pte_pagealloc() and pmap_segtab_init() ? usually you use pmap_steal_memory to do that. But for mpc85xx I just allocate the kernel initial segmap in the .bss. But the page tables were from allocated using uvm can do prebootstrap allocations. Are you referring to the following code? /* * Now actually allocate the kernel PTE array (must be done * after virtual_end is initialized). */ const vaddr_t kv_segtabs = avail[0].start; KASSERT(kv_segtabs == endkernel); KASSERT(avail[0].size = NBPG * kv_nsegtabs); printf( kv_nsegtabs=%#PRIxVSIZE, kv_nsegtabs); printf( kv_segtabs=%#PRIxVADDR, kv_segtabs); avail[0].start += NBPG * kv_nsegtabs; avail[0].size -= NBPG * kv_nsegtabs; endkernel += NBPG * kv_nsegtabs; /* * Initialize the kernel's two-level page level. This only wastes * an extra page for the segment table and allows the user/kernel * access to be common. */ pt_entry_t **ptp = stp-seg_tab[VM_MIN_KERNEL_ADDRESS SEGSHIFT]; pt_entry_t *ptep = (void *)kv_segtabs; memset(ptep, 0, NBPG * kv_nsegtabs); for (size_t i = 0; i kv_nsegtabs; i++, ptep += NPTEPG) { *ptp++ = ptep; } FYI I am using those files for my pmap: uvm/pmap/pmap.c uvm/pmap/pmap_segtab.c uvm/pmap/pmap_tlb.c I am taking inspiration from the PPC Book-E (mpc85xx) code. Regards, -- Yann
Re: [Milkymist port] virtual memory management
On Wed, May 29, 2013 at 07:51:15PM +0200, Yann Sionneau wrote: I am wondering how I can manage virtual memory (especially how to avoid tlb miss, or deal with them) in exception handlers. At first my idea was to do most of the low level stuff in exception handlers with MMU turned off, I was told it was a very bad idea. LM32 MMU (for now at least) turns itself off upon any CPU exception, therefore I plan on turning it on right away in the exception handler. This leads to the following scenario I don't know how to deal with: [snip] hold on, hold on. What's the high-level picture? Does the kernel normally run with the MMU on or off? What's the intended scheme for TLB refill? Are the page tables supposed to be mapped in virtual memory (mips, vax) or placed in physical memory (x86)? -- David A. Holland dholl...@netbsd.org