trap.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*****************************************************************
  2. * trap.c
  3. * by Zhiyi Huang, [email protected]
  4. * University of Otago
  5. *
  6. ********************************************************************/
  7. #include "types.h"
  8. #include "defs.h"
  9. #include "param.h"
  10. #include "memlayout.h"
  11. #include "mmu.h"
  12. #include "proc.h"
  13. #include "arm.h"
  14. #include "traps.h"
  15. #include "spinlock.h"
  16. extern u8 *vectors;
  17. void cprintf(char*, ...);
  18. void dsb_barrier(void);
  19. void flush_idcache(void);
  20. void *memmove(void *dst, const void *src, uint n);
  21. void set_mode_sp(char *, uint);
  22. struct spinlock tickslock;
  23. uint ticks;
  24. void enable_intrs(void)
  25. {
  26. intctrlregs *ip;
  27. ip = (intctrlregs *)INT_REGS_BASE;
  28. ip->gpuenable[0] |= 1 << 29; // enable the miniuart through Aux
  29. //ip->gpuenable[1] |= 1 << 25; // enable uart
  30. ip->armenable |= 1 << 0; // enable the system timer
  31. }
  32. void disable_intrs(void)
  33. {
  34. intctrlregs *ip;
  35. int disable;
  36. ip = (intctrlregs *)INT_REGS_BASE;
  37. disable = ~0;
  38. ip->gpudisable[0] = disable;
  39. ip->gpudisable[1] = disable;
  40. ip->armdisable = disable;
  41. ip->fiqctrl = 0;
  42. }
  43. void tvinit(void)
  44. {
  45. uint *d, *s;
  46. char *ptr;
  47. /* initialize the exception vectors */
  48. d = (uint *)HVECTORS;
  49. s = (uint *)&vectors;
  50. memmove(d, s, sizeof(Vpage0));
  51. /* cacheuwbinv(); drain write buffer and prefetch buffer
  52. * writeback and invalidate data cache
  53. * invalidate instruction cache
  54. */
  55. dsb_barrier();
  56. flush_idcache();
  57. ptr = kalloc();
  58. memset(ptr, 0, PGSIZE);
  59. set_mode_sp(ptr+4096, 0xD1);/* fiq mode, fiq and irq are disabled */
  60. ptr = kalloc();
  61. memset(ptr, 0, PGSIZE);
  62. set_mode_sp(ptr+4096, 0xD2);/* irq mode, fiq and irq are disabled */
  63. ptr = kalloc();
  64. memset(ptr, 0, PGSIZE);
  65. set_mode_sp(ptr+4096, 0xDB);/* undefined mode, fiq and irq are disabled */
  66. ptr = kalloc();
  67. memset(ptr, 0, PGSIZE);
  68. set_mode_sp(ptr+4096, 0xD7);/* abort mode, fiq and irq are disabled */
  69. ptr = kalloc();
  70. memset(ptr, 0, PGSIZE);
  71. set_mode_sp(ptr+4096, 0xD6);/* secure monitor mode, fiq and irq are disabled */
  72. ptr = kalloc();
  73. memset(ptr, 0, PGSIZE);
  74. set_mode_sp(ptr+4096, 0xDF);/* system mode, fiq and irq are disabled */
  75. dsb_barrier();
  76. }
  77. void trap_oops(struct trapframe *tf)
  78. {
  79. cprintf("trapno: %x, spsr: %x, sp: %x, pc: %x cpsr: %x ifar: %x\n", tf->trapno, tf->spsr, tf->sp, tf->pc, tf->cpsr, tf->ifar);
  80. cprintf("Saved registers: r0: %x, r1: %x, r2: %x, r3: %x, r4: %x, r5: %x\n", tf->r0, tf->r1, tf->r2, tf->r3, tf->r4, tf->r5);
  81. cprintf("More registers: r6: %x, r7: %x, r8: %x, r9: %x, r10: %x, r11: %x, r12: %x\n", tf->r6, tf->r7, tf->r8, tf->r9, tf->r10, tf->r11, tf->r12);
  82. //NotOkLoop();
  83. }
  84. void handle_irq(struct trapframe *tf)
  85. {
  86. intctrlregs *ip;
  87. /*cprintf("trapno: %x, spsr: %x, sp: %x, lr: %x cpsr: %x ifar: %x\n", tf->trapno, tf->spsr, tf->sp, tf->pc, tf->cpsr, tf->ifar);
  88. cprintf("Saved registers: r0: %x, r1: %x, r2: %x, r3: %x, r4: %x, r5: %x, r6: %x\n", tf->r0, tf->r1, tf->r2, tf->r3, tf->r4, tf->r5, tf->r6);
  89. cprintf("More registers: r6: %x, r7: %x, r8: %x, r9: %x, r10: %x, r11: %x, r12: %x, r13: %x, r14: %x\n", tf->r7, tf->r8, tf->r9, tf->r10, tf->r11, tf->r12, tf->r13, tf->r14);
  90. */
  91. ip = (intctrlregs *)INT_REGS_BASE;
  92. while(ip->gpupending[0] || ip->gpupending[1] || ip->armpending){
  93. if(ip->gpupending[0] & (1 << 3)) {
  94. timer3intr();
  95. }
  96. if(ip->gpupending[0] & (1 << 29)) {
  97. miniuartintr();
  98. }
  99. }
  100. }
  101. //PAGEBREAK: 41
  102. void
  103. trap(struct trapframe *tf)
  104. {
  105. intctrlregs *ip;
  106. uint istimer;
  107. //cprintf("Trap %d from cpu %d eip %x (cr2=0x%x)\n",
  108. // tf->trapno, curr_cpu->id, tf->eip, 0);
  109. //trap_oops(tf);
  110. if(tf->trapno == T_SYSCALL){
  111. if(curr_proc->killed)
  112. exit();
  113. curr_proc->tf = tf;
  114. syscall();
  115. if(curr_proc->killed)
  116. exit();
  117. return;
  118. }
  119. istimer = 0;
  120. switch(tf->trapno){
  121. case T_IRQ:
  122. ip = (intctrlregs *)INT_REGS_BASE;
  123. while(ip->gpupending[0] || ip->gpupending[1] || ip->armpending){
  124. if(ip->gpupending[0] & (1 << IRQ_TIMER3)) {
  125. istimer = 1;
  126. timer3intr();
  127. }
  128. if(ip->gpupending[0] & (1 << IRQ_MINIUART)) {
  129. miniuartintr();
  130. }
  131. }
  132. break;
  133. default:
  134. if(curr_proc == 0 || (tf->spsr & 0xF) != USER_MODE){
  135. // In kernel, it must be our mistake.
  136. cprintf("unexpected trap %d from cpu %d addr %x spsr %x cpsr %x ifar %x\n",
  137. tf->trapno, curr_cpu->id, tf->pc, tf->spsr, tf->cpsr, tf->ifar);
  138. panic("trap");
  139. }
  140. // In user space, assume process misbehaved.
  141. cprintf("pid %d %s: trap %d on cpu %d "
  142. "addr 0x%x spsr 0x%x cpsr 0x%x ifar 0x%x--kill proc\n",
  143. curr_proc->pid, curr_proc->name, tf->trapno, curr_cpu->id, tf->pc,
  144. tf->spsr, tf->cpsr, tf->ifar);
  145. curr_proc->killed = 1;
  146. }
  147. // Force process exit if it has been killed and is in user space.
  148. // (If it is still executing in the kernel, let it keep running
  149. // until it gets to the regular system call return.)
  150. //cprintf("Proc pointer: %d\n", curr_proc);
  151. if(curr_proc){
  152. if(curr_proc->killed && (tf->spsr&0xF) == USER_MODE)
  153. exit();
  154. // Force process to give up CPU on clock tick.
  155. // If interrupts were on while locks held, would need to check nlock.
  156. if(curr_proc->state == RUNNING && istimer)
  157. yield();
  158. // Check if the process has been killed since we yielded
  159. if(curr_proc->killed && (tf->spsr&0xF) == USER_MODE)
  160. exit();
  161. }
  162. //cprintf("Proc pointer: %d after\n", curr_proc);
  163. }