]> rtime.felk.cvut.cz Git - l4.git/blobdiff - kernel/fiasco/src/kern/arm/trap_state.cpp
update
[l4.git] / kernel / fiasco / src / kern / arm / trap_state.cpp
index 25d351594ee09b0534c56618ae2796043bf2364d..47695ee7d64012c9c498465cb2ebfef4f439e1ab 100644 (file)
@@ -3,6 +3,67 @@ INTERFACE:
 
 #include "l4_types.h"
 #include "entry_frame.h"
+#include <cxx/bitfield>
+
+class Ts_error_code
+{
+public:
+  Ts_error_code() = default;
+  explicit Ts_error_code(Mword ec) : _raw(ec) {}
+  Mword _raw;
+
+  Mword raw() const { return _raw; }
+
+  CXX_BITFIELD_MEMBER(26, 31, ec, _raw);
+  CXX_BITFIELD_MEMBER(25, 25, il, _raw);
+  CXX_BITFIELD_MEMBER(24, 24, cv, _raw);
+  CXX_BITFIELD_MEMBER(20, 23, cond, _raw);
+
+  /** \pre ec == 0x01 */
+  CXX_BITFIELD_MEMBER( 0,  0, wfe_trapped, _raw);
+
+  CXX_BITFIELD_MEMBER(17, 19, mcr_opc2, _raw);
+  CXX_BITFIELD_MEMBER(16, 19, mcrr_opc1, _raw);
+  CXX_BITFIELD_MEMBER(14, 16, mcr_opc1, _raw);
+  CXX_BITFIELD_MEMBER(10, 13, mcr_crn, _raw);
+  CXX_BITFIELD_MEMBER(10, 13, mcrr_rt2, _raw);
+  CXX_BITFIELD_MEMBER( 5,  8, mcr_rt, _raw);
+  CXX_BITFIELD_MEMBER( 1,  4, mcr_crm, _raw);
+  CXX_BITFIELD_MEMBER( 0,  0, mcr_read, _raw);
+
+  Mword mcr_coproc_register() const { return _raw & 0xffc1f; }
+
+  static Mword mcr_coproc_register(unsigned opc1, unsigned crn, unsigned crm, unsigned opc2)
+  { return   mcr_opc1_bfm_t::val_dirty(opc1)
+           | mcr_crn_bfm_t::val_dirty(crn)
+           | mcr_crm_bfm_t::val_dirty(crm)
+           | mcr_opc2_bfm_t::val_dirty(opc2); }
+
+  static Mword mrc_coproc_register(unsigned opc1, unsigned crn, unsigned crm, unsigned opc2)
+  { return mcr_coproc_register(opc1, crn, crm, opc2) | 1; }
+
+  CXX_BITFIELD_MEMBER(12, 19, ldc_imm, _raw);
+  CXX_BITFIELD_MEMBER( 5,  8, ldc_rn, _raw);
+  CXX_BITFIELD_MEMBER( 4,  4, ldc_offset_form, _raw);
+  CXX_BITFIELD_MEMBER( 1,  3, ldc_addressing_mode, _raw);
+
+  CXX_BITFIELD_MEMBER( 5,  5, cpt_simd, _raw);
+  CXX_BITFIELD_MEMBER( 0,  3, cpt_cpnr, _raw);
+
+  CXX_BITFIELD_MEMBER( 0,  3, bxj_rm, _raw);
+
+  CXX_BITFIELD_MEMBER( 0, 15, svc_imm, _raw);
+
+  CXX_BITFIELD_MEMBER(24, 24, pf_isv, _raw);
+  CXX_BITFIELD_MEMBER(22, 23, pf_sas, _raw);
+  CXX_BITFIELD_MEMBER(21, 21, pf_sse, _raw);
+  CXX_BITFIELD_MEMBER(16, 19, pf_srt, _raw);
+  CXX_BITFIELD_MEMBER( 9,  9, pf_ea, _raw);
+  CXX_BITFIELD_MEMBER( 8,  8, pf_cache_maint, _raw);
+  CXX_BITFIELD_MEMBER( 7,  7, pf_s1ptw, _raw);
+  CXX_BITFIELD_MEMBER( 6,  6, pf_write, _raw);
+  CXX_BITFIELD_MEMBER( 0,  5, pf_fsc, _raw);
+};
 
 class Trap_state_regs
 {
@@ -14,6 +75,9 @@ public:
 
   Mword tpidruro;
   Mword r[13];
+
+  Ts_error_code hsr() const { return Ts_error_code(error_code); }
+  Ts_error_code &hsr() { return reinterpret_cast<Ts_error_code&>(error_code); }
 };
 
 class Trap_state : public Trap_state_regs, public Return_frame
