Mercurial > hg > Members > tobaru > CbC_xv6
diff src/arm.c @ 0:83c23a36980d
Init
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 26 May 2017 23:11:05 +0900 |
parents | |
children | 0956648d24e5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/arm.c Fri May 26 23:11:05 2017 +0900 @@ -0,0 +1,127 @@ +// BSP support routine +#include "types.h" +#include "defs.h" +#include "param.h" +#include "memlayout.h" +#include "proc.h" +#include "arm.h" +#include "mmu.h" + +void cli (void) +{ + uint val; + + // ok, enable paging using read/modify/write + asm("MRS %[v], cpsr": [v]"=r" (val)::); + val |= DIS_INT; + asm("MSR cpsr_cxsf, %[v]": :[v]"r" (val):); +} + +void sti (void) +{ + uint val; + + // ok, enable paging using read/modify/write + asm("MRS %[v], cpsr": [v]"=r" (val)::); + val &= ~DIS_INT; + asm("MSR cpsr_cxsf, %[v]": :[v]"r" (val):); +} + +// return the cpsr used for user program +uint spsr_usr () +{ + uint val; + + // ok, enable paging using read/modify/write + asm("MRS %[v], cpsr": [v]"=r" (val)::); + val &= ~MODE_MASK; + val |= USR_MODE; + + return val; +} + +// return whether interrupt is currently enabled +int int_enabled () +{ + uint val; + + // ok, enable paging using read/modify/write + asm("MRS %[v], cpsr": [v]"=r" (val)::); + + return !(val & DIS_INT); +} + +// Pushcli/popcli are like cli/sti except that they are matched: +// it takes two popcli to undo two pushcli. Also, if interrupts +// are off, then pushcli, popcli leaves them off. + +void pushcli (void) +{ + int enabled; + + enabled = int_enabled(); + + cli(); + + if (cpu->ncli++ == 0) { + cpu->intena = enabled; + } +} + +void popcli (void) +{ + if (int_enabled()) { + panic("popcli - interruptible"); + } + + if (--cpu->ncli < 0) { + cprintf("cpu (%d)->ncli: %d\n", cpu, cpu->ncli); + panic("popcli -- ncli < 0"); + } + + if ((cpu->ncli == 0) && cpu->intena) { + sti(); + } +} + +// Record the current call stack in pcs[] by following the call chain. +// In ARM ABI, the function prologue is as: +// push {fp, lr} +// add fp, sp, #4 +// so, fp points to lr, the return address +void getcallerpcs (void * v, uint pcs[]) +{ + uint *fp; + int i; + + fp = (uint*) v; + + for (i = 0; i < N_CALLSTK; i++) { + if ((fp == 0) || (fp < (uint*) KERNBASE) || (fp == (uint*) 0xffffffff)) { + break; + } + + fp = fp - 1; // points fp to the saved fp + pcs[i] = fp[1]; // saved lr + fp = (uint*) fp[0]; // saved fp + } + + for (; i < N_CALLSTK; i++) { + pcs[i] = 0; + } +} + +void show_callstk (char *s) +{ + int i; + uint pcs[N_CALLSTK]; + + cprintf("%s\n", s); + + getcallerpcs(get_fp(), pcs); + + for (i = N_CALLSTK - 1; i >= 0; i--) { + cprintf("%d: 0x%x\n", i + 1, pcs[i]); + } + +}