Changeset 10e0cee in mainline
- Timestamp:
- 2006-06-18T00:31:14Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1bb2e7a
- Parents:
- 8e3bf3e2
- Location:
- arch/ppc32
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/ppc32/Makefile.inc
r8e3bf3e2 r10e0cee 56 56 DEFS += -DCONFIG_PAGE_PT 57 57 58 ## Compile with support for address space identifiers. 59 # 60 61 CONFIG_ASID = y 62 CONFIG_ASID_FIFO = y 63 58 64 ## Compile with support for software integer division. 59 65 # -
arch/ppc32/include/arch.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32 30 30 * @{ 31 31 */ … … 40 40 #endif 41 41 42 42 /** @} 43 43 */ 44 -
arch/ppc32/include/boot/boot.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32 30 30 * @{ 31 31 */ … … 83 83 84 84 typedef struct { 85 memmap_t memmap; 85 86 taskmap_t taskmap; 86 memmap_t memmap;87 87 screen_t screen; 88 88 keyboard_t keyboard; … … 95 95 #endif 96 96 97 97 /** @} 98 98 */ 99 -
arch/ppc32/include/exception.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32 30 30 * @{ 31 31 */ … … 101 101 #endif 102 102 103 103 /** @} 104 104 */ 105 -
arch/ppc32/include/interrupt.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32interrupt 30 30 * @{ 31 31 */ … … 57 57 #endif 58 58 59 59 /** @} 60 60 */ 61 -
arch/ppc32/include/mm/as.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 45 45 #define USTACK_ADDRESS_ARCH (0x7fffffff-(PAGE_SIZE-1)) 46 46 47 #define as_install_arch(as)48 49 47 extern void as_arch_init(void); 50 48 51 49 #endif 52 50 53 51 /** @} 54 52 */ 55 -
arch/ppc32/include/mm/asid.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 36 36 #define __ppc32_ASID_H__ 37 37 38 typedef int asid_t; 38 #include <arch/types.h> 39 39 40 #define ASID_MAX_ARCH 340 #define ASID_MAX_ARCH 4096 41 41 42 #define asid_get() (ASID_START+1) 43 #define asid_put(asid) 42 typedef __u32 asid_t; 44 43 45 44 #endif 46 45 47 46 /** @} 48 47 */ 49 -
arch/ppc32/include/mm/frame.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 53 53 #endif 54 54 55 55 /** @} 56 56 */ 57 -
arch/ppc32/include/mm/memory_init.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 44 44 #endif 45 45 46 46 /** @} 47 47 */ 48 -
arch/ppc32/include/mm/page.h
r8e3bf3e2 r10e0cee 133 133 extern void page_arch_init(void); 134 134 135 typedef struct {136 unsigned v : 1; /**< Valid */137 unsigned vsid : 24; /**< Virtual Segment ID */138 unsigned h : 1; /**< Primary/secondary hash */139 unsigned api : 6; /**< Abbreviated Page Index */140 unsigned rpn : 20; /**< Real Page Number */141 unsigned reserved0 : 3;142 unsigned r : 1; /**< Reference */143 unsigned c : 1; /**< Change */144 unsigned wimg : 4; /**< Access control */145 unsigned reserved1 : 1;146 unsigned pp : 2; /**< Page protection */147 } phte_t;148 149 extern void pht_refill(int n, istate_t *istate);150 extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));151 extern void pht_init(void);152 153 135 #endif /* __ASM__ */ 154 136 -
arch/ppc32/include/mm/tlb.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 36 36 #define __ppc32_TLB_H__ 37 37 38 typedef struct { 39 unsigned v : 1; /**< Valid */ 40 unsigned vsid : 24; /**< Virtual Segment ID */ 41 unsigned h : 1; /**< Primary/secondary hash */ 42 unsigned api : 6; /**< Abbreviated Page Index */ 43 unsigned rpn : 20; /**< Real Page Number */ 44 unsigned reserved0 : 3; 45 unsigned r : 1; /**< Reference */ 46 unsigned c : 1; /**< Change */ 47 unsigned wimg : 4; /**< Access control */ 48 unsigned reserved1 : 1; 49 unsigned pp : 2; /**< Page protection */ 50 } phte_t; 51 52 extern void pht_refill(int n, istate_t *istate); 53 extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); 54 extern void pht_init(void); 38 55 39 56 #endif 40 57 41 58 /** @} 42 59 */ 43 -
arch/ppc32/include/types.h
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32 30 30 * @{ 31 31 */ … … 66 66 #endif 67 67 68 68 /** @} 69 69 */ 70 -
arch/ppc32/src/exception.S
r8e3bf3e2 r10e0cee 138 138 CONTEXT_STORE 139 139 140 #li r3, 2141 #mr r4, sp142 #addi r4, r4, 8143 #bl pht_real_refill144 145 #cmpwi r3, 0146 #bne iret_real140 li r3, 2 141 mr r4, sp 142 addi r4, r4, 8 143 bl pht_real_refill 144 145 cmpwi r3, 0 146 bne iret_real 147 147 148 148 li r3, 2 … … 154 154 CONTEXT_STORE 155 155 156 #li r3, 3157 #mr r4, sp158 #addi r4, r4, 8159 #bl pht_real_refill160 161 #cmpwi r3, 0162 #bne iret_real156 li r3, 3 157 mr r4, sp 158 addi r4, r4, 8 159 bl pht_real_refill 160 161 cmpwi r3, 0 162 bne iret_real 163 163 164 164 li r3, 3 -
arch/ppc32/src/interrupt.c
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32interrupt 30 30 * @{ 31 31 */ … … 40 40 #include <ipc/sysipc.h> 41 41 #include <arch/drivers/pic.h> 42 #include <arch/mm/tlb.h> 42 43 43 44 … … 93 94 } 94 95 95 96 /** @} 96 97 */ 97 -
arch/ppc32/src/mm/as.c
r8e3bf3e2 r10e0cee 35 35 #include <arch/mm/as.h> 36 36 #include <genarch/mm/as_pt.h> 37 #include <genarch/mm/asid_fifo.h> 38 #include <arch.h> 37 39 38 40 /** Architecture dependent address space init. */ … … 40 42 { 41 43 as_operations = &as_pt_operations; 44 asid_fifo_init(); 45 } 46 47 /** Install address space. 48 * 49 * Install ASID. 50 * 51 * @param as Address space structure. 52 * 53 */ 54 void as_install_arch(as_t *as) 55 { 56 asid_t asid; 57 ipl_t ipl; 58 __u8 sr; 59 60 ipl = interrupts_disable(); 61 spinlock_lock(&as->lock); 62 63 asid = as->asid; 64 65 /* Lower 2 GB, user and supervisor access */ 66 for (sr = 0; sr < 8; sr++) { 67 asm volatile ( 68 "mtsrin %0, %1\n" 69 : 70 : "r" (0x6000 + (asid << 4) + sr), "r" (sr * 0x1000) 71 ); 72 } 73 74 /* Upper 2 GB, only supervisor access */ 75 for (sr = 8; sr < 16; sr++) { 76 asm volatile ( 77 "mtsrin %0, %1\n" 78 : 79 : "r" (0x4000 + (asid << 4) + sr), "r" (sr * 0x1000) 80 ); 81 } 82 83 spinlock_unlock(&as->lock); 84 interrupts_restore(ipl); 42 85 } 43 86 -
arch/ppc32/src/mm/frame.c
r8e3bf3e2 r10e0cee 67 67 frame_mark_unavailable(0, 8); 68 68 69 /* Mark the Page Hash Table frames as unavailable */ 70 __u32 sdr1; 71 asm volatile ( 72 "mfsdr1 %0\n" 73 : "=r" (sdr1) 74 ); 75 frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); // FIXME 69 76 } 70 77 -
arch/ppc32/src/mm/memory_init.c
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 53 53 } 54 54 55 55 /** @} 56 56 */ 57 -
arch/ppc32/src/mm/page.c
r8e3bf3e2 r10e0cee 33 33 */ 34 34 35 #include <arch/mm/page.h>36 35 #include <genarch/mm/page_pt.h> 37 #include <arch/mm/frame.h>38 #include <arch/asm.h>39 #include <arch/interrupt.h>40 36 #include <mm/frame.h> 41 #include <mm/page.h>42 37 #include <mm/as.h> 43 #include <arch.h>44 #include <arch/types.h>45 #include <arch/exception.h>46 38 #include <align.h> 47 39 #include <config.h> 48 #include <print.h>49 #include <symtab.h>50 51 52 /** Try to find PTE for faulting address53 *54 * Try to find PTE for faulting address.55 * The as->lock must be held on entry to this function56 * if lock is true.57 *58 * @param as Address space.59 * @param lock Lock/unlock the address space.60 * @param badvaddr Faulting virtual address.61 * @param access Access mode that caused the fault.62 * @param istate Pointer to interrupted state.63 * @param pfrc Pointer to variable where as_page_fault() return code will be stored.64 * @return PTE on success, NULL otherwise.65 *66 */67 static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, int access, istate_t *istate, int *pfrc)68 {69 /*70 * Check if the mapping exists in page tables.71 */72 pte_t *pte = page_mapping_find(as, badvaddr);73 if ((pte) && (pte->p)) {74 /*75 * Mapping found in page tables.76 * Immediately succeed.77 */78 return pte;79 } else {80 int rc;81 82 /*83 * Mapping not found in page tables.84 * Resort to higher-level page fault handler.85 */86 page_table_unlock(as, lock);87 switch (rc = as_page_fault(badvaddr, access, istate)) {88 case AS_PF_OK:89 /*90 * The higher-level page fault handler succeeded,91 * The mapping ought to be in place.92 */93 page_table_lock(as, lock);94 pte = page_mapping_find(as, badvaddr);95 ASSERT((pte) && (pte->p));96 return pte;97 case AS_PF_DEFER:98 page_table_lock(as, lock);99 *pfrc = rc;100 return NULL;101 case AS_PF_FAULT:102 page_table_lock(as, lock);103 printf("Page fault.\n");104 *pfrc = rc;105 return NULL;106 default:107 panic("unexpected rc (%d)\n", rc);108 }109 }110 }111 112 113 static void pht_refill_fail(__address badvaddr, istate_t *istate)114 {115 char *symbol = "";116 char *sym2 = "";117 118 char *s = get_symtab_entry(istate->pc);119 if (s)120 symbol = s;121 s = get_symtab_entry(istate->lr);122 if (s)123 sym2 = s;124 panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);125 }126 127 128 static void pht_insert(const __address vaddr, const pfn_t pfn)129 {130 __u32 page = (vaddr >> 12) & 0xffff;131 __u32 api = (vaddr >> 22) & 0x3f;132 133 __u32 vsid;134 asm volatile (135 "mfsrin %0, %1\n"136 : "=r" (vsid)137 : "r" (vaddr)138 );139 140 __u32 sdr1;141 asm volatile (142 "mfsdr1 %0\n"143 : "=r" (sdr1)144 );145 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);146 147 /* Primary hash (xor) */148 __u32 h = 0;149 __u32 hash = vsid ^ page;150 __u32 base = (hash & 0x3ff) << 3;151 __u32 i;152 bool found = false;153 154 /* Find unused or colliding155 PTE in PTEG */156 for (i = 0; i < 8; i++) {157 if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) {158 found = true;159 break;160 }161 }162 163 if (!found) {164 /* Secondary hash (not) */165 __u32 base2 = (~hash & 0x3ff) << 3;166 167 /* Find unused or colliding168 PTE in PTEG */169 for (i = 0; i < 8; i++) {170 if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) {171 found = true;172 base = base2;173 h = 1;174 break;175 }176 }177 178 if (!found) {179 // TODO: A/C precedence groups180 i = page % 8;181 }182 }183 184 phte[base + i].v = 1;185 phte[base + i].vsid = vsid;186 phte[base + i].h = h;187 phte[base + i].api = api;188 phte[base + i].rpn = pfn;189 phte[base + i].r = 0;190 phte[base + i].c = 0;191 phte[base + i].pp = 2; // FIXME192 }193 194 195 static void pht_real_insert(const __address vaddr, const pfn_t pfn)196 {197 __u32 page = (vaddr >> 12) & 0xffff;198 __u32 api = (vaddr >> 22) & 0x3f;199 200 __u32 vsid;201 asm volatile (202 "mfsrin %0, %1\n"203 : "=r" (vsid)204 : "r" (vaddr)205 );206 207 __u32 sdr1;208 asm volatile (209 "mfsdr1 %0\n"210 : "=r" (sdr1)211 );212 phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);213 214 /* Primary hash (xor) */215 __u32 h = 0;216 __u32 hash = vsid ^ page;217 __u32 base = (hash & 0x3ff) << 3;218 __u32 i;219 bool found = false;220 221 /* Find unused or colliding222 PTE in PTEG */223 for (i = 0; i < 8; i++) {224 if ((!phte_physical[base + i].v) || ((phte_physical[base + i].vsid == vsid) && (phte_physical[base + i].api == api))) {225 found = true;226 break;227 }228 }229 230 if (!found) {231 /* Secondary hash (not) */232 __u32 base2 = (~hash & 0x3ff) << 3;233 234 /* Find unused or colliding235 PTE in PTEG */236 for (i = 0; i < 8; i++) {237 if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) {238 found = true;239 base = base2;240 h = 1;241 break;242 }243 }244 245 if (!found) {246 // TODO: A/C precedence groups247 i = page % 8;248 }249 }250 251 phte_physical[base + i].v = 1;252 phte_physical[base + i].vsid = vsid;253 phte_physical[base + i].h = h;254 phte_physical[base + i].api = api;255 phte_physical[base + i].rpn = pfn;256 phte_physical[base + i].r = 0;257 phte_physical[base + i].c = 0;258 phte_physical[base + i].pp = 2; // FIXME259 }260 261 262 /** Process Instruction/Data Storage Interrupt263 *264 * @param n Interrupt vector number.265 * @param istate Interrupted register context.266 *267 */268 void pht_refill(int n, istate_t *istate)269 {270 __address badvaddr;271 pte_t *pte;272 int pfrc;273 as_t *as;274 bool lock;275 276 if (AS == NULL) {277 as = AS_KERNEL;278 lock = false;279 } else {280 as = AS;281 lock = true;282 }283 284 if (n == VECTOR_DATA_STORAGE) {285 asm volatile (286 "mfdar %0\n"287 : "=r" (badvaddr)288 );289 } else290 badvaddr = istate->pc;291 292 page_table_lock(as, lock);293 294 pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc);295 if (!pte) {296 switch (pfrc) {297 case AS_PF_FAULT:298 goto fail;299 break;300 case AS_PF_DEFER:301 /*302 * The page fault came during copy_from_uspace()303 * or copy_to_uspace().304 */305 page_table_unlock(as, lock);306 return;307 default:308 panic("Unexpected pfrc (%d)\n", pfrc);309 }310 }311 312 pte->a = 1; /* Record access to PTE */313 pht_insert(badvaddr, pte->pfn);314 315 page_table_unlock(as, lock);316 return;317 318 fail:319 page_table_unlock(as, lock);320 pht_refill_fail(badvaddr, istate);321 }322 323 324 /** Process Instruction/Data Storage Interrupt in Real Mode325 *326 * @param n Interrupt vector number.327 * @param istate Interrupted register context.328 *329 */330 bool pht_real_refill(int n, istate_t *istate)331 {332 __address badvaddr;333 334 if (n == VECTOR_DATA_STORAGE) {335 asm volatile (336 "mfdar %0\n"337 : "=r" (badvaddr)338 );339 } else340 badvaddr = istate->pc;341 342 __u32 physmem;343 asm volatile (344 "mfsprg3 %0\n"345 : "=r" (physmem)346 );347 348 if ((badvaddr >= PA2KA(0)) && (badvaddr <= PA2KA(physmem))) {349 pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);350 return true;351 }352 353 return false;354 }355 356 357 void pht_init(void)358 {359 // FIXME360 361 __u32 sdr1;362 asm volatile (363 "mfsdr1 %0\n"364 : "=r" (sdr1)365 );366 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);367 368 memsetb((__address) phte, 65536, 0);369 }370 371 40 372 41 void page_arch_init(void) -
arch/ppc32/src/mm/tlb.c
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 34 34 35 35 #include <mm/tlb.h> 36 37 38 /** Initialize Page Hash Table. 39 * 40 * Setup the Page Hash Table with no entries. 41 * 42 */ 36 #include <arch/mm/tlb.h> 37 #include <arch/interrupt.h> 38 #include <mm/as.h> 39 #include <arch.h> 40 #include <print.h> 41 #include <symtab.h> 42 43 44 /** Try to find PTE for faulting address 45 * 46 * Try to find PTE for faulting address. 47 * The as->lock must be held on entry to this function 48 * if lock is true. 49 * 50 * @param as Address space. 51 * @param lock Lock/unlock the address space. 52 * @param badvaddr Faulting virtual address. 53 * @param access Access mode that caused the fault. 54 * @param istate Pointer to interrupted state. 55 * @param pfrc Pointer to variable where as_page_fault() return code will be stored. 56 * @return PTE on success, NULL otherwise. 57 * 58 */ 59 static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, int access, istate_t *istate, int *pfrc) 60 { 61 /* 62 * Check if the mapping exists in page tables. 63 */ 64 pte_t *pte = page_mapping_find(as, badvaddr); 65 if ((pte) && (pte->p)) { 66 /* 67 * Mapping found in page tables. 68 * Immediately succeed. 69 */ 70 return pte; 71 } else { 72 int rc; 73 74 /* 75 * Mapping not found in page tables. 76 * Resort to higher-level page fault handler. 77 */ 78 page_table_unlock(as, lock); 79 switch (rc = as_page_fault(badvaddr, access, istate)) { 80 case AS_PF_OK: 81 /* 82 * The higher-level page fault handler succeeded, 83 * The mapping ought to be in place. 84 */ 85 page_table_lock(as, lock); 86 pte = page_mapping_find(as, badvaddr); 87 ASSERT((pte) && (pte->p)); 88 return pte; 89 case AS_PF_DEFER: 90 page_table_lock(as, lock); 91 *pfrc = rc; 92 return NULL; 93 case AS_PF_FAULT: 94 page_table_lock(as, lock); 95 printf("Page fault.\n"); 96 *pfrc = rc; 97 return NULL; 98 default: 99 panic("unexpected rc (%d)\n", rc); 100 } 101 } 102 } 103 104 105 static void pht_refill_fail(__address badvaddr, istate_t *istate) 106 { 107 char *symbol = ""; 108 char *sym2 = ""; 109 110 char *s = get_symtab_entry(istate->pc); 111 if (s) 112 symbol = s; 113 s = get_symtab_entry(istate->lr); 114 if (s) 115 sym2 = s; 116 panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); 117 } 118 119 120 static void pht_insert(const __address vaddr, const pfn_t pfn) 121 { 122 __u32 page = (vaddr >> 12) & 0xffff; 123 __u32 api = (vaddr >> 22) & 0x3f; 124 125 __u32 vsid; 126 asm volatile ( 127 "mfsrin %0, %1\n" 128 : "=r" (vsid) 129 : "r" (vaddr) 130 ); 131 132 __u32 sdr1; 133 asm volatile ( 134 "mfsdr1 %0\n" 135 : "=r" (sdr1) 136 ); 137 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 138 139 /* Primary hash (xor) */ 140 __u32 h = 0; 141 __u32 hash = vsid ^ page; 142 __u32 base = (hash & 0x3ff) << 3; 143 __u32 i; 144 bool found = false; 145 146 /* Find unused or colliding 147 PTE in PTEG */ 148 for (i = 0; i < 8; i++) { 149 if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) { 150 found = true; 151 break; 152 } 153 } 154 155 if (!found) { 156 /* Secondary hash (not) */ 157 __u32 base2 = (~hash & 0x3ff) << 3; 158 159 /* Find unused or colliding 160 PTE in PTEG */ 161 for (i = 0; i < 8; i++) { 162 if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) { 163 found = true; 164 base = base2; 165 h = 1; 166 break; 167 } 168 } 169 170 if (!found) { 171 // TODO: A/C precedence groups 172 i = page % 8; 173 } 174 } 175 176 phte[base + i].v = 1; 177 phte[base + i].vsid = vsid; 178 phte[base + i].h = h; 179 phte[base + i].api = api; 180 phte[base + i].rpn = pfn; 181 phte[base + i].r = 0; 182 phte[base + i].c = 0; 183 phte[base + i].pp = 2; // FIXME 184 } 185 186 187 static void pht_real_insert(const __address vaddr, const pfn_t pfn) 188 { 189 __u32 page = (vaddr >> 12) & 0xffff; 190 __u32 api = (vaddr >> 22) & 0x3f; 191 192 __u32 vsid; 193 asm volatile ( 194 "mfsrin %0, %1\n" 195 : "=r" (vsid) 196 : "r" (vaddr) 197 ); 198 199 __u32 sdr1; 200 asm volatile ( 201 "mfsdr1 %0\n" 202 : "=r" (sdr1) 203 ); 204 phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000); 205 206 /* Primary hash (xor) */ 207 __u32 h = 0; 208 __u32 hash = vsid ^ page; 209 __u32 base = (hash & 0x3ff) << 3; 210 __u32 i; 211 bool found = false; 212 213 /* Find unused or colliding 214 PTE in PTEG */ 215 for (i = 0; i < 8; i++) { 216 if ((!phte_physical[base + i].v) || ((phte_physical[base + i].vsid == vsid) && (phte_physical[base + i].api == api))) { 217 found = true; 218 break; 219 } 220 } 221 222 if (!found) { 223 /* Secondary hash (not) */ 224 __u32 base2 = (~hash & 0x3ff) << 3; 225 226 /* Find unused or colliding 227 PTE in PTEG */ 228 for (i = 0; i < 8; i++) { 229 if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) { 230 found = true; 231 base = base2; 232 h = 1; 233 break; 234 } 235 } 236 237 if (!found) { 238 // TODO: A/C precedence groups 239 i = page % 8; 240 } 241 } 242 243 phte_physical[base + i].v = 1; 244 phte_physical[base + i].vsid = vsid; 245 phte_physical[base + i].h = h; 246 phte_physical[base + i].api = api; 247 phte_physical[base + i].rpn = pfn; 248 phte_physical[base + i].r = 0; 249 phte_physical[base + i].c = 0; 250 phte_physical[base + i].pp = 2; // FIXME 251 } 252 253 254 /** Process Instruction/Data Storage Interrupt 255 * 256 * @param n Interrupt vector number. 257 * @param istate Interrupted register context. 258 * 259 */ 260 void pht_refill(int n, istate_t *istate) 261 { 262 __address badvaddr; 263 pte_t *pte; 264 int pfrc; 265 as_t *as; 266 bool lock; 267 268 if (AS == NULL) { 269 as = AS_KERNEL; 270 lock = false; 271 } else { 272 as = AS; 273 lock = true; 274 } 275 276 if (n == VECTOR_DATA_STORAGE) { 277 asm volatile ( 278 "mfdar %0\n" 279 : "=r" (badvaddr) 280 ); 281 } else 282 badvaddr = istate->pc; 283 284 page_table_lock(as, lock); 285 286 pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc); 287 if (!pte) { 288 switch (pfrc) { 289 case AS_PF_FAULT: 290 goto fail; 291 break; 292 case AS_PF_DEFER: 293 /* 294 * The page fault came during copy_from_uspace() 295 * or copy_to_uspace(). 296 */ 297 page_table_unlock(as, lock); 298 return; 299 default: 300 panic("Unexpected pfrc (%d)\n", pfrc); 301 } 302 } 303 304 pte->a = 1; /* Record access to PTE */ 305 pht_insert(badvaddr, pte->pfn); 306 307 page_table_unlock(as, lock); 308 return; 309 310 fail: 311 page_table_unlock(as, lock); 312 pht_refill_fail(badvaddr, istate); 313 } 314 315 316 /** Process Instruction/Data Storage Interrupt in Real Mode 317 * 318 * @param n Interrupt vector number. 319 * @param istate Interrupted register context. 320 * 321 */ 322 bool pht_real_refill(int n, istate_t *istate) 323 { 324 __address badvaddr; 325 326 if (n == VECTOR_DATA_STORAGE) { 327 asm volatile ( 328 "mfdar %0\n" 329 : "=r" (badvaddr) 330 ); 331 } else 332 badvaddr = istate->pc; 333 334 __u32 physmem; 335 asm volatile ( 336 "mfsprg3 %0\n" 337 : "=r" (physmem) 338 ); 339 340 if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) { 341 pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12); 342 return true; 343 } 344 345 return false; 346 } 347 348 43 349 void tlb_arch_init(void) 44 350 { … … 56 362 57 363 58 /** Invalidate all entries in TLB that belong to specified address space.59 *60 * @param asid This parameter is ignored as the architecture doesn't support it.61 */62 364 void tlb_invalidate_asid(asid_t asid) 63 365 { 366 // TODO 64 367 tlb_invalidate_all(); 65 368 } 66 369 67 /** Invalidate TLB entries for specified page range belonging to specified address space. 68 * 69 * @param asid This parameter is ignored as the architecture doesn't support it. 70 * @param page Address of the first page whose entry is to be invalidated. 71 * @param cnt Number of entries to invalidate. 72 */ 370 73 371 void tlb_invalidate_pages(asid_t asid, __address page, count_t cnt) 74 372 { 373 // TODO 75 374 tlb_invalidate_all(); 76 375 } 77 376 78 377 79 80 /** Print contents of Page Hash Table. */81 378 void tlb_print(void) 82 379 { 83 } 84 85 /** @} 86 */ 87 380 // TODO 381 } 382 383 /** @} 384 */ -
arch/ppc32/src/proc/scheduler.c
r8e3bf3e2 r10e0cee 27 27 */ 28 28 29 29 /** @addtogroup ppc32proc 30 30 * @{ 31 31 */ … … 47 47 void before_thread_runs_arch(void) 48 48 { 49 pht_init();50 49 tlb_invalidate_all(); 51 50 asm volatile ( … … 60 59 } 61 60 62 61 /** @} 63 62 */ 64
Note:
See TracChangeset
for help on using the changeset viewer.