Magic‐1 Page Table Flags - retrotruestory/M1DEV GitHub Wiki

Magic-1 Page Table Flags: Critical Technical Details

Core Page Table Flags

Page table entries (PTEs) in Magic-1 are 16-bit values where the high bits contain flags and low bits contain the physical page number. These flags control memory access permissions and behavior:

// Documented page flags - high bits of page table entry
#define PAGE_PRESENT        0x8000  // Must be set for valid pages
#define PAGE_NOT_PRESENT    0x0000  // Invalid/unmapped page
#define PAGE_WRITEABLE      0x4000  // Enable write access
#define PAGE_NOT_WRITEABLE  0x0000  // Read-only access
#define PAGE_SRAM           0x2000  // Access physical SRAM
#define PAGE_DEVICE         0x0000  // Access hardware device memory
#define PAGE_WAIT           0x0000  // Wait states enabled
#define PAGE_NO_WAIT        0x1000  // No wait states (faster)

Flag Combinations and Usage Patterns

Critical Combinations

// Common PTE patterns based on usage
#define CODE_PAGE_FLAGS  (PAGE_PRESENT | PAGE_SRAM | PAGE_NOT_WRITEABLE)
#define DATA_PAGE_FLAGS  (PAGE_PRESENT | PAGE_SRAM | PAGE_WRITEABLE)
#define STACK_PAGE_FLAGS (PAGE_PRESENT | PAGE_SRAM | PAGE_WRITEABLE)
#define DEVICE_PAGE_FLAGS (PAGE_PRESENT | PAGE_DEVICE | PAGE_WRITEABLE)

Memory Region-Specific Configurations

// Code pages (read-only execution)
write_code_pte(address, page | PAGE_PRESENT | PAGE_SRAM | PAGE_NOT_WRITEABLE);

// Data pages (read-write data)
write_data_pte(address, page | PAGE_PRESENT | PAGE_SRAM | PAGE_WRITEABLE);

// Device memory (hardware registers)
write_data_pte(0xF800, 31 | PAGE_PRESENT | PAGE_DEVICE | PAGE_WRITEABLE);

// Fast memory access (no wait states)
write_data_pte(address, page | PAGE_PRESENT | PAGE_SRAM | PAGE_NO_WAIT | PAGE_WRITEABLE);

Extended Flags (Implementation-Dependent)

Some Magic-1 implementations support additional flags for advanced memory management:

// Extended flags - availability depends on hardware version
#define PAGE_REFERENCED   0x0800  // Page has been accessed (for LRU)
#define PAGE_MODIFIED     0x0400  // Page has been modified (dirty bit)
#define PAGE_CACHEABLE    0x0200  // Page can be cached
#define PAGE_GLOBAL       0x0100  // Page stays in TLB on context switch

Critical Rules for Page Table Management

  1. Device Page Mapping Rule (MOST CRITICAL):

    // This mapping MUST be present in EVERY page table configuration
    // Failing to map device page properly will cause system lockup
    write_data_pte(0xF800, 31 | (PAGE_PRESENT | PAGE_WRITEABLE | PAGE_DEVICE));
    
  2. Page Presence Requirement:

    // PAGE_PRESENT flag must be set for any accessible page
    // Accessing non-present pages causes hardware fault
    
  3. Write Protection:

    // Writing to pages without PAGE_WRITEABLE causes hardware fault
    // Always set PAGE_WRITEABLE for stack and data pages
    
  4. Hardware/Software Translation:

    // For PTE entry: high bits = flags, low bits = physical page number
    // Physical page calculation: (pte & 0x0FFF) * PAGE_SIZE
    
  5. Page Size Constraints:

    // Magic-1 uses fixed 2KB page size (2048 bytes)
    // Each process has 32 code pages and 32 data pages maximum
    

Page Table Structure and Access

// Page table base calculation
uint16_t *get_code_pt_base(int pid) {
    return (uint16_t*)(PTB_BASE + (pid * 128));
}

uint16_t *get_data_pt_base(int pid) {
    return (uint16_t*)(PTB_BASE + (pid * 128) + 64);
}

// PTE access functions
uint16_t read_code_pte(uint16_t virt_addr) {
    uint16_t *pt = get_code_pt_base(current_pid);
    return pt[virt_addr >> 11];  // 2KB pages = 11 bit shift
}

void write_data_pte(uint16_t virt_addr, uint16_t pte) {
    uint16_t *pt = get_data_pt_base(current_pid);
    pt[virt_addr >> 11] = pte;
}

Context Switching and Page Tables

When switching between processes, the page tables must be properly managed:

// Switch to process page tables
void set_pid(int pid) {
    // Set PID register in hardware
    __asm__ volatile ("copy pid,%0" : : "r" (pid));
    
    // Flush TLB after PID change (if hardware has TLB)
    __asm__ volatile ("flushtlb");
}

Performance Considerations

  1. Fast Memory Configuration:

    // Configure frequently accessed pages with no wait states
    write_code_pte(addr, page | PAGE_PRESENT | PAGE_SRAM | PAGE_NO_WAIT);
    
  2. Device vs. SRAM Timing:

    // Device access is slower than SRAM access
    // Use PAGE_SRAM whenever possible for better performance
    
  3. Page Table Locality:

    // Keep related pages together in physical memory
    // Process pages within same region for better cache behavior
    

Understanding and properly using these page table flags is critical for Magic-1 system programming, particularly for bootloaders, operating systems, and any code that manipulates memory mapping directly.