]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/trap_state.cpp
update
[l4.git] / kernel / fiasco / src / kern / arm / trap_state.cpp
1
2 INTERFACE:
3
4 #include "l4_types.h"
5 #include "entry_frame.h"
6 #include <cxx/bitfield>
7
8 class Ts_error_code
9 {
10 public:
11   Ts_error_code() = default;
12   explicit Ts_error_code(Mword ec) : _raw(ec) {}
13   Mword _raw;
14
15   Mword raw() const { return _raw; }
16
17   CXX_BITFIELD_MEMBER(26, 31, ec, _raw);
18   CXX_BITFIELD_MEMBER(25, 25, il, _raw);
19   CXX_BITFIELD_MEMBER(24, 24, cv, _raw);
20   CXX_BITFIELD_MEMBER(20, 23, cond, _raw);
21
22   /** \pre ec == 0x01 */
23   CXX_BITFIELD_MEMBER( 0,  0, wfe_trapped, _raw);
24
25   CXX_BITFIELD_MEMBER(17, 19, mcr_opc2, _raw);
26   CXX_BITFIELD_MEMBER(16, 19, mcrr_opc1, _raw);
27   CXX_BITFIELD_MEMBER(14, 16, mcr_opc1, _raw);
28   CXX_BITFIELD_MEMBER(10, 13, mcr_crn, _raw);
29   CXX_BITFIELD_MEMBER(10, 13, mcrr_rt2, _raw);
30   CXX_BITFIELD_MEMBER( 5,  8, mcr_rt, _raw);
31   CXX_BITFIELD_MEMBER( 1,  4, mcr_crm, _raw);
32   CXX_BITFIELD_MEMBER( 0,  0, mcr_read, _raw);
33
34   Mword mcr_coproc_register() const { return _raw & 0xffc1f; }
35
36   static Mword mcr_coproc_register(unsigned opc1, unsigned crn, unsigned crm, unsigned opc2)
37   { return   mcr_opc1_bfm_t::val_dirty(opc1)
38            | mcr_crn_bfm_t::val_dirty(crn)
39            | mcr_crm_bfm_t::val_dirty(crm)
40            | mcr_opc2_bfm_t::val_dirty(opc2); }
41
42   static Mword mrc_coproc_register(unsigned opc1, unsigned crn, unsigned crm, unsigned opc2)
43   { return mcr_coproc_register(opc1, crn, crm, opc2) | 1; }
44
45   CXX_BITFIELD_MEMBER(12, 19, ldc_imm, _raw);
46   CXX_BITFIELD_MEMBER( 5,  8, ldc_rn, _raw);
47   CXX_BITFIELD_MEMBER( 4,  4, ldc_offset_form, _raw);
48   CXX_BITFIELD_MEMBER( 1,  3, ldc_addressing_mode, _raw);
49
50   CXX_BITFIELD_MEMBER( 5,  5, cpt_simd, _raw);
51   CXX_BITFIELD_MEMBER( 0,  3, cpt_cpnr, _raw);
52
53   CXX_BITFIELD_MEMBER( 0,  3, bxj_rm, _raw);
54
55   CXX_BITFIELD_MEMBER( 0, 15, svc_imm, _raw);
56
57   CXX_BITFIELD_MEMBER(24, 24, pf_isv, _raw);
58   CXX_BITFIELD_MEMBER(22, 23, pf_sas, _raw);
59   CXX_BITFIELD_MEMBER(21, 21, pf_sse, _raw);
60   CXX_BITFIELD_MEMBER(16, 19, pf_srt, _raw);
61   CXX_BITFIELD_MEMBER( 9,  9, pf_ea, _raw);
62   CXX_BITFIELD_MEMBER( 8,  8, pf_cache_maint, _raw);
63   CXX_BITFIELD_MEMBER( 7,  7, pf_s1ptw, _raw);
64   CXX_BITFIELD_MEMBER( 6,  6, pf_write, _raw);
65   CXX_BITFIELD_MEMBER( 0,  5, pf_fsc, _raw);
66 };
67
68 class Trap_state_regs
69 {
70 public:
71 //  static int (*base_handler)(Trap_state *) asm ("BASE_TRAP_HANDLER");
72
73   Mword pf_address;
74   Mword error_code;
75
76   Mword tpidruro;
77   Mword r[13];
78
79   Ts_error_code hsr() const { return Ts_error_code(error_code); }
80   Ts_error_code &hsr() { return reinterpret_cast<Ts_error_code&>(error_code); }
81 };
82
83 class Trap_state : public Trap_state_regs, public Return_frame
84 {
85 public:
86   typedef int (*Handler)(Trap_state*, unsigned cpu);
87   bool exclude_logging() { return false; }
88 };
89
90
91 //-----------------------------------------------------------------
92 IMPLEMENTATION [arm && !hyp]:
93
94 #include "processor.h"
95
96 PUBLIC inline NEEDS["processor.h"]
97 void
98 Trap_state::sanitize_user_state()
99 {
100   psr &= ~(Proc::Status_mode_mask | Proc::Status_interrupts_mask);
101   psr |= Proc::Status_mode_user | Proc::Status_always_mask;
102 }
103
104
105 //-----------------------------------------------------------------
106 IMPLEMENTATION [arm && hyp]:
107
108 #include "processor.h"
109
110 PUBLIC inline NEEDS["processor.h"]
111 void
112 Trap_state::sanitize_user_state()
113 {
114   psr &= ~Proc::Status_interrupts_mask;
115   psr |= Proc::Status_always_mask;
116
117   if ((psr & Proc::Status_mode_mask) == Proc::PSR_m_hyp)
118     psr = (psr & ~Proc::Status_mode_mask) | Proc::PSR_m_usr;
119 }
120
121
122 //-----------------------------------------------------------------
123 IMPLEMENTATION:
124
125 #include <cstdio>
126
127 PUBLIC inline
128 void
129 Trap_state::set_ipc_upcall()
130 {
131   hsr().ec() = 0x3f;
132 }
133
134 PUBLIC inline
135 void
136 Trap_state::set_pagefault(Mword pfa, Mword error)
137 {
138   pf_address = pfa;
139   error_code = error;
140 }
141
142 PUBLIC inline
143 unsigned long
144 Trap_state::ip() const
145 { return pc; }
146
147 PUBLIC inline
148 unsigned long
149 Trap_state::trapno() const
150 { return hsr().ec(); }
151
152 PUBLIC inline
153 Mword
154 Trap_state::error() const
155 { return error_code; }
156
157 PUBLIC inline
158 bool
159 Trap_state::exception_is_undef_insn() const
160 { return hsr().ec() == 0; }
161
162 PUBLIC inline
163 bool
164 Trap_state::is_debug_exception() const
165 { return false; }
166
167 PUBLIC
168 void
169 Trap_state::dump()
170 {
171   char const *excpts[] =
172     {/*  0 */ "undef insn",  "WFx",        0,            "MCR (CP15)",
173      /*  4 */ "MCRR (CP15)", "MCR (CP14)", "LDC (CP14)", "coproc trap",
174      /*  8 */ "MRC (CP10)",  0,            "BXJ",        0,
175      /*  C */ "MRRC (CP14)", 0,            0,            0,
176      /* 10 */ 0,             "SVC",        "HVC",        "SMC",
177      /* 14 */ 0, 0, 0, 0,
178      /* 18 */ 0, 0, 0, 0,
179      /* 1C */ 0, 0, 0, 0,
180      /* 20 */ "prefetch abt (usr)", "prefetch abt (kernel)", 0, 0,
181      /* 24 */ "data abt (user)",    "data abt (kernel)",     0, 0,
182      /* 28 */ 0, 0, 0, 0,
183      /* 2C */ 0, 0, 0, 0,
184      /* 30 */ 0, 0, 0, 0,
185      /* 34 */ 0, 0, 0, 0,
186      /* 38 */ 0, 0, 0, 0,
187      /* 3C */ 0, 0, 0, "<IPC>"};
188
189   printf("EXCEPTION: (%02x) %s pfa=%08lx, error=%08lx\n",
190          (unsigned)hsr().ec(), excpts[hsr().ec()] ? excpts[hsr().ec()] : "",
191          pf_address, error_code);
192
193   printf("R[0]: %08lx %08lx %08lx %08lx  %08lx %08lx %08lx %08lx\n"
194          "R[8]: %08lx %08lx %08lx %08lx  %08lx %08lx %08lx %08lx\n",
195          r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7],
196          r[8], r[9], r[10], r[11], r[12], usp, ulr, pc);
197 }
198