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
-
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));
-
Page Presence Requirement:
// PAGE_PRESENT flag must be set for any accessible page // Accessing non-present pages causes hardware fault
-
Write Protection:
// Writing to pages without PAGE_WRITEABLE causes hardware fault // Always set PAGE_WRITEABLE for stack and data pages
-
Hardware/Software Translation:
// For PTE entry: high bits = flags, low bits = physical page number // Physical page calculation: (pte & 0x0FFF) * PAGE_SIZE
-
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
-
Fast Memory Configuration:
// Configure frequently accessed pages with no wait states write_code_pte(addr, page | PAGE_PRESENT | PAGE_SRAM | PAGE_NO_WAIT);
-
Device vs. SRAM Timing:
// Device access is slower than SRAM access // Use PAGE_SRAM whenever possible for better performance
-
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.