Module Name: src
Committed By: riastradh
Date: Sun Dec 19 12:03:30 UTC 2021
Modified Files:
src/sys/external/bsd/drm2/include/linux: io-mapping.h
Log Message:
drm: Allow >page-sized io_mapping_map_wc.
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 \
src/sys/external/bsd/drm2/include/linux/io-mapping.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/external/bsd/drm2/include/linux/io-mapping.h
diff -u src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.9 src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.10
--- src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.9 Sun Dec 19 11:57:43 2021
+++ src/sys/external/bsd/drm2/include/linux/io-mapping.h Sun Dec 19 12:03:30 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: io-mapping.h,v 1.9 2021/12/19 11:57:43 riastradh Exp $ */
+/* $NetBSD: io-mapping.h,v 1.10 2021/12/19 12:03:30 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -45,7 +45,8 @@ struct io_mapping {
bus_addr_t base; /* Linux API */
bus_size_t size; /* Linux API */
vaddr_t diom_va;
- bool diom_mapped;
+ bus_size_t diom_mapsize;
+ bool diom_atomic;
};
static inline bool
@@ -77,7 +78,8 @@ bus_space_io_mapping_init_wc(bus_space_t
mapping->diom_bst = bst;
mapping->base = addr;
mapping->size = size;
- mapping->diom_mapped = false;
+ mapping->diom_mapsize = 0;
+ mapping->diom_atomic = false;
/* Allocate kva for one page. */
mapping->diom_va = uvm_km_alloc(kernel_map, PAGE_SIZE, PAGE_SIZE,
@@ -91,7 +93,8 @@ static inline void
io_mapping_fini(struct io_mapping *mapping)
{
- KASSERT(!mapping->diom_mapped);
+ KASSERT(mapping->diom_mapsize == 0);
+ KASSERT(!mapping->diom_atomic);
uvm_km_free(kernel_map, mapping->diom_va, PAGE_SIZE, UVM_KMF_VAONLY);
mapping->diom_va = 0; /* paranoia */
@@ -124,53 +127,93 @@ static inline void *
io_mapping_map_wc(struct io_mapping *mapping, bus_addr_t offset,
bus_size_t size)
{
+ bus_size_t pg, npgs = size >> PAGE_SHIFT;
+ vaddr_t va;
paddr_t cookie;
- KASSERT(size == PAGE_SIZE);
KASSERT(0 == (offset & (PAGE_SIZE - 1)));
KASSERT(PAGE_SIZE <= mapping->size);
KASSERT(offset <= (mapping->size - PAGE_SIZE));
KASSERT(__type_fit(off_t, offset));
- KASSERT(!mapping->diom_mapped);
+ KASSERT(mapping->diom_mapsize == 0);
+ KASSERT(!mapping->diom_atomic);
- cookie = bus_space_mmap(mapping->diom_bst, mapping->base, offset,
- PROT_READ|PROT_WRITE,
- BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE);
- KASSERT(cookie != (paddr_t)-1);
+ va = uvm_km_alloc(kernel_map, size, PAGE_SIZE,
+ UVM_KMF_VAONLY|UVM_KMF_WAITVA);
+ for (pg = 0; pg < npgs; pg++) {
+ cookie = bus_space_mmap(mapping->diom_bst, mapping->base,
+ offset + pg*PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE);
+ KASSERT(cookie != (paddr_t)-1);
- pmap_kenter_pa(mapping->diom_va, pmap_phys_address(cookie),
- PROT_READ|PROT_WRITE, pmap_mmap_flags(cookie));
+ pmap_kenter_pa(va, pmap_phys_address(cookie),
+ PROT_READ|PROT_WRITE, pmap_mmap_flags(cookie));
+ }
pmap_update(pmap_kernel());
- mapping->diom_mapped = true;
- return (void *)mapping->diom_va;
+ mapping->diom_mapsize = size;
+ mapping->diom_atomic = false;
+ return (void *)va;
}
static inline void
io_mapping_unmap(struct io_mapping *mapping, void *ptr __diagused)
{
+ vaddr_t va = (vaddr_t)ptr;
- KASSERT(mapping->diom_mapped);
- KASSERT(mapping->diom_va == (vaddr_t)ptr);
+ KASSERT(mapping->diom_mapsize);
+ KASSERT(!mapping->diom_atomic);
+ KASSERT(mapping->diom_va != va);
- pmap_kremove(mapping->diom_va, PAGE_SIZE);
+ pmap_kremove(va, PAGE_SIZE);
pmap_update(pmap_kernel());
- mapping->diom_mapped = false;
+ uvm_km_free(kernel_map, va, mapping->diom_mapsize, UVM_KMF_VAONLY);
+
+ mapping->diom_mapsize = 0;
+ mapping->diom_atomic = false;
}
static inline void *
-io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
+io_mapping_map_atomic_wc(struct io_mapping *mapping, bus_addr_t offset)
{
+ paddr_t cookie;
+
+ KASSERT(0 == (offset & (PAGE_SIZE - 1)));
+ KASSERT(PAGE_SIZE <= mapping->size);
+ KASSERT(offset <= (mapping->size - PAGE_SIZE));
+ KASSERT(__type_fit(off_t, offset));
+ KASSERT(mapping->diom_mapsize == 0);
+ KASSERT(!mapping->diom_atomic);
+
+ cookie = bus_space_mmap(mapping->diom_bst, mapping->base, offset,
+ PROT_READ|PROT_WRITE,
+ BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE);
+ KASSERT(cookie != (paddr_t)-1);
+
+ pmap_kenter_pa(mapping->diom_va, pmap_phys_address(cookie),
+ PROT_READ|PROT_WRITE, pmap_mmap_flags(cookie));
+ pmap_update(pmap_kernel());
- return io_mapping_map_wc(mapping, offset, PAGE_SIZE);
+ mapping->diom_mapsize = PAGE_SIZE;
+ mapping->diom_atomic = true;
+ return (void *)mapping->diom_va;
}
static inline void
-io_mapping_unmap_atomic(struct io_mapping *mapping, void *ptr)
+io_mapping_unmap_atomic(struct io_mapping *mapping, void *ptr __diagused)
{
- io_mapping_unmap(mapping, ptr);
+ KASSERT(mapping->diom_mapsize);
+ KASSERT(mapping->diom_atomic);
+ KASSERT(mapping->diom_va == (vaddr_t)ptr);
+
+ pmap_kremove(mapping->diom_va, PAGE_SIZE);
+ pmap_update(pmap_kernel());
+
+ mapping->diom_mapsize = 0;
+ mapping->diom_atomic = false;
}
#endif /* _LINUX_IO_MAPPING_H_ */