9 #include <linux/module.h>
10 #include <linux/kernel.h>
13 #include <linux/list.h>
16 #include <asm/pgtable.h>
35 #define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT)
37 #define dvma_entry_use(baddr) (iommu_use[dvma_index(baddr)])
48 static struct hole initholes[64];
52 static unsigned long dvma_allocs;
53 static unsigned long dvma_frees;
54 static unsigned long long dvma_alloc_bytes;
55 static unsigned long long dvma_free_bytes;
57 static void print_use(
void)
63 printk(
"dvma entry usage:\n");
71 printk(
"dvma entry: %08lx len %08lx\n",
76 printk(
"%d entries in use total\n", j);
78 printk(
"allocation/free calls: %lu/%lu\n", dvma_allocs, dvma_frees);
79 printk(
"allocation/free bytes: %Lx/%Lx\n", dvma_alloc_bytes,
83 static void print_holes(
struct list_head *holes)
89 printk(
"listing dvma holes\n");
93 if((hole->
start == 0) && (hole->
end == 0) && (hole->
size == 0))
96 printk(
"hole: start %08lx end %08lx size %08lx\n", hole->
start, hole->
end, hole->
size);
99 printk(
"end of hole listing...\n");
104 static inline int refill(
void)
123 list_move(&(prev->
list), &hole_cache);
132 static inline struct hole *rmcache(
void)
136 if(list_empty(&hole_cache)) {
138 printk(
"out of dvma hole cache!\n");
150 static inline unsigned long get_baddr(
int len,
unsigned long align)
156 if(list_empty(&hole_list)) {
158 printk(
"out of dvma holes! (printing hole cache)\n");
159 print_holes(&hole_cache);
166 unsigned long newlen;
171 newlen = len + ((hole->
end - len) & (align-1));
175 if(hole->
size > newlen) {
177 hole->
size -= newlen;
181 dvma_alloc_bytes += newlen;
184 }
else if(hole->
size == newlen) {
185 list_move(&(hole->
list), &hole_cache);
189 dvma_alloc_bytes += newlen;
196 printk(
"unable to find dvma hole!\n");
201 static inline int free_baddr(
unsigned long baddr)
207 unsigned long orig_baddr;
217 dvma_free_bytes += len;
223 if(hole->
end == baddr) {
227 }
else if(hole->
start == (baddr + len)) {
238 hole->
end = baddr + len;
242 list_add(&(hole->
list), cur);
254 INIT_LIST_HEAD(&hole_list);
255 INIT_LIST_HEAD(&hole_cache);
258 for(i = 0; i < 64; i++)
259 list_add(&(initholes[i].
list), &hole_cache);
266 list_add(&(hole->
list), &hole_list);
268 memset(iommu_use, 0,
sizeof(iommu_use));
294 printk(
"dvma_map request %08lx bytes from %08lx\n",
307 baddr = get_baddr(len, align);
311 return (baddr + off);
313 printk(
"dvma_map failed kaddr %lx baddr %lx len %x\n", kaddr, baddr, len);
323 addr = (
unsigned long)baddr;
325 if(!(addr & 0x00f00000))
345 printk(
"dvma_malloc request %lx bytes\n", len);
352 if((baddr = (
unsigned long)
dvma_map_align(kaddr, len, align)) == 0) {
366 printk(
"mapped %08lx bytes %08lx kern -> %08lx bus\n",
370 return (
void *)
vaddr;