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>
22 #include <sys/param.h>
29 #include "sanitycheck.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");
42 assert(!(phys
% VM_PAGE_SIZE
));
47 newpb
->firstregion
= NULL
;
53 void pb_free(struct phys_block
*pb
)
55 if(pb
->phys
!= MAP_NONE
)
56 free_mem(ABS2CLICK(pb
->phys
), 1);
60 void pb_link(struct phys_region
*newphysr
, struct phys_block
*newpb
,
61 vir_bytes offset
, struct vir_region
*parent
)
64 newphysr
->offset
= offset
;
66 newphysr
->parent
= parent
;
67 newphysr
->next_ph_list
= newpb
->firstregion
;
68 newphysr
->memtype
= parent
->memtype
;
69 newpb
->firstregion
= newphysr
;);
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");
83 /* New physical region. */
84 pb_link(newphysr
, newpb
, offset
, region
);
86 physblock_set(region
, offset
, newphysr
);
91 /*===========================================================================*
93 *===========================================================================*/
94 void pb_unreferenced(struct vir_region
*region
, struct phys_region
*pr
, int rm
)
96 struct phys_block
*pb
;
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
;);
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
;);
117 assert(others
); /* Otherwise, wasn't on the list. */
120 if(pb
->refcount
== 0) {
121 assert(!pb
->firstregion
);
123 if((r
= region
->memtype
->ev_unreference(pr
)) != OK
)
124 panic("unref failed, %d", r
);
131 if(rm
) physblock_set(region
, pr
->offset
, NULL
);