1 /* 2 ** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 ** Distributed under the terms of the MIT License. 4 */ 5 #ifndef _KERNEL_ARCH_PPC_MMU_H 6 #define _KERNEL_ARCH_PPC_MMU_H 7 8 9 #include <SupportDefs.h> 10 #include <string.h> 11 12 #include <arch_cpu.h> 13 14 15 /*** BAT - block address translation ***/ 16 17 enum bat_length { 18 BAT_LENGTH_128kB = 0x0000, 19 BAT_LENGTH_256kB = 0x0001, 20 BAT_LENGTH_512kB = 0x0003, 21 BAT_LENGTH_1MB = 0x0007, 22 BAT_LENGTH_2MB = 0x000f, 23 BAT_LENGTH_4MB = 0x001f, 24 BAT_LENGTH_8MB = 0x003f, 25 BAT_LENGTH_16MB = 0x007f, 26 BAT_LENGTH_32MB = 0x00ff, 27 BAT_LENGTH_64MB = 0x01ff, 28 BAT_LENGTH_128MB = 0x03ff, 29 BAT_LENGTH_256MB = 0x07ff, 30 }; 31 32 enum bat_protection { 33 BAT_READ_ONLY = 1, 34 BAT_READ_WRITE = 2, 35 }; 36 37 struct block_address_translation { 38 // upper 32 bit 39 uint32 page_index : 15; // BEPI, block effective page index 40 uint32 _reserved0 : 4; 41 uint32 length : 11; 42 uint32 kernel_valid : 1; // Vs, Supervisor-state valid 43 uint32 user_valid : 1; // Vp, User-state valid 44 // lower 32 bit 45 uint32 physical_block_number : 15; // BPRN 46 uint32 write_through : 1; // WIMG 47 uint32 caching_inhibited : 1; 48 uint32 memory_coherent : 1; 49 uint32 guarded : 1; 50 uint32 _reserved1 : 1; 51 uint32 protection : 2; 52 53 block_address_translation() 54 { 55 Clear(); 56 } 57 58 void SetVirtualAddress(void *address) 59 { 60 page_index = uint32(address) >> 17; 61 } 62 63 void SetPhysicalAddress(void *address) 64 { 65 physical_block_number = uint32(address) >> 17; 66 } 67 68 void Clear() 69 { 70 memset((void *)this, 0, sizeof(block_address_translation)); 71 } 72 }; 73 74 struct segment_descriptor { 75 uint32 type : 1; // 0 for page translation descriptors 76 uint32 kernel_protection_key : 1; // Ks, Supervisor-state protection key 77 uint32 user_protection_key : 1; // Kp, User-state protection key 78 uint32 no_execute_protection : 1; 79 uint32 _reserved : 4; 80 uint32 virtual_segment_id : 24; 81 82 segment_descriptor() 83 { 84 Clear(); 85 } 86 87 segment_descriptor(uint32 value) 88 { 89 *((uint32 *)this) = value; 90 } 91 92 void Clear() 93 { 94 memset((void *)this, 0, sizeof(segment_descriptor)); 95 } 96 }; 97 98 99 /*** PTE - page table entry ***/ 100 101 enum pte_protection { 102 PTE_READ_ONLY = 3, 103 PTE_READ_WRITE = 2, 104 }; 105 106 struct page_table_entry { 107 // upper 32 bit 108 uint32 valid : 1; 109 uint32 virtual_segment_id : 24; 110 uint32 secondary_hash : 1; 111 uint32 abbr_page_index : 6; 112 // lower 32 bit 113 uint32 physical_page_number : 20; 114 uint32 _reserved0 : 3; 115 uint32 referenced : 1; 116 uint32 changed : 1; 117 uint32 write_through : 1; // WIMG 118 uint32 caching_inhibited : 1; 119 uint32 memory_coherent : 1; 120 uint32 guarded : 1; 121 uint32 _reserved1 : 1; 122 uint32 page_protection : 2; 123 124 static uint32 PrimaryHash(uint32 virtualSegmentID, uint32 virtualAddress); 125 static uint32 SecondaryHash(uint32 virtualSegmentID, uint32 virtualAddress); 126 static uint32 SecondaryHash(uint32 primaryHash); 127 }; 128 129 struct page_table_entry_group { 130 struct page_table_entry entry[8]; 131 }; 132 133 extern void ppc_get_page_table(page_table_entry_group **_pageTable, size_t *_size); 134 extern void ppc_set_page_table(page_table_entry_group *pageTable, size_t size); 135 136 static inline segment_descriptor 137 ppc_get_segment_register(void *virtualAddress) 138 { 139 return (segment_descriptor)get_sr(virtualAddress); 140 } 141 142 143 static inline void 144 ppc_set_segment_register(void *virtualAddress, segment_descriptor segment) 145 { 146 set_sr(virtualAddress, *(uint32 *)&segment); 147 } 148 149 #endif /* _KERNEL_ARCH_PPC_MMU_H */ 150