xref: /minix3/minix/servers/vm/mem_directphys.c (revision 0b98e8aad89f2bd4ba80b523d73cf29e9dd82ce1)
1 
2 /* This file implements the methods of direct physical mapping.
3  *
4  * A direct physical mapping is done by accepting the physical
5  * memory address and range from the caller and allowing direct
6  * access to it. Most significantly, no physical memory is allocated
7  * when it's mapped or freed when it's unmapped. E.g. device memory.
8  */
9 
10 #include "vm.h"
11 #include "proto.h"
12 #include "region.h"
13 #include "glo.h"
14 
15 /* These functions are static so as to not pollute the
16  * global namespace, and are accessed through their function
17  * pointers.
18  */
19 
20 static int phys_unreference(struct phys_region *pr);
21 static int phys_writable(struct phys_region *pr);
22 static int phys_pagefault(struct vmproc *vmp, struct vir_region *region,
23         struct phys_region *ph, int write, vfs_callback_t cb, void *state,
24 	int len, int *io);
25 static int phys_copy(struct vir_region *vr, struct vir_region *newvr);
26 static int phys_pt_flags(struct vir_region *vr);
27 
28 struct mem_type mem_type_directphys = {
29 	.name = "physical memory mapping",
30 	.ev_copy = phys_copy,
31 	.ev_unreference = phys_unreference,
32 	.writable = phys_writable,
33 	.ev_pagefault = phys_pagefault,
34 	.pt_flags = phys_pt_flags
35 };
36 
37 static int phys_pt_flags(struct vir_region *vr){
38 #if defined(__arm__)
39 	return ARM_VM_PTE_DEVICE;
40 #else
41 	return 0;
42 #endif
43 }
44 
45 static int phys_unreference(struct phys_region *pr)
46 {
47 	return OK;
48 }
49 
50 static int phys_pagefault(struct vmproc *vmp, struct vir_region *region,
51     struct phys_region *ph, int write, vfs_callback_t cb, void *state,
52     int len, int *io)
53 {
54 	phys_bytes arg = region->param.phys, phmem;
55 	assert(arg != MAP_NONE);
56 	assert(ph->ph->phys == MAP_NONE);
57 	phmem = arg + ph->offset;
58 	assert(phmem != MAP_NONE);
59 	ph->ph->phys = phmem;
60 	return OK;
61 }
62 
63 static int phys_writable(struct phys_region *pr)
64 {
65         assert(pr->ph->refcount > 0);
66         return pr->ph->phys != MAP_NONE;
67 }
68 
69 void phys_setphys(struct vir_region *vr, phys_bytes phys)
70 {
71 	vr->param.phys = phys;
72 }
73 
74 static int phys_copy(struct vir_region *vr, struct vir_region *newvr)
75 {
76 	newvr->param.phys = vr->param.phys;
77 
78 	return OK;
79 }
80