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"
33 struct phys_block
*pb_new(phys_bytes phys
)
35 struct phys_block
*newpb
;
37 if(!SLABALLOC(newpb
)) {
38 printf("vm: pb_new: couldn't allocate phys block\n");
43 assert(!(phys
% VM_PAGE_SIZE
));
48 newpb
->firstregion
= NULL
;
54 void pb_free(struct phys_block
*pb
)
56 if(pb
->phys
!= MAP_NONE
)
57 free_mem(ABS2CLICK(pb
->phys
), 1);
61 void pb_link(struct phys_region
*newphysr
, struct phys_block
*newpb
,
62 vir_bytes offset
, struct vir_region
*parent
)
65 newphysr
->offset
= offset
;
67 newphysr
->parent
= parent
;
68 newphysr
->next_ph_list
= newpb
->firstregion
;
69 newphysr
->memtype
= parent
->memtype
;
70 newpb
->firstregion
= newphysr
;);
74 struct phys_region
*pb_reference(struct phys_block
*newpb
,
75 vir_bytes offset
, struct vir_region
*region
)
77 struct phys_region
*newphysr
;
79 if(!SLABALLOC(newphysr
)) {
80 printf("vm: pb_reference: couldn't allocate phys region\n");
84 /* New physical region. */
85 pb_link(newphysr
, newpb
, offset
, region
);
87 physr_insert(region
->phys
, newphysr
);
92 /*===========================================================================*
94 *===========================================================================*/
95 void pb_unreferenced(struct vir_region
*region
, struct phys_region
*pr
, int rm
)
97 struct phys_block
*pb
;
100 assert(pb
->refcount
> 0);
101 USE(pb
, pb
->refcount
--;);
102 assert(pb
->refcount
>= 0);
104 if(pb
->firstregion
== pr
) {
105 USE(pb
, pb
->firstregion
= pr
->next_ph_list
;);
107 struct phys_region
*others
;
109 for(others
= pb
->firstregion
; others
;
110 others
= others
->next_ph_list
) {
111 assert(others
->ph
== pb
);
112 if(others
->next_ph_list
== pr
) {
113 USE(others
, others
->next_ph_list
= pr
->next_ph_list
;);
118 assert(others
); /* Otherwise, wasn't on the list. */
121 if(pb
->refcount
== 0) {
122 assert(!pb
->firstregion
);
124 if((r
= region
->memtype
->ev_unreference(pr
)) != OK
)
125 panic("unref failed, %d", r
);
132 if(rm
) physr_remove(region
->phys
, pr
->offset
);