X-Git-Url: https://rtime.felk.cvut.cz/gitweb/l4.git/blobdiff_plain/35719fdd2ff27177690edb32843d32e092a006e3..5658d2ec9c1081516a8868259fa867926e25ab3f:/kernel/fiasco/src/kern/arm/thread-arm.cpp diff --git a/kernel/fiasco/src/kern/arm/thread-arm.cpp b/kernel/fiasco/src/kern/arm/thread-arm.cpp index f73f23721..8dc4cbf85 100644 --- a/kernel/fiasco/src/kern/arm/thread-arm.cpp +++ b/kernel/fiasco/src/kern/arm/thread-arm.cpp @@ -4,6 +4,8 @@ class Trap_state; EXTENSION class Thread { +public: + static void init_per_cpu(unsigned cpu); private: bool _in_exception; @@ -59,6 +61,8 @@ Thread::fast_return_to_user(Mword ip, Mword sp, Vcpu_state *arg) // fill_user_state() fill_user_state(); + load_tpidruro(); + r->psr &= ~Proc::Status_thumb; { @@ -74,6 +78,12 @@ Thread::fast_return_to_user(Mword ip, Mword sp, Vcpu_state *arg) panic("__builtin_trap()"); } +IMPLEMENT_DEFAULT inline +void +Thread::init_per_cpu(unsigned) +{} + + // // Public services // @@ -244,6 +254,8 @@ extern "C" { void slowtrap_entry(Trap_state *ts) { + if (0) + printf("Trap: pfa=%08lx pc=%08lx err=%08lx psr=%lx\n", ts->pf_address, ts->pc, ts->error_code, ts->psr); Thread *t = current_thread(); LOG_TRAP; @@ -379,7 +391,7 @@ Thread::Thread() r->ip(0); r->psr = Proc::Status_mode_user; - state_add(Thread_dead | Thread_suspended); + state_add_dirty(Thread_dead, false); // ok, we're ready to go! } @@ -459,7 +471,7 @@ Thread::do_trigger_exception(Entry_frame *r, void *ret_handler) } -PRIVATE static inline +PRIVATE static inline NEEDS[Thread::get_ts_tpidruro] bool FIASCO_WARN_RESULT Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv, unsigned char rights) @@ -471,30 +483,30 @@ Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv, if (EXPECT_FALSE(rcv->exception_triggered())) { // triggered exception pending - Mem::memcpy_mwords (ts, snd_utcb->values, s > 15 ? 15 : s); - if (EXPECT_TRUE(s > 19)) + Mem::memcpy_mwords (ts, snd_utcb->values, s > 16 ? 16 : s); + if (EXPECT_TRUE(s > 20)) { // sanitize processor mode // XXX: fix race - snd_utcb->values[19] &= ~Proc::Status_mode_mask; // clear mode - snd_utcb->values[19] |= Proc::Status_mode_supervisor - | Proc::Status_interrupts_disabled; + snd_utcb->values[20] &= ~Proc::Status_mode_mask; // clear mode + snd_utcb->values[20] |= Proc::Status_mode_supervisor + | Proc::Status_interrupts_disabled; Continuation::User_return_frame const *s - = reinterpret_cast((char*)&snd_utcb->values[15]); + = reinterpret_cast((char*)&snd_utcb->values[16]); rcv->_exc_cont.set(ts, s); } } else { - Mem::memcpy_mwords (ts, snd_utcb->values, s > 18 ? 18 : s); - if (EXPECT_TRUE(s > 18)) - ts->pc = snd_utcb->values[18]; + Mem::memcpy_mwords (ts, snd_utcb->values, s > 19 ? 19 : s); if (EXPECT_TRUE(s > 19)) + ts->pc = snd_utcb->values[19]; + if (EXPECT_TRUE(s > 20)) { // sanitize processor mode - Mword p = snd_utcb->values[19]; + Mword p = snd_utcb->values[20]; p &= ~(Proc::Status_mode_mask | Proc::Status_interrupts_mask); // clear mode & irqs p |= Proc::Status_mode_user; ts->psr = p; @@ -507,6 +519,8 @@ Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv, if ((tag.flags() & 0x8000) && (rights & L4_fpage::W)) rcv->utcb().access()->user[2] = snd_utcb->values[25]; + rcv->get_ts_tpidruro(ts); + bool ret = transfer_msg_items(tag, snd, snd_utcb, rcv, rcv->utcb().access(), rights); @@ -515,7 +529,8 @@ Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv, } -PRIVATE static inline NEEDS[Thread::save_fpu_state_to_utcb] +PRIVATE static inline NEEDS[Thread::save_fpu_state_to_utcb, + Thread::set_ts_tpidruro] bool FIASCO_WARN_RESULT Thread::copy_ts_to_utcb(L4_msg_tag const &, Thread *snd, Thread *rcv, unsigned char rights) @@ -523,20 +538,22 @@ Thread::copy_ts_to_utcb(L4_msg_tag const &, Thread *snd, Thread *rcv, Trap_state *ts = (Trap_state*)snd->_utcb_handler; { - Lock_guard guard (&cpu_lock); + auto guard = lock_guard(cpu_lock); Utcb *rcv_utcb = rcv->utcb().access(); - Mem::memcpy_mwords (rcv_utcb->values, ts, 15); + snd->set_ts_tpidruro(ts); + + Mem::memcpy_mwords(rcv_utcb->values, ts, 16); Continuation::User_return_frame *d - = reinterpret_cast((char*)&rcv_utcb->values[15]); + = reinterpret_cast((char*)&rcv_utcb->values[16]); snd->_exc_cont.get(d, ts); if (EXPECT_TRUE(!snd->exception_triggered())) { - rcv_utcb->values[18] = ts->pc; - rcv_utcb->values[19] = ts->psr; + rcv_utcb->values[19] = ts->pc; + rcv_utcb->values[20] = ts->psr; } if (rcv_utcb->inherit_fpu() && (rights & L4_fpage::W)) @@ -547,11 +564,17 @@ Thread::copy_ts_to_utcb(L4_msg_tag const &, Thread *snd, Thread *rcv, return true; } -PROTECTED inline +PROTECTED inline NEEDS[Thread::set_tpidruro] L4_msg_tag -Thread::invoke_arch(L4_msg_tag /*tag*/, Utcb * /*utcb*/) +Thread::invoke_arch(L4_msg_tag tag, Utcb *utcb) { - return commit_result(-L4_err::ENosys); + switch (utcb->values[0] & Opcode_mask) + { + case Op_set_tpidruro_arm: + return set_tpidruro(tag, utcb); + default: + return commit_result(-L4_err::ENosys); + } } PROTECTED inline @@ -603,6 +626,37 @@ Thread::vcpu_resume_user_arch() : : "r" (utcb().access(true)->values[25]) : "memory"); } +PRIVATE inline +L4_msg_tag +Thread::set_tpidruro(L4_msg_tag tag, Utcb *utcb) +{ + if (EXPECT_FALSE(tag.words() < 2)) + return commit_result(-L4_err::EInval); + + _tpidruro = utcb->values[1]; + if (EXPECT_FALSE(state() & Thread_vcpu_enabled)) + arch_update_vcpu_state(vcpu_state().access()); + + if (this == current_thread()) + load_tpidruro(); + + return commit_result(0); +} + +PRIVATE inline +void +Thread::get_ts_tpidruro(Trap_state *ts) +{ + _tpidruro = ts->tpidruro; +} + +PRIVATE inline +void +Thread::set_ts_tpidruro(Trap_state *ts) +{ + ts->tpidruro = _tpidruro; +} + // ------------------------------------------------------------------------ IMPLEMENTATION [arm && !armv6plus]: @@ -611,6 +665,23 @@ void Thread::vcpu_resume_user_arch() {} +PRIVATE inline +L4_msg_tag +Thread::set_tpidruro(L4_msg_tag, Utcb *) +{ + return commit_result(-L4_err::EInval); +} + +PRIVATE inline +void +Thread::get_ts_tpidruro(Trap_state *) +{} + +PRIVATE inline +void +Thread::set_ts_tpidruro(Trap_state *) +{} + //----------------------------------------------------------------------------- IMPLEMENTATION [mp]: @@ -702,14 +773,14 @@ Thread::handle_fpu_trap(Unsigned32 opcode, Trap_state *ts) if (Fpu::is_enabled()) { - assert(Fpu::owner(current_cpu()) == current_thread()); + assert(Fpu::fpu.current().owner() == current()); if (Fpu::is_emu_insn(opcode)) - return Fpu::emulate_insns(opcode, ts, current_cpu()); + return Fpu::emulate_insns(opcode, ts); } else if (current_thread()->switchin_fpu()) { if (Fpu::is_emu_insn(opcode)) - return Fpu::emulate_insns(opcode, ts, current_cpu()); + return Fpu::emulate_insns(opcode, ts); ts->pc -= (ts->psr & Proc::Status_thumb) ? 2 : 4; return true; }