aboutsummaryrefslogtreecommitdiff
path: root/pk/handlers.c
blob: 2947903862152adea54a191a9c759bdd746ff02b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "pcr.h"
#include "pk.h"

int have_fp = 1;

void handle_breakpoint(trapframe_t* tf)
{
  printk("Breakpoint\n");
  dump_tf(tf);
  tf->epc += 4;
}

void handle_fp_disabled(trapframe_t* tf)
{
  if(have_fp)
  {
    init_fp_regs();
    tf->sr |= SR_EF;
  }
  else
  {
#ifdef PK_ENABLE_FP_EMULATION
    if(emulate_fp(tf) != 0)
    {
      dump_tf(tf);
      panic("FPU emulation failed!");
    }
#else
    panic("FPU emulation disabled! pc %lx, insn %x",tf->epc,(uint32_t)tf->insn);
#endif
  }
}

void handle_badtrap(trapframe_t* tf)
{
  dump_tf(tf);
  panic("Bad trap vector!");
}

void handle_privileged_instruction(trapframe_t* tf)
{
  dump_tf(tf);
  panic("A privileged instruction was executed!");
}

void handle_illegal_instruction(trapframe_t* tf)
{
#ifdef PK_ENABLE_FP_EMULATION
  if(emulate_fp(tf) == 0)
    return;
#endif

  dump_tf(tf);
  panic("An illegal instruction was executed!");
}

void handle_misaligned_fetch(trapframe_t* tf)
{
  dump_tf(tf);
  panic("Misaligned instruction access!");
}

void handle_misaligned_ldst(trapframe_t* tf)
{
  dump_tf(tf);
  panic("Misaligned data access!");
}

void handle_fault_fetch(trapframe_t* tf)
{
  dump_tf(tf);
  panic("Faulting instruction access!");
}

void handle_fault_load(trapframe_t* tf)
{
  dump_tf(tf);
  panic("Faulting load!");
}

void handle_fault_store(trapframe_t* tf)
{
  dump_tf(tf);
  panic("Faulting store!");
}

void handle_timer_interrupt(trapframe_t* tf)
{
  mtpcr(mfpcr(PCR_COMPARE)+TIMER_PERIOD,PCR_COMPARE);
}

void handle_trap(trapframe_t* tf)
{
  typedef void (*trap_handler)(trapframe_t*);
  const static trap_handler trap_handlers[] = {
    handle_misaligned_fetch,
    handle_fault_fetch,
    handle_illegal_instruction,
    handle_privileged_instruction,
    handle_fp_disabled,
    handle_syscall,
    handle_breakpoint,
    handle_misaligned_ldst,
    handle_fault_load,
    handle_fault_store,
    handle_badtrap,
    handle_badtrap,
    handle_badtrap,
    handle_badtrap,
    handle_badtrap,
    handle_badtrap,
    handle_badtrap, /* irq 0 */
    handle_badtrap, /* irq 1 */
    handle_badtrap, /* irq 2 */
    handle_badtrap, /* irq 3 */
    handle_badtrap, /* irq 4 */
    handle_badtrap, /* irq 5 */
    handle_badtrap, /* irq 6 */
    handle_timer_interrupt, /* irq 7 */
  };

  kassert(tf->cause < sizeof(trap_handlers)/sizeof(trap_handlers[0]));

  trap_handlers[tf->cause](tf);

  pop_tf(tf);
}