void
pmm_mark_page_occupied(pid_t owner, uintptr_t ppn, pp_attr_t attr)
{
- pm_table[ppn] = (struct pp_struct) {
- .owner = owner,
- .ref_counts = 1,
- .attr = attr
- };
+ pm_table[ppn] =
+ (struct pp_struct){ .owner = owner, .ref_counts = 1, .attr = attr };
}
void
pmm_mark_chunk_free(uintptr_t start_ppn, size_t page_count)
{
- for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++)
- {
+ for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) {
pm_table[i].ref_counts = 0;
}
}
void
-pmm_mark_chunk_occupied(pid_t owner, uint32_t start_ppn, size_t page_count, pp_attr_t attr)
+pmm_mark_chunk_occupied(pid_t owner,
+ uint32_t start_ppn,
+ size_t page_count,
+ pp_attr_t attr)
{
- for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++)
- {
- pm_table[i] = (struct pp_struct) {
- .owner = owner,
- .ref_counts = 1,
- .attr = attr
- };
+ for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) {
+ pm_table[i] =
+ (struct pp_struct){ .owner = owner, .ref_counts = 1, .attr = attr };
}
}
// 我们跳过位于0x0的页。我们不希望空指针是指向一个有效的内存空间。
#define LOOKUP_START 1
-size_t pg_lookup_ptr;
+volatile size_t pg_lookup_ptr;
void
pmm_init(uintptr_t mem_upper_lim)
// mark all as occupied
for (size_t i = 0; i < PM_BMP_MAX_SIZE; i++) {
- pm_table[i] = (struct pp_struct) {
- .owner = 0,
- .attr = 0,
- .ref_counts = 1
- };
+ pm_table[i] =
+ (struct pp_struct){ .owner = 0, .attr = 0, .ref_counts = 1 };
}
}
void*
-pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr) {
+pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr)
+{
size_t p1 = 0;
size_t p2 = 0;
- while (p2 < max_pg && p2 - p1 < num_pages)
- {
- (!(&pm_table[p2])->ref_counts) ? (p2++) : (p1 = p2);
+ while (p2 < max_pg && p2 - p1 < num_pages) {
+ (!(&pm_table[p2])->ref_counts) ? (p2++) : (p1 = ++p2);
}
- if (p2 < max_pg) {
+ if (p2 == max_pg && p2 - p1 < num_pages) {
return NULL;
}
pm = &pm_table[pg_lookup_ptr];
if (!pm->ref_counts) {
- *pm = (struct pp_struct) {
- .attr = attr,
- .owner = owner,
- .ref_counts = 1
- };
+ *pm = (struct pp_struct){ .attr = attr,
+ .owner = owner,
+ .ref_counts = 1 };
good_page_found = pg_lookup_ptr << 12;
break;
} else {
pmm_free_page(pid_t owner, void* page)
{
struct pp_struct* pm = &pm_table[(intptr_t)page >> 12];
-
+
// Is this a MMIO mapping or double free?
if (((intptr_t)page >> 12) >= max_pg || !(pm->ref_counts)) {
return 0;
}
- // TODO: 检查权限,保证:1) 只有正在使用该页(包括被分享者)的进程可以释放; 2) 内核可释放所有页。
+ // 如果是锁定页,则不作处理
+ if ((pm->attr & PP_FGLOCKED)) {
+ return 0;
+ }
+
+ // TODO: 检查权限,保证:1) 只有正在使用该页(包括被分享者)的进程可以释放;
+ // 2) 内核可释放所有页。
pm->ref_counts--;
return 1;
}
-int pmm_ref_page(pid_t owner, void* page) {
- (void*) owner; // TODO: do smth with owner
-
+int
+pmm_ref_page(pid_t owner, void* page)
+{
+ (void*)owner; // TODO: do smth with owner
+
uint32_t ppn = (uintptr_t)page >> 12;
-
+
if (ppn >= PM_BMP_MAX_SIZE) {
return 0;
}
return 1;
}
-struct pp_struct* pmm_query(void* pa) {
+struct pp_struct*
+pmm_query(void* pa)
+{
uint32_t ppn = (uintptr_t)pa >> 12;
-
+
if (ppn >= PM_BMP_MAX_SIZE) {
return NULL;
}