1433d6423SLionel Sambuc #ifndef PROC_H 2433d6423SLionel Sambuc #define PROC_H 3433d6423SLionel Sambuc 4433d6423SLionel Sambuc #include <minix/const.h> 5433d6423SLionel Sambuc #include <sys/cdefs.h> 6433d6423SLionel Sambuc 7433d6423SLionel Sambuc #ifndef __ASSEMBLY__ 8433d6423SLionel Sambuc 9433d6423SLionel Sambuc /* Here is the declaration of the process table. It contains all process 10433d6423SLionel Sambuc * data, including registers, flags, scheduling priority, memory map, 11433d6423SLionel Sambuc * accounting, message passing (IPC) information, and so on. 12433d6423SLionel Sambuc * 13433d6423SLionel Sambuc * Many assembly code routines reference fields in it. The offsets to these 14433d6423SLionel Sambuc * fields are defined in the assembler include file sconst.h. When changing 15433d6423SLionel Sambuc * struct proc, be sure to change sconst.h to match. 16433d6423SLionel Sambuc */ 17433d6423SLionel Sambuc #include <minix/com.h> 18433d6423SLionel Sambuc #include <minix/portio.h> 19433d6423SLionel Sambuc #include "const.h" 20433d6423SLionel Sambuc #include "priv.h" 21433d6423SLionel Sambuc 22433d6423SLionel Sambuc struct proc { 23433d6423SLionel Sambuc struct stackframe_s p_reg; /* process' registers saved in stack frame */ 24433d6423SLionel Sambuc struct segframe p_seg; /* segment descriptors */ 25433d6423SLionel Sambuc proc_nr_t p_nr; /* number of this process (for fast access) */ 26433d6423SLionel Sambuc struct priv *p_priv; /* system privileges structure */ 27433d6423SLionel Sambuc volatile u32_t p_rts_flags; /* process is runnable only if zero */ 28433d6423SLionel Sambuc volatile u32_t p_misc_flags; /* flags that do not suspend the process */ 29433d6423SLionel Sambuc 30433d6423SLionel Sambuc char p_priority; /* current process priority */ 31433d6423SLionel Sambuc u64_t p_cpu_time_left; /* time left to use the cpu */ 32433d6423SLionel Sambuc unsigned p_quantum_size_ms; /* assigned time quantum in ms 33433d6423SLionel Sambuc FIXME remove this */ 34433d6423SLionel Sambuc struct proc *p_scheduler; /* who should get out of quantum msg */ 35433d6423SLionel Sambuc unsigned p_cpu; /* what CPU is the process running on */ 36433d6423SLionel Sambuc #ifdef CONFIG_SMP 37433d6423SLionel Sambuc bitchunk_t p_cpu_mask[BITMAP_CHUNKS(CONFIG_MAX_CPUS)]; /* what CPUs is the 38433d6423SLionel Sambuc process allowed to 39433d6423SLionel Sambuc run on */ 40433d6423SLionel Sambuc bitchunk_t p_stale_tlb[BITMAP_CHUNKS(CONFIG_MAX_CPUS)]; /* On which cpu are 41433d6423SLionel Sambuc possibly stale entries from this process and has 42433d6423SLionel Sambuc to be fresed the next kernel touches this 43433d6423SLionel Sambuc processes memory 44433d6423SLionel Sambuc */ 45433d6423SLionel Sambuc #endif 46433d6423SLionel Sambuc 47433d6423SLionel Sambuc /* Accounting statistics that get passed to the process' scheduler */ 48433d6423SLionel Sambuc struct { 49433d6423SLionel Sambuc u64_t enter_queue; /* time when enqueued (cycles) */ 50433d6423SLionel Sambuc u64_t time_in_queue; /* time spent in queue */ 51433d6423SLionel Sambuc unsigned long dequeues; 52433d6423SLionel Sambuc unsigned long ipc_sync; 53433d6423SLionel Sambuc unsigned long ipc_async; 54433d6423SLionel Sambuc unsigned long preempted; 55433d6423SLionel Sambuc } p_accounting; 56433d6423SLionel Sambuc 57*6b0f33d0SDavid van Moolenbroek clock_t p_dequeued; /* uptime at which process was last dequeued */ 58*6b0f33d0SDavid van Moolenbroek 59433d6423SLionel Sambuc clock_t p_user_time; /* user time in ticks */ 60433d6423SLionel Sambuc clock_t p_sys_time; /* sys time in ticks */ 61433d6423SLionel Sambuc 62433d6423SLionel Sambuc clock_t p_virt_left; /* number of ticks left on virtual timer */ 63433d6423SLionel Sambuc clock_t p_prof_left; /* number of ticks left on profile timer */ 64433d6423SLionel Sambuc 65433d6423SLionel Sambuc u64_t p_cycles; /* how many cycles did the process use */ 66433d6423SLionel Sambuc u64_t p_kcall_cycles; /* kernel cycles caused by this proc (kcall) */ 67433d6423SLionel Sambuc u64_t p_kipc_cycles; /* cycles caused by this proc (ipc) */ 68433d6423SLionel Sambuc 691f3ef2b2SDavid van Moolenbroek u64_t p_tick_cycles; /* cycles accumulated for up to a clock tick */ 701f3ef2b2SDavid van Moolenbroek struct cpuavg p_cpuavg; /* running CPU average, for ps(1) */ 711f3ef2b2SDavid van Moolenbroek 72433d6423SLionel Sambuc struct proc *p_nextready; /* pointer to next ready process */ 73433d6423SLionel Sambuc struct proc *p_caller_q; /* head of list of procs wishing to send */ 74433d6423SLionel Sambuc struct proc *p_q_link; /* link to next proc wishing to send */ 75433d6423SLionel Sambuc endpoint_t p_getfrom_e; /* from whom does process want to receive? */ 76433d6423SLionel Sambuc endpoint_t p_sendto_e; /* to whom does process want to send? */ 77433d6423SLionel Sambuc 78433d6423SLionel Sambuc sigset_t p_pending; /* bit map for pending kernel signals */ 79433d6423SLionel Sambuc 80433d6423SLionel Sambuc char p_name[PROC_NAME_LEN]; /* name of the process, including \0 */ 81433d6423SLionel Sambuc 82433d6423SLionel Sambuc endpoint_t p_endpoint; /* endpoint number, generation-aware */ 83433d6423SLionel Sambuc 84433d6423SLionel Sambuc message p_sendmsg; /* Message from this process if SENDING */ 85433d6423SLionel Sambuc message p_delivermsg; /* Message for this process if MF_DELIVERMSG */ 86433d6423SLionel Sambuc vir_bytes p_delivermsg_vir; /* Virtual addr this proc wants message at */ 87433d6423SLionel Sambuc 88433d6423SLionel Sambuc /* If handler functions detect a process wants to do something with 89433d6423SLionel Sambuc * memory that isn't present, VM has to fix it. Until it has asked 90433d6423SLionel Sambuc * what needs to be done and fixed it, save necessary state here. 91433d6423SLionel Sambuc * 92433d6423SLionel Sambuc * The requester gets a copy of its request message in reqmsg and gets 93433d6423SLionel Sambuc * VMREQUEST set. 94433d6423SLionel Sambuc */ 95433d6423SLionel Sambuc struct { 96433d6423SLionel Sambuc struct proc *nextrestart; /* next in vmrestart chain */ 97433d6423SLionel Sambuc struct proc *nextrequestor; /* next in vmrequest chain */ 98433d6423SLionel Sambuc #define VMSTYPE_SYS_NONE 0 99433d6423SLionel Sambuc #define VMSTYPE_KERNELCALL 1 100433d6423SLionel Sambuc #define VMSTYPE_DELIVERMSG 2 101433d6423SLionel Sambuc #define VMSTYPE_MAP 3 102433d6423SLionel Sambuc 103433d6423SLionel Sambuc int type; /* suspended operation */ 10450b7f13fSCristiano Giuffrida union ixfer_saved{ 105433d6423SLionel Sambuc /* VMSTYPE_SYS_MESSAGE */ 106433d6423SLionel Sambuc message reqmsg; /* suspended request message */ 107433d6423SLionel Sambuc } saved; 108433d6423SLionel Sambuc 109433d6423SLionel Sambuc /* Parameters of request to VM */ 110433d6423SLionel Sambuc int req_type; 111433d6423SLionel Sambuc endpoint_t target; 11250b7f13fSCristiano Giuffrida union ixfer_params{ 113433d6423SLionel Sambuc struct { 114433d6423SLionel Sambuc vir_bytes start, length; /* memory range */ 115433d6423SLionel Sambuc u8_t writeflag; /* nonzero for write access */ 116433d6423SLionel Sambuc } check; 117433d6423SLionel Sambuc } params; 118433d6423SLionel Sambuc /* VM result when available */ 119433d6423SLionel Sambuc int vmresult; 120433d6423SLionel Sambuc 121433d6423SLionel Sambuc /* If the suspended operation is a sys_call, its details are 122433d6423SLionel Sambuc * stored here. 123433d6423SLionel Sambuc */ 124433d6423SLionel Sambuc } p_vmrequest; 125433d6423SLionel Sambuc 126433d6423SLionel Sambuc int p_found; /* consistency checking variables */ 127433d6423SLionel Sambuc int p_magic; /* check validity of proc pointers */ 128433d6423SLionel Sambuc 129433d6423SLionel Sambuc /* if MF_SC_DEFER is set, this struct is valid and contains the 130433d6423SLionel Sambuc * do_ipc() arguments that are still to be executed 131433d6423SLionel Sambuc */ 132433d6423SLionel Sambuc struct { reg_t r1, r2, r3; } p_defer; 133433d6423SLionel Sambuc 134433d6423SLionel Sambuc #if DEBUG_TRACE 135433d6423SLionel Sambuc int p_schedules; 136433d6423SLionel Sambuc #endif 137433d6423SLionel Sambuc }; 138433d6423SLionel Sambuc 139433d6423SLionel Sambuc #endif /* __ASSEMBLY__ */ 140433d6423SLionel Sambuc 141433d6423SLionel Sambuc /* Bits for the runtime flags. A process is runnable iff p_rts_flags == 0. */ 142433d6423SLionel Sambuc #define RTS_SLOT_FREE 0x01 /* process slot is free */ 143433d6423SLionel Sambuc #define RTS_PROC_STOP 0x02 /* process has been stopped */ 144433d6423SLionel Sambuc #define RTS_SENDING 0x04 /* process blocked trying to send */ 145433d6423SLionel Sambuc #define RTS_RECEIVING 0x08 /* process blocked trying to receive */ 146433d6423SLionel Sambuc #define RTS_SIGNALED 0x10 /* set when new kernel signal arrives */ 147433d6423SLionel Sambuc #define RTS_SIG_PENDING 0x20 /* unready while signal being processed */ 148433d6423SLionel Sambuc #define RTS_P_STOP 0x40 /* set when process is being traced */ 149433d6423SLionel Sambuc #define RTS_NO_PRIV 0x80 /* keep forked system process from running */ 150433d6423SLionel Sambuc #define RTS_NO_ENDPOINT 0x100 /* process cannot send or receive messages */ 151433d6423SLionel Sambuc #define RTS_VMINHIBIT 0x200 /* not scheduled until pagetable set by VM */ 152433d6423SLionel Sambuc #define RTS_PAGEFAULT 0x400 /* process has unhandled pagefault */ 153433d6423SLionel Sambuc #define RTS_VMREQUEST 0x800 /* originator of vm memory request */ 154433d6423SLionel Sambuc #define RTS_VMREQTARGET 0x1000 /* target of vm memory request */ 155433d6423SLionel Sambuc #define RTS_PREEMPTED 0x4000 /* this process was preempted by a higher 156433d6423SLionel Sambuc priority process and we should pick a new one 157433d6423SLionel Sambuc to run. Processes with this flag should be 158433d6423SLionel Sambuc returned to the front of their current 159433d6423SLionel Sambuc priority queue if they are still runnable 160433d6423SLionel Sambuc before we pick a new one 161433d6423SLionel Sambuc */ 162433d6423SLionel Sambuc #define RTS_NO_QUANTUM 0x8000 /* process ran out of its quantum and we should 163433d6423SLionel Sambuc pick a new one. Process was dequeued and 164433d6423SLionel Sambuc should be enqueued at the end of some run 165433d6423SLionel Sambuc queue again */ 166433d6423SLionel Sambuc #define RTS_BOOTINHIBIT 0x10000 /* not ready until VM has made it */ 167433d6423SLionel Sambuc 168433d6423SLionel Sambuc /* A process is runnable iff p_rts_flags == 0. */ 169433d6423SLionel Sambuc #define rts_f_is_runnable(flg) ((flg) == 0) 170433d6423SLionel Sambuc #define proc_is_runnable(p) (rts_f_is_runnable((p)->p_rts_flags)) 171433d6423SLionel Sambuc 172433d6423SLionel Sambuc #define proc_is_preempted(p) ((p)->p_rts_flags & RTS_PREEMPTED) 173433d6423SLionel Sambuc #define proc_no_quantum(p) ((p)->p_rts_flags & RTS_NO_QUANTUM) 174433d6423SLionel Sambuc #define proc_ptr_ok(p) ((p)->p_magic == PMAGIC) 175433d6423SLionel Sambuc #define proc_used_fpu(p) ((p)->p_misc_flags & (MF_FPU_INITIALIZED)) 176433d6423SLionel Sambuc 177433d6423SLionel Sambuc /* test whether the process is scheduled by the kernel's default policy */ 178433d6423SLionel Sambuc #define proc_kernel_scheduler(p) ((p)->p_scheduler == NULL || \ 179433d6423SLionel Sambuc (p)->p_scheduler == (p)) 180433d6423SLionel Sambuc 181433d6423SLionel Sambuc /* Macro to return: on which process is a certain process blocked? 182433d6423SLionel Sambuc * return endpoint number (can be ANY) or NONE. It's important to 183433d6423SLionel Sambuc * check RTS_SENDING first, and then RTS_RECEIVING, as they could 184433d6423SLionel Sambuc * both be on (if a ipc_sendrec() blocks on sending), and p_getfrom_e 185433d6423SLionel Sambuc * could be nonsense even though RTS_RECEIVING is on. 186433d6423SLionel Sambuc */ 187433d6423SLionel Sambuc #define P_BLOCKEDON(p) \ 188433d6423SLionel Sambuc ( \ 189433d6423SLionel Sambuc ((p)->p_rts_flags & RTS_SENDING) ? \ 190433d6423SLionel Sambuc (p)->p_sendto_e : \ 191433d6423SLionel Sambuc ( \ 192433d6423SLionel Sambuc ( \ 193433d6423SLionel Sambuc ((p)->p_rts_flags & RTS_RECEIVING) ? \ 194433d6423SLionel Sambuc (p)->p_getfrom_e : \ 195433d6423SLionel Sambuc NONE \ 196433d6423SLionel Sambuc ) \ 197433d6423SLionel Sambuc ) \ 198433d6423SLionel Sambuc ) 199433d6423SLionel Sambuc 200433d6423SLionel Sambuc /* These runtime flags can be tested and manipulated by these macros. */ 201433d6423SLionel Sambuc 202433d6423SLionel Sambuc #define RTS_ISSET(rp, f) (((rp)->p_rts_flags & (f)) == (f)) 203433d6423SLionel Sambuc 204433d6423SLionel Sambuc 205433d6423SLionel Sambuc /* Set flag and dequeue if the process was runnable. */ 206433d6423SLionel Sambuc #define RTS_SET(rp, f) \ 207433d6423SLionel Sambuc do { \ 208433d6423SLionel Sambuc const int rts = (rp)->p_rts_flags; \ 209433d6423SLionel Sambuc (rp)->p_rts_flags |= (f); \ 210433d6423SLionel Sambuc if(rts_f_is_runnable(rts) && !proc_is_runnable(rp)) { \ 211433d6423SLionel Sambuc dequeue(rp); \ 212433d6423SLionel Sambuc } \ 213433d6423SLionel Sambuc } while(0) 214433d6423SLionel Sambuc 215433d6423SLionel Sambuc /* Clear flag and enqueue if the process was not runnable but is now. */ 216433d6423SLionel Sambuc #define RTS_UNSET(rp, f) \ 217433d6423SLionel Sambuc do { \ 218433d6423SLionel Sambuc int rts; \ 219433d6423SLionel Sambuc rts = (rp)->p_rts_flags; \ 220433d6423SLionel Sambuc (rp)->p_rts_flags &= ~(f); \ 221433d6423SLionel Sambuc if(!rts_f_is_runnable(rts) && proc_is_runnable(rp)) { \ 222433d6423SLionel Sambuc enqueue(rp); \ 223433d6423SLionel Sambuc } \ 224433d6423SLionel Sambuc } while(0) 225433d6423SLionel Sambuc 226433d6423SLionel Sambuc /* Set flags to this value. */ 227433d6423SLionel Sambuc #define RTS_SETFLAGS(rp, f) \ 228433d6423SLionel Sambuc do { \ 229433d6423SLionel Sambuc if(proc_is_runnable(rp) && (f)) { dequeue(rp); } \ 230433d6423SLionel Sambuc (rp)->p_rts_flags = (f); \ 231433d6423SLionel Sambuc } while(0) 232433d6423SLionel Sambuc 233433d6423SLionel Sambuc /* Misc flags */ 234433d6423SLionel Sambuc #define MF_REPLY_PEND 0x001 /* reply to IPC_REQUEST is pending */ 235433d6423SLionel Sambuc #define MF_VIRT_TIMER 0x002 /* process-virtual timer is running */ 236433d6423SLionel Sambuc #define MF_PROF_TIMER 0x004 /* process-virtual profile timer is running */ 237433d6423SLionel Sambuc #define MF_KCALL_RESUME 0x008 /* processing a kernel call was interrupted, 238433d6423SLionel Sambuc most likely because we need VM to resolve a 239433d6423SLionel Sambuc problem or a long running copy was preempted. 240433d6423SLionel Sambuc We need to resume the kernel call execution 241433d6423SLionel Sambuc now 242433d6423SLionel Sambuc */ 243433d6423SLionel Sambuc #define MF_DELIVERMSG 0x040 /* Copy message for him before running */ 244433d6423SLionel Sambuc #define MF_SIG_DELAY 0x080 /* Send signal when no longer sending */ 245433d6423SLionel Sambuc #define MF_SC_ACTIVE 0x100 /* Syscall tracing: in a system call now */ 246433d6423SLionel Sambuc #define MF_SC_DEFER 0x200 /* Syscall tracing: deferred system call */ 247433d6423SLionel Sambuc #define MF_SC_TRACE 0x400 /* Syscall tracing: trigger syscall events */ 248433d6423SLionel Sambuc #define MF_FPU_INITIALIZED 0x1000 /* process already used math, so fpu 249433d6423SLionel Sambuc * regs are significant (initialized)*/ 250433d6423SLionel Sambuc #define MF_SENDING_FROM_KERNEL 0x2000 /* message of this process is from kernel */ 251433d6423SLionel Sambuc #define MF_CONTEXT_SET 0x4000 /* don't touch context */ 252433d6423SLionel Sambuc #define MF_SPROF_SEEN 0x8000 /* profiling has seen this process */ 253433d6423SLionel Sambuc #define MF_FLUSH_TLB 0x10000 /* if set, TLB must be flushed before letting 254433d6423SLionel Sambuc this process run again. Currently it only 255433d6423SLionel Sambuc applies to SMP */ 256433d6423SLionel Sambuc #define MF_SENDA_VM_MISS 0x20000 /* set if a processes wanted to receive an asyn 257433d6423SLionel Sambuc message from this sender but could not 258433d6423SLionel Sambuc because of VM modifying the sender's address 259433d6423SLionel Sambuc space*/ 260433d6423SLionel Sambuc #define MF_STEP 0x40000 /* Single-step process */ 2618bab0dfaSBen Gras #define MF_MSGFAILED 0x80000 262366d18b2SDavid van Moolenbroek #define MF_NICED 0x100000 /* user has lowered max process priority */ 263433d6423SLionel Sambuc 264433d6423SLionel Sambuc /* Magic process table addresses. */ 265433d6423SLionel Sambuc #define BEG_PROC_ADDR (&proc[0]) 266433d6423SLionel Sambuc #define BEG_USER_ADDR (&proc[NR_TASKS]) 267433d6423SLionel Sambuc #define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS]) 268433d6423SLionel Sambuc 269433d6423SLionel Sambuc #define proc_addr(n) (&(proc[NR_TASKS + (n)])) 270433d6423SLionel Sambuc #define proc_nr(p) ((p)->p_nr) 271433d6423SLionel Sambuc 272433d6423SLionel Sambuc #define isokprocn(n) ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS) 273433d6423SLionel Sambuc #define isemptyn(n) isemptyp(proc_addr(n)) 274433d6423SLionel Sambuc #define isemptyp(p) ((p)->p_rts_flags == RTS_SLOT_FREE) 275433d6423SLionel Sambuc #define iskernelp(p) ((p) < BEG_USER_ADDR) 276433d6423SLionel Sambuc #define iskerneln(n) ((n) < 0) 277433d6423SLionel Sambuc #define isuserp(p) isusern((p) >= BEG_USER_ADDR) 278433d6423SLionel Sambuc #define isusern(n) ((n) >= 0) 279433d6423SLionel Sambuc #define isrootsysn(n) ((n) == ROOT_SYS_PROC_NR) 280433d6423SLionel Sambuc 281433d6423SLionel Sambuc #ifndef __ASSEMBLY__ 282433d6423SLionel Sambuc 283433d6423SLionel Sambuc EXTERN struct proc proc[NR_TASKS + NR_PROCS]; /* process table */ 284433d6423SLionel Sambuc 285433d6423SLionel Sambuc int mini_send(struct proc *caller_ptr, endpoint_t dst_e, message *m_ptr, 286433d6423SLionel Sambuc int flags); 287433d6423SLionel Sambuc 288433d6423SLionel Sambuc #endif /* __ASSEMBLY__ */ 289433d6423SLionel Sambuc 290433d6423SLionel Sambuc #endif /* PROC_H */ 291