///////////////////////////////////////////////////////////////////////////////// // File : ctx_handler.h // Date : 01/04/2012 // Authors : alain greiner & joel porquet // Copyright (c) UPMC-LIP6 ///////////////////////////////////////////////////////////////////////////////// // The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel. // This code is used to support context switch when several threads are executing // in time multiplexing on a single processor. // The threads are statically allocated to a processor in the boot phase, and // there is one private scheduler per processor. Each sheduler occupies 8K bytes, // and contains up to 14 thread contexts (thread_id is from 0 to 13). // The thread context [13] is reserved for the "idle" thread that is // launched by the scheduler when there is no other runable thread. ///////////////////////////////////////////////////////////////////////////////// // A thread context is an array of 64 uint32 words => 256 bytes. // It contains copies of processor registers (when the thread is preempted) // and some general informations associated to a thread, such as the private // peripheral channels allocated to the thread, the vspace index, the two // thread index, and the runnable status. ///////////////////////////////////////////////////////////////////////////////// // ctx[0] <- *** |ctx[8] <- $8 |ctx[16]<- $16 |ctx[24]<- $24 // ctx[1] <- $1 |ctx[9] <- $9 |ctx[17]<- $17 |ctx[25]<- $25 // ctx[2] <- $2 |ctx[10]<- $10 |ctx[18]<- $18 |ctx[26]<- LO // ctx[3] <- $3 |ctx[11]<- $11 |ctx[19]<- $19 |ctx[27]<- HI // ctx[4] <- A0 |ctx[12]<- $12 |ctx[20]<- $20 |ctx[28]<- $28 // ctx[5] <- A1 |ctx[13]<- $13 |ctx[21]<- $21 |ctx[29]<- SP // ctx[6] <- A2 |ctx[14]<- $14 |ctx[22]<- $22 |ctx[30]<- $30 // ctx[7] <- A3 |ctx[15]<- $15 |ctx[23]<- $23 |ctx[31]<- RA // // ctx[32]<- EPC |ctx[40]<- TTY |ctx[48]<- TRDID |ctx[56]<- *** // ctx[33]<- CR |ctx[41]<- CMA_FB |ctx[49]<- LTID |ctx[57]<- *** // ctx[34]<- SR |ctx[42]<- CMA_RX |ctx[50]<- NORUN |ctx[58]<- *** // ctx[35]<- BVAR |ctx[43]<- CMA_TX |ctx[51]<- COPROC |ctx[59]<- *** // ctx[36]<- PTAB |ctx[44]<- NIC_RX |ctx[52]<- ENTRY |ctx[60]<- *** // ctx[37]<- NPT2 |ctx[45]<- NIC_TX |ctx[53]<- SIGS |ctx[61]<- *** // ctx[38]<- *** |ctx[46]<- TIM |ctx[54]<- VSID |ctx[62]<- *** // ctx[39]<- PTPR |ctx[47]<- HBA |ctx[55]<- LOCKS |ctx[63]<- *** ///////////////////////////////////////////////////////////////////////////////// #ifndef _CTX_HANDLER_H #define _CTX_HANDLER_H #include ///////////////////////////////////////////////////////////////////////////////// // Definition of some thread context slots indexes ///////////////////////////////////////////////////////////////////////////////// #define CTX_A0_ID 4 // Argument 0 #define CTX_A1_ID 5 // Argument 1 #define CTX_A2_ID 6 // Argument 2 #define CTX_A3_ID 7 // Argument 3 #define CTX_SP_ID 29 // Stack Pointer #define CTX_RA_ID 31 // Return Address #define CTX_EPC_ID 32 // Exception Program Counter (CP0) #define CTX_CR_ID 33 // Cause Register (CP0) #define CTX_SR_ID 34 // Status Register (CP0) #define CTX_BVAR_ID 35 // Bad Virtual Address Register (CP0) #define CTX_PTAB_ID 36 // Page Table Virtual address #define CTX_NPT2_ID 37 // Next free PT2 index // 38 #define CTX_PTPR_ID 39 // Page Table Pointer Register (PADDR>>13) #define CTX_TTY_ID 40 // private TTY channel index #define CTX_CMA_FB_ID 41 // private CMA channel index for FBF write #define CTX_CMA_RX_ID 42 // private CMA channel index for NIC_TX #define CTX_CMA_TX_ID 43 // private CMA channel index for NIC_RX #define CTX_NIC_RX_ID 44 // private NIC channel index RX transfer #define CTX_NIC_TX_ID 45 // private NIC channel index TX transfer #define CTX_TIM_ID 46 // ptivate TIM channel index #define CTX_HBA_ID 47 // private HBA channel index #define CTX_TRDID_ID 48 // Global Thread Index ( x | y | p | ltid ) #define CTX_LTID_ID 49 // Local Thread Index in scheduler #define CTX_NORUN_ID 50 // bit-vector : thread runable if all zero #define CTX_COPROC_ID 51 // coprocessor coordinates (cluster_xy) #define CTX_ENTRY_ID 52 // Virtual address of thread entry point #define CTX_SIGS_ID 53 // bit-vector : pending signals #define CTX_VSID_ID 54 // Vspace Index #define CTX_LOCKS_ID 55 // bit-vector : kernel locks taken ///////////////////////////////////////////////////////////////////////////////// // Definition of the NORUN bit-vector masks ///////////////////////////////////////////////////////////////////////////////// #define NORUN_MASK_THREAD 0x00000001 // Task not active #define NORUN_MASK_IOC 0x00000002 // Task blocked on IOC transfer #define NORUN_MASK_COPROC 0x00000004 // Task blocked on COPROC transfer #define NORUN_MASK_TTY 0x00000008 // Task blocked on TTY_RX transfer ///////////////////////////////////////////////////////////////////////////////// // Definition of the SIGS bit-vector masks ///////////////////////////////////////////////////////////////////////////////// #define SIGS_MASK_KILL 0x00000001 // Task desactivated at next tick ///////////////////////////////////////////////////////////////////////////////// // Definition of the LOCKS bit-vector masks ///////////////////////////////////////////////////////////////////////////////// #define LOCKS_MASK_BDV 0x00000001 // BDV kernel lock taken #define LOCKS_MASK_FAT 0x00000002 // FAT kernel lock taken #define LOCKS_MASK_FBF 0x00000004 // FBF kernel lock taken ///////////////////////////////////////////////////////////////////////////////// // Task context and scheduler structures ///////////////////////////////////////////////////////////////////////////////// typedef struct thread_context_s // 256 bytes { unsigned int slot[64]; } thread_context_t; typedef struct static_scheduler_s // 8 Kbytes { thread_context_t context[14]; // at most 14 threads (including idle_thread) unsigned int threads; // actual number of allocated threads unsigned int current; // current thread index unsigned int hwi_vector[32]; // hardware interrupt vector unsigned int pti_vector[32]; // timer interrupt vector unsigned int wti_vector[32]; // software interrupt vector unsigned int reserved[30]; // padding to 4 Kbytes unsigned int idle_stack[1024]; // private stack for idle stack (4Kbytes) } static_scheduler_t; #define IDLE_THREAD_INDEX 13 ///////////////////////////////////////////////////////////////////////////////// // Extern Functions ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// // This function performs a context switch between the running thread // and another thread, using a round-robin sheduling policy between all // threads allocated to a given processor (static allocation). // It selects the next runable thread to resume execution. // If the only runable thread is the current thread, return without context switch. // If there is no runable thread, the scheduler switch to the default "idle" thread. // The return address contained in $31 is saved in the current thread context // (in the ctx[31] slot), and the function actually returns to the address // contained in the ctx[31] slot of the next thread context. ///////////////////////////////////////////////////////////////////////////////// extern void _ctx_switch(); ///////////////////////////////////////////////////////////////////////////////// // The address of this function is used to initialise the return address // in the "idle" thread context. ///////////////////////////////////////////////////////////////////////////////// extern void _ctx_eret(); ///////////////////////////////////////////////////////////////////////////////// // This function is executed thread when no other thread can be executed. ///////////////////////////////////////////////////////////////////////////////// extern void _idle_thread(); #endif