5 IMPLEMENTATION [ppc32]:
13 #include "thread_state.h"
14 #include "trap_state.h"
16 #include "vmem_alloc.h"
19 FSR_STATUS_MASK = 0x0d,
22 FSR_PERMISSION = 0x0d,
25 Per_cpu<Thread::Dbg_stack> DEFINE_PER_CPU Thread::dbg_stack;
29 Thread::print_page_fault_error(Mword e)
31 char const *const excpts[] =
32 { "reset","undef. insn", "swi", "pref. abort", "data abort",
33 "XXX", "XXX", "XXX" };
35 unsigned ex = (e >> 20) & 0x07;
37 printf("(%lx) %s, %s(%c)",e & 0xff, excpts[ex],
38 (e & 0x00010000)?"user":"kernel",
39 (e & 0x00020000)?'r':'w');
50 asm volatile (" mfdbatl %0, %2 \n"
52 : "=r"(batl), "=r"(batu) : "i"(0));
53 printf("DBAT0 U:%08lx L:%08lx\n", batu, batl);
54 asm volatile (" mfdbatl %0, %2 \n"
56 : "=r"(batl), "=r"(batu) : "i"(1));
57 printf("DBAT1 U:%08lx L:%08lx\n", batu, batl);
58 asm volatile (" mfdbatl %0, %2 \n"
60 : "=r"(batl), "=r"(batu) : "i"(2));
61 printf("DBAT2 U:%08lx L:%08lx\n", batu, batl);
62 asm volatile (" mfdbatl %0, %2 \n"
64 : "=r"(batl), "=r"(batu) : "i"(3));
65 printf("DBAT3 U:%08lx L:%08lx\n", batu, batl);
67 asm volatile (" mfibatl %0, %2 \n"
69 : "=r"(batl), "=r"(batu) : "i"(0));
70 printf("IBAT0 U:%08lx L:%08lx\n", batu, batl);
71 asm volatile (" mfibatl %0, %2 \n"
73 : "=r"(batl), "=r"(batu) : "i"(1));
74 printf("IBAT1 U:%08lx L:%08lx\n", batu, batl);
75 asm volatile (" mfibatl %0, %2 \n"
77 : "=r"(batl), "=r"(batu) : "i"(2));
78 printf("IBAT2 U:%08lx L:%08lx\n", batu, batl);
79 asm volatile (" mfibatl %0, %2 \n"
81 : "=r"(batl), "=r"(batu) : "i"(3));
82 printf("IBAT3 U:%08lx L:%08lx\n", batu, batl);
85 PUBLIC template<typename T> inline
87 Thread::fast_return_to_user(Mword ip, Mword sp, T arg)
89 (void)ip; (void)sp; (void)arg;
90 //assert_kdb(check that exiting privs are user privs);
92 panic("__builtin_trap()");
99 user_invoke_generic();
100 assert(current()->state() & Thread_ready);
102 Return_frame *r = nonull_static_cast<Return_frame*>(current()->regs());
103 Kip *kip = (EXPECT_FALSE(current_thread()->mem_space()->is_sigma0())) ?
109 asm volatile(" mfsr %0, 0 \n"
111 : "=r"(vsid), "=r"(utcb));
112 printf("\n[%lx]leaving kernel ip %lx sp %lx vsid %lx\n",
113 current_thread()->dbg_id(), r->ip(), r->sp(), vsid);
114 printf("kernel_sp %p kip %p utcb %08lx\n", current_thread()->regs() + 1, kip, utcb);
116 asm volatile ( " mtsprg1 %[kernel_sp] \n" //correct kernel stack
119 " mtsrr1 %[state] \n"
121 " mr %%r3, %[kip] \n"
126 [state]"r" (Msr::Msr_user),
128 [kernel_sp]"r" (current_thread()->regs() + 1)
135 IMPLEMENT inline NEEDS["space.h", <cstdio>, "types.h" ,"config.h"]
136 bool Thread::handle_sigma0_page_fault(Address pfa)
138 bool ret = (mem_space()->v_insert(Mem_space::Phys_addr(pfa & Config::PAGE_MASK),
139 Mem_space::Addr(pfa & Config::PAGE_MASK),
140 Mem_space::Size(Config::PAGE_SIZE),
141 Mem_space::Page_writable |
142 Mem_space::Page_user_accessible |
143 Mem_space::Page_cacheable
145 != Mem_space::Insert_err_nomem);
151 void except_notimpl(void)
153 Mword etype, dar, dsisr, vsid, msr, ksp;
154 asm volatile(" mflr %0 \n"
160 : "=r"(etype), "=r"(dar), "=r"(dsisr), "=r"(vsid), "=r"(msr), "=r"(ksp) : : "memory");
161 printf("\n\n[dbg_id: %lx] Exception: %lx\n", current_thread()->dbg_id(), etype & ~0xff);
162 Entry_frame *e = current()->regs();
164 e->Return_frame::dump();
165 printf("MSR %08lx DAR %08lx DSISR %08lx VSID: %08lx KSP: %08lx\n\n", msr, dar, dsisr,vsid, ksp);
166 e->Syscall_frame::dump();
167 e->Return_frame::dump_scratch();
176 * The low-level page fault handler called from entry.S. We're invoked with
177 * interrupts turned off. Apart from turning on interrupts
178 * all casesi, just forwards
179 * the call to Thread::handle_page_fault().
180 * @param pfa page-fault virtual address
181 * @param error_code CPU error code
182 * @return true if page fault could be resolved, false otherwise
184 Mword pagefault_entry(const Mword pfa, const Mword error_code,
185 const Mword pc, Return_frame *ret_frame)
187 //printf("Page fault at %08lx (%s)\n", pfa, PF::is_read_error(error_code)?"ro":"rw" );
188 if(EXPECT_TRUE(PF::is_usermode_error(error_code)))
190 if (current_thread()->vcpu_pagefault(pfa, error_code, pc))
193 current_thread()->state_del(Thread_cancel);
197 //lookup in page cache
198 if(current_mem_space()->try_htab_fault((Address)(pfa & Config::PAGE_MASK)))
201 int ret = current_thread()->handle_page_fault(pfa, error_code, pc, ret_frame);
206 void slowtrap_entry(Trap_state * /*ts*/)
215 Thread::pagein_tcb_request(Return_frame * /*regs*/)
225 Return_frame *rf = nonull_static_cast<Return_frame*>(current()->regs());
226 //disable power savings mode, when we come from privileged mode
227 if(EXPECT_FALSE(rf->user_mode()))
228 rf->srr1 = Proc::wake(rf->srr1);
230 Timer::update_system_clock();
231 current_thread()->handle_timer_interrupt();
234 //---------------------------------------------------------------------------
235 IMPLEMENTATION [ppc32]:
238 @param id user-visible thread ID of the sender
239 @param init_prio initial priority
240 @param mcp thread's maximum controlled priority
241 @post state() != Thread_invalid
245 : Sender (0), // select optimized version of constructor
246 _pager(Thread_ptr::Invalid),
247 _exc_handler(Thread_ptr::Invalid),
251 assert(state() == Thread_invalid);
255 if (Config::stack_depth)
256 std::memset((char*)this + sizeof(Thread), '5',
257 Config::thread_block_size-sizeof(Thread)-64);
259 // set a magic value -- we use it later to verify the stack hasn't
265 *reinterpret_cast<void(**)()> (--_kernel_sp) = user_invoke;
267 // clear out user regs that can be returned from the thread_ex_regs
268 // system call to prevent covert channel
269 Entry_frame *r = regs();
273 state_add(Thread_dead | Thread_suspended);
274 // ok, we're ready to go!
279 Thread::user_sp() const
280 { return regs()->sp(); }
284 Thread::user_sp(Mword sp)
285 { return regs()->sp(sp); }
287 IMPLEMENT inline NEEDS[Thread::exception_triggered]
289 Thread::user_ip() const
290 { return exception_triggered() ? _exc_cont.ip() : regs()->ip(); }
294 Thread::user_flags() const
297 IMPLEMENT inline NEEDS[Thread::exception_triggered]
299 Thread::user_ip(Mword ip)
301 if (exception_triggered())
305 Entry_frame *r = regs();
310 PUBLIC inline NEEDS ["trap_state.h"]
312 Thread::send_exception_arch(Trap_state * /*ts*/)
315 return 1; // We did it
320 Thread::vcpu_resume_user_arch()
324 PRIVATE static inline
326 Thread::save_fpu_state_to_utcb(Trap_state *, Utcb *)
332 Thread::do_trigger_exception(Entry_frame * /*r*/, void * /*ret_handler*/)
338 PRIVATE static inline
339 bool FIASCO_WARN_RESULT
340 Thread::copy_utcb_to_ts(L4_msg_tag const &/*tag*/, Thread * /*snd*/,
341 Thread * /*rcv*/, unsigned char /*rights*/)
347 PRIVATE static inline
348 bool FIASCO_WARN_RESULT
349 Thread::copy_ts_to_utcb(L4_msg_tag const &, Thread * /*snd*/, Thread * /*rcv*/,
350 unsigned char /*rights*/)
358 Thread::invoke_arch(L4_msg_tag & /*tag*/, Utcb * /*utcb*/)
365 Thread::sys_control_arch(Utcb *)
370 //-----------------------------------------------------------------------------
371 IMPLEMENTATION [!mp]:
375 Thread::check_for_ipi(unsigned)