On Wed, Mar 24, 2010 at 01:07:15PM -0500, David Young wrote: > Can it be implemented like this? > > void * > bus_space_physload(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, > vm_prot_t prot, int flags) > { > bus_space_handle_t bsh; > void *p; > int rc; > > rc = bus_space_map(bst, addr, size, flags | BUS_SPACE_MAP_LINEAR, &bsh); > if (rc != 0) > return NULL; > > p = bus_space_vaddr(bst, bsh); > > if (p == NULL) { > bus_space_unmap(bst, bsh, size); > return NULL; > } > > rc = vm_map_protect(kernel_map, (vaddr_t)p, (vaddr_t)p + size, prot, > true); > > if (rc != 0) { > bus_space_unmap(bst, bsh, size); > return NULL; > } > > return p; > }
No, like this: void * bus_space_physload(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, int prot, int flags) { const bus_addr_t busp = addr; const bus_addr_t busq = addr + size; const paddr_t physp = bus_space_mmap(t, busp, 0, prot, flags); const paddr_t physq = bus_space_mmap(t, busq, 0, prot, flags); /* return struct vm_physseg * as a cookie */ return uvm_page_physload_device( physp, /* physical start */ physq); /* physical end */ } bus_space_physload(9) registers a physical address region into VM, with protection and some properties (vm_memattr_t in FreeBSD, or enum pmem_props in your pmem(9) proposal). Probably it'll have struct vm_page_md for VM_PROT_EXEC regions for XIP. I've decided to *not* allocate unmanaged regions here. Unmanaged regions are tracked by bus_space(9) tags / handles. They're always mapped read/write, and uncached. No need to keep their states. Eventually we'll return bus_space_physload(9) cookie back to cdev_mmap(9), which in turn passes the cookie to pmap_enter(9). This means that we can pass device's physical address and its properties. bus_dmamem_mmap(9) and bus_space_mmap(9) exposing paddr_t is wrong. cdev_mmap(9) should return either "struct vm_page *" (bus_dmamem_mmap(9) == DMA memory) or "struct vm_physseg *" + "off_t" (bus_space_physload(9) == device region). Masao -- Masao Uebayashi / Tombi Inc. / Tel: +81-90-9141-4635