Changeset 440
- Timestamp:
- Nov 3, 2014, 11:03:55 AM (10 years ago)
- Location:
- soft/giet_vm/giet_kernel
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/ctx_handler.c
r428 r440 6 6 ////////////////////////////////////////////////////////////////////////////////// 7 7 8 #include <ctx_handler.h> 8 9 #include <giet_config.h> 9 #include <tim_driver.h> 10 #include <utils.h> 11 #include <kernel_utils.h> 10 12 #include <xcu_driver.h> 11 #include <tty_driver.h>12 #include <utils.h>13 #include <ctx_handler.h>14 #include <mapping_info.h>15 #include <sys_handler.h>16 13 14 ////////// defined in giet_kernel/switch.s file ///////// 17 15 extern void _task_switch(unsigned int *, unsigned int *); 18 16 19 ///////////////////////////////////////////////////////////////////////////////// 20 // This function performs a context switch between the running task 21 // and another task, using a round-robin sheduling policy between all 22 // tasks allocated to a given processor (static allocation). 23 // It selects the next runable task to resume execution. 24 // If the only runable task is the current task, return without context switch. 25 // If there is no runable task, the scheduler switch to the default "idle" task. 26 ///////////////////////////////////////////////////////////////////////////////// 27 // Implementation note 28 // The return address contained in $31 is saved in the current task context 29 // (in the ctx[31] slot), and the function actually returns to the address 30 // contained in the ctx[31] slot of the next task context. 31 ///////////////////////////////////////////////////////////////////////////////// 17 ////////////////// 32 18 void _ctx_switch() 33 19 { … … 98 84 } //end _ctx_switch() 99 85 100 ///////////////////////////////////////////////////////////////////////////////////// 101 // This function is executed as the"idle" task when no other task can be executed 102 ///////////////////////////////////////////////////////////////////////////////////// 86 ///////////////// 103 87 void _idle_task() 104 88 { … … 107 91 unsigned int x = cluster_xy >> Y_WIDTH; 108 92 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 109 unsigned int lpid= gpid & ((1<<P_WIDTH)-1);93 unsigned int p = gpid & ((1<<P_WIDTH)-1); 110 94 111 95 while(1) … … 126 110 127 111 // warning message 128 _printf("\n[GIET WARNING] Processor[%d,%d,%d] still idle at cycle %d\n", 129 x, y, lpid, _get_proctime() ); 112 _puts("\n[GIET WARNING] Processor["); 113 _putd( x ); 114 _puts(","); 115 _putd( y ); 116 _puts(","); 117 _putd( p ); 118 _puts("] still idle at cycle "); 119 _putd( _get_proctime() ); 120 _puts("\n"); 130 121 } 131 122 } // end ctx_idle() 132 123 133 124 134 ///////////////////////////////////////////////////////////////////////////////// 135 // The address of this function is used to initialise the return address 136 // in the "idle" task context. 137 ///////////////////////////////////////////////////////////////////////////////// 125 //////////////// 138 126 void _ctx_eret() 139 127 { -
soft/giet_vm/giet_kernel/ctx_handler.h
r396 r440 9 9 // in time multiplexing on a single processor. 10 10 // The tasks are statically allocated to a processor in the boot phase, and 11 // there is one private scheduler per processor. Each sheduler occupies 4K bytes,11 // there is one private scheduler per processor. Each sheduler occupies 8K bytes, 12 12 // and contains up to 14 task contexts (task_id is from 0 to 13). 13 13 // The task context [13] is reserved for the "idle" task that does nothing, and … … 15 15 ///////////////////////////////////////////////////////////////////////////////////////// 16 16 // A task context is an array of 64 words = 256 bytes. 17 // It contains copies of processor registers (when the task is preempted): 18 // - GPR[i], generally stored in slot (i). $0, $26 & $27 are not saved. 19 // - HI & LO registers 20 // - CP0 registers: EPC, SR, CR, BVAR 21 // - CP2 registers : PTPR 22 // It contains some general informations associated to the task: 23 // - TTY : TTY channel global index 24 // - NIC : NIC channel global index 25 // - CMA : CMA channel global index 26 // - HBA : HBA channel global index 27 // - DMA : DMA channel local index 28 // - TIM : TIM channel local index 29 // - PTAB : page table virtual base address 30 // - LTID : Task local index (in scheduler) 31 // - VSID : Virtual space index 32 // - RUN : Task state (0 => sleeping / 1 => runnable ) 33 // - TRDID : Thread ID index (in vspace) 34 // 17 // It contains copies of processor registers (when the task is preempted) 18 // and some general informations associated to a task, such as the peripherals 19 // allocated to the task (private peripheral channel for multi-channels peripherals). 20 ///////////////////////////////////////////////////////////////////////////////////////// 35 21 // ctx[0] <- *** |ctx[8] <- $8 |ctx[16]<- $16 |ctx[24]<- $24 36 22 // ctx[1] <- $1 |ctx[9] <- $9 |ctx[17]<- $17 |ctx[25]<- $25 … … 42 28 // ctx[7] <- $7 |ctx[15]<- $15 |ctx[23]<- $23 |ctx[31]<- RA 43 29 // 44 // ctx[32]<- EPC |ctx[40]<- TTY |ctx[48]<- TRDID | 45 // ctx[33]<- CR |ctx[41]<- DMA46 // ctx[34]<- SR |ctx[42]<- NIC47 // ctx[35]<- BVAR |ctx[43]<- TIM48 // ctx[36]<- PTAB |ctx[44]<- HBA49 // ctx[37]<- LTID |ctx[45]<- CMA50 // ctx[38]<- VSID |ctx[46]<- GTID51 // ctx[39]<- PTPR |ctx[47]<- RUN 30 // ctx[32]<- EPC |ctx[40]<- TTY |ctx[48]<- TRDID |ctx[56]<- *** 31 // ctx[33]<- CR |ctx[41]<- FBCMA |ctx[49]<- GTID |ctx[57]<- *** 32 // ctx[34]<- SR |ctx[42]<- TXCMA |ctx[50]<- *** |ctx[58]<- *** 33 // ctx[35]<- BVAR |ctx[43]<- RXCMA |ctx[51]<- *** |ctx[59]<- *** 34 // ctx[36]<- PTAB |ctx[44]<- NIC |ctx[52]<- *** |ctx[60]<- *** 35 // ctx[37]<- LTID |ctx[45]<- HBA |ctx[53]<- *** |ctx[61]<- *** 36 // ctx[38]<- VSID |ctx[46]<- TIM |ctx[54]<- *** |ctx[62]<- *** 37 // ctx[39]<- PTPR |ctx[47]<- RUN |ctx[55]<- *** |ctx[63]<- *** 52 38 ///////////////////////////////////////////////////////////////////////////////////////// 53 39 … … 56 42 57 43 #include <giet_config.h> 44 45 ///////////////////////////////////////////////////////////////////////////////// 46 // Definition of the task context slots indexes 47 ///////////////////////////////////////////////////////////////////////////////// 48 49 #define CTX_SP_ID 29 // Stack Pointer 50 #define CTX_RA_ID 31 // Return Address 51 52 #define CTX_EPC_ID 32 // Exception Program Counter (CP0) 53 #define CTX_CR_ID 33 // Cause Register (CP0) 54 #define CTX_SR_ID 34 // Status Register (CP0) 55 #define CTX_BVAR_ID 35 // Bad Virtual Address Register (CP0) 56 #define CTX_PTAB_ID 36 // Page Table Virtual address 57 #define CTX_LTID_ID 37 // Local Task Index (in scheduler) 58 #define CTX_VSID_ID 38 // Vspace Index 59 #define CTX_PTPR_ID 39 // Page Table Pointer Register (PADDR>>13) 60 61 #define CTX_TTY_ID 40 // private TTY channel index 62 #define CTX_FBCMA_ID 41 // private CMA channel index for FBF write 63 #define CTX_TXCMA_ID 42 // private CMA channel index for NIC TX 64 #define CTX_RXCMA_ID 43 // private CMA channel index for NIC RX 65 #define CTX_NIC_ID 44 // private NIC channel index 66 #define CTX_HBA_ID 45 // private HBA channel index 67 #define CTX_TIM_ID 46 // ptivate TIM channel index 68 #define CTX_RUN_ID 47 // Boolean: task runable 69 70 #define CTX_TRDID_ID 48 // Thread Task Index in vspace 71 #define CTX_GTID_ID 49 // Global Task Index in all system 72 73 ///////////////////////////////////////////////////////////////////////////////// 58 74 59 75 ///////////////////////////////////////////////////////////////////////////////// … … 73 89 } static_scheduler_t; 74 90 91 #define IDLE_TASK_INDEX 13 92 75 93 76 94 ///////////////////////////////////////////////////////////////////////////////// 77 // "idle" task index and stack size definition 95 // Schedulers array 96 ///////////////////////////////////////////////////////////////////////////////// 97 extern static_scheduler_t _scheduler[]; 98 99 ///////////////////////////////////////////////////////////////////////////////// 100 // External Functions 78 101 ///////////////////////////////////////////////////////////////////////////////// 79 102 80 #define IDLE_TASK_INDEX 13 103 ///////////////////////////////////////////////////////////////////////////////// 104 // This function performs a context switch between the running task 105 // and another task, using a round-robin sheduling policy between all 106 // tasks allocated to a given processor (static allocation). 107 // It selects the next runable task to resume execution. 108 // If the only runable task is the current task, return without context switch. 109 // If there is no runable task, the scheduler switch to the default "idle" task. 110 // The return address contained in $31 is saved in the current task context 111 // (in the ctx[31] slot), and the function actually returns to the address 112 // contained in the ctx[31] slot of the next task context. 113 ///////////////////////////////////////////////////////////////////////////////// 114 extern void _ctx_switch(); 81 115 82 116 ///////////////////////////////////////////////////////////////////////////////// 83 // Definition of the task context slots indexes 117 // The address of this function is used to initialise the return address 118 // in the "idle" task context. 84 119 ///////////////////////////////////////////////////////////////////////////////// 120 extern void _ctx_eret(); 85 121 86 #define CTX_SP_ID 29 // Stack Pointer 87 #define CTX_RA_ID 31 // Return Address 88 89 #define CTX_EPC_ID 32 // Exception Program Counter (CP0) 90 #define CTX_CR_ID 33 // Cause Register (CP0) 91 #define CTX_SR_ID 34 // Status Register (CP0) 92 #define CTX_BVAR_ID 35 // Bad Virtual Address Register (CP0) 93 #define CTX_PTAB_ID 36 // Page Table Virtual address 94 #define CTX_LTID_ID 37 // Local Task Index (in scheduler) 95 #define CTX_VSID_ID 38 // Vspace Index 96 #define CTX_PTPR_ID 39 // Page Table Pointer Register (PADDR>>13) 97 98 #define CTX_TTY_ID 40 // global TTY channel 99 #define CTX_DMA_ID 41 // local DMA channel 100 #define CTX_NIC_ID 42 // global NIC channel 101 #define CTX_TIM_ID 43 // local TIMER channel 102 #define CTX_HBA_ID 44 // global HBA channel 103 #define CTX_CMA_ID 45 // global CMA channel 104 #define CTX_GTID_ID 46 // Global Task Index 105 #define CTX_RUN_ID 47 // Boolean: task runable 106 107 #define CTX_TRDID_ID 48 // Thread Index in vspace 108 109 ////////////////////////////////////////////////////////////////////////////////// 110 // context switch functions 111 ////////////////////////////////////////////////////////////////////////////////// 112 113 extern void _ctx_switch(); 114 extern void _ctx_eret(); 122 ///////////////////////////////////////////////////////////////////////////////// 123 // This function is executed task when no other task can be executed. 124 ///////////////////////////////////////////////////////////////////////////////// 115 125 extern void _idle_task(); 116 126 117 extern static_scheduler_t _scheduler[];118 127 119 128 #endif -
soft/giet_vm/giet_kernel/exc_handler.c
r428 r440 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The exc_handler.c and exc_handler.h files are part of the GIET nano-kernel.8 // They contains the exception handler code.9 ///////////////////////////////////////////////////////////////////////////////////10 7 11 8 #include <exc_handler.h> 12 9 #include <ctx_handler.h> 13 10 #include <sys_handler.h> 14 #include <tty_driver.h>15 11 #include <utils.h> 12 #include <kernel_utils.h> 16 13 17 14 /////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_kernel/exc_handler.h
r258 r440 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The exc_handler.c and exc_handler.h files are part of the GIET nano-kernel. 8 // They define the exception handler code. 9 /////////////////////////////////////////////////////////////////////////////////// 10 7 11 8 12 #ifndef _EXCP_HANDLER_H … … 10 14 11 15 /////////////////////////////////////////////////////////////////////////////////// 12 // Exception Vector Table (indexed by cause register )16 // Exception Vector Table (indexed by cause register XCODE field) 13 17 /////////////////////////////////////////////////////////////////////////////////// 14 18 15 19 typedef void (*_exc_func_t)(void); 20 16 21 extern const _exc_func_t _cause_vector[16]; 17 22 -
soft/giet_vm/giet_kernel/irq_handler.c
r428 r440 11 11 #include <ctx_handler.h> 12 12 #include <tim_driver.h> 13 #include <icu_driver.h>14 13 #include <xcu_driver.h> 15 14 #include <tty_driver.h> … … 22 21 #include <mapping_info.h> 23 22 #include <utils.h> 24 25 #if !defined( USE_XCU ) 26 # error: You must define USE_XCU in the hard_config.h file 27 #endif 23 #include <kernel_utils.h> 28 24 29 25 #if NB_TIM_CHANNELS 30 extern volatile unsigned char _user_timer_event[X_SIZE*Y_SIZE*NB_TIM_CHANNELS] ; 31 #endif 32 33 /////////////////////////////////////////////////////////////////////////////////// 34 // This function uses the ICU or XICU component (Interrupt Controler Unit) 35 // to get the interrupt vector entry. There is one ICU or XICU component per 36 // cluster, and this component can support up to NB_PROCS_MAX output IRQs. 37 // It returns the highest priority active interrupt index (smaller 38 // indexes have the highest priority). 39 // Any value larger than 31 means "no active interrupt", and no ISR is executed. 40 // 41 // There is three interrupt vectors per processor (stored in the processor's 42 // scheduler) for the three HWI, PTI, and WTI interrupts types. 43 // Each interrupt vector entry contains three bits fields: 44 // - isr_id bits[15:0] : defines the type of ISR to be executed. 45 // - channel_id bits[30:16] : defines the channel for multi-channels peripherals. 46 // - valid bit 31 : valid interrupt vector entry 47 // If the peripheral is replicated in clusters, the channel_id is 48 // a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id 49 /////////////////////////////////////////////////////////////////////////////////// 26 extern volatile unsigned char _user_timer_event[NB_TIM_CHANNELS] ; 27 #endif 28 29 // ISR_TYPE names for display 30 char* _isr_type_name[] = { "DEFAULT", 31 "TICK" , 32 "TTY_RX" , 33 "TTY_TX" , 34 "BDV" , 35 "TIMER" , 36 "WAKUP" , 37 "NIC_RX" , 38 "NIC_TX" , 39 "CMA" , 40 "MMC" , 41 "DMA" , 42 "SPI" }; 43 ///////////////// 50 44 void _irq_demux() 51 45 { … … 61 55 unsigned int icu_out_index = lpid * IRQ_PER_PROCESSOR; 62 56 63 #if USE_XCU64 57 _xcu_get_index( cluster_xy, icu_out_index, &irq_id, &irq_type ); 65 #else66 irq_type = IRQ_TYPE_HWI;67 _icu_get_index( cluster_xy, icu_out_index, &irq_id );68 #endif69 58 70 59 if (irq_id < 32) … … 137 126 } 138 127 139 /////////////////////////////////////////////////////////////////////////////////// 140 // The default ISR is called when there is no active IRQ when the interrupt 141 // handler is called. It simply displays a warning message on TTY[0]. 142 /////////////////////////////////////////////////////////////////////////////////// 128 /////////////////// 143 129 void _isr_default() 144 130 { … … 155 141 156 142 157 /////////////////////////////////////////////////////////////////////////////////// 158 // This ISR can only be executed after a WTI (IPI) to force a context switch 159 // on a remote processor. The context switch is only executed if the current task 160 // is the IDLE_TASK, or if the value written in the mailbox is non zero. 161 /////////////////////////////////////////////////////////////////////////////////// 143 //////////////////////////////////////////////////////////// 162 144 void _isr_wakup( unsigned int irq_type, // HWI / WTI / PTI 163 145 unsigned int irq_id, // index returned by ICU … … 175 157 if ( irq_type != IRQ_TYPE_WTI ) 176 158 { 177 // we don't take the TTY lock to avoid deadlocks178 159 _puts("[GIET ERROR] _isr_wakup() not called by a WTI on processor["); 179 160 _putd( x ); … … 209 190 // context swich if required 210 191 if ( (task == IDLE_TASK_INDEX) || (value != 0) ) _ctx_switch(); 211 } 212 213 ///////////////////////////////////////////////////////////////////////////////////// 214 // This ISR is in charge of context switch, and handles the IRQs generated by 215 // the "system" timers contained in the MULTI_TIMER or in the XICU component. 216 // The ISR acknowledges the IRQ, and calls the _ctx_switch() function. 217 ///////////////////////////////////////////////////////////////////////////////////// 192 } // end _isr_wakup 193 194 /////////////////////////////////////////////////////////// 218 195 void _isr_tick( unsigned int irq_type, // HWI / WTI / PTI 219 196 unsigned int irq_id, // index returned by ICU … … 222 199 unsigned int gpid = _get_procid(); 223 200 unsigned int cluster_xy = gpid >> P_WIDTH; 224 225 // acknowledge HWI or PTI 226 if ( irq_type == IRQ_TYPE_HWI ) _timer_reset_irq( cluster_xy, channel ); 227 else _xcu_timer_reset_irq( cluster_xy, irq_id ); 228 229 #if GIET_DEBUG_IRQS // we don't take the lock to avoid deadlock 230 unsigned int x = cluster_xy >> Y_WIDTH; 231 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 232 unsigned int lpid = gpid & ((1<<P_WIDTH)-1); 201 unsigned int x = cluster_xy >> Y_WIDTH; 202 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 203 unsigned int lpid = gpid & ((1<<P_WIDTH)-1); 204 205 if ( irq_type != IRQ_TYPE_PTI ) 206 { 207 _puts("[GIET ERROR] _isr_tick() not called by a PTI on processor["); 208 _putd( x ); 209 _puts(","); 210 _putd( y ); 211 _puts(","); 212 _putd( lpid ); 213 _puts("] at cycle "); 214 _putd( _get_proctime() ); 215 _puts("\n"); 216 _exit(); 217 } 218 219 // acknowledge PTI 220 _xcu_timer_reset_irq( cluster_xy, irq_id ); 221 222 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlock 233 223 _puts("\n[IRQS DEBUG] Processor["); 234 224 _putd( x ); … … 244 234 // context switch 245 235 _ctx_switch(); 246 } 236 } // end _isr_tick 247 237 248 238 -
soft/giet_vm/giet_kernel/irq_handler.h
r322 r440 36 36 }; 37 37 38 /////////////////////////////////////////////////////////////////////////////// 39 // Prototypes of the Interrupt Service Routines (ISRs) supported by the GIET.40 /////////////////////////////////////////////////////////////////////////////// 38 /////////////////////////////////////////////////////////////////////////////////// 39 // irq_handler functions 40 /////////////////////////////////////////////////////////////////////////////////// 41 41 42 /////////////////////////////////////////////////////////////////////////////////// 43 // This function access the ICU or XICU component (Interrupt Controler Unit) 44 // to get the interrupt vector entry. There is one ICU or XICU component per 45 // cluster, and this component can support up to NB_PROCS_MAX output IRQs. 46 // It returns the highest priority active interrupt index (smaller 47 // indexes have the highest priority). 48 // Any value larger than 31 means "no active interrupt", and no ISR is executed. 49 // 50 // There is three interrupt vectors per processor (stored in the processor's 51 // scheduler) for the three HWI, PTI, and WTI interrupts types. 52 // Each interrupt vector entry contains three bits fields: 53 // - isr_id bits[15:0] : defines the type of ISR to be executed. 54 // - channel_id bits[30:16] : defines the channel for multi-channels peripherals. 55 // - valid bit 31 : valid interrupt vector entry 56 // If the peripheral is replicated in clusters, the channel_id is 57 // a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id 58 /////////////////////////////////////////////////////////////////////////////////// 42 59 extern void _irq_demux(); 43 60 61 /////////////////////////////////////////////////////////////////////////////////// 62 // This default ISR is called when the interrupt handler is called, 63 // and there is no active IRQ. It simply displays a warning message on TTY[0]. 64 /////////////////////////////////////////////////////////////////////////////////// 44 65 extern void _isr_default(); 45 66 67 /////////////////////////////////////////////////////////////////////////////////// 68 // This ISR can only be executed after a WTI (IPI) to force a context switch 69 // on a remote processor. The context switch is only executed if the current task 70 // is the IDLE_TASK, or if the value written in the mailbox is non zero. 71 /////////////////////////////////////////////////////////////////////////////////// 72 extern void _isr_wakup( unsigned int irq_type, 73 unsigned int irq_id, 74 unsigned int channel ); 75 76 ///////////////////////////////////////////////////////////////////////////////////// 77 // This ISR is in charge of context switch, and handles the IRQs generated by 78 // the "system" timers. It can be PTI in case of XCU, or it can be HWI generated 79 // by an external timer in case of ICU. 80 // The ISR acknowledges the IRQ, and calls the _ctx_switch() function. 81 ///////////////////////////////////////////////////////////////////////////////////// 46 82 extern void _isr_tick( unsigned int irq_type, 47 83 unsigned int irq_id, 48 84 unsigned int channel ); 49 50 extern void _isr_wakup( unsigned int irq_type,51 unsigned int irq_id,52 unsigned int channel );53 85 54 86 #endif -
soft/giet_vm/giet_kernel/kernel_init.c
r428 r440 5 5 // Copyright (c) UPMC-LIP6 6 6 //////////////////////////////////////////////////////////////////////////////////// 7 // The kernel_init.c file is part of the GIET-VM nano-kernel. 8 // 9 // This nano-kernel has been written for the MIPS32 processor. 10 // The virtual adresses are on 32 bits and use the (unsigned int) type, but the 11 // physicals addresses can have up to 40 bits, and use the (unsigned long long) type. 12 // It natively supports clusterised shared mmemory multi-processors architectures, 13 // where each processor is identified by a composite index [x,y,lpid], 14 // and where there is one physical memory bank per cluster. 15 // 16 // The kernel_init() function is executed sequencially by all procesors. 17 // It completes the system initialisation that has been started by processor[0,0,0] 18 // in the boot_init() function. It makes the following assuptions, regarding the work 19 // bone by the boot code: 20 // 21 // 1) The page tables associated to the various vspaces have been build 22 // in physical memory, and can be used by the kernel code. 23 // 24 // 2) All schedulers (this include all task contexts) have been initialised, 25 // Both the virtual and the physical base addresses of the page tables 26 // are available in the CTX_PTAB and CTX_PTPR slots. 27 // 28 // 3) The CP0_SCHED register of each processor contains a pointer on its 29 // private scheduler (virtual address). 30 // 31 // 4) The CP2_PTPR register of each processor contains a pointer on 32 // the vspace_0 page table (physical address>>13). 33 // 34 // 5) For all processors, the MMU is activated (CP2_MODE contains 0xF). 35 // 36 // This code must be loaded in .kinit section, in order to control seg_kinit_base, 37 // as this address is used by the boot code to jump into kernel code. 38 // 39 // Each processor performs the following actions: 40 // 1/ contribute to _schedulers_paddr[] array initialisation. 41 // 2/ contribute to _ptabs_paddr[] and _ptabs_vaddr arrays initialisation 42 // 3/ completes task context initialisation for ech allocated task 43 // 4/ compute and set the ICU mask for its private ICU channel 44 // 5/ initialise its private TICK timer (if tasks > 0) 45 // 6/ initialise the "idle" task context in its private scheduler 46 // 7/ initialise SP, SR, PTPR, EPC registers and jump to user code with an eret. 7 // This kernel_init.c file is part of the GIET-VM nano-kernel. 47 8 //////////////////////////////////////////////////////////////////////////////////// 48 9 49 10 #include <giet_config.h> 50 51 // kernel libraries 11 #include <hard_config.h> 52 12 #include <utils.h> 13 #include <kernel_utils.h> 53 14 #include <fat32.h> 54 55 //for peripheral initialisation56 #include <dma_driver.h>57 #include <fbf_driver.h>58 #include <tty_driver.h>59 #include <icu_driver.h>60 15 #include <xcu_driver.h> 61 #include <ioc_driver.h>62 #include <mmc_driver.h>63 #include <mwr_driver.h>64 #include <nic_driver.h>65 #include <tim_driver.h>66 67 16 #include <ctx_handler.h> 68 17 #include <irq_handler.h> 69 70 18 #include <mapping_info.h> 71 19 #include <mips32_registers.h> … … 146 94 { 147 95 // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH) 148 // lpid : local processor id in a cluster ( lpid< NB_PROCS_MAX)96 // p : local processor id in a cluster ( p < NB_PROCS_MAX) 149 97 // cpid : "continuous" processor index = (((x * Y_SIZE + y) * NB_PROCS_MAX) + p 150 98 … … 153 101 unsigned int x = cluster_xy >> Y_WIDTH & ((1<<X_WIDTH)-1); 154 102 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 155 unsigned int lpid= gpid & ((1<<P_WIDTH)-1);156 unsigned int cpid = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + lpid;103 unsigned int p = gpid & ((1<<P_WIDTH)-1); 104 unsigned int cpid = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + p; 157 105 158 106 … … 160 108 while( cpid != kernel_init_barrier ) asm volatile ( "nop" ); 161 109 162 // Step 1 : each processor get its scheduler virtual address from CP0 register163 // and contribute to initialise the _schedulers[] array110 // Step 1 : each processor get its scheduler virtual address from CP0_SCHED register 111 // and contributes to _schedulers[] array initialisation 164 112 165 113 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 166 114 unsigned int tasks = psched->tasks; 167 115 168 _schedulers[x][y][ lpid] = psched;116 _schedulers[x][y][p] = psched; 169 117 170 118 #if GIET_DEBUG_INIT … … 172 120 " - scheduler vbase = %x\n" 173 121 " - tasks = %d\n", 174 x, y, lpid, (unsigned int)psched, tasks );122 x, y, p, (unsigned int)psched, tasks ); 175 123 #endif 176 124 … … 181 129 // - set CTX_EPC slot that must contain the task entry point, 182 130 // and contain only at this point the virtual address of the memory 183 // location containing this entry point. We must switch the PTPR 184 // to use the page table corresponding to the task. 131 // location containing this entry point. 185 132 186 133 unsigned int ltid; … … 188 135 for (ltid = 0; ltid < tasks; ltid++) 189 136 { 190 unsigned int vsid = _get_task_slot( x, y, lpid, ltid , CTX_VSID_ID );191 unsigned int ptab = _get_task_slot( x, y, lpid, ltid , CTX_PTAB_ID );192 unsigned int ptpr = _get_task_slot( x, y, lpid, ltid , CTX_PTPR_ID );137 unsigned int vsid = _get_task_slot( x, y, p, ltid , CTX_VSID_ID ); 138 unsigned int ptab = _get_task_slot( x, y, p, ltid , CTX_PTAB_ID ); 139 unsigned int ptpr = _get_task_slot( x, y, p, ltid , CTX_PTPR_ID ); 193 140 194 141 // initialize PTABS arrays … … 199 146 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] contributes to PTABS arrays\n" 200 147 " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n", 201 x, y, lpid,148 x, y, p, 202 149 vsid, ptab, vsid, ((unsigned long long)ptpr)<<13 ); 203 150 #endif … … 209 156 // compute ctx_ra 210 157 unsigned int ctx_ra = (unsigned int)(&_ctx_eret); 211 _set_task_slot( x, y, lpid, ltid, CTX_RA_ID, ctx_ra );158 _set_task_slot( x, y, p, ltid, CTX_RA_ID, ctx_ra ); 212 159 213 160 // compute ctx_epc 214 unsigned int* ptr = (unsigned int*)_get_task_slot( x, y, lpid, ltid, CTX_EPC_ID );215 _set_task_slot( x, y, lpid, ltid, CTX_EPC_ID, *ptr );161 unsigned int* ptr = (unsigned int*)_get_task_slot( x, y, p, ltid, CTX_EPC_ID ); 162 _set_task_slot( x, y, p, ltid, CTX_EPC_ID, *ptr ); 216 163 217 164 #if GIET_DEBUG_INIT … … 219 166 " - ctx_epc = %x\n" 220 167 " - ctx_ra = %x\n", 221 x, y, lpid, ltid,222 _get_task_slot( x, y, lpid, ltid, CTX_EPC_ID ),223 _get_task_slot( x, y, lpid, ltid, CTX_RA_ID ) );168 x, y, p, ltid, 169 _get_task_slot( x, y, p, ltid, CTX_EPC_ID ), 170 _get_task_slot( x, y, p, ltid, CTX_RA_ID ) ); 224 171 #endif 225 172 226 173 } // end for tasks 227 174 228 // step 4 : compute and set ICU orXCU masks175 // step 4 : compute and set XCU masks 229 176 230 177 unsigned int isr_switch_index = 0xFFFFFFFF; … … 252 199 #if GIET_DEBUG_INIT 253 200 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] sets XCU masks\n" 254 " - ICU HWI_MASK = %x\n" 255 " - ICU WTI_MASK = %x\n" 256 " - ICU PTI_MASK = %x\n", 257 x, y, lpid, hwi_mask, wti_mask, pti_mask ); 258 #endif 259 260 unsigned int channel = lpid * IRQ_PER_PROCESSOR; 261 262 #if USE_XCU 201 " - XCU HWI_MASK = %x\n" 202 " - XCU WTI_MASK = %x\n" 203 " - XCU PTI_MASK = %x\n", 204 x, y, p, hwi_mask, wti_mask, pti_mask ); 205 #endif 206 207 unsigned int channel = p * IRQ_PER_PROCESSOR; 208 263 209 _xcu_set_mask( cluster_xy, channel, hwi_mask, IRQ_TYPE_HWI ); 264 210 _xcu_set_mask( cluster_xy, channel, wti_mask, IRQ_TYPE_WTI ); 265 211 _xcu_set_mask( cluster_xy, channel, pti_mask, IRQ_TYPE_PTI ); 266 #else267 _icu_set_mask( cluster_xy, channel, hwi_mask );268 #endif269 212 270 213 // step 5 : start TICK timer if at least one task … … 275 218 { 276 219 _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n", 277 x, y, lpid);220 x, y, p ); 278 221 _exit(); 279 222 } 280 223 281 224 // start system timer 282 283 #if USE_XCU284 225 _xcu_timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE ); 285 #else286 _timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE );287 #endif288 226 289 227 } … … 291 229 #if GIET_DEBUG_INIT 292 230 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] starts TICK timer\n", 293 x, y, lpid);231 x, y, p ); 294 232 #endif 295 233 … … 302 240 unsigned int pstack = ((unsigned int)psched) + 0x2000; 303 241 304 _set_task_slot( x, y, lpid, IDLE_TASK_INDEX, CTX_SP_ID, pstack);305 _set_task_slot( x, y, lpid, IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int) &_ctx_eret);306 _set_task_slot( x, y, lpid, IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_idle_task);242 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_SP_ID, pstack); 243 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int) &_ctx_eret); 244 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_idle_task); 307 245 308 246 #if GIET_DEBUG_INIT … … 310 248 " - stack_base = %x\n" 311 249 " - stack_size = 0x1000\n", 312 x, y, lpid, pstack - 0x1000 );250 x, y, p, pstack - 0x1000 ); 313 251 #endif 314 252 … … 324 262 325 263 _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n", 326 x, y, lpid);264 x, y, p ); 327 265 } 328 266 else … … 331 269 } 332 270 333 unsigned int sp_value = _get_task_slot( x, y, lpid, ltid, CTX_SP_ID);334 unsigned int sr_value = _get_task_slot( x, y, lpid, ltid, CTX_SR_ID);335 unsigned int ptpr_value = _get_task_slot( x, y, lpid, ltid, CTX_PTPR_ID);336 unsigned int epc_value = _get_task_slot( x, y, lpid, ltid, CTX_EPC_ID);271 unsigned int sp_value = _get_task_slot( x, y, p, ltid, CTX_SP_ID); 272 unsigned int sr_value = _get_task_slot( x, y, p, ltid, CTX_SR_ID); 273 unsigned int ptpr_value = _get_task_slot( x, y, p, ltid, CTX_PTPR_ID); 274 unsigned int epc_value = _get_task_slot( x, y, p, ltid, CTX_EPC_ID); 337 275 338 276 #if GIET_DEBUG_INIT 339 277 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] reach barrier at cycle %d\n", 340 x, y, lpid, _get_proctime() );278 x, y, p, _get_proctime() ); 341 279 #endif 342 280 … … 353 291 " - ptpr = %x\n" 354 292 " - epc = %x\n", 355 x, y, lpid, _get_proctime(),293 x, y, p, _get_proctime(), 356 294 sp_value, sr_value, ptpr_value, epc_value ); 357 295 #endif -
soft/giet_vm/giet_kernel/sys_handler.c
r428 r440 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.8 // It define the syscall_vector[] (at the end of this file), as well as the9 // associated syscall handlers that are not related to peripherals.10 // The syscall handlers for peripherals are defined in the drivers.c file.11 ///////////////////////////////////////////////////////////////////////////////////12 7 13 8 #include <sys_handler.h> … … 16 11 #include <ioc_driver.h> 17 12 #include <nic_driver.h> 18 #include <fbf_driver.h> 13 #include <mmc_driver.h> 14 #include <cma_driver.h> 19 15 #include <ctx_handler.h> 20 16 #include <fat32.h> 21 17 #include <utils.h> 18 #include <kernel_utils.h> 22 19 #include <vmem.h> 23 20 #include <hard_config.h> … … 28 25 # error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file 29 26 #endif 27 28 //////////////////////////////////////////////////////////////////////////// 29 // Channel allocators for peripherals 30 // (TTY[0] is reserved for kernel) 31 //////////////////////////////////////////////////////////////////////////// 32 33 unsigned int _tty_channel_allocator = 1; 34 unsigned int _tim_channel_allocator = 0; 35 unsigned int _cma_channel_allocator = 0; 36 unsigned int _nic_channel_allocator = 0; 30 37 31 38 //////////////////////////////////////////////////////////////////////////// … … 35 42 const void * _syscall_vector[64] = 36 43 { 37 &_ proc_xyp,/* 0x00 */38 &_get_proctime, /* 0x01 */39 &_ tty_write,/* 0x02 */40 &_ tty_read,/* 0x03 */41 &_ timer_start,/* 0x04 */42 &_ timer_stop,/* 0x05 */43 &_ tty_get_lock,/* 0x06 */44 &_ tty_release_lock,/* 0x07 */45 &_ heap_info,/* 0x08 */46 &_ local_task_id, /* 0x09 */47 &_ global_task_id, /* 0x0A */48 &_ fb_cma_init,/* 0x0B */49 &_ fb_cma_write,/* 0x0C */50 &_ fb_cma_stop,/* 0x0D */51 &_ task_exit,/* 0x0E */52 &_ procs_number,/* 0x0F */53 54 &_ fb_sync_write,/* 0x10 */55 &_ fb_sync_read,/* 0x11 */56 &_ thread_id,/* 0x12 */57 &_sys_ukn, /* 0x13 */58 &_sys_ ukn,/* 0x14 */59 &_sys_ ukn,/* 0x15 */60 &_sys_ ukn,/* 0x16 */61 &_sys_ukn, /* 0x17 */62 &_sys_ukn, /* 0x18 */63 &_context_switch, /* 0x19 */64 &_ vobj_get_vbase,/* 0x1A */65 &_ get_xy_from_ptr,/* 0x1B */66 &_ nic_cma_start,/* 0x1C */67 &_ nic_cma_stop, /* 0x1D */68 &_ nic_sync_read,/* 0x1E */69 &_ nic_sync_write,/* 0x1F */70 71 &_fat_user_open, /* 0x20 */72 &_fat_user_read, /* 0x21 */73 &_fat_user_write, /* 0x22 */74 &_fat_user_lseek, /* 0x23 */75 &_fat_fstat, /* 0x24 */76 &_fat_close, /* 0x25 */77 &_sys_ukn, /* 0x26 */78 &_sys_ukn, /* 0x27 */79 &_sys_ukn, /* 0x28 */80 &_sys_ukn, /* 0x29 */81 &_sys_ukn, /* 0x2A */82 &_sys_ukn, /* 0x2B */83 &_sys_ukn, /* 0x2C */84 &_sys_ukn, /* 0x2D */85 &_sys_ukn, /* 0x2E */86 &_sys_ukn, /* 0x2F */87 88 &_sys_ukn, /* 0x30 */89 &_sys_ukn, /* 0x31 */90 &_sys_ukn, /* 0x32 */91 &_sys_ukn, /* 0x33 */92 &_sys_ukn, /* 0x34 */93 &_sys_ukn, /* 0x35 */94 &_sys_ukn, /* 0x36 */95 &_sys_ukn, /* 0x37 */96 &_sys_ukn, /* 0x38 */97 &_sys_ukn, /* 0x39 */98 &_sys_ukn, /* 0x3A */99 &_sys_ukn, /* 0x3B */100 &_sys_ukn, /* 0x3C */101 &_sys_ukn, /* 0x3D */102 &_sys_ukn, /* 0x3E */103 &_sys_ukn, /* 0x3F */44 &_sys_proc_xyp, /* 0x00 */ 45 &_get_proctime, /* 0x01 */ 46 &_sys_tty_write, /* 0x02 */ 47 &_sys_tty_read, /* 0x03 */ 48 &_sys_tty_alloc, /* 0x04 */ 49 &_sys_tty_get_lock, /* 0x05 */ 50 &_sys_tty_release_lock, /* 0x06 */ 51 &_sys_heap_info, /* 0x07 */ 52 &_sys_local_task_id, /* 0x08 */ 53 &_sys_global_task_id, /* 0x09 */ 54 &_sys_fbf_cma_alloc, /* 0x0A */ 55 &_sys_fbf_cma_start, /* 0x0B */ 56 &_sys_fbf_cma_display, /* 0x0C */ 57 &_sys_fbf_cma_stop, /* 0x0D */ 58 &_sys_task_exit, /* 0x0E */ 59 &_sys_procs_number, /* 0x0F */ 60 61 &_sys_fbf_sync_write, /* 0x10 */ 62 &_sys_fbf_sync_read, /* 0x11 */ 63 &_sys_thread_id, /* 0x12 */ 64 &_sys_ukn, /* 0x13 */ 65 &_sys_tim_alloc, /* 0x14 */ 66 &_sys_tim_start, /* 0x15 */ 67 &_sys_tim_stop, /* 0x16 */ 68 &_sys_ukn, /* 0x17 */ 69 &_sys_ukn, /* 0x18 */ 70 &_context_switch, /* 0x19 */ 71 &_sys_vobj_get_vbase, /* 0x1A */ 72 &_sys_vobj_get_length, /* 0x1B */ 73 &_sys_xy_from_ptr, /* 0x1C */ 74 &_sys_nic_alloc, /* 0x1D */ 75 &_sys_nic_sync_send, /* 0x1E */ 76 &_sys_nic_sync_receive, /* 0x1F */ 77 78 &_fat_user_open, /* 0x20 */ 79 &_fat_user_read, /* 0x21 */ 80 &_fat_user_write, /* 0x22 */ 81 &_fat_user_lseek, /* 0x23 */ 82 &_fat_fstat, /* 0x24 */ 83 &_fat_close, /* 0x25 */ 84 &_sys_ukn, /* 0x26 */ 85 &_sys_ukn, /* 0x27 */ 86 &_sys_ukn, /* 0x28 */ 87 &_sys_ukn, /* 0x29 */ 88 &_sys_ukn, /* 0x2A */ 89 &_sys_ukn, /* 0x2B */ 90 &_sys_ukn, /* 0x2C */ 91 &_sys_ukn, /* 0x2D */ 92 &_sys_ukn, /* 0x2E */ 93 &_sys_ukn, /* 0x2F */ 94 95 &_sys_ukn, /* 0x30 */ 96 &_sys_ukn, /* 0x31 */ 97 &_sys_ukn, /* 0x32 */ 98 &_sys_ukn, /* 0x33 */ 99 &_sys_ukn, /* 0x34 */ 100 &_sys_ukn, /* 0x35 */ 101 &_sys_ukn, /* 0x36 */ 102 &_sys_ukn, /* 0x37 */ 103 &_sys_ukn, /* 0x38 */ 104 &_sys_ukn, /* 0x39 */ 105 &_sys_ukn, /* 0x3A */ 106 &_sys_ukn, /* 0x3B */ 107 &_sys_ukn, /* 0x3C */ 108 &_sys_ukn, /* 0x3D */ 109 &_sys_ukn, /* 0x3E */ 110 &_sys_ukn, /* 0x3F */ 104 111 }; 105 112 106 113 ////////////////////////////////////////////////////////////////////////////// 107 // function executed in case of undefined syscall114 // TTY related syscall handlers 108 115 ////////////////////////////////////////////////////////////////////////////// 109 void _sys_ukn() 110 { 111 _printf("\n\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() ); 112 _exit(); 116 117 //////////////////// 118 int _sys_tty_alloc() 119 { 120 // get a new TTY terminal index 121 unsigned int channel = _tty_channel_allocator; 122 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 123 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 124 125 if ( channel >= NB_TTY_CHANNELS ) 126 { 127 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : not enough TTY channels\n"); 128 return -1; 129 } 130 else 131 { 132 _printf("\n[GIET WARNING] TTY channel %d allocated " 133 " to thread %d in vspace %d\n", channel, thread, vspace ); 134 } 135 136 // register timer index in task context 137 _set_context_slot( CTX_TTY_ID, _tty_channel_allocator ); 138 139 // update timer allocator 140 _tty_channel_allocator++; 141 142 return 0; 143 } 144 145 ///////////////////////////////////////////////// 146 int _sys_tty_write( const char* buffer, 147 unsigned int length, // number of characters 148 unsigned int channel) // channel index 149 { 150 unsigned int nwritten; 151 152 // compute and check tty channel 153 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 154 if( channel >= NB_TTY_CHANNELS ) return -1; 155 156 // write string to TTY channel 157 for (nwritten = 0; nwritten < length; nwritten++) 158 { 159 // check tty's status 160 if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 ) break; 161 162 // write one byte 163 if (buffer[nwritten] == '\n') 164 { 165 _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' ); 166 } 167 _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] ); 168 } 169 170 return nwritten; 171 } 172 173 //////////////////////////////////////////////// 174 int _sys_tty_read( char* buffer, 175 unsigned int length, // unused 176 unsigned int channel) // channel index 177 { 178 // compute and check tty channel 179 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 180 if( channel >= NB_TTY_CHANNELS ) return -1; 181 182 // read one character from TTY channel 183 if (_tty_rx_full[channel] == 0) 184 { 185 return 0; 186 } 187 else 188 { 189 *buffer = _tty_rx_buf[channel]; 190 _tty_rx_full[channel] = 0; 191 return 1; 192 } 193 } 194 195 /////////////////////////////////////////// 196 int _sys_tty_get_lock( unsigned int channel, 197 unsigned int * save_sr_ptr ) 198 { 199 // compute and check tty channel 200 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 201 if( channel >= NB_TTY_CHANNELS ) return -1; 202 203 _it_disable( save_sr_ptr ); 204 _get_lock( &_tty_lock[channel] ); 205 return 0; 206 } 207 208 /////////////////////////////////////////////// 209 int _sys_tty_release_lock( unsigned int channel, 210 unsigned int * save_sr_ptr ) 211 { 212 // compute and check tty channel 213 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 214 if( channel >= NB_TTY_CHANNELS ) return -1; 215 216 _release_lock( &_tty_lock[channel] ); 217 _it_restore( save_sr_ptr ); 218 return 0; 113 219 } 114 220 115 221 ////////////////////////////////////////////////////////////////////////////// 116 // This function returns the processor (x,y,p) identifiers.222 // TIM related syscall handlers 117 223 ////////////////////////////////////////////////////////////////////////////// 118 void _proc_xyp( unsigned int* x, 119 unsigned int* y, 120 unsigned int* p ) 224 225 //////////////////// 226 int _sys_tim_alloc() 227 { 228 // get a new timer index 229 unsigned int channel = _tim_channel_allocator; 230 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 231 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 232 233 if ( channel >= NB_TIM_CHANNELS ) 234 { 235 _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n"); 236 return -1; 237 } 238 else 239 { 240 _printf("\n[GIET WARNING] TIM channel %d allocated " 241 " to thread %d in vspace %d\n", channel, thread, vspace ); 242 } 243 244 // register timer index in task context 245 _set_context_slot( CTX_TIM_ID, channel ); 246 247 // update timer allocator 248 _tim_channel_allocator++; 249 250 return 0; 251 } 252 253 ///////////////////////////////////////// 254 int _sys_tim_start( unsigned int period ) 255 { 256 // get timer index 257 unsigned int channel = _get_context_slot( CTX_TIM_ID ); 258 if ( channel >= NB_TIM_CHANNELS ) 259 { 260 _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n"); 261 return -1; 262 } 263 264 // start timer 265 _timer_start( channel, period ); 266 267 return 0; 268 } 269 270 /////////////////// 271 int _sys_tim_stop() 272 { 273 // get timer index 274 unsigned int channel = _get_context_slot( CTX_TIM_ID ); 275 if ( channel >= NB_TIM_CHANNELS ) 276 { 277 _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n"); 278 return -1; 279 } 280 281 // stop timer 282 _timer_stop( channel ); 283 284 return 0; 285 } 286 287 ////////////////////////////////////////////////////////////////////////////// 288 // NIC related syscall handlers 289 ////////////////////////////////////////////////////////////////////////////// 290 291 //////////////////// 292 int _sys_nic_alloc() 293 { 294 // get a new NIC channel index 295 unsigned int channel = _nic_channel_allocator; 296 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 297 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 298 299 if ( channel >= NB_NIC_CHANNELS ) 300 { 301 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : not enough NIC channels\n"); 302 return -1; 303 } 304 else 305 { 306 _printf("\n[GIET WARNING] NIC channel %d allocated " 307 " to thread %d in vspace %d\n", channel, thread, vspace ); 308 } 309 310 // register channel index in task context 311 _set_context_slot( CTX_NIC_ID, channel ); 312 313 // update NIC channel allocator 314 _nic_channel_allocator++; 315 316 return 0; 317 } 318 319 //////////////////////////////////// 320 int _sys_nic_sync_send( void* vbuf ) 321 { 322 unsigned int ppn; 323 unsigned int flags; 324 unsigned int vaddr = (unsigned int)vbuf; 325 326 // get NIC channel index 327 unsigned int channel = _get_context_slot( CTX_NIC_ID ); 328 if ( channel >= NB_NIC_CHANNELS ) 329 { 330 _printf("\n[GIET_ERROR] in _sys_nic_sync_send() : illegal NIC channel index\n"); 331 return -1; 332 } 333 334 // get page table pointer 335 unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID ); 336 337 // Compute user buffer physical address and check access rights 338 unsigned int ko = _v2p_translate( (page_table_t*)user_ptab, 339 vaddr, 340 &ppn, 341 &flags ); 342 if ( ko ) 343 { 344 _printf("\n[GIET ERROR] in _sys_nic_sync_send() : user buffer unmapped\n"); 345 return -1; 346 } 347 if ( (flags & PTE_U) == 0 ) 348 { 349 _printf("\n[GIET ERROR] in _sys_nic_sync_send() : illegal buffer address\n"); 350 return -1; 351 } 352 unsigned long long pbuf = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 353 354 _nic_sync_send( channel, pbuf ); 355 356 return 0; 357 } 358 359 /////////////////////////////////////// 360 int _sys_nic_sync_receive( void* vbuf ) 361 { 362 unsigned int ppn; 363 unsigned int flags; 364 unsigned int vaddr = (unsigned int)vbuf; 365 366 // get NIC channel index 367 unsigned int channel = _get_context_slot( CTX_NIC_ID ); 368 if ( channel >= NB_NIC_CHANNELS ) 369 { 370 _printf("\n[GIET_ERROR] in _sys_nic_sync_send() : illegal NIC channel index\n"); 371 return -1; 372 } 373 374 // get page table pointer 375 unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID ); 376 377 // Compute user buffer physical address and check access rights 378 unsigned int ko = _v2p_translate( (page_table_t*)user_ptab, 379 vaddr, 380 &ppn, 381 &flags ); 382 if ( ko ) 383 { 384 _printf("\n[GIET ERROR] in _sys_nic_sync_send() : user buffer unmapped\n"); 385 return -1; 386 } 387 if ( (flags & PTE_U) == 0 ) 388 { 389 _printf("\n[GIET ERROR] in _sys_nic_sync_send() : illegal buffer address\n"); 390 return -1; 391 } 392 unsigned long long pbuf = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 393 394 _nic_sync_receive( channel, pbuf ); 395 396 return 0; 397 } 398 399 ///////////////////////////////////////////////////////////////////////////////////////// 400 // FBF related syscall handlers 401 ///////////////////////////////////////////////////////////////////////////////////////// 402 403 // Array of fbf_chbuf descriptors, indexed by the CMA channel index. 404 __attribute__((section (".unckdata"))) 405 volatile fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(32))); 406 407 // Physical addresses of these fbf_chbuf descriptors (required for L2 cache sync) 408 __attribute__((section (".unckdata"))) 409 unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS]; 410 411 ///////////////////////////////////////////// 412 int _sys_fbf_sync_write( unsigned int offset, 413 void* buffer, 414 unsigned int length ) 415 { 416 char* fbf_address = (char *)SEG_FBF_BASE + offset; 417 memcpy( fbf_address, buffer, length); 418 419 return 0; 420 } 421 422 ///////////////////////////////////////////// 423 int _sys_fbf_sync_read( unsigned int offset, 424 void* buffer, 425 unsigned int length ) 426 { 427 char* fbf_address = (char *)SEG_FBF_BASE + offset; 428 memcpy( buffer, fbf_address, length); 429 430 return 0; 431 } 432 433 //////////////////////// 434 int _sys_fbf_cma_alloc() 435 { 436 #if NB_CMA_CHANNELS > 0 437 438 // get a new CMA channel index 439 unsigned int channel = _cma_channel_allocator; 440 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 441 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 442 443 if ( channel >= NB_CMA_CHANNELS ) 444 { 445 _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : not enough CMA channels\n"); 446 return -1; 447 } 448 else 449 { 450 _printf("\n[GIET WARNING] FBF_CMA channel %d allocated " 451 " to thread %d in vspace %d\n", channel, thread, vspace ); 452 } 453 454 // register channel index in task context 455 _set_context_slot( CTX_FBCMA_ID, channel ); 456 457 // update CMA channel allocator 458 _cma_channel_allocator++; 459 460 return 0; 461 462 #else 463 464 _printf("\n[GIET ERROR] in _fb_cma_start() : NB_CMA_CHANNELS = 0\n"); 465 return -1; 466 467 #endif 468 } // end sys_fbf_cma_alloc() 469 470 //////////////////////////////////////////// 471 int _sys_fbf_cma_start( void* vbase0, 472 void* vbase1, 473 unsigned int length ) 474 { 475 #if NB_CMA_CHANNELS > 0 476 477 unsigned int ptab; // page table virtual address 478 unsigned int ko; // unsuccessfull V2P translation 479 unsigned int vaddr; // virtual address 480 unsigned int flags; // protection flags 481 unsigned int ppn; // physical page number 482 unsigned long long chbuf_paddr; // physical address of source chbuf descriptor 483 484 // get channel index 485 unsigned int channel = _get_context_slot( CTX_FBCMA_ID ); 486 487 if ( channel >= NB_CMA_CHANNELS ) 488 { 489 _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n"); 490 return -1; 491 } 492 493 #if GIET_DEBUG_FBF_CMA 494 _printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_start()\n" 495 " - channel = %d\n" 496 " - buf0 vbase = %x\n" 497 " - buf1 vbase = %x\n" 498 " - buffer size = %x\n", 499 channel, 500 (unsigned int)vbase0, 501 (unsigned int)vbase1, 502 length ); 503 #endif 504 505 // checking user buffers virtual addresses and length alignment 506 if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 507 { 508 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not word aligned\n"); 509 return -1; 510 } 511 512 // get page table virtual address 513 ptab = _get_context_slot(CTX_PTAB_ID); 514 515 // compute frame buffer physical address and initialize _fbf_chbuf[channel] 516 vaddr = ((unsigned int)SEG_FBF_BASE); 517 ko = _v2p_translate( (page_table_t*) ptab, 518 (vaddr >> 12), 519 &ppn, 520 &flags ); 521 if (ko) 522 { 523 _printf("\n[GIET ERROR] in _fb_cma_start() : frame buffer unmapped\n"); 524 return -1; 525 } 526 527 _fbf_chbuf[channel].fbf = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 528 529 // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel] 530 vaddr = (unsigned int)vbase0; 531 ko = _v2p_translate( (page_table_t*) ptab, 532 (vaddr >> 12), 533 &ppn, 534 &flags ); 535 if (ko) 536 { 537 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 unmapped\n"); 538 return -1; 539 } 540 if ((flags & PTE_U) == 0) 541 { 542 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 not in user space\n"); 543 return -1; 544 } 545 546 _fbf_chbuf[channel].buf0 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 547 548 // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel] 549 vaddr = (unsigned int)vbase1; 550 ko = _v2p_translate( (page_table_t*) ptab, 551 (vaddr >> 12), 552 &ppn, 553 &flags ); 554 if (ko) 555 { 556 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 unmapped\n"); 557 return -1; 558 } 559 if ((flags & PTE_U) == 0) 560 { 561 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 not in user space\n"); 562 return -1; 563 } 564 565 _fbf_chbuf[channel].buf1 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 566 567 // initializes buffer length 568 _fbf_chbuf[channel].length = length; 569 570 // Compute and register physical adress of the chbuf descriptor 571 vaddr = (unsigned int)(&_fbf_chbuf[channel]); 572 ko = _v2p_translate( (page_table_t*) ptab, 573 (vaddr >> 12), 574 &ppn, 575 &flags ); 576 if (ko) 577 { 578 _printf("\n[GIET ERROR] in _fbf_cma_start() : chbuf descriptor unmapped\n"); 579 return -1; 580 } 581 582 chbuf_paddr = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF); 583 584 _fbf_chbuf_paddr[channel] = chbuf_paddr; 585 586 587 if ( USE_IOB ) 588 { 589 // SYNC request for channel descriptor 590 _mmc_sync( chbuf_paddr, 32 ); 591 } 592 593 #if GIET_DEBUG_FBF_CMA 594 _printf(" - fbf pbase = %l\n" 595 " - buf0 pbase = %l\n" 596 " - buf1 pbase = %l\n" 597 " - chbuf pbase = %l\n", 598 _fbf_chbuf[channel].fbf, 599 _fbf_chbuf[channel].buf0, 600 _fbf_chbuf[channel].buf1, 601 chbuf_paddr ); 602 #endif 603 604 // call CMA driver to start transfer 605 _cma_start_channel( channel, 606 chbuf_paddr, 607 2, 608 chbuf_paddr + 16, 609 1, 610 length ); 611 return 0; 612 613 #else 614 615 _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n"); 616 return -1; 617 618 #endif 619 } // end _sys_fbf_cma_start() 620 621 ///////////////////////////////////////////////////// 622 int _sys_fbf_cma_display( unsigned int buffer_index ) 623 { 624 #if NB_CMA_CHANNELS > 0 625 626 volatile paddr_t buf_paddr; 627 unsigned int full = 1; 628 629 // get channel index 630 unsigned int channel = _get_context_slot( CTX_FBCMA_ID ); 631 632 if ( channel >= NB_CMA_CHANNELS ) 633 { 634 _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : CMA channel index too large\n"); 635 return -1; 636 } 637 638 #if GIET_DEBUG_FBF_CMA 639 _printf("\n[FBF_CMA DEBUG] enters _sys_fb_cma_display()\n" 640 " - channel = %d\n" 641 " - buffer = %d\n", 642 channel, buffer_index ); 643 #endif 644 645 // waiting user buffer empty 646 while ( full ) 647 { 648 if ( USE_IOB ) 649 { 650 // INVAL L1 cache for the chbuf descriptor, 651 _dcache_buf_invalidate( (unsigned int)&_fbf_chbuf[channel], 32 ); 652 653 // INVAL L2 cache for the chbuf descriptor, 654 _mmc_inval( _fbf_chbuf_paddr[channel], 32 ); 655 } 656 657 // read user buffer descriptor 658 if ( buffer_index == 0 ) buf_paddr = _fbf_chbuf[channel].buf0; 659 else buf_paddr = _fbf_chbuf[channel].buf1; 660 661 full = ( (unsigned int)(buf_paddr>>63) ); 662 } 663 664 if ( USE_IOB ) 665 { 666 // SYNC request for the user buffer, because 667 // it will be read from XRAM by the CMA component 668 _mmc_sync( buf_paddr, _fbf_chbuf[channel].length ); 669 } 670 671 // set user buffer status 672 if ( buffer_index == 0 ) _fbf_chbuf[channel].buf0 = buf_paddr | 0x8000000000000000ULL; 673 else _fbf_chbuf[channel].buf1 = buf_paddr | 0x8000000000000000ULL; 674 675 // reset fbf buffer status 676 _fbf_chbuf[channel].fbf = _fbf_chbuf[channel].fbf & 0x7FFFFFFFFFFFFFFFULL; 677 678 if ( USE_IOB ) 679 { 680 // SYNC request for the channel descriptor, because 681 // it will be read from XRAM by the CMA component 682 _mmc_sync( _fbf_chbuf_paddr[channel], 32 ); 683 } 684 685 #if GIET_DEBUG_FBF_CMA 686 _printf(" - fbf pbase = %l\n" 687 " - buf0 pbase = %l\n" 688 " - buf1 pbase = %l\n", 689 _fbf_chbuf[channel].fbf, 690 _fbf_chbuf[channel].buf0, 691 _fbf_chbuf[channel].buf1 ); 692 #endif 693 694 695 return 0; 696 697 #else 698 699 _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n"); 700 return -1; 701 702 #endif 703 } // end _sys_fbf_cma_display() 704 705 /////////////////////// 706 int _sys_fbf_cma_stop() 707 { 708 #if NB_CMA_CHANNELS > 0 709 710 // get channel index 711 unsigned int channel = _get_context_slot( CTX_FBCMA_ID ); 712 713 if ( channel >= NB_CMA_CHANNELS ) 714 { 715 _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n"); 716 return -1; 717 } 718 719 // Desactivate CMA channel 720 _cma_stop_channel( channel ); 721 722 return 0; 723 724 #else 725 726 _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n"); 727 return -1; 728 729 #endif 730 } // end _sys_fbf_cma_stop() 731 732 733 ////////////////////////////////////////////////////////////////////////////// 734 // Miscelaneous syscall handlers 735 ////////////////////////////////////////////////////////////////////////////// 736 737 /////////////// 738 int _sys_ukn() 739 { 740 _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() ); 741 return -1; 742 } 743 744 //////////////////////////////////// 745 int _sys_proc_xyp( unsigned int* x, 746 unsigned int* y, 747 unsigned int* p ) 121 748 { 122 749 unsigned int gpid = _get_procid(); // global processor index from CPO register … … 125 752 *y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 126 753 *p = gpid & ((1<<P_WIDTH)-1); 127 } 128 //////////////////////////////////////////////////////////////////////////// 129 // Task suicide... after printing a death message. 130 //////////////////////////////////////////////////////////////////////////// 131 void _task_exit( char* string ) 754 755 return 0; 756 } 757 758 ////////////////////////////////// 759 int _sys_task_exit( char* string ) 132 760 { 133 761 unsigned int date = _get_proctime(); … … 141 769 unsigned int task_id = _get_context_slot(CTX_LTID_ID); 142 770 143 // print deathmessage771 // print exit message 144 772 _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d" 145 773 "\n Cause : %s\n\n", … … 151 779 // deschedule 152 780 _context_switch(); 781 782 return 0; 153 783 } 154 784 155 ////////////////////////////////////////////////////////////////////////////// 156 // returns in buffer argument the number of processors in the cluster 157 // specified by the cluster_id argument. 158 ////////////////////////////////////////////////////////////////////////////// 159 unsigned int _procs_number(unsigned int cluster_id, 160 unsigned int* buffer) 785 ////////////////////// 786 int _context_switch() 787 { 788 unsigned int save_sr; 789 790 _it_disable( &save_sr ); 791 _ctx_switch(); 792 _it_restore( &save_sr ); 793 794 return 0; 795 } 796 797 //////////////////////// 798 int _sys_local_task_id() 799 { 800 return _get_context_slot(CTX_LTID_ID); 801 } 802 803 ///////////////////////// 804 int _sys_global_task_id() 805 { 806 return _get_context_slot(CTX_GTID_ID); 807 } 808 809 //////////////////// 810 int _sys_thread_id() 811 { 812 return _get_context_slot(CTX_TRDID_ID); 813 } 814 815 ////////////////////////////////////// 816 int _sys_procs_number( unsigned int x, 817 unsigned int y, 818 unsigned int* number ) 161 819 { 162 820 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 163 821 mapping_cluster_t * cluster = _get_cluster_base(header); 164 822 165 if ( cluster_id < X_SIZE * Y_SIZE )166 { 167 * buffer = cluster[cluster_id].procs;823 if ( (x < X_SIZE) && (y < Y_SIZE) ) 824 { 825 *number = cluster[(x*Y_SIZE)+y].procs; 168 826 return 0; 169 827 } 170 828 else 171 829 { 172 return 1; 173 } 174 } 175 176 ///////////////////////////////////////////////////////////////////////////// 177 // Returns current task local index. 178 ///////////////////////////////////////////////////////////////////////////// 179 unsigned int _local_task_id() 180 { 181 return _get_context_slot(CTX_LTID_ID); 182 } 183 184 ///////////////////////////////////////////////////////////////////////////// 185 // Returns current task global index. 186 ///////////////////////////////////////////////////////////////////////////// 187 unsigned int _global_task_id() 188 { 189 return _get_context_slot(CTX_GTID_ID); 190 } 191 192 ///////////////////////////////////////////////////////////////////////////// 193 // Returns current thread index. 194 ///////////////////////////////////////////////////////////////////////////// 195 unsigned int _thread_id() 196 { 197 return _get_context_slot(CTX_TRDID_ID); 198 } 199 200 ///////////////////////////////////////////////////////////////////////////// 201 // This function writes in res_vobj a pointer on a vobj 202 // identified by the (vspace_name / vobj_name ) couple. 203 // returns 0 if success, >0 if not found 204 ///////////////////////////////////////////////////////////////////////////// 205 int _get_vobj( char* vspace_name, 206 char* vobj_name, 207 mapping_vobj_t** res_vobj ) 830 _printf("\n[GIET ERROR] in _sys_procs_number() : illegal (x,y) coordinates\n" ); 831 return -1; 832 } 833 } 834 835 /////////////////////////////////////////////////////// 836 int _sys_vobj_get_vbase( char* vspace_name, 837 char* vobj_name, 838 unsigned int* vbase ) 208 839 { 209 840 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; … … 226 857 if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 227 858 { 228 * res_vobj = &vobj[vobj_id];859 *vbase = vobj[vobj_id].vbase; 229 860 return 0; 230 861 } … … 232 863 } 233 864 } 234 return 1; //not found 235 } 236 237 ///////////////////////////////////////////////////////////////////////////// 238 // This function writes in vobj_vbase the virtual base address of a vobj 239 // identified by the (vspace_name / vobj_name ) couple. 240 // returns 0 if success, >0 if not found 241 ///////////////////////////////////////////////////////////////////////////// 242 unsigned int _vobj_get_vbase( char* vspace_name, 243 char* vobj_name, 244 unsigned int* vobj_vbase ) 245 { 246 mapping_vobj_t* res_vobj; 247 unsigned int ret; 248 if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 249 { 250 return ret; 251 } 252 *vobj_vbase = res_vobj->vbase; 253 return 0; 254 } 255 256 ///////////////////////////////////////////////////////////////////////////// 257 // This function writes in vobj_length the length of a vobj 258 // identified by the (vspace_name / vobj_name ) couple. 259 // returns 0 if success, >0 if not found 260 ///////////////////////////////////////////////////////////////////////////// 261 unsigned int _vobj_get_length( char* vspace_name, 262 char* vobj_name, 263 unsigned int* vobj_length ) 264 { 265 mapping_vobj_t * res_vobj; 266 unsigned int ret; 267 if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 268 { 269 return ret; 270 } 271 *vobj_length = res_vobj->length; 272 return 0; 273 } 274 275 ///////////////////////////////////////////////////////////////////////////// 276 // This function returns in the (x,y) arguments the coordinates of the 277 // where is mapped the ptr virtual address. It use the _get_context_slot() 278 // function to get the calling task page table, and uses the _v2p_translate() 279 // function to obtain the physical address. 280 // returns 0 if success, > 0 if ptr not mapped in the calling task vspace. 281 ///////////////////////////////////////////////////////////////////////////// 282 283 unsigned int _get_xy_from_ptr( void* ptr, 284 unsigned int* px, 285 unsigned int* py ) 865 return -1; // not found 866 } 867 868 ///////////////////////////////////////////////////////// 869 int _sys_vobj_get_length( char* vspace_name, 870 char* vobj_name, 871 unsigned int* length ) 872 { 873 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 874 mapping_vspace_t * vspace = _get_vspace_base(header); 875 mapping_vobj_t * vobj = _get_vobj_base(header); 876 877 unsigned int vspace_id; 878 unsigned int vobj_id; 879 880 // scan vspaces 881 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 882 { 883 if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 884 { 885 // scan vobjs 886 for (vobj_id = vspace[vspace_id].vobj_offset; 887 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 888 vobj_id++) 889 { 890 if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 891 { 892 *length = vobj[vobj_id].length; 893 return 0; 894 } 895 } 896 } 897 } 898 return -1; // not found 899 } 900 901 //////////////////////////////////////// 902 int _sys_xy_from_ptr( void* ptr, 903 unsigned int* x, 904 unsigned int* y ) 286 905 { 287 906 unsigned int ret; … … 294 913 295 914 // compute the physical address 296 if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) ) 297 { 298 return ret; 299 } 300 301 *px = (ppn>>24) & 0xF; 302 *py = (ppn>>20) & 0xF; 303 return 0; 304 } 305 306 //////////////////////////////////////////////////////////////////////////// 307 // This sysrem function deschedule the requestint task. 308 // It mask interrupts before calling the _ctx_switch, and restore it 309 // when the task is rescheduled. 310 //////////////////////////////////////////////////////////////////////////// 311 void _context_switch() 312 { 313 unsigned int save_sr; 314 315 _it_disable( &save_sr ); 316 _ctx_switch(); 317 _it_restore( &save_sr ); 318 } 915 if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) ) return -1; 916 917 *x = (ppn>>24) & 0xF; 918 *y = (ppn>>20) & 0xF; 919 return 0; 920 } 921 922 ///////////////////////////////////////// 923 int _sys_heap_info( unsigned int* vaddr, 924 unsigned int* length, 925 unsigned int x, 926 unsigned int y ) 927 { 928 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 929 mapping_task_t * tasks = _get_task_base(header); 930 mapping_vobj_t * vobjs = _get_vobj_base(header); 931 mapping_vspace_t * vspaces = _get_vspace_base(header); 932 933 unsigned int task_id; 934 unsigned int vspace_id; 935 unsigned int vobj_id = 0xFFFFFFFF; 936 937 // searching the heap vobj_id 938 if ( (x < X_SIZE) && (y < Y_SIZE) ) // searching a task in cluster(x,y) 939 { 940 // get vspace global index 941 vspace_id = _get_context_slot(CTX_VSID_ID); 942 943 // scan all tasks in vspace 944 unsigned int min = vspaces[vspace_id].task_offset ; 945 unsigned int max = min + vspaces[vspace_id].tasks ; 946 for ( task_id = min ; task_id < max ; task_id++ ) 947 { 948 if ( tasks[task_id].clusterid == (x * Y_SIZE + y) ) 949 { 950 vobj_id = tasks[task_id].heap_vobj_id; 951 if ( vobj_id != 0xFFFFFFFF ) break; 952 } 953 } 954 } 955 else // searching in the calling task 956 { 957 task_id = _get_context_slot(CTX_GTID_ID); 958 vobj_id = tasks[task_id].heap_vobj_id; 959 } 960 961 // analysing the vobj_id 962 if ( vobj_id != 0xFFFFFFFF ) 963 { 964 *vaddr = vobjs[vobj_id].vbase; 965 *length = vobjs[vobj_id].length; 966 return 0; 967 } 968 else 969 { 970 *vaddr = 0; 971 *length = 0; 972 return -1; 973 } 974 } // end _sys_heap_info() 975 319 976 320 977 // Local Variables: -
soft/giet_vm/giet_kernel/sys_handler.h
r428 r440 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel. 8 // It define the syscall_vector[] (at the end of this file), as well as the 9 // associated syscall handlers. 10 /////////////////////////////////////////////////////////////////////////////////// 7 11 8 12 #ifndef _SYS_HANDLER_H 9 13 #define _SYS_HANDLER_H 10 14 11 ////////////////////////////////////////////////////////////////////////////////// 15 #include <mapping_info.h> 16 17 /////////////////////////////////////////////////////////////////////////////////// 12 18 // Syscall Vector Table (indexed by syscall index) 13 ////////////////////////////////////////////////////////////////////////////////// 19 /////////////////////////////////////////////////////////////////////////////////// 14 20 15 21 extern const void * _syscall_vector[64]; 16 22 23 /////////////////////////////////////////////////////////////////////////////////// 24 // This structure can be used by the vci_chbuf_dma component to transfer a stream 25 // of images from two buffers in user space to the frame buffer in kernel space. 26 // It contains two chbuf descriptors 27 // - The SRC chbuf contains two buffers (buf0 & buf1), that can be in user space. 28 // - The DST cbuf contains one single buffer (fbf), that is the frame buffer. 29 /////////////////////////////////////////////////////////////////////////////////// 30 31 typedef struct fbf_chbuf_s 32 { 33 unsigned long long buf0; // physical address + status for user buffer 0 34 unsigned long long buf1; // physical address + status for user buffer 1 35 unsigned long long fbf; // physical address + status for user buffer 0 36 unsigned int length; // buffer length (bytes) 37 unsigned int padding; // for 32 bytes alignment 38 } fbf_chbuf_t; 39 17 40 ////////////////////////////////////////////////////////////////////////////////// 18 // Prototypes os the syscall handlers (other than peripheral drivers)41 // TTY related syscall handlers 19 42 ////////////////////////////////////////////////////////////////////////////////// 20 43 21 void _sys_ukn();44 int _sys_tty_alloc(); 22 45 23 void _proc_xyp( unsigned int* x,24 unsigned int* y,25 unsigned int* p);46 int _sys_tty_write( const char* buffer, 47 unsigned int length, 48 unsigned int channel ); 26 49 27 void _task_exit(); 50 int _sys_tty_read( char* buffer, 51 unsigned int length, 52 unsigned int channel ); 28 53 29 void _context_switch(); 54 int _sys_tty_get_lock( unsigned int channel, 55 unsigned int * save_sr_ptr ); 30 56 31 unsigned int _local_task_id(); 57 int _sys_tty_release_lock( unsigned int channel, 58 unsigned int * save_sr_ptr ); 32 59 33 unsigned int _global_task_id(); 60 ////////////////////////////////////////////////////////////////////////////// 61 // TIM related syscall handlers 62 ////////////////////////////////////////////////////////////////////////////// 34 63 35 unsigned int _thread_id();64 int _sys_tim_alloc(); 36 65 37 unsigned int _procs_number( unsigned int cluster_id, 38 unsigned int* number ); 66 int _sys_tim_start( unsigned int period ); 39 67 40 unsigned int _vobj_get_vbase( char* vspace_name, 41 char* vobj_name, 42 unsigned int* vobj_vbase ); 68 int _sys_tim_stop(); 43 69 44 unsigned int _vobj_get_length( char* vspace_name, 45 char* vobj_name, 46 unsigned int* vobj_length ); 70 ////////////////////////////////////////////////////////////////////////////// 71 // NIC related syscall handlers 72 ////////////////////////////////////////////////////////////////////////////// 47 73 48 unsigned int _get_xy_from_ptr( void* ptr, 49 unsigned int* x, 50 unsigned int* y ); 74 int _sys_nic_alloc(); 51 75 76 int _sys_nic_sync_send( void* vbuf ); 77 78 int _sys_nic_sync_receive( void* vbuf ); 79 80 ////////////////////////////////////////////////////////////////////////////// 81 // FBF related syscall handlers 82 ////////////////////////////////////////////////////////////////////////////// 83 84 int _sys_fbf_sync_write( unsigned int offset, 85 void* buffer, 86 unsigned int length ); 87 88 int _sys_fbf_sync_read( unsigned int offset, 89 void* buffer, 90 unsigned int length ); 91 92 int _sys_fbf_cma_alloc(); 93 94 int _sys_fbf_cma_start( void* vbase0, 95 void* vbase1, 96 unsigned int length ); 97 98 int _sys_fbf_cma_display( unsigned int buffer_index ); 99 100 int _sys_fbf_cma_stop(); 101 102 ////////////////////////////////////////////////////////////////////////////// 103 // Miscelaneous syscall handlers 104 ////////////////////////////////////////////////////////////////////////////// 105 106 int _sys_ukn(); 107 108 int _sys_proc_xyp( unsigned int* x, 109 unsigned int* y, 110 unsigned int* p ); 111 112 int _sys_task_exit( char* string ); 113 114 int _context_switch(); 115 116 int _sys_local_task_id(); 117 118 int _sys_global_task_id(); 119 120 int _sys_thread_id(); 121 122 int _sys_procs_number( unsigned int x, 123 unsigned int y, 124 unsigned int* number ); 125 126 int _sys_vobj_get_vbase( char* vspace_name, 127 char* vobj_name, 128 unsigned int* vbase ); 129 130 int _sys_vobj_get_length( char* vspace_name, 131 char* vobj_name, 132 unsigned int* length ); 133 134 int _sys_xy_from_ptr( void* ptr, 135 unsigned int* x, 136 unsigned int* y ); 137 138 int _sys_heap_info( unsigned int* vaddr, 139 unsigned int* length, 140 unsigned int x, 141 unsigned int y ); 52 142 53 143 #endif
Note: See TracChangeset
for help on using the changeset viewer.