@@ -24,9 +88,9 @@ public:
 };
 
 
-IMPLEMENTATION:
+//-----------------------------------------------------------------
+IMPLEMENTATION [arm && !hyp]:
 
-#include <cstdio>
 #include "processor.h"
 
 PUBLIC inline NEEDS["processor.h"]
@@ -37,11 +101,34 @@ Trap_state::sanitize_user_state()
   psr |= Proc::Status_mode_user | Proc::Status_always_mask;
 }
 
+
+//-----------------------------------------------------------------
+IMPLEMENTATION [arm && hyp]:
+
+#include "processor.h"
+
+PUBLIC inline NEEDS["processor.h"]
+void
+Trap_state::sanitize_user_state()
+{
+  psr &= ~Proc::Status_interrupts_mask;
+  psr |= Proc::Status_always_mask;
+
+  if ((psr & Proc::Status_mode_mask) == Proc::PSR_m_hyp)
+    psr = (psr & ~Proc::Status_mode_mask) | Proc::PSR_m_usr;
+}
+
+
+//-----------------------------------------------------------------
+IMPLEMENTATION:
+
+#include <cstdio>
+
 PUBLIC inline
 void
 Trap_state::set_ipc_upcall()
 {
-  error_code = 0x00600000;
+  hsr().ec() = 0x3f;
 }
 
 PUBLIC inline
@@ -60,7 +147,7 @@ Trap_state::ip() const
 PUBLIC inline
 unsigned long
 Trap_state::trapno() const
-{ return error_code >> 16; }
+{ return hsr().ec(); }
 
 PUBLIC inline
 Mword
@@ -70,7 +157,7 @@ Trap_state::error() const
 PUBLIC inline
 bool
 Trap_state::exception_is_undef_insn() const
-{ return (error_code & 0x00f00000) == 0x00100000; }
+{ return hsr().ec() == 0; }
 
 PUBLIC inline
 bool
@@ -82,11 +169,26 @@ void
 Trap_state::dump()
 {
   char const *excpts[] =
-    { "reset", "undefined insn", "swi", "prefetch abort",
-      "data abort", "trigexc", "%&#", "%&#" };
-
-  printf("EXCEPTION: %s pfa=%08lx, error=%08lx\n",
-         excpts[(error_code & 0x00700000) >> 20], pf_address, error_code);
+    {/*  0 */ "undef insn",  "WFx",        0,            "MCR (CP15)",
+     /*  4 */ "MCRR (CP15)", "MCR (CP14)", "LDC (CP14)", "coproc trap",
+     /*  8 */ "MRC (CP10)",  0,            "BXJ",        0,
+     /*  C */ "MRRC (CP14)", 0,            0,            0,
+     /* 10 */ 0,             "SVC",        "HVC",        "SMC",
+     /* 14 */ 0, 0, 0, 0,
+     /* 18 */ 0, 0, 0, 0,
+     /* 1C */ 0, 0, 0, 0,
+     /* 20 */ "prefetch abt (usr)", "prefetch abt (kernel)", 0, 0,
+     /* 24 */ "data abt (user)",    "data abt (kernel)",     0, 0,
+     /* 28 */ 0, 0, 0, 0,
+     /* 2C */ 0, 0, 0, 0,
+     /* 30 */ 0, 0, 0, 0,
+     /* 34 */ 0, 0, 0, 0,
+     /* 38 */ 0, 0, 0, 0,
+     /* 3C */ 0, 0, 0, "<IPC>"};
+
+  printf("EXCEPTION: (%02x) %s pfa=%08lx, error=%08lx\n",
+         (unsigned)hsr().ec(), excpts[hsr().ec()] ? excpts[hsr().ec()] : "",
+         pf_address, error_code);
 
   printf("R[0]: %08lx %08lx %08lx %08lx  %08lx %08lx %08lx %08lx\n"
          "R[8]: %08lx %08lx %08lx %08lx  %08lx %08lx %08lx %08lx\n",