5 IMPLEMENTATION [sparc]:
13 #include "thread_state.h"
14 #include "trap_state.h"
18 FSR_STATUS_MASK = 0x0d,
21 FSR_PERMISSION = 0x0d,
24 DEFINE_PER_CPU Per_cpu<Thread::Dbg_stack> Thread::dbg_stack;
28 Thread::print_page_fault_error(Mword e)
30 char const *const excpts[] =
31 { "reset","undef. insn", "swi", "pref. abort", "data abort",
32 "XXX", "XXX", "XXX" };
34 unsigned ex = (e >> 20) & 0x07;
36 printf("(%lx) %s, %s(%c)",e & 0xff, excpts[ex],
37 (e & 0x00010000)?"user":"kernel",
38 (e & 0x00020000)?'r':'w');
50 PUBLIC template<typename T> inline
52 Thread::fast_return_to_user(Mword ip, Mword sp, T arg)
54 (void)ip; (void)sp; (void)arg;
55 //assert_kdb(check that exiting privs are user privs);
57 panic("__builtin_trap()");
64 user_invoke_generic();
65 assert(current()->state() & Thread_ready);
67 Return_frame *r = nonull_static_cast<Return_frame*>(current()->regs());
68 Kip *kip = (EXPECT_FALSE(current_thread()->mem_space()->is_sigma0())) ?
72 Mword vsid = 0xF000, utcb = 0xBAAA;
74 printf("\n[%lx]leaving kernel ip %lx sp %lx vsid %lx\n",
75 current_thread()->dbg_id(), r->ip(), r->sp(), vsid);
76 printf("kernel_sp %p kip %p utcb %08lx\n", current_thread()->regs() + 1, kip, utcb);
81 IMPLEMENT inline NEEDS["space.h", <cstdio>, "types.h" ,"config.h"]
82 bool Thread::handle_sigma0_page_fault(Address pfa)
84 bool ret = (mem_space()->v_insert(Mem_space::Phys_addr(pfa & Config::PAGE_MASK),
85 Mem_space::Addr(pfa & Config::PAGE_MASK),
86 Mem_space::Size(Config::PAGE_SIZE),
87 Mem_space::Page_writable |
88 Mem_space::Page_user_accessible |
89 Mem_space::Page_cacheable
91 != Mem_space::Insert_err_nomem);
97 void except_notimpl(void)
106 * The low-level page fault handler called from entry.S. We're invoked with
107 * interrupts turned off. Apart from turning on interrupts
108 * all casesi, just forwards
109 * the call to Thread::handle_page_fault().
110 * @param pfa page-fault virtual address
111 * @param error_code CPU error code
112 * @return true if page fault could be resolved, false otherwise
114 Mword pagefault_entry(const Mword pfa, const Mword error_code,
115 const Mword pc, Return_frame *ret_frame)
117 //printf("Page fault at %08lx (%s)\n", pfa, PF::is_read_error(error_code)?"ro":"rw" );
118 if(EXPECT_TRUE(PF::is_usermode_error(error_code)))
120 if (current_thread()->vcpu_pagefault(pfa, error_code, pc))
123 current_thread()->state_del(Thread_cancel);
127 int ret = current_thread()->handle_page_fault(pfa, error_code, pc, ret_frame);
132 void slowtrap_entry(Trap_state * /*ts*/)
141 Thread::pagein_tcb_request(Return_frame * /*regs*/)
151 Return_frame *rf = nonull_static_cast<Return_frame*>(current()->regs());
152 //disable power savings mode, when we come from privileged mode
153 if(EXPECT_FALSE(rf->user_mode()))
154 rf->srr1 = Proc::wake(rf->srr1);
156 Timer::update_system_clock(current_cpu());
157 current_thread()->handle_timer_interrupt();
160 //---------------------------------------------------------------------------
161 IMPLEMENTATION [sparc]:
164 @param id user-visible thread ID of the sender
165 @param init_prio initial priority
166 @param mcp thread's maximum controlled priority
167 @post state() != Thread_invalid
171 : Sender (0), // select optimized version of constructor
172 _pager(Thread_ptr::Invalid),
173 _exc_handler(Thread_ptr::Invalid),
177 assert(state(false) == Thread_invalid);
180 _space.space(Kernel_task::kernel_task());
182 // set a magic value -- we use it later to verify the stack hasn't
188 *reinterpret_cast<void(**)()> (--_kernel_sp) = user_invoke;
190 // clear out user regs that can be returned from the thread_ex_regs
191 // system call to prevent covert channel
192 Entry_frame *r = regs();
196 state_add_dirty(Thread_dead, false);
197 // ok, we're ready to go!
202 Thread::user_sp() const
203 { return regs()->sp(); }
207 Thread::user_sp(Mword sp)
208 { return regs()->sp(sp); }
210 IMPLEMENT inline NEEDS[Thread::exception_triggered]
212 Thread::user_ip() const
213 { return exception_triggered() ? _exc_cont.ip() : regs()->ip(); }
217 Thread::user_flags() const
220 IMPLEMENT inline NEEDS[Thread::exception_triggered]
222 Thread::user_ip(Mword ip)
224 if (exception_triggered())
228 Entry_frame *r = regs();
233 PUBLIC inline NEEDS ["trap_state.h"]
235 Thread::send_exception_arch(Trap_state * /*ts*/)
238 return 1; // We did it
243 Thread::vcpu_resume_user_arch()
247 PRIVATE static inline
249 Thread::save_fpu_state_to_utcb(Trap_state *, Utcb *)
255 Thread::do_trigger_exception(Entry_frame * /*r*/, void * /*ret_handler*/)
261 PRIVATE static inline
262 bool FIASCO_WARN_RESULT
263 Thread::copy_utcb_to_ts(L4_msg_tag const &/*tag*/, Thread * /*snd*/,
264 Thread * /*rcv*/, unsigned char /*rights*/)
270 PRIVATE static inline
271 bool FIASCO_WARN_RESULT
272 Thread::copy_ts_to_utcb(L4_msg_tag const &, Thread * /*snd*/, Thread * /*rcv*/,
273 unsigned char /*rights*/)
281 Thread::invoke_arch(L4_msg_tag /*tag*/, Utcb * /*utcb*/)
283 return commit_result(-L4_err::ENosys);
288 Thread::sys_control_arch(Utcb *)
293 //-----------------------------------------------------------------------------
294 IMPLEMENTATION [!mp]:
298 Thread::check_for_ipi(unsigned)