2 * Copyright (c) 2009 The Regents of the University of California
3 * Barret Rhoden <brho@cs.berkeley.edu>
4 * See LICENSE for details.
8 #include <ros/common.h>
15 /* mmap2() semantics on the offset (num pages, not bytes) */
16 void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
17 int fd, size_t offset)
20 printk("[kernel] mmap() does not support files yet.\n");
21 return (void*SAFE)TC(-1);
23 /* TODO: make this work, instead of a ghetto hack
24 * Find a valid range, make sure it doesn't run into the kernel
25 * make sure there's enough memory (not exceeding quotas)
26 * allocate and map the pages, update appropriate structures (vm_region)
27 * return appropriate pointer
28 * Right now, all we can do is give them the range they ask for.
30 //void *tmp = get_free_va_range(p->env_pgdir, addr, len);
31 //printk("tmp = 0x%08x\n", tmp);
33 printk("[kernel] mmap() requires an address, since it's ghetto\n");
34 return (void*SAFE)TC(-1);
36 // brief sanity check. must be page aligned and not reaching too high
38 printk("[kernel] mmap() page align your addr.\n");
39 return (void*SAFE)TC(-1);
41 int num_pages = ROUNDUP(len, PGSIZE) / PGSIZE;
43 // TODO: grab the appropriate mm_lock
44 spin_lock_irqsave(&p->proc_lock);
45 // make sure all pages are available, and in a reasonable range
46 // TODO: can probably do this better with vm_regions.
47 // can also consider not mapping to 0x00000000
48 for (int i = 0; i < num_pages; i++) {
49 a_pte = pgdir_walk(p->env_pgdir, (void*SNT)addr, 0);
50 if (a_pte && *a_pte & PTE_P)
52 if (addr + i*PGSIZE >= USTACKBOT)
56 for (int i = 0; i < num_pages; i++) {
57 if (upage_alloc(p, &a_page))
59 // TODO: give them the permissions they actually want
60 if (page_insert(p->env_pgdir, a_page, (void*SNT)addr + i*PGSIZE,
66 // TODO: release the appropriate mm_lock
67 spin_unlock_irqsave(&p->proc_lock);
68 return (void*SAFE)TC(addr);
70 // TODO: if there's a failure, we should go back through the addr+len range
71 // and dealloc everything. or at least define what we want to do if we run
74 // TODO: release the appropriate mm_lock
75 spin_unlock_irqsave(&p->proc_lock);
76 // not a kernel problem, like if they ask to mmap a mapped location.
77 printd("[kernel] mmap() aborted!\n");
78 // mmap's semantics. we need a better error propagation system
79 return (void*SAFE)TC(-1); // this is also ridiculous