xref: /minix3/minix/servers/vm/mem_anon_contig.c (revision 48e74378c704462d3f3a44232a8578541c8543a6)
1433d6423SLionel Sambuc 
2433d6423SLionel Sambuc /* This file implements the methods of physically contiguous anonymous memory. */
3433d6423SLionel Sambuc 
4433d6423SLionel Sambuc #include <assert.h>
5433d6423SLionel Sambuc 
6433d6423SLionel Sambuc #include "proto.h"
7433d6423SLionel Sambuc #include "vm.h"
8433d6423SLionel Sambuc #include "region.h"
9433d6423SLionel Sambuc #include "glo.h"
10433d6423SLionel Sambuc 
11433d6423SLionel Sambuc static int anon_contig_reference(struct phys_region *, struct phys_region *);
12433d6423SLionel Sambuc static int anon_contig_unreference(struct phys_region *pr);
13433d6423SLionel Sambuc static int anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region,
14433d6423SLionel Sambuc 	struct phys_region *ph, int write, vfs_callback_t cb, void *state,
15433d6423SLionel Sambuc 	int len, int *io);
16433d6423SLionel Sambuc static int anon_contig_sanitycheck(struct phys_region *pr, const char *file, int line);
17433d6423SLionel Sambuc static int anon_contig_writable(struct phys_region *pr);
18*48e74378SBen Gras static void anon_contig_split(struct vmproc *vmp, struct vir_region *vr,
19*48e74378SBen Gras                         struct vir_region *r1, struct vir_region *r2);
20433d6423SLionel Sambuc static int anon_contig_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l);
21433d6423SLionel Sambuc static int anon_contig_new(struct vir_region *vr);
22433d6423SLionel Sambuc static int anon_contig_pt_flags(struct vir_region *vr);
23433d6423SLionel Sambuc 
24433d6423SLionel Sambuc struct mem_type mem_type_anon_contig = {
25433d6423SLionel Sambuc 	.name = "anonymous memory (physically contiguous)",
26433d6423SLionel Sambuc 	.ev_new = anon_contig_new,
27433d6423SLionel Sambuc 	.ev_reference = anon_contig_reference,
28433d6423SLionel Sambuc 	.ev_unreference = anon_contig_unreference,
29433d6423SLionel Sambuc 	.ev_pagefault = anon_contig_pagefault,
30433d6423SLionel Sambuc 	.ev_resize = anon_contig_resize,
31*48e74378SBen Gras 	.ev_split = anon_contig_split,
32433d6423SLionel Sambuc 	.ev_sanitycheck = anon_contig_sanitycheck,
33433d6423SLionel Sambuc 	.writable = anon_contig_writable,
34433d6423SLionel Sambuc 	.pt_flags = anon_contig_pt_flags,
35433d6423SLionel Sambuc };
36433d6423SLionel Sambuc 
anon_contig_pt_flags(struct vir_region * vr)37433d6423SLionel Sambuc static int anon_contig_pt_flags(struct vir_region *vr){
38433d6423SLionel Sambuc #if defined(__arm__)
39433d6423SLionel Sambuc 	return  ARM_VM_PTE_DEVICE;
40433d6423SLionel Sambuc #else
41433d6423SLionel Sambuc 	return  0;
42433d6423SLionel Sambuc #endif
43433d6423SLionel Sambuc }
44433d6423SLionel Sambuc 
anon_contig_pagefault(struct vmproc * vmp,struct vir_region * region,struct phys_region * ph,int write,vfs_callback_t cb,void * state,int len,int * io)45433d6423SLionel Sambuc static int anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region,
46433d6423SLionel Sambuc 	struct phys_region *ph, int write, vfs_callback_t cb, void *state,
47433d6423SLionel Sambuc 	int len, int *io)
48433d6423SLionel Sambuc {
49433d6423SLionel Sambuc 	panic("anon_contig_pagefault: pagefault cannot happen");
50433d6423SLionel Sambuc }
51433d6423SLionel Sambuc 
anon_contig_new(struct vir_region * region)52433d6423SLionel Sambuc static int anon_contig_new(struct vir_region *region)
53433d6423SLionel Sambuc {
54433d6423SLionel Sambuc         u32_t allocflags;
55433d6423SLionel Sambuc 	phys_bytes new_pages, new_page_cl, cur_ph;
56433d6423SLionel Sambuc 	phys_bytes p, pages;
57433d6423SLionel Sambuc 
58433d6423SLionel Sambuc         allocflags = vrallocflags(region->flags);
59433d6423SLionel Sambuc 
60433d6423SLionel Sambuc 	pages = region->length/VM_PAGE_SIZE;
61433d6423SLionel Sambuc 
62433d6423SLionel Sambuc 	assert(physregions(region) == 0);
63433d6423SLionel Sambuc 
64433d6423SLionel Sambuc 	for(p = 0; p < pages; p++) {
65433d6423SLionel Sambuc 		struct phys_block *pb = pb_new(MAP_NONE);
66433d6423SLionel Sambuc 		struct phys_region *pr = NULL;
67433d6423SLionel Sambuc 		if(pb)
68433d6423SLionel Sambuc 			pr = pb_reference(pb, p * VM_PAGE_SIZE, region, &mem_type_anon_contig);
69433d6423SLionel Sambuc 		if(!pr) {
70433d6423SLionel Sambuc 			if(pb) pb_free(pb);
71433d6423SLionel Sambuc 			map_free(region);
72433d6423SLionel Sambuc 			return ENOMEM;
73433d6423SLionel Sambuc 		}
74433d6423SLionel Sambuc 	}
75433d6423SLionel Sambuc 
76433d6423SLionel Sambuc 	assert(physregions(region) == pages);
77433d6423SLionel Sambuc 
78433d6423SLionel Sambuc 	if((new_page_cl = alloc_mem(pages, allocflags)) == NO_MEM) {
79433d6423SLionel Sambuc 		map_free(region);
80433d6423SLionel Sambuc 		return ENOMEM;
81433d6423SLionel Sambuc 	}
82433d6423SLionel Sambuc 
83433d6423SLionel Sambuc 	cur_ph = new_pages = CLICK2ABS(new_page_cl);
84433d6423SLionel Sambuc 
85433d6423SLionel Sambuc 	for(p = 0; p < pages; p++) {
86433d6423SLionel Sambuc 		struct phys_region *pr = physblock_get(region, p * VM_PAGE_SIZE);
87433d6423SLionel Sambuc 		assert(pr);
88433d6423SLionel Sambuc 		assert(pr->ph);
89433d6423SLionel Sambuc 		assert(pr->ph->phys == MAP_NONE);
90433d6423SLionel Sambuc 		assert(pr->offset == p * VM_PAGE_SIZE);
91433d6423SLionel Sambuc 		pr->ph->phys = cur_ph + pr->offset;
92433d6423SLionel Sambuc 	}
93433d6423SLionel Sambuc 
94433d6423SLionel Sambuc 	return OK;
95433d6423SLionel Sambuc }
96433d6423SLionel Sambuc 
anon_contig_resize(struct vmproc * vmp,struct vir_region * vr,vir_bytes l)97433d6423SLionel Sambuc static int anon_contig_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l)
98433d6423SLionel Sambuc {
99433d6423SLionel Sambuc 	printf("VM: cannot resize physically contiguous memory.\n");
100433d6423SLionel Sambuc 	return ENOMEM;
101433d6423SLionel Sambuc }
102433d6423SLionel Sambuc 
anon_contig_reference(struct phys_region * pr,struct phys_region * newpr)103433d6423SLionel Sambuc static int anon_contig_reference(struct phys_region *pr,
104433d6423SLionel Sambuc 	struct phys_region *newpr)
105433d6423SLionel Sambuc {
106433d6423SLionel Sambuc 	printf("VM: cannot fork with physically contig memory.\n");
107433d6423SLionel Sambuc 	return ENOMEM;
108433d6423SLionel Sambuc }
109433d6423SLionel Sambuc 
110433d6423SLionel Sambuc /* Methods inherited from the anonymous memory methods. */
111433d6423SLionel Sambuc 
anon_contig_unreference(struct phys_region * pr)112433d6423SLionel Sambuc static int anon_contig_unreference(struct phys_region *pr)
113433d6423SLionel Sambuc {
114433d6423SLionel Sambuc 	return mem_type_anon.ev_unreference(pr);
115433d6423SLionel Sambuc }
116433d6423SLionel Sambuc 
anon_contig_sanitycheck(struct phys_region * pr,const char * file,int line)117433d6423SLionel Sambuc static int anon_contig_sanitycheck(struct phys_region *pr, const char *file, int line)
118433d6423SLionel Sambuc {
119433d6423SLionel Sambuc 	return mem_type_anon.ev_sanitycheck(pr, file, line);
120433d6423SLionel Sambuc }
121433d6423SLionel Sambuc 
anon_contig_writable(struct phys_region * pr)122433d6423SLionel Sambuc static int anon_contig_writable(struct phys_region *pr)
123433d6423SLionel Sambuc {
124433d6423SLionel Sambuc 	return mem_type_anon.writable(pr);
125433d6423SLionel Sambuc }
126433d6423SLionel Sambuc 
anon_contig_split(struct vmproc * vmp,struct vir_region * vr,struct vir_region * r1,struct vir_region * r2)127*48e74378SBen Gras static void anon_contig_split(struct vmproc *vmp, struct vir_region *vr,
128*48e74378SBen Gras                         struct vir_region *r1, struct vir_region *r2)
129*48e74378SBen Gras {
130*48e74378SBen Gras 	return;
131*48e74378SBen Gras }
132*48e74378SBen Gras 
133