Skip site navigation (1)Skip section navigation (2)
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>