Page table management - retrotruestory/M1DEV GitHub Wiki

Here's how to optimize page table management using Magic-1's specialized instructions:

        .cseg
        .global _write_page_entry
        .global _read_page_entry
        .global _map_page
        .global _unmap_page

// Write a page table entry (PTE)
// void write_page_entry(uint16_t pte, void* addr, int is_code)
_write_page_entry:
        enter   8
        push    b
        push    c
        
        ld.16   a,12(sp)   ; Load PTE value
        ld.16   b,14(sp)   ; Load virtual address
        ld.16   c,16(sp)   ; Load is_code flag
        
        cmp.16  c,#0       ; Check if code or data page
        br.eq   .data_page
        
        wcpte   a,(b)      ; Write code page table entry
        br      .done
        
.data_page:
        wdpte   a,(b)      ; Write data page table entry
        
.done:  pop     c
        pop     b
        leave
        ret

// Map a physical page to virtual address
// void map_page(uint16_t phys_page, void* virt_addr, int is_code, int is_writable)
_map_page:
        enter   8
        push    b
        push    c
        
        ld.16   a,12(sp)   ; Load physical page number
        ld.16   b,14(sp)   ; Load virtual address
        ld.16   c,16(sp)   ; Load is_code flag
        
        ; Build PTE: Present(1) + Writable(param) + RAM(1) + Page(11 bits)
        or.16   a,#0x8000  ; Set present bit
        
        ld.16   c,18(sp)   ; Load writable flag
        cmp.16  c,#0
        br.eq   .readonly
        
        or.16   a,#0x4000  ; Set writable bit
        
.readonly:
        or.16   a,#0x2000  ; Set RAM bit
        
        ; Write PTE
        push    c
        ld.16   c,18(sp)   ; Reload is_code flag
        wcpte   a,(b)      ; Write to page table
        pop     c
        
        pop     c
        pop     b
        leave
        ret

Create a C interface:

#ifndef PAGE_MGMT_H
#define PAGE_MGMT_H

#include <stdint.h>

// Page table entry flags
#define PTE_PRESENT    0x8000
#define PTE_WRITABLE   0x4000
#define PTE_RAM        0x2000
#define PTE_MASK       0x07FF  // 11 bits for page number

// Function declarations
void write_page_entry(uint16_t pte, void* addr, int is_code);
void map_page(uint16_t phys_page, void* virt_addr, int is_code, int is_writable);

// Helper macros
#define PAGE_SIZE       2048
#define PAGES_PER_PROC  32
#define CODE_PAGE       1
#define DATA_PAGE       0

#endif

Example usage:

#include <stdio.h>
#include "page_mgmt.h"

void setup_process_memory(int pid) {
    uint16_t code_base = pid * PAGES_PER_PROC;
    uint16_t data_base = code_base + PAGES_PER_PROC;
    
    // Map code pages (read-only)
    for(int i = 0; i < PAGES_PER_PROC; i++) {
        void* virt_addr = (void*)(i * PAGE_SIZE);
        map_page(code_base + i, virt_addr, CODE_PAGE, 0);
    }
    
    // Map data pages (read-write)
    for(int i = 0; i < PAGES_PER_PROC; i++) {
        void* virt_addr = (void*)((i + PAGES_PER_PROC) * PAGE_SIZE);
        map_page(data_base + i, virt_addr, DATA_PAGE, 1);
    }
}

Update Makefile:

CC = clcc
AS = m1_as
CFLAGS = -O2
OBJECTS = page_mgmt.o test_paging.o

test_paging: $(OBJECTS)
    $(CC) $(CFLAGS) -o $@ $(OBJECTS)

%.o: %.s
    $(AS) -o $@ $<

%.o: %.c
    $(CC) $(CFLAGS) -c $<

clean:
    rm -f test_paging *.o

Key features:

  • Direct use of wcpte/wdpte instructions for page table management
  • Hardware-assisted page table updates
  • Support for both code and data pages
  • Page protection flags (present, writable, RAM)
  • Process memory isolation

This implementation is particularly useful for:

  • Process memory management
  • Virtual memory setup
  • Memory protection
  • Process isolation
  • Page table manipulation in kernel mode
⚠️ **GitHub.com Fallback** ⚠️