Date: Mon, 21 Jul 2003 14:47:31 +0100 From: Bruce M Simpson <bms@spc.org> To: hackers@freebsd.org Subject: PAE correctness Message-ID: <20030721134731.GF22295@spc.org>
next in thread | raw e-mail | index | archive | help
--DSayHWYpDlRfCAAQ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I should be most grateful if someone reviews the attached code fragment and let me know how to do the right thing for PAE whilst remaining machine-independent. My previous version of this code was written after reading the pre-busdma'd bktr(4) driver, which used pmap_kenter() - bad puppy! Should I even be using pmap_map() in this case? This does make the assumption that the cardbus/pccard drivers take care of pushing the memory window into PCI visibility, and that the PCI regions can be mapped into the 'real' memory address space. I should note I also peeked at sparc64_bus_mem_map() this morning for pointers. Love and hugs, BMS --DSayHWYpDlRfCAAQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="foo.c" ... struct pcmem_softc { ... /* common memory mapping descriptors */ vm_paddr_t sc_cm_base; vm_paddr_t sc_cm_size; vm_offset_t sc_cm_kva_base; vm_size_t sc_cm_kva_size; ... }; ... /* * pcmem_phys_map(): * * Map the common memory window of the PCMCIA memory card in an * architecture-independent and SMP coherent manner. Record the * addresses used within the card's soft-state structure for * later use by pcmem_phys_unmap(). * * The pccard code does not map the window for us, therefore * this code is necessary. * * Returns the first mapped virtual address of the card's common * memory, or 0 to indicate failure. * * XXX needs address arithmetic review for PAE */ static vm_offset_t pcmem_phys_map(struct pcmem_softc *sc) { vm_paddr_t pa, off, psize; vm_offset_t va; vm_size_t vsize; /* clip all address ranges to within page boundaries */ pa = trunc_page(sc->sc_cm_base); psize = round_page(sc->sc_cm_size); vsize = (vm_size_t) psize; off = sc->sc_cm_base - pa; /* reserve a non-pageable memory range within the kva. */ va = kmem_alloc_nofault(kernel_map, vsize); if (va == (vm_offset_t) 0) return (0); va = pmap_map(&va, pa, pa + psize, VM_PROT_READ); if (va == (vm_offset_t) 0) { kmem_free(kernel_map, va, vsize); return (0); } sc->sc_cm_kva_size = vsize; sc->sc_cm_kva_base = va; return (va + off); } /* * pcmem_phys_unmap(): * * Unmap the common memory window of the PCMCIA memory card in an * architecture-independent and SMP coherent manner. */ static void pcmem_phys_unmap(struct pcmem_softc *sc) { pmap_remove(kernel_pmap, sc->sc_cm_kva_base, sc->sc_cm_kva_size); kmem_free(kernel_map, sc->sc_cm_kva_base, sc->sc_cm_kva_size); sc->sc_cm_kva_base = sc->sc_cm_kva_size = 0; } --DSayHWYpDlRfCAAQ--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030721134731.GF22295>