Changeset 46c20c8 in mainline for kernel/arch/ppc32/src
- Timestamp:
- 2010-11-26T20:08:10Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 45df59a
- Parents:
- fb150d78 (diff), ffdd2b9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- kernel/arch/ppc32/src
- Files:
-
- 17 edited
-
asm.S (modified) (7 diffs)
-
boot/boot.S (modified) (1 diff)
-
context.S (modified) (2 diffs)
-
cpu/cpu.c (modified) (2 diffs)
-
ddi/ddi.c (modified) (2 diffs)
-
debug/stacktrace.c (modified) (1 diff)
-
debug/stacktrace_asm.S (modified) (2 diffs)
-
drivers/pic.c (modified) (2 diffs)
-
exception.S (modified) (4 diffs)
-
fpu_context.S (modified) (2 diffs)
-
interrupt.c (modified) (6 diffs)
-
mm/as.c (modified) (1 diff)
-
mm/frame.c (modified) (4 diffs)
-
mm/page.c (modified) (1 diff)
-
mm/tlb.c (modified) (21 diffs)
-
ppc32.c (modified) (5 diffs)
-
proc/scheduler.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ppc32/src/asm.S
rfb150d78 r46c20c8 1 # 2 #Copyright (c) 2005 Martin Decky3 #All rights reserved.4 # 5 #Redistribution and use in source and binary forms, with or without6 #modification, are permitted provided that the following conditions7 #are met:8 # 9 #- Redistributions of source code must retain the above copyright10 #notice, this list of conditions and the following disclaimer.11 #- Redistributions in binary form must reproduce the above copyright12 #notice, this list of conditions and the following disclaimer in the13 #documentation and/or other materials provided with the distribution.14 #- The name of the author may not be used to endorse or promote products15 #derived from this software without specific prior written permission.16 # 17 #THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR18 #IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES19 #OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.20 #IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,21 #INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT22 #NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,23 #DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY24 #THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT25 #(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF26 #THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.27 # 1 /* 2 * Copyright (c) 2005 Martin Decky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * - The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 28 29 29 #include <arch/asm/regname.h> 30 #include <arch/cpu.h> 30 31 31 32 .text … … 41 42 .global memcpy_from_uspace_failover_address 42 43 .global memcpy_to_uspace_failover_address 44 .global early_putchar 43 45 44 46 userspace_asm: 45 46 # r3 = uspace_uarg 47 # r4 = stack 48 # r5 = entry 49 50 # disable interrupts 51 47 48 /* 49 * r3 = uspace_uarg 50 * r4 = stack 51 * r5 = entry 52 */ 53 54 /* Disable interrupts */ 55 52 56 mfmsr r31 53 57 rlwinm r31, r31, 0, 17, 15 54 58 mtmsr r31 55 59 56 # set entry point60 /* Set entry point */ 57 61 58 62 mtsrr0 r5 59 63 60 # set problem state, enable interrupts61 62 ori r31, r31, msr_pr63 ori r31, r31, msr_ee64 /* Set problem state, enable interrupts */ 65 66 ori r31, r31, MSR_PR 67 ori r31, r31, MSR_EE 64 68 mtsrr1 r31 65 69 66 # set stack70 /* Set stack */ 67 71 68 72 mr sp, r4 69 70 # %r6 is defined to hold pcb_ptr - set it to 071 73 74 /* %r6 is defined to hold pcb_ptr - set it to 0 */ 75 72 76 xor r6, r6, r6 73 77 74 # jump to userspace78 /* Jump to userspace */ 75 79 76 80 rfi … … 78 82 iret: 79 83 80 # disable interrupts84 /* Disable interrupts */ 81 85 82 86 mfmsr r31 … … 140 144 iret_syscall: 141 145 142 # reset decrementer143 146 /* Reset decrementer */ 147 144 148 li r31, 1000 145 149 mtdec r31 146 150 147 # disable interrupts151 /* Disable interrupts */ 148 152 149 153 mfmsr r31 … … 201 205 lwz r12, 156(sp) 202 206 lwz sp, 160(sp) 203 207 204 208 rfi 205 209 … … 213 217 memcpy_from_uspace: 214 218 memcpy_to_uspace: 215 219 216 220 srwi. r7, r5, 3 217 221 addi r6, r3, -4 218 222 addi r4, r4, -4 219 beq 2f223 beq 2f 220 224 221 225 andi. r0, r6, 3 … … 225 229 1: 226 230 227 lwz r7, 4(r4)228 lwzu r8, 8(r4)229 stw r7, 4(r6)230 stwu r8, 8(r6)231 bdnz 1b232 233 andi. r5, r5, 7231 lwz r7, 4(r4) 232 lwzu r8, 8(r4) 233 stw r7, 4(r6) 234 stwu r8, 8(r6) 235 bdnz 1b 236 237 andi. r5, r5, 7 234 238 235 239 2: 236 240 237 cmplwi 0, r5, 4238 blt 3f239 240 lwzu r0, 4(r4)241 addi r5, r5, -4242 stwu r0, 4(r6)241 cmplwi 0, r5, 4 242 blt 3f 243 244 lwzu r0, 4(r4) 245 addi r5, r5, -4 246 stwu r0, 4(r6) 243 247 244 248 3: 245 249 246 cmpwi 0, r5, 0247 beqlr248 mtctr r5249 addi r4, r4, 3250 addi r6, r6, 3250 cmpwi 0, r5, 0 251 beqlr 252 mtctr r5 253 addi r4, r4, 3 254 addi r6, r6, 3 251 255 252 256 4: 253 257 254 lbzu r0, 1(r4)255 stbu r0, 1(r6)256 bdnz 4b257 blr258 lbzu r0, 1(r4) 259 stbu r0, 1(r6) 260 bdnz 4b 261 blr 258 262 259 263 5: 260 264 261 subfic r0, r0, 4262 mtctr r0265 subfic r0, r0, 4 266 mtctr r0 263 267 264 268 6: 265 269 266 lbz r7, 4(r4)267 addi r4, r4, 1268 stb r7, 4(r6)269 addi r6, r6, 1270 bdnz 6b271 subf r5, r0, r5272 rlwinm. r7, r5, 32-3, 3, 31273 beq 2b274 mtctr r7275 b 1b270 lbz r7, 4(r4) 271 addi r4, r4, 1 272 stb r7, 4(r6) 273 addi r6, r6, 1 274 bdnz 6b 275 subf r5, r0, r5 276 rlwinm. r7, r5, 32-3, 3, 31 277 beq 2b 278 mtctr r7 279 b 1b 276 280 277 281 memcpy_from_uspace_failover_address: 278 282 memcpy_to_uspace_failover_address: 279 # return zero, failure283 /* Return zero, failure */ 280 284 xor r3, r3, r3 281 285 blr 286 287 early_putchar: 288 blr -
kernel/arch/ppc32/src/boot/boot.S
rfb150d78 r46c20c8 47 47 48 48 # r3 contains physical address of bootinfo_t 49 # r4 contains size of bootinfo_t50 51 cmpwi r4, 052 beq bootinfo_end53 49 54 50 addis r3, r3, 0x8000 55 56 lis r31, bootinfo@ha57 addi r31, r31, bootinfo@l # r31 = bootinfo58 59 bootinfo_loop:60 61 lwz r30, 0(r3)62 stw r30, 0(r31)63 64 addi r3, r3, 465 addi r31, r31, 466 subi r4, r4, 467 68 cmpwi r4, 069 bgt bootinfo_loop70 71 bootinfo_end:72 73 51 bl arch_pre_main 74 52 b main_bsp -
kernel/arch/ppc32/src/context.S
rfb150d78 r46c20c8 29 29 #include <arch/context_offset.h> 30 30 31 .text 31 .text 32 32 33 33 .global context_save_arch … … 46 46 li r3, 1 47 47 blr 48 48 49 49 context_restore_arch: 50 50 CONTEXT_RESTORE_ARCH_CORE r3 -
kernel/arch/ppc32/src/cpu/cpu.c
rfb150d78 r46c20c8 34 34 35 35 #include <arch/cpu.h> 36 #include <arch/cpuid.h>37 36 #include <cpu.h> 38 37 #include <arch.h> … … 45 44 void cpu_identify(void) 46 45 { 47 cpu_info_t info; 48 49 cpu_version(&info); 50 CPU->arch.version = info.version; 51 CPU->arch.revision = info.revision; 46 cpu_version(&CPU->arch); 52 47 } 53 48 54 void cpu_print_report(cpu_t * m)49 void cpu_print_report(cpu_t *cpu) 55 50 { 56 c har *name;51 const char *name; 57 52 58 switch ( m->arch.version) {53 switch (cpu->arch.version) { 59 54 case 8: 60 name = " (PowerPC 750)";55 name = "PowerPC 750"; 61 56 break; 62 57 case 9: 63 name = " (PowerPC 604e)";58 name = "PowerPC 604e"; 64 59 break; 65 60 case 0x81: 66 name = " (PowerPC 8260)";61 name = "PowerPC 8260"; 67 62 break; 68 63 case 0x8081: 69 name = " (PowerPC 826xA)";64 name = "PowerPC 826xA"; 70 65 break; 71 66 default: 72 name = " ";67 name = "unknown"; 73 68 } 74 69 75 printf("cpu%d: version=%d%s, revision=%d\n", m->id, m->arch.version, name, m->arch.revision); 70 printf("cpu%u: version=%" PRIu16" (%s), revision=%" PRIu16 "\n", cpu->id, 71 cpu->arch.version, name, cpu->arch.revision); 76 72 } 77 73 -
kernel/arch/ppc32/src/ddi/ddi.c
rfb150d78 r46c20c8 35 35 #include <ddi/ddi.h> 36 36 #include <proc/task.h> 37 #include < arch/types.h>37 #include <typedefs.h> 38 38 39 39 /** Enable I/O space range for task. … … 46 46 * 47 47 * @return 0 on success or an error code from errno.h. 48 * 48 49 */ 49 50 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) -
kernel/arch/ppc32/src/debug/stacktrace.c
rfb150d78 r46c20c8 35 35 #include <stacktrace.h> 36 36 #include <syscall/copy.h> 37 #include <arch/types.h>38 37 #include <typedefs.h> 39 38 40 bool kernel_frame_pointer_validate(uintptr_t fp) 39 #define FRAME_OFFSET_FP_PREV 0 40 #define FRAME_OFFSET_RA 1 41 42 bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx) 41 43 { 42 return false;44 return ctx->fp != 0; 43 45 } 44 46 45 bool kernel_frame_pointer_prev( uintptr_t fp, uintptr_t *prev)47 bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev) 46 48 { 47 return false; 49 uint32_t *stack = (void *) ctx->fp; 50 *prev = stack[FRAME_OFFSET_FP_PREV]; 51 return true; 48 52 } 49 53 50 bool kernel_return_address_get( uintptr_t fp, uintptr_t *ra)54 bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra) 51 55 { 52 return false; 56 uint32_t *stack = (void *) ctx->fp; 57 *ra = stack[FRAME_OFFSET_RA]; 58 return true; 53 59 } 54 60 55 bool uspace_ frame_pointer_validate(uintptr_t fp)61 bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx) 56 62 { 57 return false;63 return ctx->fp != 0; 58 64 } 59 65 60 bool uspace_frame_pointer_prev( uintptr_t fp, uintptr_t *prev)66 bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev) 61 67 { 62 return false; 68 return !copy_from_uspace((void *) prev, 69 (uint32_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev)); 63 70 } 64 71 65 bool uspace_return_address_get( uintptr_t fp, uintptr_t *ra)72 bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra) 66 73 { 67 return false; 74 return !copy_from_uspace((void *) ra, 75 (uint32_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra)); 68 76 } 69 77 -
kernel/arch/ppc32/src/debug/stacktrace_asm.S
rfb150d78 r46c20c8 27 27 # 28 28 29 #include <arch/asm/regname.h> 30 29 31 .text 30 32 … … 33 35 34 36 frame_pointer_get: 37 mr r3, sp 35 38 blr 36 39 37 40 program_counter_get: 41 mflr r3 38 42 blr -
kernel/arch/ppc32/src/drivers/pic.c
rfb150d78 r46c20c8 32 32 /** @file 33 33 */ 34 35 34 36 35 #include <arch/drivers/pic.h> … … 79 78 } 80 79 81 /** Return number of pending interrupt */ 82 int pic_get_pending(void) 80 /** Return number of pending interrupts 81 * 82 */ 83 uint8_t pic_get_pending(void) 83 84 { 84 85 if (pic) { 85 int pending;86 uint32_t pending; 86 87 87 88 pending = pic[PIC_PENDING_LOW]; 88 if (pending )89 if (pending != 0) 89 90 return fnzb32(pending); 90 91 91 92 pending = pic[PIC_PENDING_HIGH]; 92 if (pending )93 if (pending != 0) 93 94 return fnzb32(pending) + 32; 94 95 } 95 96 96 return -1;97 return 255; 97 98 } 98 99 -
kernel/arch/ppc32/src/exception.S
rfb150d78 r46c20c8 28 28 29 29 #include <arch/asm/regname.h> 30 #include <arch/cpu.h> 30 31 #include <arch/mm/page.h> 31 32 … … 34 35 .macro CONTEXT_STORE 35 36 36 # save R12 in SPRG1, backup CR in R1237 # save r12 in SPRG1, backup CR in r12 37 38 # save SP in SPRG2 38 39 39 40 mtsprg1 r12 40 41 mfcr r12 … … 288 289 289 290 mfmsr r12 290 ori r12, r12, ( msr_ir | msr_dr)@l291 ori r12, r12, (MSR_IR | MSR_DR)@l 291 292 mtsrr1 r12 292 293 … … 307 308 308 309 mfmsr r12 309 ori r12, r12, ( msr_ir | msr_dr)@l310 ori r12, r12, (MSR_IR | MSR_DR)@l 310 311 mtsrr1 r12 311 312 -
kernel/arch/ppc32/src/fpu_context.S
rfb150d78 r46c20c8 30 30 #include <arch/context_offset.h> 31 31 32 .text 32 .text 33 33 34 34 .global fpu_context_save … … 87 87 88 88 blr 89 89 90 90 fpu_context_restore: 91 91 // FPU_CONTEXT_LOAD r3 -
kernel/arch/ppc32/src/interrupt.c
rfb150d78 r46c20c8 36 36 #include <interrupt.h> 37 37 #include <arch/interrupt.h> 38 #include < arch/types.h>38 #include <typedefs.h> 39 39 #include <arch.h> 40 40 #include <time/clock.h> … … 44 44 #include <print.h> 45 45 46 47 46 void start_decrementer(void) 48 47 { 49 48 asm volatile ( 50 "mtdec %0\n" 51 : 52 : "r" (1000) 49 "mtdec %[dec]\n" 50 :: [dec] "r" (1000) 53 51 ); 54 52 } 55 53 54 void istate_decode(istate_t *istate) 55 { 56 printf("r0 =%#0" PRIx32 "\tr1 =%p\tr2 =%#0" PRIx32 "\n", 57 istate->r0, (void *) istate->sp, istate->r2); 58 59 printf("r3 =%#0" PRIx32 "\tr4 =%#0" PRIx32 "\tr5 =%#0" PRIx32 "\n", 60 istate->r3, istate->r4, istate->r5); 61 62 printf("r6 =%#0" PRIx32 "\tr7 =%#0" PRIx32 "\tr8 =%#0" PRIx32 "\n", 63 istate->r6, istate->r7, istate->r8); 64 65 printf("r9 =%#0" PRIx32 "\tr10=%#0" PRIx32 "\tr11=%#0" PRIx32 "\n", 66 istate->r9, istate->r10, istate->r11); 67 68 printf("r12=%#0" PRIx32 "\tr13=%#0" PRIx32 "\tr14=%#0" PRIx32 "\n", 69 istate->r12, istate->r13, istate->r14); 70 71 printf("r15=%#0" PRIx32 "\tr16=%#0" PRIx32 "\tr17=%#0" PRIx32 "\n", 72 istate->r15, istate->r16, istate->r17); 73 74 printf("r18=%#0" PRIx32 "\tr19=%#0" PRIx32 "\tr20=%#0" PRIx32 "\n", 75 istate->r18, istate->r19, istate->r20); 76 77 printf("r21=%#0" PRIx32 "\tr22=%#0" PRIx32 "\tr23=%#0" PRIx32 "\n", 78 istate->r21, istate->r22, istate->r23); 79 80 printf("r24=%#0" PRIx32 "\tr25=%#0" PRIx32 "\tr26=%#0" PRIx32 "\n", 81 istate->r24, istate->r25, istate->r26); 82 83 printf("r27=%#0" PRIx32 "\tr28=%#0" PRIx32 "\tr29=%#0" PRIx32 "\n", 84 istate->r27, istate->r28, istate->r29); 85 86 printf("r30=%#0" PRIx32 "\tr31=%#0" PRIx32 "\n", 87 istate->r30, istate->r31); 88 89 printf("cr =%#0" PRIx32 "\tpc =%p\tlr =%p\n", 90 istate->cr, (void *) istate->pc, (void *) istate->lr); 91 92 printf("ctr=%#0" PRIx32 "\txer=%#0" PRIx32 "\tdar=%#0" PRIx32 "\n", 93 istate->ctr, istate->xer, istate->dar); 94 95 printf("srr1=%p\n", (void *) istate->srr1); 96 } 56 97 57 /** Handler of external interrupts */ 58 static void exception_external(int n, istate_t *istate) 98 /** External interrupts handler 99 * 100 */ 101 static void exception_external(unsigned int n, istate_t *istate) 59 102 { 60 int inum;103 uint8_t inum; 61 104 62 while ((inum = pic_get_pending()) != -1) {105 while ((inum = pic_get_pending()) != 255) { 63 106 irq_t *irq = irq_dispatch_and_lock(inum); 64 107 if (irq) { … … 80 123 } 81 124 82 spinlock_unlock(&irq->lock);125 irq_spinlock_unlock(&irq->lock, false); 83 126 } else { 84 127 /* … … 86 129 */ 87 130 #ifdef CONFIG_DEBUG 88 printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum); 131 printf("cpu%u: spurious interrupt (inum=%" PRIu8 ")\n", 132 CPU->id, inum); 89 133 #endif 90 134 } … … 92 136 } 93 137 94 95 static void exception_decrementer(int n, istate_t *istate) 138 static void exception_decrementer(unsigned int n, istate_t *istate) 96 139 { 97 140 start_decrementer(); … … 99 142 } 100 143 101 102 144 /* Initialize basic tables for exception dispatching */ 103 145 void interrupt_init(void) 104 146 { 105 exc_register(VECTOR_DATA_STORAGE, "data_storage", pht_refill); 106 exc_register(VECTOR_INSTRUCTION_STORAGE, "instruction_storage", pht_refill); 107 exc_register(VECTOR_EXTERNAL, "external", exception_external); 108 exc_register(VECTOR_DECREMENTER, "timer", exception_decrementer); 147 exc_register(VECTOR_DATA_STORAGE, "data_storage", true, 148 pht_refill); 149 exc_register(VECTOR_INSTRUCTION_STORAGE, "instruction_storage", true, 150 pht_refill); 151 exc_register(VECTOR_EXTERNAL, "external", true, 152 exception_external); 153 exc_register(VECTOR_DECREMENTER, "timer", true, 154 exception_decrementer); 109 155 } 110 156 -
kernel/arch/ppc32/src/mm/as.c
rfb150d78 r46c20c8 55 55 void as_install_arch(as_t *as) 56 56 { 57 asid_t asid;58 57 uint32_t sr; 59 60 asid = as->asid;61 58 62 59 /* Lower 2 GB, user and supervisor access */ 63 for (sr = 0; sr < 8; sr++) { 64 asm volatile ( 65 "mtsrin %0, %1\n" 66 : 67 : "r" ((0x6000 << 16) + (asid << 4) + sr), "r" (sr << 28) 68 ); 69 } 60 for (sr = 0; sr < 8; sr++) 61 sr_set(0x6000, as->asid, sr); 70 62 71 63 /* Upper 2 GB, only supervisor access */ 72 for (sr = 8; sr < 16; sr++) { 73 asm volatile ( 74 "mtsrin %0, %1\n" 75 : 76 : "r" ((0x4000 << 16) + (asid << 4) + sr), "r" (sr << 28) 77 ); 78 } 64 for (sr = 8; sr < 16; sr++) 65 sr_set(0x4000, as->asid, sr); 79 66 } 80 67 -
kernel/arch/ppc32/src/mm/frame.c
rfb150d78 r46c20c8 27 27 */ 28 28 29 /** @addtogroup ppc32mm 29 /** @addtogroup ppc32mm 30 30 * @{ 31 31 */ … … 41 41 42 42 uintptr_t last_frame = 0; 43 memmap_t memmap; 43 44 44 45 void physmem_print(void) 45 46 { 46 unsigned int i;47 printf("[base ] [size ]\n"); 47 48 48 printf("Base Size\n"); 49 printf("---------- ----------\n"); 50 51 for (i = 0; i < bootinfo.memmap.count; i++) { 52 printf("%#10x %#10x\n", bootinfo.memmap.zones[i].start, 53 bootinfo.memmap.zones[i].size); 49 size_t i; 50 for (i = 0; i < memmap.cnt; i++) { 51 printf("%p %#0zx\n", memmap.zones[i].start, 52 memmap.zones[i].size); 54 53 } 55 54 } … … 59 58 pfn_t minconf = 2; 60 59 size_t i; 61 pfn_t start, conf;62 size_t size;63 60 64 for (i = 0; i < bootinfo.memmap.count; i++) { 65 start = ADDR2PFN(ALIGN_UP(bootinfo.memmap.zones[i].start, FRAME_SIZE)); 66 size = SIZE2FRAMES(ALIGN_DOWN(bootinfo.memmap.zones[i].size, FRAME_SIZE)); 61 for (i = 0; i < memmap.cnt; i++) { 62 /* To be safe, make the available zone possibly smaller */ 63 uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start, 64 FRAME_SIZE); 65 size_t new_size = ALIGN_DOWN(memmap.zones[i].size - 66 (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE); 67 67 68 if ((minconf < start) || (minconf >= start + size)) 69 conf = start; 68 pfn_t pfn = ADDR2PFN(new_start); 69 size_t count = SIZE2FRAMES(new_size); 70 71 pfn_t conf; 72 if ((minconf < pfn) || (minconf >= pfn + count)) 73 conf = pfn; 70 74 else 71 75 conf = minconf; 72 76 73 zone_create(start, size, conf, 0); 74 if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE)) 75 last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE); 77 zone_create(pfn, count, conf, 0); 78 79 if (last_frame < ALIGN_UP(new_start + new_size, FRAME_SIZE)) 80 last_frame = ALIGN_UP(new_start + new_size, FRAME_SIZE); 76 81 } 77 82 … … 81 86 82 87 /* Mark the Page Hash Table frames as unavailable */ 83 uint32_t sdr1; 84 asm volatile ( 85 "mfsdr1 %0\n" 86 : "=r" (sdr1) 87 ); 88 frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); // FIXME 88 uint32_t sdr1 = sdr1_get(); 89 90 // FIXME: compute size of PHT exactly 91 frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); 89 92 } 90 93 -
kernel/arch/ppc32/src/mm/page.c
rfb150d78 r46c20c8 45 45 } 46 46 47 48 47 uintptr_t hw_map(uintptr_t physaddr, size_t size) 49 48 { 50 49 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > 51 50 KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) 52 panic("Unable to map physical memory %p (% " PRIs "bytes).",53 physaddr, size);51 panic("Unable to map physical memory %p (%zu bytes).", 52 (void *) physaddr, size); 54 53 55 54 uintptr_t virtaddr = PA2KA(last_frame); 56 55 pfn_t i; 56 page_table_lock(AS_KERNEL, true); 57 57 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) 58 58 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), 59 59 physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); 60 page_table_unlock(AS_KERNEL, true); 60 61 61 62 last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); -
kernel/arch/ppc32/src/mm/tlb.c
rfb150d78 r46c20c8 45 45 46 46 static unsigned int seed = 10; 47 static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;48 47 static unsigned int seed_real 48 __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42; 49 49 50 50 /** Try to find PTE for faulting address 51 51 * 52 * Try to find PTE for faulting address. 53 * The as->lock must be held on entry to this function 54 * if lock is true. 55 * 56 * @param as Address space. 57 * @param lock Lock/unlock the address space. 58 * @param badvaddr Faulting virtual address. 59 * @param access Access mode that caused the fault. 60 * @param istate Pointer to interrupted state. 61 * @param pfrc Pointer to variable where as_page_fault() return code 62 * will be stored. 63 * @return PTE on success, NULL otherwise. 64 * 65 */ 66 static pte_t * 67 find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, 52 * @param as Address space. 53 * @param lock Lock/unlock the address space. 54 * @param badvaddr Faulting virtual address. 55 * @param access Access mode that caused the fault. 56 * @param istate Pointer to interrupted state. 57 * @param pfrc Pointer to variable where as_page_fault() return code 58 * will be stored. 59 * 60 * @return PTE on success, NULL otherwise. 61 * 62 */ 63 static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access, 68 64 istate_t *istate, int *pfrc) 69 65 { 66 ASSERT(mutex_locked(&as->lock)); 67 70 68 /* 71 69 * Check if the mapping exists in page tables. 72 */ 70 */ 73 71 pte_t *pte = page_mapping_find(as, badvaddr); 74 72 if ((pte) && (pte->present)) { … … 79 77 return pte; 80 78 } else { 81 int rc;82 83 79 /* 84 80 * Mapping not found in page tables. 85 81 * Resort to higher-level page fault handler. 86 82 */ 87 page_table_unlock(as, lock); 88 switch (rc = as_page_fault(badvaddr, access, istate)) { 83 page_table_unlock(as, true); 84 85 int rc = as_page_fault(badvaddr, access, istate); 86 switch (rc) { 89 87 case AS_PF_OK: 90 88 /* … … 92 90 * The mapping ought to be in place. 93 91 */ 94 page_table_lock(as, lock);92 page_table_lock(as, true); 95 93 pte = page_mapping_find(as, badvaddr); 96 94 ASSERT((pte) && (pte->present)); … … 98 96 return pte; 99 97 case AS_PF_DEFER: 100 page_table_lock(as, lock);98 page_table_lock(as, true); 101 99 *pfrc = rc; 102 100 return NULL; 103 101 case AS_PF_FAULT: 104 page_table_lock(as, lock);102 page_table_lock(as, true); 105 103 *pfrc = rc; 106 104 return NULL; 107 105 default: 108 106 panic("Unexpected rc (%d).", rc); 109 } 110 } 111 } 112 107 } 108 } 109 } 113 110 114 111 static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate) 115 112 { 116 char *symbol; 117 char *sym2; 118 119 symbol = symtab_fmt_name_lookup(istate->pc); 120 sym2 = symtab_fmt_name_lookup(istate->lr); 121 122 fault_if_from_uspace(istate, 123 "PHT Refill Exception on %p.", badvaddr); 124 panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr, 125 istate->pc, symbol, sym2); 126 } 127 113 fault_if_from_uspace(istate, "PHT Refill Exception on %p.", 114 (void *) badvaddr); 115 panic_memtrap(istate, PF_ACCESS_UNKNOWN, badvaddr, 116 "PHT Refill Exception."); 117 } 128 118 129 119 static void pht_insert(const uintptr_t vaddr, const pte_t *pte) … … 132 122 uint32_t api = (vaddr >> 22) & 0x3f; 133 123 134 uint32_t vsid; 135 asm volatile ( 136 "mfsrin %0, %1\n" 137 : "=r" (vsid) 138 : "r" (vaddr) 139 ); 140 141 uint32_t sdr1; 142 asm volatile ( 143 "mfsdr1 %0\n" 144 : "=r" (sdr1) 145 ); 124 uint32_t vsid = sr_get(vaddr); 125 uint32_t sdr1 = sdr1_get(); 126 127 // FIXME: compute size of PHT exactly 146 128 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 147 129 … … 218 200 } 219 201 220 221 202 /** Process Instruction/Data Storage Exception 222 203 * … … 225 206 * 226 207 */ 227 void pht_refill(int n, istate_t *istate) 228 { 208 void pht_refill(unsigned int n, istate_t *istate) 209 { 210 as_t *as = (AS == NULL) ? AS_KERNEL : AS; 229 211 uintptr_t badvaddr; 230 pte_t *pte;231 int pfrc;232 as_t *as;233 bool lock;234 235 if (AS == NULL) {236 as = AS_KERNEL;237 lock = false;238 } else {239 as = AS;240 lock = true;241 }242 212 243 213 if (n == VECTOR_DATA_STORAGE) … … 245 215 else 246 216 badvaddr = istate->pc; 247 248 page_table_lock(as, lock); 249 250 pte = find_mapping_and_check(as, lock, badvaddr, 217 218 page_table_lock(as, true); 219 220 int pfrc; 221 pte_t *pte = find_mapping_and_check(as, badvaddr, 251 222 PF_ACCESS_READ /* FIXME */, istate, &pfrc); 223 252 224 if (!pte) { 253 225 switch (pfrc) { … … 260 232 * or copy_to_uspace(). 261 233 */ 262 page_table_unlock(as, lock);234 page_table_unlock(as, true); 263 235 return; 264 236 default: … … 267 239 } 268 240 269 pte->accessed = 1; /* Record access to PTE */ 241 /* Record access to PTE */ 242 pte->accessed = 1; 270 243 pht_insert(badvaddr, pte); 271 244 272 page_table_unlock(as, lock);245 page_table_unlock(as, true); 273 246 return; 274 247 275 248 fail: 276 page_table_unlock(as, lock);249 page_table_unlock(as, true); 277 250 pht_refill_fail(badvaddr, istate); 278 251 } 279 280 252 281 253 /** Process Instruction/Data Storage Exception in Real Mode … … 285 257 * 286 258 */ 287 bool pht_refill_real( int n, istate_t *istate)259 bool pht_refill_real(unsigned int n, istate_t *istate) 288 260 { 289 261 uintptr_t badvaddr; … … 294 266 badvaddr = istate->pc; 295 267 296 uint32_t physmem; 297 asm volatile ( 298 "mfsprg3 %0\n" 299 : "=r" (physmem) 300 ); 268 uint32_t physmem = physmem_top(); 301 269 302 270 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) … … 306 274 uint32_t api = (badvaddr >> 22) & 0x3f; 307 275 308 uint32_t vsid; 309 asm volatile ( 310 "mfsrin %0, %1\n" 311 : "=r" (vsid) 312 : "r" (badvaddr) 313 ); 314 315 uint32_t sdr1; 316 asm volatile ( 317 "mfsdr1 %0\n" 318 : "=r" (sdr1) 319 ); 276 uint32_t vsid = sr_get(badvaddr); 277 uint32_t sdr1 = sdr1_get(); 278 279 // FIXME: compute size of PHT exactly 320 280 phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); 321 281 … … 399 359 } 400 360 401 402 361 /** Process ITLB/DTLB Miss Exception in Real Mode 403 362 * 404 363 * 405 364 */ 406 void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) 365 void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi, 366 ptelo_t ptelo, istate_t *istate) 407 367 { 408 368 uint32_t badvaddr = tlbmiss & 0xfffffffc; 409 410 uint32_t physmem; 411 asm volatile ( 412 "mfsprg3 %0\n" 413 : "=r" (physmem) 414 ); 369 uint32_t physmem = physmem_top(); 415 370 416 371 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) … … 423 378 uint32_t index = 0; 424 379 asm volatile ( 425 "mtspr 981, % 0\n"426 "mtspr 982, % 1\n"427 "tlbld % 2\n"428 "tlbli % 2\n"429 : "=r" (index)430 : "r" (ptehi),431 "r" (ptelo)380 "mtspr 981, %[ptehi]\n" 381 "mtspr 982, %[ptelo]\n" 382 "tlbld %[index]\n" 383 "tlbli %[index]\n" 384 : [index] "=r" (index) 385 : [ptehi] "r" (ptehi), 386 [ptelo] "r" (ptelo) 432 387 ); 433 388 } 434 389 435 436 390 void tlb_arch_init(void) 437 391 { … … 439 393 } 440 394 441 442 395 void tlb_invalidate_all(void) 443 396 { 444 397 uint32_t index; 398 445 399 asm volatile ( 446 "li % 0, 0\n"400 "li %[index], 0\n" 447 401 "sync\n" 448 402 449 403 ".rept 64\n" 450 " tlbie %0\n"451 " addi %0, %0, 0x1000\n"404 " tlbie %[index]\n" 405 " addi %[index], %[index], 0x1000\n" 452 406 ".endr\n" 453 407 … … 455 409 "tlbsync\n" 456 410 "sync\n" 457 : "=r" (index)411 : [index] "=r" (index) 458 412 ); 459 413 } 460 414 461 462 415 void tlb_invalidate_asid(asid_t asid) 463 416 { 464 uint32_t sdr1; 465 asm volatile ( 466 "mfsdr1 %0\n" 467 : "=r" (sdr1) 468 ); 417 uint32_t sdr1 = sdr1_get(); 418 419 // FIXME: compute size of PHT exactly 469 420 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 470 421 471 uint32_t i;422 size_t i; 472 423 for (i = 0; i < 8192; i++) { 473 424 if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && … … 475 426 phte[i].v = 0; 476 427 } 428 477 429 tlb_invalidate_all(); 478 430 } 479 480 431 481 432 void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) … … 485 436 } 486 437 487 488 438 #define PRINT_BAT(name, ureg, lreg) \ 489 439 asm volatile ( \ 490 "mfspr %0," #ureg "\n" \ 491 "mfspr %1," #lreg "\n" \ 492 : "=r" (upper), "=r" (lower) \ 440 "mfspr %[upper], " #ureg "\n" \ 441 "mfspr %[lower], " #lreg "\n" \ 442 : [upper] "=r" (upper), \ 443 [lower] "=r" (lower) \ 493 444 ); \ 445 \ 494 446 mask = (upper & 0x1ffc) >> 2; \ 495 447 if (upper & 3) { \ 496 448 uint32_t tmp = mask; \ 497 449 length = 128; \ 450 \ 498 451 while (tmp) { \ 499 452 if ((tmp & 1) == 0) { \ … … 506 459 } else \ 507 460 length = 0; \ 508 printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \ 509 sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \ 510 lower & 0xffff0000, length, mask, \ 461 \ 462 printf(name ": page=%#0" PRIx32 " frame=%#0" PRIx32 \ 463 " length=%#0" PRIx32 " KB (mask=%#0" PRIx32 ")%s%s\n", \ 464 upper & UINT32_C(0xffff0000), lower & UINT32_C(0xffff0000), \ 465 length, mask, \ 511 466 ((upper >> 1) & 1) ? " supervisor" : "", \ 512 467 (upper & 1) ? " user" : ""); 513 468 514 515 469 void tlb_print(void) 516 470 { … … 518 472 519 473 for (sr = 0; sr < 16; sr++) { 520 uint32_t vsid; 521 asm volatile ( 522 "mfsrin %0, %1\n" 523 : "=r" (vsid) 524 : "r" (sr << 28) 525 ); 526 printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr, 527 sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, 474 uint32_t vsid = sr_get(sr << 28); 475 476 printf("sr[%02" PRIu32 "]: vsid=%#0" PRIx32 " (asid=%" PRIu32 ")" 477 "%s%s\n", sr, vsid & UINT32_C(0x00ffffff), 478 (vsid & UINT32_C(0x00ffffff)) >> 4, 528 479 ((vsid >> 30) & 1) ? " supervisor" : "", 529 480 ((vsid >> 29) & 1) ? " user" : ""); -
kernel/arch/ppc32/src/ppc32.c
rfb150d78 r46c20c8 53 53 #include <align.h> 54 54 #include <macros.h> 55 #include <str ing.h>55 #include <str.h> 56 56 #include <print.h> 57 57 … … 65 65 66 66 /** Performs ppc32-specific initialization before main_bsp() is called. */ 67 void arch_pre_main(void) 68 { 69 init.cnt = bootinfo.taskmap.count; 70 71 uint32_t i; 72 73 for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { 74 init.tasks[i].addr = bootinfo.taskmap.tasks[i].addr; 75 init.tasks[i].size = bootinfo.taskmap.tasks[i].size; 67 void arch_pre_main(bootinfo_t *bootinfo) 68 { 69 /* Copy tasks map. */ 70 init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); 71 size_t i; 72 for (i = 0; i < init.cnt; i++) { 73 init.tasks[i].addr = (uintptr_t) bootinfo->taskmap.tasks[i].addr; 74 init.tasks[i].size = bootinfo->taskmap.tasks[i].size; 76 75 str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN, 77 bootinfo.taskmap.tasks[i].name); 76 bootinfo->taskmap.tasks[i].name); 77 } 78 79 /* Copy physical memory map. */ 80 memmap.total = bootinfo->memmap.total; 81 memmap.cnt = min(bootinfo->memmap.cnt, MEMMAP_MAX_RECORDS); 82 for (i = 0; i < memmap.cnt; i++) { 83 memmap.zones[i].start = bootinfo->memmap.zones[i].start; 84 memmap.zones[i].size = bootinfo->memmap.zones[i].size; 78 85 } 79 86 80 87 /* Copy boot allocations info. */ 81 ballocs.base = bootinfo.ballocs.base; 82 ballocs.size = bootinfo.ballocs.size; 83 84 ofw_tree_init(bootinfo.ofw_root); 88 ballocs.base = bootinfo->ballocs.base; 89 ballocs.size = bootinfo->ballocs.size; 90 91 /* Copy OFW tree. */ 92 ofw_tree_init(bootinfo->ofw_root); 85 93 } 86 94 … … 193 201 pic_init(assigned_address[0].addr, PAGE_SIZE, &pic_cir, 194 202 &pic_cir_arg); 195 203 196 204 #ifdef CONFIG_MAC_KBD 197 205 uintptr_t pa = assigned_address[0].addr + 0x16000; … … 215 223 } 216 224 } 217 225 218 226 /* 219 227 * This is the necessary evil until the userspace driver is entirely … … 276 284 { 277 285 // TODO 278 while ( 1);286 while (true); 279 287 } 280 288 -
kernel/arch/ppc32/src/proc/scheduler.c
rfb150d78 r46c20c8 39 39 #include <arch.h> 40 40 41 /** Perform ppc32 specific tasks needed before the new task is run. */ 41 /** Perform ppc32 specific tasks needed before the new task is run. 42 * 43 */ 42 44 void before_task_runs_arch(void) 43 45 { 44 46 } 45 47 46 /** Perform ppc32 specific tasks needed before the new thread is scheduled. */ 48 /** Perform ppc32 specific tasks needed before the new thread is scheduled. 49 * 50 */ 47 51 void before_thread_runs_arch(void) 48 52 { 49 53 tlb_invalidate_all(); 54 50 55 asm volatile ( 51 "mtsprg0 %0\n" 52 : 53 : "r" (KA2PA(&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA])) 56 "mtsprg0 %[ksp]\n" 57 :: [ksp] "r" (KA2PA(&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA])) 54 58 ); 55 59 }
Note:
See TracChangeset
for help on using the changeset viewer.
