xref: /minix/minix/servers/vm/mem_anon_contig.c (revision 7f5f010b)
1 
2 /* This file implements the methods of physically contiguous anonymous memory. */
3 
4 #include <assert.h>
5 
6 #include "proto.h"
7 #include "vm.h"
8 #include "region.h"
9 #include "glo.h"
10 
11 static int anon_contig_reference(struct phys_region *, struct phys_region *);
12 static int anon_contig_unreference(struct phys_region *pr);
13 static int anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region,
14 	struct phys_region *ph, int write, vfs_callback_t cb, void *state,
15 	int len, int *io);
16 static int anon_contig_sanitycheck(struct phys_region *pr, const char *file, int line);
17 static int anon_contig_writable(struct phys_region *pr);
18 static int anon_contig_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l);
19 static int anon_contig_new(struct vir_region *vr);
20 static int anon_contig_pt_flags(struct vir_region *vr);
21 
22 struct mem_type mem_type_anon_contig = {
23 	.name = "anonymous memory (physically contiguous)",
24 	.ev_new = anon_contig_new,
25 	.ev_reference = anon_contig_reference,
26 	.ev_unreference = anon_contig_unreference,
27 	.ev_pagefault = anon_contig_pagefault,
28 	.ev_resize = anon_contig_resize,
29 	.ev_sanitycheck = anon_contig_sanitycheck,
30 	.writable = anon_contig_writable,
31 	.pt_flags = anon_contig_pt_flags,
32 };
33 
34 static int anon_contig_pt_flags(struct vir_region *vr){
35 #if defined(__arm__)
36 	return  ARM_VM_PTE_DEVICE;
37 #else
38 	return  0;
39 #endif
40 }
41 
42 static int anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region,
43 	struct phys_region *ph, int write, vfs_callback_t cb, void *state,
44 	int len, int *io)
45 {
46 	panic("anon_contig_pagefault: pagefault cannot happen");
47 }
48 
49 static int anon_contig_new(struct vir_region *region)
50 {
51         u32_t allocflags;
52 	phys_bytes new_pages, new_page_cl, cur_ph;
53 	phys_bytes p, pages;
54 
55         allocflags = vrallocflags(region->flags);
56 
57 	pages = region->length/VM_PAGE_SIZE;
58 
59 	assert(physregions(region) == 0);
60 
61 	for(p = 0; p < pages; p++) {
62 		struct phys_block *pb = pb_new(MAP_NONE);
63 		struct phys_region *pr = NULL;
64 		if(pb)
65 			pr = pb_reference(pb, p * VM_PAGE_SIZE, region, &mem_type_anon_contig);
66 		if(!pr) {
67 			if(pb) pb_free(pb);
68 			map_free(region);
69 			return ENOMEM;
70 		}
71 	}
72 
73 	assert(physregions(region) == pages);
74 
75 	if((new_page_cl = alloc_mem(pages, allocflags)) == NO_MEM) {
76 		map_free(region);
77 		return ENOMEM;
78 	}
79 
80 	cur_ph = new_pages = CLICK2ABS(new_page_cl);
81 
82 	for(p = 0; p < pages; p++) {
83 		struct phys_region *pr = physblock_get(region, p * VM_PAGE_SIZE);
84 		assert(pr);
85 		assert(pr->ph);
86 		assert(pr->ph->phys == MAP_NONE);
87 		assert(pr->offset == p * VM_PAGE_SIZE);
88 		pr->ph->phys = cur_ph + pr->offset;
89 	}
90 
91 	return OK;
92 }
93 
94 static int anon_contig_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l)
95 {
96 	printf("VM: cannot resize physically contiguous memory.\n");
97 	return ENOMEM;
98 }
99 
100 static int anon_contig_reference(struct phys_region *pr,
101 	struct phys_region *newpr)
102 {
103 	printf("VM: cannot fork with physically contig memory.\n");
104 	return ENOMEM;
105 }
106 
107 /* Methods inherited from the anonymous memory methods. */
108 
109 static int anon_contig_unreference(struct phys_region *pr)
110 {
111 	return mem_type_anon.ev_unreference(pr);
112 }
113 
114 static int anon_contig_sanitycheck(struct phys_region *pr, const char *file, int line)
115 {
116 	return mem_type_anon.ev_sanitycheck(pr, file, line);
117 }
118 
119 static int anon_contig_writable(struct phys_region *pr)
120 {
121 	return mem_type_anon.writable(pr);
122 }
123 
124