Reference count page tables

This commit is contained in:
2025-12-08 17:40:12 +01:00
parent 0de8cca8bb
commit 9c8946de51
3 changed files with 20 additions and 4 deletions

View File

@ -38,7 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* Bootstrap Bitmap Allocator */
#define BBA_BLOCK_SIZE (4096)
#define BBA_SIZE (BBA_BLOCK_SIZE * 128)
#define BBA_SIZE (BBA_BLOCK_SIZE * 256)
#define BBA_BM_SIZE (BBA_BLOCK_SIZE)
struct bba {

View File

@ -52,6 +52,7 @@ static struct page_dir *mm_alloc_pd(void) {
memset(pd, 0, sizeof(*pd));
sl_init(&pd->sl, "pd");
pd->pd = (volatile uint32_t *)bba_alloc();
memset(pd->pt_refcount, 0, sizeof(pd->pt_refcount));
return pd;
}
@ -60,6 +61,7 @@ static struct page_dir *mm_alloc_existing_pd(uptr_t ptr) {
memset(pd, 0, sizeof(*pd));
sl_init(&pd->sl, "pd");
pd->pd = (volatile uint32_t *)ptr;
memset(pd->pt_refcount, 0, sizeof(pd->pt_refcount));
return pd;
}
@ -85,9 +87,13 @@ void mm_map_page(struct page_dir *pd, uptr_t vaddr, uptr_t paddr, uint32_t flags
pt[i] = 0;
uptr_t phys_pt = (uptr_t)pt - VIRT_BASE;
pd->pd[pd_idx] = phys_pt | PF_PRESENT | PF_WRITABLE;
pd->pt_refcount[pd_idx] = 1;
} else {
uptr_t pt_phys = pd->pd[pd_idx] & ~(PAGE_SIZE - 1);
pt = (volatile uint32_t *)(pt_phys + VIRT_BASE);
if (!(pt[pt_idx] & PF_PRESENT))
pd->pt_refcount[pd_idx]++;
}
pt[pt_idx] = (paddr & ~(PAGE_SIZE - 1)) | (flags & ~PF_LOCK);
@ -112,7 +118,17 @@ void mm_unmap_page(struct page_dir *pd, uptr_t vaddr, uint32_t flags) {
pt = (volatile uint32_t *)(pt_phys + VIRT_BASE);
}
pt[pt_idx] &= ~PF_PRESENT;
if (pt[pt_idx] & PF_PRESENT) {
pt[pt_idx] &= ~PF_PRESENT;
if (pd->pt_refcount[pd_idx] > 0)
pd->pt_refcount[pd_idx]--;
if (pd->pt_refcount[pd_idx] == 0) {
bba_free((uptr_t)pt);
pd->pd[pd_idx] = 0;
}
}
__asm__ volatile ("invlpg (%0)" :: "r"(vaddr) : "memory");

View File

@ -48,11 +48,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
I use this here, because when (un)mapping an entire page range
it would be inefficient to constantly (un)lock. */
#define KERNEL_HEAP_START 0xF0000000
#define MEM_PROBE_HEAP_START 0xE0000000
#define KERNEL_HEAP_START 0xF0000000
struct page_dir {
volatile uint32_t *pd;
uint16_t pt_refcount[1024];
struct spinlock sl;
};