/* This file implements the methods of direct physical mapping. * * A direct physical mapping is done by accepting the physical * memory address and range from the caller and allowing direct * access to it. Most significantly, no physical memory is allocated * when it's mapped or freed when it's unmapped. E.g. device memory. */ #include "vm.h" #include "proto.h" #include "region.h" #include "glo.h" /* These functions are static so as to not pollute the * global namespace, and are accessed through their function * pointers. */ static int phys_unreference(struct phys_region *pr); static int phys_writable(struct phys_region *pr); static int phys_pagefault(struct vmproc *vmp, struct vir_region *region, struct phys_region *ph, int write, vfs_callback_t cb, void *state, int len, int *io); static int phys_copy(struct vir_region *vr, struct vir_region *newvr); static int phys_pt_flags(struct vir_region *vr); struct mem_type mem_type_directphys = { .name = "physical memory mapping", .ev_copy = phys_copy, .ev_unreference = phys_unreference, .writable = phys_writable, .ev_pagefault = phys_pagefault, .pt_flags = phys_pt_flags }; static int phys_pt_flags(struct vir_region *vr){ #if defined(__arm__) return ARM_VM_PTE_DEVICE; #else return 0; #endif } static int phys_unreference(struct phys_region *pr) { return OK; } static int phys_pagefault(struct vmproc *vmp, struct vir_region *region, struct phys_region *ph, int write, vfs_callback_t cb, void *state, int len, int *io) { phys_bytes arg = region->param.phys, phmem; assert(arg != MAP_NONE); assert(ph->ph->phys == MAP_NONE); phmem = arg + ph->offset; assert(phmem != MAP_NONE); ph->ph->phys = phmem; return OK; } static int phys_writable(struct phys_region *pr) { assert(pr->ph->refcount > 0); return pr->ph->phys != MAP_NONE; } void phys_setphys(struct vir_region *vr, phys_bytes phys) { vr->param.phys = phys; } static int phys_copy(struct vir_region *vr, struct vir_region *newvr) { newvr->param.phys = vr->param.phys; return OK; }