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 void anon_contig_split(struct vmproc *vmp, struct vir_region *vr, 19 struct vir_region *r1, struct vir_region *r2); 20 static int anon_contig_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l); 21 static int anon_contig_new(struct vir_region *vr); 22 static int anon_contig_pt_flags(struct vir_region *vr); 23 24 struct mem_type mem_type_anon_contig = { 25 .name = "anonymous memory (physically contiguous)", 26 .ev_new = anon_contig_new, 27 .ev_reference = anon_contig_reference, 28 .ev_unreference = anon_contig_unreference, 29 .ev_pagefault = anon_contig_pagefault, 30 .ev_resize = anon_contig_resize, 31 .ev_split = anon_contig_split, 32 .ev_sanitycheck = anon_contig_sanitycheck, 33 .writable = anon_contig_writable, 34 .pt_flags = anon_contig_pt_flags, 35 }; 36 37 static int anon_contig_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 anon_contig_pagefault(struct vmproc *vmp, struct vir_region *region, 46 struct phys_region *ph, int write, vfs_callback_t cb, void *state, 47 int len, int *io) 48 { 49 panic("anon_contig_pagefault: pagefault cannot happen"); 50 } 51 52 static int anon_contig_new(struct vir_region *region) 53 { 54 u32_t allocflags; 55 phys_bytes new_pages, new_page_cl, cur_ph; 56 phys_bytes p, pages; 57 58 allocflags = vrallocflags(region->flags); 59 60 pages = region->length/VM_PAGE_SIZE; 61 62 assert(physregions(region) == 0); 63 64 for(p = 0; p < pages; p++) { 65 struct phys_block *pb = pb_new(MAP_NONE); 66 struct phys_region *pr = NULL; 67 if(pb) 68 pr = pb_reference(pb, p * VM_PAGE_SIZE, region, &mem_type_anon_contig); 69 if(!pr) { 70 if(pb) pb_free(pb); 71 map_free(region); 72 return ENOMEM; 73 } 74 } 75 76 assert(physregions(region) == pages); 77 78 if((new_page_cl = alloc_mem(pages, allocflags)) == NO_MEM) { 79 map_free(region); 80 return ENOMEM; 81 } 82 83 cur_ph = new_pages = CLICK2ABS(new_page_cl); 84 85 for(p = 0; p < pages; p++) { 86 struct phys_region *pr = physblock_get(region, p * VM_PAGE_SIZE); 87 assert(pr); 88 assert(pr->ph); 89 assert(pr->ph->phys == MAP_NONE); 90 assert(pr->offset == p * VM_PAGE_SIZE); 91 pr->ph->phys = cur_ph + pr->offset; 92 } 93 94 return OK; 95 } 96 97 static int anon_contig_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l) 98 { 99 printf("VM: cannot resize physically contiguous memory.\n"); 100 return ENOMEM; 101 } 102 103 static int anon_contig_reference(struct phys_region *pr, 104 struct phys_region *newpr) 105 { 106 printf("VM: cannot fork with physically contig memory.\n"); 107 return ENOMEM; 108 } 109 110 /* Methods inherited from the anonymous memory methods. */ 111 112 static int anon_contig_unreference(struct phys_region *pr) 113 { 114 return mem_type_anon.ev_unreference(pr); 115 } 116 117 static int anon_contig_sanitycheck(struct phys_region *pr, const char *file, int line) 118 { 119 return mem_type_anon.ev_sanitycheck(pr, file, line); 120 } 121 122 static int anon_contig_writable(struct phys_region *pr) 123 { 124 return mem_type_anon.writable(pr); 125 } 126 127 static void anon_contig_split(struct vmproc *vmp, struct vir_region *vr, 128 struct vir_region *r1, struct vir_region *r2) 129 { 130 return; 131 } 132 133