示例#1
0
void *miomap(unsigned long addr, int size, int protect) {
    char *vaddr;
    int i;
    unsigned long flags = pte_flags_from_protect(protect);
    int pages = PAGES(size);

    vaddr = (char *) PTOB(rmap_alloc(vmap, pages));
    if (vaddr == NULL) return NULL;

    for (i = 0; i < pages; i++) {
        map_page(vaddr + PTOB(i), BTOP(addr) + i, flags | PT_PRESENT);
    }

    return vaddr;
}
示例#2
0
void miounmap(void *addr, int size) {
    int i;
    int pages = PAGES(size);

    for (i = 0; i < pages; i++) unmap_page((char *) addr + PTOB(i));
    rmap_free(vmap, BTOP(addr), pages);
}
示例#3
0
void *vmmap(void *addr, unsigned long size, int protect, struct file *filp, off64_t offset, int *rc) {
    int pages = PAGES(size);
    unsigned long flags = pte_flags_from_protect(protect);
    struct filemap *fm;
    int i;
    char *vaddr;

    if (rc) *rc = 0;
    if (size == 0 || flags == 0xFFFFFFFF) {
        if (rc) *rc = -EINVAL;
        return NULL;
    }
    addr = (void *) PAGEADDR(addr);
    if (addr == NULL) {
        addr = (void *) PTOB(rmap_alloc(vmap, pages));
        if (addr == NULL) {
            if (rc) *rc = -ENOMEM;
            return NULL;
        }
    } else {
        if (rmap_reserve(vmap, BTOP(addr), pages)) {
            if (rc) *rc = -ENOMEM;
            return NULL;
        }
    }

    fm = (struct filemap *) kmalloc(sizeof(struct filemap));
    if (!fm) {
        rmap_free(vmap, BTOP(addr), pages);
        if (rc) *rc = -ENOMEM;
        return NULL;
    }
    init_object(&fm->object, OBJECT_FILEMAP);
    fm->self = halloc(&fm->object);
    fm->file = halloc(&filp->iob.object);
    if (fm->self < 0 || fm->file < 0) {
        if (rc) *rc = -ENFILE;
        return NULL;
    }
    hprotect(fm->self);
    hprotect(fm->file);
    fm->offset = offset;
    fm->pages = pages;
    fm->object.signaled = 1;
    fm->addr = addr;
    fm->size = size;
    fm->protect = flags | PT_FILE;

    vaddr = (char *) addr;
    flags = (flags & ~PT_USER) | PT_FILE;
    for (i = 0; i < pages; i++) {
        map_page(vaddr, fm->self, flags);
        vaddr += PAGESIZE;
    }

    return addr;
}
示例#4
0
文件: pdir.c 项目: HarryR/sanos
void map_page(void *vaddr, unsigned long pfn, unsigned long flags) {
  // Allocate page table if not already done
  if ((GET_PDE(vaddr) & PT_PRESENT) == 0) {
    unsigned long pdfn;

    pdfn = alloc_pageframe('PTAB');
    if (USERSPACE(vaddr)) {
      SET_PDE(vaddr, PTOB(pdfn) | PT_PRESENT | PT_WRITABLE | PT_USER);
    } else {
      SET_PDE(vaddr, PTOB(pdfn) | PT_PRESENT | PT_WRITABLE);
    }

    memset(ptab + PDEIDX(vaddr) * PTES_PER_PAGE, 0, PAGESIZE);
    register_page_table(pdfn);
  }

  // Map page frame into address space
  SET_PTE(vaddr, PTOB(pfn) | flags);
}
示例#5
0
文件: pdir.c 项目: HarryR/sanos
void init_pdir() {
  unsigned long i;

  // Clear identity mapping of the first 4 MB made by the os loader
  for (i = 0; i < PTES_PER_PAGE; i++) SET_PTE(PTOB(i), 0);
}
示例#6
0
void *vmalloc(void *addr, unsigned long size, int type, int protect, unsigned long tag, int *rc) {
    int pages = PAGES(size);
    unsigned long flags = pte_flags_from_protect(protect);
    int i;

    if (rc) *rc = 0;
    if (size == 0) {
        if (rc) *rc = -EINVAL;
        return NULL;
    }
    if ((type & MEM_COMMIT) != 0 && flags == 0xFFFFFFFF) {
        if (rc) *rc = -EINVAL;
        return NULL;
    }
    addr = (void *) PAGEADDR(addr);
    if (!addr && (type & MEM_COMMIT) != 0) type |= MEM_RESERVE;
    if (!tag) tag = 'VM';

    if (type & MEM_RESERVE) {
        if (addr == NULL) {
            if (type & MEM_ALIGN64K) {
                addr = (void *) PTOB(rmap_alloc_align(vmap, pages, 64 * 1024 / PAGESIZE));
            } else {
                addr = (void *) PTOB(rmap_alloc(vmap, pages));
            }

            if (addr == NULL) {
                if (rc) *rc = -ENOMEM;
                return NULL;
            }
        } else {
            if (rmap_reserve(vmap, BTOP(addr), pages)) {
                if (rc) *rc = -ENOMEM;
                return NULL;
            }
        }
    } else {
        if (!valid_range(addr, size)) {
            if (rc) *rc = -EFAULT;
            return NULL;
        }
    }

    if (type & MEM_COMMIT) {
        char *vaddr;
        unsigned long pfn;

        vaddr = (char *) addr;
        for (i = 0; i < pages; i++) {
            if (page_mapped(vaddr)) {
                set_page_flags(vaddr, flags | PT_PRESENT);
            } else {
                pfn = alloc_pageframe(tag);
                if (pfn == 0xFFFFFFFF) {
                    if (rc) *rc = -ENOMEM;
                    return NULL;
                }

                map_page(vaddr, pfn, flags | PT_PRESENT);
                memset(vaddr, 0, PAGESIZE);
            }
            vaddr += PAGESIZE;
        }
    }

    return addr;
}