PAE correctness
Bruce M Simpson
bms at spc.org
Mon Jul 21 06:49:49 PDT 2003
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
-------------- next part --------------
...
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;
}
More information about the freebsd-hackers
mailing list