kernel: restore setting KTS_NONE
[minix.git] / servers / vm / pb.c
blobb2d33c1bfe64f96902878d6578eb5eabead03bd3
2 #define _SYSTEM 1
4 #include <minix/com.h>
5 #include <minix/callnr.h>
6 #include <minix/type.h>
7 #include <minix/config.h>
8 #include <minix/const.h>
9 #include <minix/sysutil.h>
10 #include <minix/syslib.h>
11 #include <minix/debug.h>
12 #include <minix/bitmap.h>
13 #include <minix/hash.h>
15 #include <sys/mman.h>
17 #include <limits.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <assert.h>
21 #include <stdint.h>
22 #include <sys/param.h>
24 #include "vm.h"
25 #include "proto.h"
26 #include "util.h"
27 #include "glo.h"
28 #include "region.h"
29 #include "sanitycheck.h"
30 #include "memlist.h"
32 struct phys_block *pb_new(phys_bytes phys)
34 struct phys_block *newpb;
36 if(!SLABALLOC(newpb)) {
37 printf("vm: pb_new: couldn't allocate phys block\n");
38 return NULL;
41 if(phys != MAP_NONE)
42 assert(!(phys % VM_PAGE_SIZE));
44 USE(newpb,
45 newpb->phys = phys;
46 newpb->refcount = 0;
47 newpb->firstregion = NULL;
50 return newpb;
53 void pb_free(struct phys_block *pb)
55 if(pb->phys != MAP_NONE)
56 free_mem(ABS2CLICK(pb->phys), 1);
57 SLABFREE(pb);
60 void pb_link(struct phys_region *newphysr, struct phys_block *newpb,
61 vir_bytes offset, struct vir_region *parent)
63 USE(newphysr,
64 newphysr->offset = offset;
65 newphysr->ph = newpb;
66 newphysr->parent = parent;
67 newphysr->next_ph_list = newpb->firstregion;
68 newphysr->memtype = parent->memtype;
69 newpb->firstregion = newphysr;);
70 newpb->refcount++;
73 struct phys_region *pb_reference(struct phys_block *newpb,
74 vir_bytes offset, struct vir_region *region)
76 struct phys_region *newphysr;
78 if(!SLABALLOC(newphysr)) {
79 printf("vm: pb_reference: couldn't allocate phys region\n");
80 return NULL;
83 /* New physical region. */
84 pb_link(newphysr, newpb, offset, region);
86 physblock_set(region, offset, newphysr);
88 return newphysr;
91 /*===========================================================================*
92 * pb_unreferenced *
93 *===========================================================================*/
94 void pb_unreferenced(struct vir_region *region, struct phys_region *pr, int rm)
96 struct phys_block *pb;
98 pb = pr->ph;
99 assert(pb->refcount > 0);
100 USE(pb, pb->refcount--;);
101 assert(pb->refcount >= 0);
103 if(pb->firstregion == pr) {
104 USE(pb, pb->firstregion = pr->next_ph_list;);
105 } else {
106 struct phys_region *others;
108 for(others = pb->firstregion; others;
109 others = others->next_ph_list) {
110 assert(others->ph == pb);
111 if(others->next_ph_list == pr) {
112 USE(others, others->next_ph_list = pr->next_ph_list;);
113 break;
117 assert(others); /* Otherwise, wasn't on the list. */
120 if(pb->refcount == 0) {
121 assert(!pb->firstregion);
122 int r;
123 if((r = region->memtype->ev_unreference(pr)) != OK)
124 panic("unref failed, %d", r);
126 SLABFREE(pb);
129 pr->ph = NULL;
131 if(rm) physblock_set(region, pr->offset, NULL);