Changeset a35b458 in mainline for kernel/arch/mips32/src
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- kernel/arch/mips32/src
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/mips32/src/asm.S
r3061bc1 ra35b458 62 62 FUNCTION_BEGIN(memcpy_to_uspace) 63 63 move $t2, $a0 /* save dst */ 64 64 65 65 addiu $v0, $a1, 3 66 66 li $v1, -4 /* 0xfffffffffffffffc */ … … 68 68 beq $a1, $v0, 3f 69 69 move $t0, $a0 70 70 71 71 0: 72 72 beq $a2, $zero, 2f 73 73 move $a3, $zero 74 74 75 75 1: 76 76 addu $v0, $a1, $a3 … … 80 80 bne $a3, $a2, 1b 81 81 sb $a0, 0($v1) 82 82 83 83 2: 84 84 jr $ra 85 85 move $v0, $t2 86 86 87 87 3: 88 88 addiu $v0, $a0, 3 … … 90 90 bne $a0, $v0, 0b 91 91 srl $t1, $a2, 2 92 92 93 93 beq $t1, $zero, 5f 94 94 move $a3, $zero 95 95 96 96 move $a3, $zero 97 97 move $a0, $zero 98 98 99 99 4: 100 100 addu $v0, $a1, $a0 … … 105 105 bne $a3, $t1, 4b 106 106 addiu $a0, $a0, 4 107 107 108 108 5: 109 109 andi $a2, $a2, 0x3 110 110 beq $a2, $zero, 2b 111 111 nop 112 112 113 113 sll $v0, $a3, 2 114 114 addu $t1, $v0, $t0 115 115 move $a3, $zero 116 116 addu $t0, $v0, $a1 117 117 118 118 6: 119 119 addu $v0, $t0, $a3 … … 123 123 bne $a3, $a2, 6b 124 124 sb $a0, 0($v1) 125 125 126 126 jr $ra 127 127 move $v0, $t2 … … 188 188 fpu_gp_save 30, $a0 189 189 fpu_gp_save 31, $a0 190 190 191 191 fpu_ct_save 1, $a0 192 192 fpu_ct_save 2, $a0 … … 259 259 fpu_gp_restore 30, $a0 260 260 fpu_gp_restore 31, $a0 261 261 262 262 fpu_ct_restore 1, $a0 263 263 fpu_ct_restore 2, $a0 -
kernel/arch/mips32/src/context.S
r3061bc1 ra35b458 47 47 sw $s8, CONTEXT_OFFSET_S8($a0) 48 48 sw $gp, CONTEXT_OFFSET_GP($a0) 49 49 50 50 sw $ra, CONTEXT_OFFSET_PC($a0) 51 51 sw $sp, CONTEXT_OFFSET_SP($a0) 52 52 53 53 # context_save returns 1 54 54 j $31 … … 67 67 lw $s8, CONTEXT_OFFSET_S8($a0) 68 68 lw $gp, CONTEXT_OFFSET_GP($a0) 69 69 70 70 lw $ra, CONTEXT_OFFSET_PC($a0) 71 71 lw $sp, CONTEXT_OFFSET_SP($a0) 72 72 73 73 # context_restore returns 0 74 74 j $31 -
kernel/arch/mips32/src/debug/stacktrace.c
r3061bc1 ra35b458 157 157 * We have a candidate for frame pointer. 158 158 */ 159 159 160 160 /* Seek to the end of this function. */ 161 161 for (cur = inst + 1; !IS_JR_RA(*cur); cur++) … … 170 170 continue; 171 171 } 172 172 173 173 if (IS_JR_RA(*inst)) { 174 174 if (!ctx->istate) … … 189 189 } while ((!IS_ADDIU_SP_SP_IMM(*inst) && !IS_ADDI_SP_SP_IMM(*inst)) || 190 190 (IMM_GET(*inst) >= 0)); 191 191 192 192 /* 193 193 * We are at the instruction which allocates the space for the current … … 210 210 if (base == SP || (has_fp && base == fp)) { 211 211 uint32_t *addr = (void *) (ctx->fp + offset); 212 212 213 213 if (offset % 4 != 0) 214 214 return false; -
kernel/arch/mips32/src/debugger.c
r3061bc1 ra35b458 138 138 { 139 139 unsigned int i; 140 140 141 141 for (i = 0; jmpinstr[i].andmask; i++) { 142 142 if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value) 143 143 return true; 144 144 } 145 145 146 146 return false; 147 147 } … … 158 158 return 1; 159 159 } 160 160 161 161 irq_spinlock_lock(&bkpoint_lock, true); 162 162 163 163 /* Check, that the breakpoints do not conflict */ 164 164 unsigned int i; … … 176 176 return 0; 177 177 } 178 179 } 180 178 179 } 180 181 181 bpinfo_t *cur = NULL; 182 182 183 183 for (i = 0; i < BKPOINTS_MAX; i++) { 184 184 if (!breakpoints[i].address) { … … 187 187 } 188 188 } 189 189 190 190 if (!cur) { 191 191 printf("Too many breakpoints.\n"); … … 193 193 return 0; 194 194 } 195 195 196 196 printf("Adding breakpoint on address %p\n", (void *) argv->intval); 197 197 198 198 cur->address = (uintptr_t) argv->intval; 199 199 cur->instruction = ((sysarg_t *) cur->address)[0]; … … 205 205 cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval; 206 206 } 207 207 208 208 if (is_jump(cur->instruction)) 209 209 cur->flags |= BKPOINT_ONESHOT; 210 210 211 211 cur->counter = 0; 212 212 213 213 /* Set breakpoint */ 214 214 *((sysarg_t *) cur->address) = 0x0d; 215 215 smc_coherence(cur->address); 216 216 217 217 irq_spinlock_unlock(&bkpoint_lock, true); 218 218 219 219 return 1; 220 220 } … … 229 229 return 0; 230 230 } 231 231 232 232 irq_spinlock_lock(&bkpoint_lock, true); 233 233 234 234 bpinfo_t *cur = &breakpoints[argv->intval]; 235 235 if (!cur->address) { … … 238 238 return 0; 239 239 } 240 240 241 241 if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) { 242 242 printf("Cannot remove one-shot breakpoint in-progress\n"); … … 244 244 return 0; 245 245 } 246 246 247 247 ((uint32_t *) cur->address)[0] = cur->instruction; 248 248 smc_coherence(((uint32_t *) cur->address)[0]); 249 249 ((uint32_t *) cur->address)[1] = cur->nextinstruction; 250 250 smc_coherence(((uint32_t *) cur->address)[1]); 251 251 252 252 cur->address = (uintptr_t) NULL; 253 253 254 254 irq_spinlock_unlock(&bkpoint_lock, true); 255 255 return 1; … … 262 262 { 263 263 unsigned int i; 264 264 265 265 printf("[nr] [count] [address ] [inprog] [oneshot] [funccall] [in symbol\n"); 266 266 267 267 for (i = 0; i < BKPOINTS_MAX; i++) { 268 268 if (breakpoints[i].address) { 269 269 const char *symbol = symtab_fmt_name_lookup( 270 270 breakpoints[i].address); 271 271 272 272 printf("%-4u %7zu %p %-8s %-9s %-10s %s\n", i, 273 273 breakpoints[i].counter, (void *) breakpoints[i].address, … … 278 278 } 279 279 } 280 280 281 281 return 1; 282 282 } … … 290 290 { 291 291 unsigned int i; 292 292 293 293 for (i = 0; i < BKPOINTS_MAX; i++) 294 294 breakpoints[i].address = (uintptr_t) NULL; 295 295 296 296 #ifdef CONFIG_KCONSOLE 297 297 cmd_initialize(&bkpts_info); … … 299 299 log(LF_OTHER, LVL_WARN, "Cannot register command %s", 300 300 bkpts_info.name); 301 301 302 302 cmd_initialize(&delbkpt_info); 303 303 if (!cmd_register(&delbkpt_info)) 304 304 log(LF_OTHER, LVL_WARN, "Cannot register command %s", 305 305 delbkpt_info.name); 306 306 307 307 cmd_initialize(&addbkpt_info); 308 308 if (!cmd_register(&addbkpt_info)) 309 309 log(LF_OTHER, LVL_WARN, "Cannot register command %s", 310 310 addbkpt_info.name); 311 311 312 312 cmd_initialize(&addbkpte_info); 313 313 if (!cmd_register(&addbkpte_info)) … … 331 331 if (cp0_cause_read() & 0x80000000) 332 332 panic("Breakpoint in branch delay slot not supported."); 333 333 334 334 irq_spinlock_lock(&bkpoint_lock, false); 335 335 336 336 bpinfo_t *cur = NULL; 337 337 uintptr_t fireaddr = istate->epc; 338 338 unsigned int i; 339 339 340 340 for (i = 0; i < BKPOINTS_MAX; i++) { 341 341 /* Normal breakpoint */ … … 345 345 break; 346 346 } 347 347 348 348 /* Reinst only breakpoint */ 349 349 if ((breakpoints[i].flags & BKPOINT_REINST) && … … 353 353 } 354 354 } 355 355 356 356 if (cur) { 357 357 if (cur->flags & BKPOINT_REINST) { … … 359 359 ((uint32_t *) cur->address)[0] = 0x0d; 360 360 smc_coherence(((uint32_t *)cur->address)[0]); 361 361 362 362 /* Return back the second */ 363 363 ((uint32_t *) cur->address)[1] = cur->nextinstruction; 364 364 smc_coherence(((uint32_t *) cur->address)[1]); 365 365 366 366 cur->flags &= ~BKPOINT_REINST; 367 367 irq_spinlock_unlock(&bkpoint_lock, false); 368 368 return; 369 369 } 370 370 371 371 if (cur->flags & BKPOINT_INPROG) 372 372 printf("Warning: breakpoint recursion\n"); 373 373 374 374 if (!(cur->flags & BKPOINT_FUNCCALL)) { 375 375 printf("***Breakpoint %u: %p in %s.\n", i, … … 377 377 symtab_fmt_name_lookup(fireaddr)); 378 378 } 379 379 380 380 /* Return first instruction back */ 381 381 ((uint32_t *)cur->address)[0] = cur->instruction; … … 392 392 (void *) fireaddr, 393 393 symtab_fmt_name_lookup(fireaddr)); 394 394 395 395 /* Move on to next instruction */ 396 396 istate->epc += 4; 397 397 } 398 398 399 399 if (cur) 400 400 cur->counter++; 401 401 402 402 if (cur && (cur->flags & BKPOINT_FUNCCALL)) { 403 403 /* Allow zero bkfunc, just for counting */ … … 414 414 atomic_set(&haltstate, 1); 415 415 irq_spinlock_unlock(&bkpoint_lock, false); 416 416 417 417 kconsole("debug", "Debug console ready.\n", false); 418 418 419 419 irq_spinlock_lock(&bkpoint_lock, false); 420 420 atomic_set(&haltstate, 0); 421 421 #endif 422 422 } 423 423 424 424 if ((cur) && (cur->address == fireaddr) 425 425 && ((cur->flags & BKPOINT_INPROG))) { … … 427 427 if ((cur->flags & BKPOINT_ONESHOT)) 428 428 cur->address = (uintptr_t) NULL; 429 429 430 430 /* Remove in-progress flag */ 431 431 cur->flags &= ~BKPOINT_INPROG; 432 432 } 433 433 434 434 irq_spinlock_unlock(&bkpoint_lock, false); 435 435 } -
kernel/arch/mips32/src/exception.c
r3061bc1 ra35b458 77 77 "lo =%#010" PRIx32 "\thi =%#010" PRIx32 "\n", 78 78 istate->epc, istate->status, istate->lo, istate->hi); 79 79 80 80 log_printf("a0 =%#010" PRIx32 "\ta1 =%#010" PRIx32 "\t" 81 81 "a2 =%#010" PRIx32 "\ta3 =%#010" PRIx32 "\n", 82 82 istate->a0, istate->a1, istate->a2, istate->a3); 83 83 84 84 log_printf("t0 =%#010" PRIx32 "\tt1 =%#010" PRIx32 "\t" 85 85 "t2 =%#010" PRIx32 "\tt3 =%#010" PRIx32 "\n", 86 86 istate->t0, istate->t1, istate->t2, istate->t3); 87 87 88 88 log_printf("t4 =%#010" PRIx32 "\tt5 =%#010" PRIx32 "\t" 89 89 "t6 =%#010" PRIx32 "\tt7 =%#010" PRIx32 "\n", 90 90 istate->t4, istate->t5, istate->t6, istate->t7); 91 91 92 92 log_printf("t8 =%#010" PRIx32 "\tt9 =%#010" PRIx32 "\t" 93 93 "v0 =%#010" PRIx32 "\tv1 =%#010" PRIx32 "\n", 94 94 istate->t8, istate->t9, istate->v0, istate->v1); 95 95 96 96 log_printf("s0 =%#010" PRIx32 "\ts1 =%#010" PRIx32 "\t" 97 97 "s2 =%#010" PRIx32 "\ts3 =%#010" PRIx32 "\n", 98 98 istate->s0, istate->s1, istate->s2, istate->s3); 99 99 100 100 log_printf("s4 =%#010" PRIx32 "\ts5 =%#010" PRIx32 "\t" 101 101 "s6 =%#010" PRIx32 "\ts7 =%#010" PRIx32 "\n", 102 102 istate->s4, istate->s5, istate->s6, istate->s7); 103 103 104 104 log_printf("s8 =%#010" PRIx32 "\tat =%#010" PRIx32 "\t" 105 105 "kt0=%#010" PRIx32 "\tkt1=%#010" PRIx32 "\n", 106 106 istate->s8, istate->at, istate->kt0, istate->kt1); 107 107 108 108 log_printf("sp =%#010" PRIx32 "\tra =%#010" PRIx32 "\t" 109 109 "gp =%#010" PRIx32 "\n", … … 171 171 ip = (cp0_cause_read() & cp0_cause_ip_mask) >> cp0_cause_ip_shift; 172 172 im = (cp0_status_read() & cp0_status_im_mask) >> cp0_status_im_shift; 173 173 174 174 unsigned int i; 175 175 for (i = 0; i < 8; i++) { … … 212 212 { 213 213 unsigned int i; 214 214 215 215 /* Clear exception table */ 216 216 for (i = 0; i < IVT_ITEMS; i++) 217 217 exc_register(i, "undef", false, 218 218 (iroutine_t) unhandled_exception); 219 219 220 220 exc_register(EXC_Bp, "bkpoint", true, 221 221 (iroutine_t) breakpoint_exception); … … 230 230 exc_register(EXC_Int, "interrupt", true, 231 231 (iroutine_t) interrupt_exception); 232 232 233 233 #ifdef CONFIG_FPU_LAZY 234 234 exc_register(EXC_CpU, "cpunus", true, 235 235 (iroutine_t) cpuns_exception); 236 236 #endif 237 237 238 238 exc_register(EXC_Sys, "syscall", true, 239 239 (iroutine_t) syscall_exception); -
kernel/arch/mips32/src/interrupt.c
r3061bc1 ra35b458 132 132 /* Count overflow detected */ 133 133 count_hi++; 134 134 135 135 lastcount = cp0_count_read(); 136 136 137 137 unsigned long drift = cp0_count_read() - nextcount; 138 138 while (drift > cp0_compare_value) { … … 140 140 CPU->missed_clock_ticks++; 141 141 } 142 142 143 143 nextcount = cp0_count_read() + cp0_compare_value - drift; 144 144 cp0_compare_write(nextcount); 145 145 146 146 /* 147 147 * We are holding a lock which prevents preemption. … … 151 151 clock(); 152 152 irq_spinlock_lock(&irq->lock, false); 153 153 154 154 if (virtual_timer_fnc != NULL) 155 155 virtual_timer_fnc(); … … 172 172 { 173 173 irq_init(IRQ_COUNT, IRQ_COUNT); 174 174 175 175 irq_initialize(&timer_irq); 176 176 timer_irq.inr = TIMER_IRQ; … … 178 178 timer_irq.handler = timer_irq_handler; 179 179 irq_register(&timer_irq); 180 180 181 181 timer_start(); 182 182 cp0_unmask_int(TIMER_IRQ); 183 183 184 184 #ifdef MACHINE_msim 185 185 irq_initialize(&dorder_irq); … … 188 188 dorder_irq.handler = dorder_irq_handler; 189 189 irq_register(&dorder_irq); 190 190 191 191 cp0_unmask_int(DORDER_IRQ); 192 192 #endif -
kernel/arch/mips32/src/mips32.c
r3061bc1 ra35b458 86 86 { 87 87 init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); 88 88 89 89 size_t i; 90 90 for (i = 0; i < init.cnt; i++) { … … 94 94 bootinfo->tasks[i].name); 95 95 } 96 96 97 97 for (i = 0; i < CPUMAP_MAX_RECORDS; i++) { 98 98 if ((bootinfo->cpumap & (1 << i)) != 0) … … 112 112 /* It is not assumed by default */ 113 113 interrupts_disable(); 114 114 115 115 /* Initialize dispatch table */ 116 116 exception_init(); … … 123 123 memcpy(CACHE_EXC, (char *) cache_error_entry, EXCEPTION_JUMP_SIZE); 124 124 smc_coherence_block(CACHE_EXC, EXCEPTION_JUMP_SIZE); 125 125 126 126 /* 127 127 * Switch to BEV normal level so that exception vectors point to the … … 130 130 cp0_status_write(cp0_status_read() & 131 131 ~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit)); 132 132 133 133 /* 134 134 * Mask all interrupts 135 135 */ 136 136 cp0_mask_all_int(); 137 137 138 138 debugger_init(); 139 139 } … … 171 171 (uintptr_t) kernel_uarg->uspace_uarg, 172 172 (uintptr_t) kernel_uarg->uspace_entry); 173 173 174 174 while (1); 175 175 } -
kernel/arch/mips32/src/mm/frame.c
r3061bc1 ra35b458 82 82 if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH)) 83 83 return false; 84 84 85 85 /* MSIM device (dkeyboard) */ 86 86 if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH)) … … 92 92 return false; 93 93 #endif 94 94 95 95 return true; 96 96 } … … 108 108 if ((frame << ZERO_PAGE_WIDTH) < KA2PA(config.base)) 109 109 return false; 110 110 111 111 /* Kernel */ 112 112 if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, 113 113 KA2PA(config.base), config.kernel_size)) 114 114 return false; 115 115 116 116 /* Kernel stack */ 117 117 if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, 118 118 KA2PA(config.stack_base), config.stack_size)) 119 119 return false; 120 120 121 121 /* Init tasks */ 122 122 bool safe = true; … … 128 128 break; 129 129 } 130 130 131 131 return safe; 132 132 } … … 161 161 ZONE_AVAILABLE | ZONE_HIGHMEM); 162 162 } 163 163 164 164 if (phys_regions_count < MAX_REGIONS) { 165 165 phys_regions[phys_regions_count].start = first; … … 182 182 { 183 183 ipl_t ipl = interrupts_disable(); 184 184 185 185 /* Clear and initialize TLB */ 186 186 cp0_pagemask_write(ZERO_PAGE_MASK); … … 194 194 tlbwi(); 195 195 } 196 196 197 197 pfn_t start_frame = 0; 198 198 pfn_t frame; 199 199 bool avail = true; 200 200 201 201 /* Walk through all 1 MB frames */ 202 202 for (frame = 0; frame < ZERO_FRAMES; frame++) { … … 211 211 tlb_prepare_entry_lo(&lo1, false, false, false, false, 0); 212 212 tlb_prepare_entry_hi(&hi, ZERO_PAGE_ASID, ZERO_PAGE_ADDR); 213 213 214 214 cp0_pagemask_write(ZERO_PAGE_MASK); 215 215 cp0_entry_lo0_write(lo0.value); … … 218 218 cp0_index_write(ZERO_PAGE_TLBI); 219 219 tlbwi(); 220 220 221 221 ZERO_PAGE_VALUE = 0; 222 222 if (ZERO_PAGE_VALUE != 0) … … 229 229 } 230 230 } 231 231 232 232 if (!avail) { 233 233 frame_add_region(start_frame, frame, true); … … 236 236 } 237 237 } 238 238 239 239 frame_add_region(start_frame, frame, true); 240 240 241 241 /* Blacklist interrupt vector frame */ 242 242 frame_mark_unavailable(0, 1); … … 267 267 frame_mark_unavailable(0, 1024 * 1024 / FRAME_SIZE); 268 268 #endif 269 269 270 270 /* Cleanup */ 271 271 cp0_pagemask_write(ZERO_PAGE_MASK); … … 275 275 cp0_index_write(ZERO_PAGE_TLBI); 276 276 tlbwi(); 277 277 278 278 interrupts_restore(ipl); 279 279 } … … 286 286 { 287 287 printf("[base ] [size ]\n"); 288 288 289 289 size_t i; 290 290 for (i = 0; i < phys_regions_count; i++) { -
kernel/arch/mips32/src/mm/tlb.c
r3061bc1 ra35b458 76 76 77 77 /* Clear and initialize TLB. */ 78 78 79 79 for (i = 0; i < TLB_ENTRY_COUNT; i++) { 80 80 cp0_index_write(i); 81 81 tlbwi(); 82 82 } 83 83 84 84 /* 85 85 * The kernel is going to make use of some wired … … 98 98 uintptr_t badvaddr; 99 99 pte_t pte; 100 100 101 101 badvaddr = cp0_badvaddr_read(); 102 102 … … 291 291 lo1_save.value = cp0_entry_lo1_read(); 292 292 mask_save.value = cp0_pagemask_read(); 293 293 294 294 printf("[nr] [asid] [vpn2 ] [mask] [gvdc] [pfn ]\n"); 295 295 296 296 for (i = 0; i < TLB_ENTRY_COUNT; i++) { 297 297 cp0_index_write(i); 298 298 tlbr(); 299 299 300 300 mask.value = cp0_pagemask_read(); 301 301 hi.value = cp0_entry_hi_read(); 302 302 lo0.value = cp0_entry_lo0_read(); 303 303 lo1.value = cp0_entry_lo1_read(); 304 304 305 305 printf("%-4u %-6u %0#10x %-#6x %1u%1u%1u%1u %0#10x\n", 306 306 i, hi.asid, HI_VPN22ADDR(hi.vpn2), mask.mask, … … 309 309 lo1.g, lo1.v, lo1.d, lo1.c, LO_PFN2ADDR(lo1.pfn)); 310 310 } 311 311 312 312 cp0_entry_hi_write(hi_save.value); 313 313 cp0_entry_lo0_write(lo0_save.value); … … 339 339 cp0_entry_lo0_write(lo0.value); 340 340 cp0_entry_lo1_write(lo1.value); 341 341 342 342 tlbwi(); 343 343 } 344 344 345 345 cp0_entry_hi_write(hi_save.value); 346 346 } … … 360 360 361 361 hi_save.value = cp0_entry_hi_read(); 362 362 363 363 for (i = 0; i < TLB_ENTRY_COUNT; i++) { 364 364 cp0_index_write(i); 365 365 tlbr(); 366 366 367 367 hi.value = cp0_entry_hi_read(); 368 368 369 369 if (hi.asid == asid) { 370 370 lo0.value = cp0_entry_lo0_read(); … … 380 380 } 381 381 } 382 382 383 383 cp0_entry_hi_write(hi_save.value); 384 384 } … … 399 399 400 400 assert(interrupts_disabled()); 401 401 402 402 if (asid == ASID_INVALID) 403 403 return; … … 431 431 } 432 432 } 433 433 434 434 cp0_entry_hi_write(hi_save.value); 435 435 } -
kernel/arch/mips32/src/start.S
r3061bc1 ra35b458 89 89 sw $s7, ISTATE_OFFSET_S7(\r) 90 90 sw $s8, ISTATE_OFFSET_S8(\r) 91 91 92 92 mflo $at 93 93 sw $at, ISTATE_OFFSET_LO(\r) 94 94 mfhi $at 95 95 sw $at, ISTATE_OFFSET_HI(\r) 96 96 97 97 sw $gp, ISTATE_OFFSET_GP(\r) 98 98 sw $ra, ISTATE_OFFSET_RA(\r) 99 99 sw $k0, ISTATE_OFFSET_KT0(\r) 100 100 sw $k1, ISTATE_OFFSET_KT1(\r) 101 101 102 102 mfc0 $t0, $status 103 103 mfc0 $t1, $epc 104 104 105 105 /* save only KSU, EXL, ERL, IE */ 106 106 and $t2, $t0, REG_SAVE_MASK 107 107 108 108 /* clear KSU, EXL, ERL, IE */ 109 109 li $t3, ~(REG_SAVE_MASK) 110 110 and $t0, $t0, $t3 111 111 112 112 sw $t2, ISTATE_OFFSET_STATUS(\r) 113 113 sw $t1, ISTATE_OFFSET_EPC(\r) … … 122 122 mfc0 $t0, $status 123 123 lw $t1, ISTATE_OFFSET_STATUS(\r) 124 124 125 125 /* mask UM, EXL, ERL, IE */ 126 126 li $t2, ~REG_SAVE_MASK 127 127 and $t0, $t0, $t2 128 128 129 129 /* copy UM, EXL, ERL, IE from saved status */ 130 130 or $t0, $t0, $t1 131 131 mtc0 $t0, $status 132 132 133 133 lw $v0, ISTATE_OFFSET_V0(\r) 134 134 lw $v1, ISTATE_OFFSET_V1(\r) … … 147 147 lw $t8, ISTATE_OFFSET_T8(\r) 148 148 lw $t9, ISTATE_OFFSET_T9(\r) 149 149 150 150 lw $gp, ISTATE_OFFSET_GP(\r) 151 151 lw $ra, ISTATE_OFFSET_RA(\r) 152 152 lw $k1, ISTATE_OFFSET_KT1(\r) 153 153 154 154 lw $at, ISTATE_OFFSET_LO(\r) 155 155 mtlo $at 156 156 lw $at, ISTATE_OFFSET_HI(\r) 157 157 mthi $at 158 158 159 159 lw $at, ISTATE_OFFSET_EPC(\r) 160 160 mtc0 $at, $epc 161 161 162 162 lw $at, ISTATE_OFFSET_AT(\r) 163 163 lw $sp, ISTATE_OFFSET_SP(\r) … … 172 172 mfc0 $k0, $status 173 173 andi $k0, 0x10 174 174 175 175 beq $k0, $0, 1f 176 176 move $k0, $sp 177 177 178 178 /* move $k0 pointer to kernel stack */ 179 179 la $k0, supervisor_sp 180 180 181 181 /* move $k0 (supervisor_sp) */ 182 182 lw $k0, ($k0) 183 183 184 184 1: 185 185 .endm … … 190 190 lui $sp, %hi(end_stack) 191 191 ori $sp, $sp, %lo(end_stack) 192 192 193 193 /* not sure about this, but might be needed for PIC code */ 194 194 lui $gp, 0x8000 195 195 196 196 /* $a1 contains physical address of bootinfo_t */ 197 197 jal mips32_pre_main 198 198 addiu $sp, -ABI_STACK_FRAME 199 199 200 200 j main_bsp 201 201 nop … … 219 219 exception_handler: 220 220 KERNEL_STACK_TO_K0 221 221 222 222 sub $k0, ISTATE_SIZE 223 223 sw $sp, ISTATE_OFFSET_SP($k0) 224 224 move $sp, $k0 225 225 226 226 mfc0 $k0, $cause 227 227 228 228 sra $k0, $k0, 0x2 /* cp0_exc_cause() part 1 */ 229 229 andi $k0, $k0, 0x1f /* cp0_exc_cause() part 2 */ 230 230 sub $k0, 8 /* 8 = SYSCALL */ 231 231 232 232 beqz $k0, syscall_shortcut 233 233 add $k0, 8 /* revert $k0 back to correct exc number */ 234 234 235 235 REGISTERS_STORE_AND_EXC_RESET $sp 236 236 237 237 move $a1, $sp 238 238 move $a0, $k0 … … 240 240 addiu $sp, -ABI_STACK_FRAME 241 241 addiu $sp, ABI_STACK_FRAME 242 242 243 243 REGISTERS_LOAD $sp 244 244 /* the $sp is automatically restored to former value */ … … 265 265 sw $t3, ISTATE_OFFSET_EPC($sp) /* save EPC */ 266 266 sw $k1, ISTATE_OFFSET_KT1($sp) /* save $k1 not saved on context switch */ 267 267 268 268 and $t4, $t2, REG_SAVE_MASK /* save only KSU, EXL, ERL, IE */ 269 269 li $t5, ~(0x1f) 270 270 and $t2, $t2, $t5 /* clear KSU, EXL, ERL */ 271 271 ori $t2, $t2, 0x1 /* set IE */ 272 272 273 273 sw $t4, ISTATE_OFFSET_STATUS($sp) 274 274 mtc0 $t2, $status 275 275 276 276 /* 277 277 * Call the higher level system call handler. … … 280 280 sw $t0, ISTATE_OFFSET_T0($sp) /* save the 5th argument on the stack */ 281 281 sw $t1, ISTATE_OFFSET_T1($sp) /* save the 6th argument on the stack */ 282 282 283 283 jal syscall_handler 284 284 sw $v0, ISTATE_OFFSET_V0($sp) /* save the syscall number on the stack */ 285 285 286 286 /* restore status */ 287 287 mfc0 $t2, $status 288 288 lw $t3, ISTATE_OFFSET_STATUS($sp) 289 289 290 290 /* 291 291 * Change back to EXL = 1 (from last exception), otherwise … … 297 297 or $t2, $t2, $t3 /* copy saved UM, EXL, ERL, IE */ 298 298 mtc0 $t2, $status 299 299 300 300 /* restore epc + 4 */ 301 301 lw $t2, ISTATE_OFFSET_EPC($sp) … … 303 303 addi $t2, $t2, 4 304 304 mtc0 $t2, $epc 305 305 306 306 lw $sp, ISTATE_OFFSET_SP($sp) /* restore $sp */ 307 307 eret … … 314 314 sw $sp, ISTATE_OFFSET_SP($k0) 315 315 move $sp, $k0 316 316 317 317 move $a0, $sp 318 318 jal tlb_refill 319 319 addiu $sp, -ABI_STACK_FRAME 320 320 addiu $sp, ABI_STACK_FRAME 321 321 322 322 REGISTERS_LOAD $sp 323 323 eret … … 330 330 sw $sp, ISTATE_OFFSET_SP($k0) 331 331 move $sp, $k0 332 332 333 333 move $a0, $sp 334 334 jal cache_error 335 335 addiu $sp, -ABI_STACK_FRAME 336 336 addiu $sp, ABI_STACK_FRAME 337 337 338 338 REGISTERS_LOAD $sp 339 339 eret
Note:
See TracChangeset
for help on using the changeset viewer.