Subject: question about mmap
To: None <tech-kern@netbsd.org>
From: Chan-youn Park <phygeeks@gmail.com>
List: tech-kern
Date: 03/09/2005 17:12:30
Hi. I'm developing a device driver on PowerPC/Sandpoint platform.
What I want to do is to implement an mmap interface in the device
driver. The device driver is for a DSP, and the DSP had its own
internal RAM which can be seen through PCI bus.
I've succeeded in seeing the memory space in the kernel, but when I
tried to see it using the mmap I've implemented, it does not work.
Well, below is the mmap code I've written.
----
paddr_t
tdspmmap(dev_t dev, off_t off, int prot)
{
struct tdsp_softc *sc;
char *name;
paddr_t paddr;
sc = device_lookup(&tdsp_cd, TDSPUNIT(dev));
if (sc == NULL){
ERROR("NULL sc is returned: "
"cannot proceed tdspmmap() anymore.\n");
return (ENXIO);
}
name = sc->sc_dev.dv_xname;
if (off >= TDSP_PMEM_MASK || off < 0){
ERROR("%s: Offset is out of range.\n", name);
return -1;
}
DEBUGF("%s: sc_pmema = 0x%08x, off = 0x%08x\n", name, sc->sc_pmema,
(int)off);
paddr = bus_space_mmap(sc->sc_pmemt, sc->sc_pmema, off, prot,
BUS_SPACE_MAP_LINEAR);
DEBUGF("%s: return value of bus_space_mmap = 0x%08x\n", name,
(u_int32_t)paddr);
return paddr;
}
----
here, pmemt and pmema is the tag and physical address of the DSP
memory space which are get using pci_mapreg_info.
And below is a part of a test application program to see the DSP memory space.
----
tdsph = open("/dev/tdsp", O_RDWR, 0);
sram.addr = mmap(0, sram.len, PROT_READ, MAP_SHARED, tdsph,
(off_t)sram.offset);
while(i < sram.len){
addr = (u_int8_t*)sram.addr + i;
printf("0x%08x: 0x%02x\n", (u_int32_t)addr, (u_int8_t)(*addr));
i++;
}
----
The printed results were meaningless data.
So I studied UVM a little bit, and found that udv_fault() calls the
device mmap function. So I checked what is happening in the middle of
udv_fault() by printing some parameters.
---
printf("phygeeks: "
"MAPPING: device: pm=0x%x, va=0x%x, pa=0x%lx, at=%d",
(int)ufi->orig_map->pmap,
(int)curr_va,
(long)paddr,
(int)mapprot);
---
when I checked the result, it was that virtual memory was correctly
pointed from the userland application, and correct physical memory
page was given to pmap_enter through paddr, and mapprot had the value
of 1(which I think is not relevant to this problem).
Therefore I think my d_mmap code is doing the right thing, because it
gives udv_fault a correct page of the desired physical memory. But
when I try to see the content of it from the userland, what I see is
only meaningless data.
What should I check to see what is wrong? And in addition, is there a
good simple code that I can study the usage of device mmap function?