Changeset 528 for soft/giet_vm
- Timestamp:
- Mar 27, 2015, 11:43:48 AM (10 years ago)
- Location:
- soft/giet_vm/giet_kernel
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/ctx_handler.c
r459 r528 8 8 #include <ctx_handler.h> 9 9 #include <giet_config.h> 10 #include <hard_config.h> 10 11 #include <utils.h> 11 12 #include <tty0.h> 12 13 #include <xcu_driver.h> 13 14 14 ////////// defined in giet_kernel/switch.s file ///////// 15 ///////////////////////////////////////////////////////////////////////////////// 16 // Extern variables and functions 17 ///////////////////////////////////////////////////////////////////////////////// 18 19 // defined in giet_kernel/switch.s file 15 20 extern void _task_switch(unsigned int *, unsigned int *); 21 22 // allocated in boot.c or kernel_init.c files 23 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 24 25 ////////////////////////////////// 26 void _ctx_display( unsigned int x, 27 unsigned int y, 28 unsigned int p, 29 unsigned int ltid, 30 char* string ) 31 { 32 static_scheduler_t* psched = _schedulers[x][y][p]; 33 _printf("\n########## task[%d,%d,%d,%d] context\n" 34 " - CTX_EPC = %x\n" 35 " - CTX_PTAB = %x\n" 36 " - CTX_PTPR = %x\n" 37 " - CTX_VSID = %x\n" 38 " - CTX_SR = %x\n" 39 " - CTX_RA = %x\n" 40 " - CTX_SP = %x\n" 41 " - CTX_RUN = %x\n" 42 "########## %s\n", 43 x , y , p , ltid , 44 psched->context[ltid][CTX_EPC_ID], 45 psched->context[ltid][CTX_PTAB_ID], 46 psched->context[ltid][CTX_PTPR_ID], 47 psched->context[ltid][CTX_VSID_ID], 48 psched->context[ltid][CTX_SR_ID], 49 psched->context[ltid][CTX_RA_ID], 50 psched->context[ltid][CTX_SP_ID], 51 psched->context[ltid][CTX_RUN_ID], 52 string ); 53 } // _ctx_display() 54 16 55 17 56 ////////////////// … … 48 87 49 88 // launch "idle" task if no runable task 50 if (found == 0) 51 { 52 next_task_id = IDLE_TASK_INDEX; 53 } 89 if (found == 0) next_task_id = IDLE_TASK_INDEX; 54 90 55 91 #if GIET_DEBUG_SWITCH 56 92 unsigned int x = cluster_xy >> Y_WIDTH; 57 93 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 58 59 _printf("\n[TASK SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n", 94 _printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n", 60 95 curr_task_id, next_task_id, x, y , lpid, _get_proctime() ); 61 96 #endif … … 66 101 unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]); 67 102 68 // reset timer counter. 69 // In all clusters, the first NB_PROCS_MAX 70 // timers are system timers (TICK) 71 72 #if USE_XCU 103 // reset TICK timer counter. 73 104 _xcu_timer_reset_cpt( cluster_xy, lpid ); 74 #else75 _timer_reset_cpt( cluster_xy, lpid);76 #endif77 105 78 106 // set current task index … … 80 108 81 109 // makes context switch 82 _task_switch(curr_ctx_vaddr, next_ctx_vaddr); 110 _task_switch( curr_ctx_vaddr , next_ctx_vaddr ); 111 83 112 } 84 113 } //end _ctx_switch() 114 85 115 86 116 ///////////////// … … 110 140 111 141 // warning message 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"); 142 _printf("\n[GIET WARNING] Processor[%d,%d,%d] still idle at cycle %d", 143 x , y , p , _get_proctime() ); 121 144 } 122 145 } // end ctx_idle() -
soft/giet_vm/giet_kernel/ctx_handler.h
r449 r528 1 ///////////////////////////////////////////////////////////////////////////////// ////////1 ///////////////////////////////////////////////////////////////////////////////// 2 2 // File : ctx_handler.h 3 3 // Date : 01/04/2012 4 4 // Authors : alain greiner & joel porquet 5 5 // Copyright (c) UPMC-LIP6 6 ///////////////////////////////////////////////////////////////////////////////// ////////6 ///////////////////////////////////////////////////////////////////////////////// 7 7 // The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel. 8 8 // This code is used to support context switch when several tasks are executing … … 13 13 // The task context [13] is reserved for the "idle" task that does nothing, and 14 14 // is launched by the scheduler when there is no other runable task. 15 ///////////////////////////////////////////////////////////////////////////////// ////////15 ///////////////////////////////////////////////////////////////////////////////// 16 16 // A task context is an array of 64 words = 256 bytes. 17 17 // It contains copies of processor registers (when the task is preempted) 18 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 ///////////////////////////////////////////////////////////////////////////////// ////////19 // allocated to the task (private peripheral channel) 20 ///////////////////////////////////////////////////////////////////////////////// 21 21 // ctx[0] <- *** |ctx[8] <- $8 |ctx[16]<- $16 |ctx[24]<- $24 22 22 // ctx[1] <- $1 |ctx[9] <- $9 |ctx[17]<- $17 |ctx[25]<- $25 … … 36 36 // ctx[38]<- VSID |ctx[46]<- TIM |ctx[54]<- *** |ctx[62]<- *** 37 37 // ctx[39]<- PTPR |ctx[47]<- HBA |ctx[55]<- *** |ctx[63]<- *** 38 ///////////////////////////////////////////////////////////////////////////////// ////////38 ///////////////////////////////////////////////////////////////////////////////// 39 39 40 40 #ifndef _CTX_HANDLER_H … … 94 94 95 95 ///////////////////////////////////////////////////////////////////////////////// 96 // Schedulers array 97 ///////////////////////////////////////////////////////////////////////////////// 98 extern static_scheduler_t _scheduler[]; 99 100 ///////////////////////////////////////////////////////////////////////////////// 101 // External Functions 96 // Extern Functions 102 97 ///////////////////////////////////////////////////////////////////////////////// 103 98 … … 126 121 extern void _idle_task(); 127 122 123 ///////////////////////////////////////////////////////////////////////////////// 124 // This function displays the context of a task identified by the processor 125 // coordinates (x,y,p), and by the local task index ltid. 126 // The string argument can be used for debug. 127 ///////////////////////////////////////////////////////////////////////////////// 128 extern void _ctx_display( unsigned int x, 129 unsigned int y, 130 unsigned int p, 131 unsigned int ltid, 132 char* string ); 128 133 129 134 #endif -
soft/giet_vm/giet_kernel/exc_handler.c
r459 r528 76 76 unsigned int task = _get_context_slot(CTX_LTID_ID); 77 77 78 78 79 _printf("\n[GIET] Exception for task %d on processor[%d,%d,%d] at cycle %d\n" 79 80 " - type : %s\n" … … 87 88 _set_context_slot(CTX_RUN_ID, 0); 88 89 89 // deschedule 90 // deschedule (suicide) 91 unsigned int save_sr; // unused 92 _it_disable( &save_sr ); 90 93 _ctx_switch(); 91 } 94 95 } // end display_cause() 92 96 93 97 static void _cause_ukn() { _display_cause(0); } -
soft/giet_vm/giet_kernel/irq_handler.c
r519 r528 1 /////////////////////////////////////////////////////////////////////////// ////////1 /////////////////////////////////////////////////////////////////////////// 2 2 // File : irq_handler.c 3 3 // Date : 01/04/2012 4 4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 6 /////////////////////////////////////////////////////////////////////////// ////////6 /////////////////////////////////////////////////////////////////////////// 7 7 8 8 #include <giet_config.h> … … 12 12 #include <tim_driver.h> 13 13 #include <xcu_driver.h> 14 #include <pic_driver.h> 14 15 #include <tty_driver.h> 15 16 #include <nic_driver.h> … … 19 20 #include <dma_driver.h> 20 21 #include <spi_driver.h> 22 #include <mwr_driver.h> 21 23 #include <mapping_info.h> 22 24 #include <utils.h> 23 25 #include <tty0.h> 24 26 25 #if NB_TIM_CHANNELS 26 extern volatile unsigned char _user_timer_event[NB_TIM_CHANNELS] ; 27 #endif 27 ///////////////////////////////////////////////////////////////////////// 28 // Global variables 29 ///////////////////////////////////////////////////////////////////////// 30 31 // array of external IRQ indexes for each (isr/channel) couple 32 __attribute__((section(".kdata"))) 33 unsigned char _ext_irq_index[GIET_ISR_TYPE_MAX][GIET_ISR_CHANNEL_MAX]; 34 35 // WTI mailbox allocators for external IRQ routing (3 allocators per proc) 36 __attribute__((section(".kdata"))) 37 unsigned char _wti_alloc_one[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 38 __attribute__((section(".kdata"))) 39 unsigned char _wti_alloc_two[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 40 __attribute__((section(".kdata"))) 41 unsigned char _wti_alloc_ter[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 42 43 ///////////////////////////////////////////////////////////////////////// 44 // this array is allocated in the boot.c or kernel_init.c 45 ///////////////////////////////////////////////////////////////////////// 46 47 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 28 48 29 49 ///////////////////////////////////////////////////////////////////////// … … 45 65 "DMA" , 46 66 "SPI" , 47 "MWR" }; 67 "MWR" , 68 "HBA" }; 69 70 //////////////////// 71 void _ext_irq_init() 72 { 73 mapping_header_t* header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 74 mapping_cluster_t* cluster = _get_cluster_base(header); 75 mapping_periph_t* periph = _get_periph_base(header); 76 mapping_irq_t* irq = _get_irq_base(header); 77 unsigned int periph_id; // peripheral index in mapping_info 78 unsigned int irq_id; // irq index in mapping_info 79 80 // get cluster_io index in mapping 81 unsigned int x_io = header->x_io; 82 unsigned int y_io = header->y_io; 83 unsigned int cluster_io = (x_io * Y_SIZE) + y_io; 84 mapping_periph_t* pic = NULL; 85 86 // scan external peripherals to find XCU 87 unsigned int min = cluster[cluster_io].periph_offset ; 88 unsigned int max = min + cluster[cluster_io].periphs ; 89 90 for ( periph_id = min ; periph_id < max ; periph_id++ ) 91 { 92 if ( periph[periph_id].type == PERIPH_TYPE_PIC ) 93 { 94 pic = &periph[periph_id]; 95 break; 96 } 97 } 98 99 if ( pic == NULL ) 100 { 101 _printf("\n[GIET ERROR] in _ext_irq_init() : No PIC component found\n"); 102 _exit(); 103 } 104 105 // scan PIC IRQS defined in mapping 106 for ( irq_id = pic->irq_offset ; 107 irq_id < pic->irq_offset + pic->irqs ; 108 irq_id++ ) 109 { 110 unsigned int type = irq[irq_id].srctype; 111 unsigned int srcid = irq[irq_id].srcid; 112 unsigned int isr = irq[irq_id].isr; 113 unsigned int channel = irq[irq_id].channel; 114 115 if ( (type != IRQ_TYPE_HWI) || 116 (srcid > 31) || 117 (isr >= GIET_ISR_TYPE_MAX) || 118 (channel >= GIET_ISR_CHANNEL_MAX) ) 119 { 120 _printf("\n[GIET ERROR] in _ext_irq_init() : Bad PIC IRQ\n" 121 " type = %d / srcid = %d / isr = %d / channel = %d\n", 122 type , srcid , isr , channel ); 123 _exit(); 124 } 125 _ext_irq_index[isr][channel] = srcid; 126 } 127 } // end _ext_irq_init() 128 129 //////////////////////////////////////////// 130 void _ext_irq_alloc( unsigned int isr_type, 131 unsigned int isr_channel, 132 unsigned int* wti_index ) 133 { 134 unsigned int wti_id; // allocated WTI mailbox index in XCU 135 unsigned int irq_id; // external IRQ index in PIC (input) 136 unsigned int wti_addr; // WTI mailbox physical address (32 lsb bits) 137 138 // check arguments 139 if ( isr_type >= GIET_ISR_TYPE_MAX ) 140 { 141 _printf("\n[GIET ERROR] in _ext_irq_alloc() : illegal ISR type\n"); 142 _exit(); 143 } 144 if ( isr_channel >= GIET_ISR_CHANNEL_MAX ) 145 { 146 _printf("\n[GIET ERROR] in _ext_irq_alloc() : illegal ISR channel\n"); 147 _exit(); 148 } 149 150 // get processor coordinates [x,y,p] 151 unsigned int gpid = _get_procid(); 152 unsigned int cluster_xy = gpid >> P_WIDTH; 153 unsigned int x = cluster_xy >> Y_WIDTH; 154 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 155 unsigned int p = gpid & ((1<<P_WIDTH)-1); 156 157 // allocate a WTI mailbox to proc[x,y,p] (blocking until success) 158 while ( 1 ) 159 { 160 if ( _wti_alloc_one[x][y][p] == 0 ) 161 { 162 _wti_alloc_one[x][y][p] = 1; 163 wti_id = p + NB_PROCS_MAX; 164 break; 165 } 166 if ( _wti_alloc_two[x][y][p] == 0 ) 167 { 168 _wti_alloc_two[x][y][p] = 1; 169 wti_id = p + 2*NB_PROCS_MAX; 170 break; 171 } 172 if ( _wti_alloc_ter[x][y][p] == 0 ) 173 { 174 _wti_alloc_ter[x][y][p] = 1; 175 wti_id = p + 3*NB_PROCS_MAX; 176 break; 177 } 178 } 179 *wti_index = wti_id; 180 181 // register the mailbox physical address in IOPIC 182 irq_id = _ext_irq_index[isr_type][isr_channel]; 183 _xcu_get_wti_address( wti_id , &wti_addr ); 184 _pic_init( irq_id , wti_addr, cluster_xy ); 185 186 // initializes the WTI interrupt vector entry for XCU 187 _schedulers[x][y][p]->wti_vector[wti_id] = isr_channel<<16 | isr_type; 188 189 } // end ext_irq_alloc() 190 191 //////////////////////////////////////////// 192 void _ext_irq_release( unsigned int isr_type, 193 unsigned int isr_channel, 194 unsigned int wti_index ) 195 { 196 unsigned int irq_id; // external IRQ index in PIC (input) 197 198 // get processor coordinates [x,y,p] 199 unsigned int gpid = _get_procid(); 200 unsigned int cluster_xy = gpid >> P_WIDTH; 201 unsigned int x = cluster_xy >> Y_WIDTH; 202 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 203 unsigned int p = gpid & ((1<<P_WIDTH)-1); 204 205 // check arguments 206 if ( isr_type >= GIET_ISR_TYPE_MAX ) 207 { 208 _printf("\n[GIET ERROR] in _ext_irq_release() illegal ISR type\n"); 209 _exit(); 210 } 211 if ( isr_channel >= GIET_ISR_CHANNEL_MAX ) 212 { 213 _printf("\n[GIET ERROR] in _ext_irq_release() : illegal ISR channel\n"); 214 _exit(); 215 } 216 217 // desactivates dynamically allocated PIC entry 218 irq_id = _ext_irq_index[isr_type][isr_channel]; 219 _pic_set_register( irq_id , IOPIC_MASK , 0 ); 220 221 // releases dynamically allocated WTI mailbox 222 if ( wti_index == p + NB_PROCS_MAX ) _wti_alloc_one[x][y][p] = 0; 223 else if ( wti_index == p + 2*NB_PROCS_MAX ) _wti_alloc_two[x][y][p] = 0; 224 else if ( wti_index == p + 3*NB_PROCS_MAX ) _wti_alloc_ter[x][y][p] = 0; 225 else 226 { 227 _printf("\n[GIET ERROR] in _ext_irq_release() : illegal WTI index\n"); 228 _exit(); 229 } 230 } // end ext_irq_release() 231 48 232 ///////////////// 49 233 void _irq_demux() … … 156 340 unsigned int x = cluster_xy >> Y_WIDTH; 157 341 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 158 unsigned int lpid = gpid & ((1<<P_WIDTH)-1); 159 160 unsigned int task = _get_current_task_id(); 161 unsigned int value; 342 unsigned int p = gpid & ((1<<P_WIDTH)-1); 343 344 unsigned int value; // WTI mailbox value 345 unsigned int save_sr; // save SR value in pre-empted task stack 346 347 unsigned int ltid = _get_current_task_id(); 162 348 163 349 if ( irq_type != IRQ_TYPE_WTI ) 164 350 { 165 _puts("[GIET ERROR] _isr_wakup() not called by a WTI on processor["); 166 _putd( x ); 167 _puts(","); 168 _putd( y ); 169 _puts(","); 170 _putd( lpid ); 171 _puts("] at cycle "); 172 _putd( _get_proctime() ); 173 _puts("\n"); 351 _printf("[GIET ERROR] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n" 352 " but not called by a WTI interrupt\n", 353 x , y , p , _get_proctime() ); 174 354 _exit(); 175 355 } … … 178 358 _xcu_get_wti_value( cluster_xy, irq_id, &value ); 179 359 180 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlocks 181 _puts("\n[IRQS DEBUG] Processor["); 182 _putd( x ); 183 _puts(","); 184 _putd( y ); 185 _puts(","); 186 _putd( lpid ); 187 _puts("] enters _isr_wakup() at cycle "); 188 _putd( _get_proctime() ); 189 _puts("\n WTI / mailbox data = "); 190 _putx( value ); 191 _puts(" / current task index = "); 192 _putd( task ); 193 _puts("\n "); 360 #if GIET_DEBUG_SWITCH 361 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n" 362 " WTI index = %d / current ltid = %d / mailbox value = %x\n", 363 x , y , p , _get_proctime() , irq_id , ltid , value ); 194 364 #endif 195 365 196 // context swich if required 197 if ( (task == IDLE_TASK_INDEX) || (value != 0) ) _ctx_switch(); 366 // enter critical section and swich context (if required) 367 if ( (ltid == IDLE_TASK_INDEX) || (value != 0) ) 368 { 369 _it_disable( &save_sr ); 370 _ctx_switch(); 371 _it_restore( &save_sr ); 372 } 373 198 374 } // end _isr_wakup 199 375 … … 207 383 unsigned int x = cluster_xy >> Y_WIDTH; 208 384 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 209 unsigned int lpid = gpid & ((1<<P_WIDTH)-1); 385 unsigned int p = gpid & ((1<<P_WIDTH)-1); 386 387 unsigned int save_sr; // save SR value in pre-empted task stack 210 388 211 389 if ( irq_type != IRQ_TYPE_PTI ) 212 390 { 213 _puts("[GIET ERROR] _isr_tick() not called by a PTI on processor["); 214 _putd( x ); 215 _puts(","); 216 _putd( y ); 217 _puts(","); 218 _putd( lpid ); 219 _puts("] at cycle "); 220 _putd( _get_proctime() ); 221 _puts("\n"); 391 _printf("[GIET ERROR] P[%d,%d,%d] enters _isr_tick() at cycle %d\n" 392 " but not called by a PTI interrupt\n", 393 x , y , p , _get_proctime() ); 222 394 _exit(); 223 395 } … … 226 398 _xcu_timer_reset_irq( cluster_xy, irq_id ); 227 399 228 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlock 229 _puts("\n[IRQS DEBUG] Processor["); 230 _putd( x ); 231 _puts(","); 232 _putd( y ); 233 _puts(","); 234 _putd( lpid ); 235 _puts("] enters _isr_tick() at cycle "); 236 _putd( _get_proctime() ); 237 _puts("\n "); 400 #if GIET_DEBUG_SWITCH 401 unsigned int ltid = _get_current_task_id(); 402 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_tick() at cycle %d\n" 403 " WTI index = %d / current ltid = %d\n", 404 x , y , p , _get_proctime() , irq_id , ltid ); 238 405 #endif 239 406 240 // context switch 407 // enter critical section and switch context 408 _it_disable( &save_sr ); 241 409 _ctx_switch(); 410 _it_restore( &save_sr ); 411 242 412 } // end _isr_tick 243 413 -
soft/giet_vm/giet_kernel/irq_handler.h
r519 r528 1 /////////////////////////////////////////////////////////////////////////// ////////1 /////////////////////////////////////////////////////////////////////////// 2 2 // File : irq_handler.h 3 3 // Date : 01/04/2012 4 4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The irq_handler.c and irq_handler.h files are part of the GIET-VM nano-kernel. 8 // They contain the code of the _irq_demux() function that access the XICU or 9 // ICU component (Interupt Controler Unit), and the various ISRs (Interrupt 10 // Service Routine) associated to the various ISR types. 11 /////////////////////////////////////////////////////////////////////////////////// 6 /////////////////////////////////////////////////////////////////////////// 7 // The irq_handler.c and irq_handler.h files are part of the GIET-VM. 8 // They contain the code of used to handlle HWI, WTI, PTI interrupts. 9 /////////////////////////////////////////////////////////////////////////// 12 10 13 11 #ifndef _IRQ_HANDLER_H 14 12 #define _IRQ_HANDLER_H 15 13 16 /////////////////////////////////////////////////////////////////////////// /////14 /////////////////////////////////////////////////////////////////////////// 17 15 // This enum must consistent with the values defined in 18 // xml_driver.c / irq_handler.c / mapping.py19 /////////////////////////////////////////////////////////////////////////// ////16 // xml_driver.c / xml_parser.c / irq_handler.c / mapping.py 17 /////////////////////////////////////////////////////////////////////////// 20 18 21 19 enum isr_type_t … … 35 33 ISR_SPI = 12, 36 34 ISR_MWR = 13, 35 ISR_HBA = 14, 37 36 }; 38 37 39 /////////////////////////////////////////////////////////////////////////////////// 38 /////////////////////////////////////////////////////////////////////////// 39 // Global variables allocated in irq_handler.c 40 /////////////////////////////////////////////////////////////////////////// 41 42 // array of external IRQ indexes for each (isr/channel) couple 43 extern unsigned char _ext_irq_index[GIET_ISR_TYPE_MAX][GIET_ISR_CHANNEL_MAX]; 44 45 // WTI mailbox allocators for external IRQ routing (3 allocators per proc) 46 extern unsigned char _wti_alloc_one[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 47 extern unsigned char _wti_alloc_two[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 48 extern unsigned char _wti_alloc_ter[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 49 50 /////////////////////////////////////////////////////////////////////////// 40 51 // irq_handler functions 41 /////////////////////////////////////////////////////////////////////////// ////////52 /////////////////////////////////////////////////////////////////////////// 42 53 43 /////////////////////////////////////////////////////////////////////////////////// 44 // This function access the ICU or XICU component (Interrupt Controler Unit) 45 // to get the interrupt vector entry. There is one ICU or XICU component per 54 /////////////////////////////////////////////////////////////////////////// 55 // This function is only used when the architecture contains an external 56 // IOPIC component. It initializes the _ext_irq_index[isr][channel] array, 57 // defining the IRQ index associated to (isr_type/isr_channel) couple. 58 // This array is used by the kernel for dynamic routing of an external IRQ 59 // signaling completion to the processor that launched the I/O operation. 60 /////////////////////////////////////////////////////////////////////////// 61 62 extern void _ext_irq_init(); 63 64 /////////////////////////////////////////////////////////////////////////// 65 // This function is only used when the architecture contains an external 66 // IOPIC component. It dynamically routes an external IRQ signaling 67 // completion of an I/O operation to the processor P[x,y,p] running 68 // the calling task. 69 // 1) it allocates a WTI mailbox in the XCU of cluster[x,y] : Each processor 70 // has 3 mailboxes, with index in [4*p+1, 4*p+2, 4*p+3]. 71 // 2) it initialises the IOPIC_ADDRESS and IOPIC_MASK registers associated 72 // to the (isr_type/isr_channel) couple. 73 // 3) it initializes the proper entry in the WTI interrupt vector associated 74 // to processor P[x,y,p]. 75 /////////////////////////////////////////////////////////////////////////// 76 77 extern void _ext_irq_alloc( unsigned int isr_type, 78 unsigned int isr_channel, 79 unsigned int* wti_index ); 80 81 /////////////////////////////////////////////////////////////////////////// 82 // This function is only used when the architecture contains an external 83 // IOPIC component. It desallocates all ressources allocated by the 84 // previous _ext_irq_alloc() function to the calling processor. 85 // 1) it desactivates the PIC entry associated to (isr_type/isr_channel). 86 // 2) it releases the WTI mailbox in the XCU of cluster[x,y]. 87 /////////////////////////////////////////////////////////////////////////// 88 89 extern void _ext_irq_release( unsigned int isr_type, 90 unsigned int isr_channel, 91 unsigned int wti_index ); 92 93 /////////////////////////////////////////////////////////////////////////// 94 // This function access the XICU component (Interrupt Controler Unit) 95 // to get the interrupt vector entry. There is one XICU component per 46 96 // cluster, and this component can support up to NB_PROCS_MAX output IRQs. 47 97 // It returns the highest priority active interrupt index (smaller 48 98 // indexes have the highest priority). 49 // Any value larger than 31 means "no active interrupt" , and no ISR is executed.99 // Any value larger than 31 means "no active interrupt". 50 100 // 51 101 // There is three interrupt vectors per processor (stored in the processor's 52 102 // scheduler) for the three HWI, PTI, and WTI interrupts types. 53 // Each interrupt vector entry contains three bits fields: 54 // - isr_id bits[15:0] : defines the type of ISR to be executed. 55 // - channel_id bits[30:16] : defines the channel for multi-channels peripherals. 56 // - valid bit 31 : valid interrupt vector entry 103 // Each interrupt vector entry contains two fields: 104 // - isr_type bits[15:0] : defines the type of ISR to be executed. 105 // - isr_channel bits[31:16] : defines the channel index 57 106 // If the peripheral is replicated in clusters, the channel_id is 58 107 // a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id 59 /////////////////////////////////////////////////////////////////////////////////// 108 /////////////////////////////////////////////////////////////////////////// 109 60 110 extern void _irq_demux(); 61 111 62 /////////////////////////////////////////////////////////////////////////// ////////112 /////////////////////////////////////////////////////////////////////////// 63 113 // This default ISR is called when the interrupt handler is called, 64 // and there is no active IRQ. It simply displays a warning message on TTY[0]. 65 /////////////////////////////////////////////////////////////////////////////////// 114 // and there is no active IRQ. It displays a warning message on TTY[0]. 115 /////////////////////////////////////////////////////////////////////////// 116 66 117 extern void _isr_default(); 67 118 68 /////////////////////////////////////////////////////////////////////////////////// 69 // This ISR can only be executed after a WTI (IPI) to force a context switch 70 // on a remote processor. The context switch is only executed if the current task 71 // is the IDLE_TASK, or if the value written in the mailbox is non zero. 72 /////////////////////////////////////////////////////////////////////////////////// 119 /////////////////////////////////////////////////////////////////////////// 120 // This ISR can only be executed after a WTI to force a context switch 121 // on a remote processor. The context switch is only executed if the 122 // current task is the IDLE_TASK, or if the value written in the mailbox 123 // is non zero. 124 /////////////////////////////////////////////////////////////////////////// 125 73 126 extern void _isr_wakup( unsigned int irq_type, 74 127 unsigned int irq_id, -
soft/giet_vm/giet_kernel/kernel_init.c
r494 r528 11 11 #include <hard_config.h> 12 12 #include <utils.h> 13 #include <vmem.h> 13 14 #include <tty0.h> 14 15 #include <kernel_malloc.h> … … 52 53 #endif 53 54 55 #if !defined(USE_PIC) 56 # error: You must define USE_PIC in the hard_config.h file 57 #endif 58 54 59 #if !defined(IDLE_TASK_INDEX) 55 60 # error: You must define IDLE_TASK_INDEX in the ctx_handler.h file … … 72 77 #endif 73 78 74 75 76 // Distributed kernel heap descriptors array 77 // __attribute__((section(".kdata"))) 78 // kernel_heap_t kernel_heap[X_SIZE][Y_SIZE]; 79 #if !defined(GIET_ISR_TYPE_MAX) 80 # error: You must define GIET_ISR_TYPE_MAX in the giet_config.h file 81 #endif 82 83 #if !defined(GIET_ISR_CHANNEL_MAX) 84 # error: You must define GIET_ISR_CHANNEL_MAX in the giet_config.h file 85 #endif 86 87 88 //////////////////////////////////////////////////////////////////////////////// 89 // Global variables 90 //////////////////////////////////////////////////////////////////////////////// 79 91 80 92 // FAT internal representation for kernel code 81 93 __attribute__((section(".kdata"))) 82 fat32_fs_t fat __attribute__((aligned(512)));94 fat32_fs_t _fat __attribute__((aligned(512))); 83 95 84 96 // array of page tables virtual addresses 85 97 __attribute__((section(".kdata"))) 86 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX] ;98 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 87 99 88 100 // array of page tables PTPR values (physical addresses >> 13) 89 101 __attribute__((section(".kdata"))) 90 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX] ;102 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 91 103 92 104 // Array of pointers on the schedulers 93 105 __attribute__((section(".kdata"))) 94 volatile static_scheduler_t* 106 volatile static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 95 107 96 108 // Synchonisation before entering parallel execution … … 102 114 unsigned int _tty0_boot_mode = 0; 103 115 104 // Distributedsynchronisation barrier for parallel init by all processors116 // synchronisation barrier for parallel init by all processors 105 117 __attribute__((section(".kdata"))) 106 118 sqt_barrier_t _all_procs_barrier __attribute__((aligned(64))); 107 119 108 120 //////////////////////////////////////////////////////////////////////////////// 121 // Extern variables 122 //////////////////////////////////////////////////////////////////////////////// 109 123 110 124 // this variable is defined in tty0.c file 111 125 extern sqt_lock_t _tty0_sqt_lock; 112 126 113 114 115 /////////////////////////////////////////////////////////////////////////////////// 116 // This kernel_init() function completes the kernel initialisation in 7 steps. 117 // Step 0 is done by processor[0,0,0]. Steps 1 to 6 are executed in parallel 118 // by all procesors. 119 // - step 0 : P[0,0,0] Initialise fat, heap descriptors, barrier and TTY0 lock. 127 //////////////////////////////////////////////////////////////////////////////// 128 // This kernel_init() function completes the kernel initialisation in 6 steps: 129 // Step 0 is done by processor[0,0,0]. Steps 1 to 4 are executed in parallel 130 // by all processors. 131 // - step 0 : P[0,0,0] Initialise various global variables. 120 132 // - step 1 : Each processor initialises scheduler pointers array. 121 133 // - step 2 : Each processor initialises PTAB pointers arrays. 122 // - step 3 : Each processor initialises its private XCU masks. 123 // - step 4 : Each processor starts its private TICK timer. 124 // - step 5 : Each processor initialises its private idle task context. 125 // - step 6 : Each processor set sp, sr, ptpr, epc registers values. 126 /////////////////////////////////////////////////////////////////////////////////// 134 // - step 3 : Each processor initialise idle task and starts TICK timer. 135 // - step 4 : Each processor set sp, sr, ptpr, epc registers values. 136 //////////////////////////////////////////////////////////////////////////////// 127 137 __attribute__((section (".kinit"))) void kernel_init() 128 138 { 129 139 // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH) 130 // x,y,p : proc essor coordinates ( x<X_SIZE / y<Y_SIZE / p<NB_PROCS_MAX )140 // x,y,p : proc coordinates ( x < X_SIZE / y < Y_SIZE / p < NB_PROCS_MAX ) 131 141 132 142 unsigned int gpid = _get_procid(); … … 137 147 138 148 //////////////////////////////////////////////////////////////////////////// 139 // Step 0 : P[0,0,0] initialises various structures 149 // Step 0 : P[0,0,0] initialises various global vaiables 150 //////////////////////////////////////////////////////////////////////////// 140 151 141 152 if ( gpid == 0 ) 142 153 { 143 // distributed kernel heap s154 // distributed kernel heap initialisation 144 155 _heap_init(); 145 156 146 157 #if GIET_DEBUG_INIT 147 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", x, y, p ); 148 #endif 149 // kernel FAT 150 _fat_init( IOC_BOOT_MODE ); 151 152 #if GIET_DEBUG_INIT 153 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", x, y, p ); 158 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", 159 x, y, p ); 154 160 #endif 155 161 // distributed lock for TTY0 … … 167 173 x , y , p ); 168 174 #endif 175 176 #if USE_PIC 177 178 // _ext_irq_index[isr][channel] initialisation 179 _ext_irq_init(); 180 181 // routing HBA IRQ to proc[0,0,0] EXT_IRQ_ONE 182 unsigned int unused = 0; 183 if ( USE_IOC_HBA ) _ext_irq_alloc( ISR_HBA , 0 , &unused ); 184 185 #if GIET_DEBUG_INIT 186 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes ext_irq init\n", 187 x , y , p ); 188 #endif 189 190 #endif // USE_PIC 169 191 170 192 // release other processors … … 176 198 } 177 199 178 /////////////////////////////////////////////////////////////////// 200 /////////////////////////////////////////////////////////////////////////// 179 201 // Step 1 : each processor get its scheduler vaddr from CP0_SCHED, 180 202 // contributes to _schedulers[] array initialisation, 181 203 // and wait completion of array initialisation. 204 /////////////////////////////////////////////////////////////////////////// 182 205 183 206 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); … … 193 216 #endif 194 217 218 ///////////////////////////////////////// 195 219 _sqt_barrier_wait( &_all_procs_barrier ); 220 ///////////////////////////////////////// 196 221 197 222 //////////////////////////////////////////////////////////////////////////// 198 223 // step 2 : each processor that is allocated at least one task loops 199 // on all allocated tasks: 200 // - contributes to _ptabs_vaddr[] & _ptabs_ptprs[] initialisation. 224 // on its allocated tasks: 225 // - contributes to _ptabs_vaddr[][][] & _ptabs_ptprs[][][] 226 // initialisation, from values stored in the tasks contexts. 201 227 // - set CTX_RA slot with the kernel _ctx_eret() virtual address. 202 228 // - set CTX_EPC slot that must contain the task entry point, 203 // and contain only at this point the virtual address of the memory 204 // location containing this entry point. 229 // and contain only at this point the virtual address of the 230 // memory slot containing this entry point. 231 //////////////////////////////////////////////////////////////////////////// 205 232 206 233 unsigned int ltid; … … 213 240 214 241 // initialize PTABS arrays 215 _ptabs_vaddr[vsid] = ptab; 216 _ptabs_ptprs[vsid] = ptpr; 217 218 #if GIET_DEBUG_INIT 219 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n" 220 " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n", 221 x, y, p, 222 vsid, ptab, vsid, ((unsigned long long)ptpr)<<13 ); 223 #endif 224 225 // set the ptpr to use the task page table 226 asm volatile( "mtc2 %0, $0 \n" 242 _ptabs_vaddr[vsid][x][y] = ptab; 243 _ptabs_ptprs[vsid][x][y] = ptpr; 244 245 // set the ptpr to use the local page table 246 asm volatile( "mtc2 %0, $0" 227 247 : : "r" (ptpr) ); 228 248 … … 232 252 233 253 // compute ctx_epc 234 unsigned int* ptr = (unsigned int*)_get_task_slot( x, y, p, ltid, CTX_EPC_ID ); 235 _set_task_slot( x, y, p, ltid, CTX_EPC_ID, *ptr ); 236 237 #if GIET_DEBUG_INIT 238 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] updates context for task %d\n" 239 " - ctx_epc = %x\n" 240 " - ctx_ra = %x\n", 241 x, y, p, ltid, 254 unsigned int* ptr = (unsigned int*)_get_task_slot(x,y,p,ltid,CTX_EPC_ID); 255 _set_task_slot(x,y,p,ltid,CTX_EPC_ID,*ptr); 256 257 #if GIET_DEBUG_INIT 258 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays" 259 " and context for task %d \n" 260 " - ptabs_vaddr[%d][%d][%d] = %x\n" 261 " - ptabs_paddr[%d][%d][%d] = %l\n" 262 " - ctx_epc = %x\n" 263 " - ctx_ra = %x\n", 264 x , y , p , ltid , 265 vsid , x , y , ptab , 266 vsid , x , y , ((unsigned long long)ptpr)<<13 , 242 267 _get_task_slot( x, y, p, ltid, CTX_EPC_ID ), 243 268 _get_task_slot( x, y, p, ltid, CTX_RA_ID ) ); … … 246 271 } // end for tasks 247 272 273 ///////////////////////////////////////// 248 274 _sqt_barrier_wait( &_all_procs_barrier ); 249 250 //////////////////////////////////////////////////////////////////////////// 251 // step 3 : compute and set XCU masks for HWI / PTI / WTI interrupts 252 253 unsigned int isr_switch_index = 0xFFFFFFFF; 254 unsigned int hwi_mask = 0; 255 unsigned int pti_mask = 0; 256 unsigned int wti_mask = 0; 257 unsigned int irq_id; // IN_IRQ index 258 unsigned int entry; // interrupt vector entry 259 260 for (irq_id = 0; irq_id < 32; irq_id++) 275 ///////////////////////////////////////// 276 277 //////////////////////////////////////////////////////////////////////////// 278 // step 3 : - Each processor complete idle task context initialisation, 279 // (only the CTX_SP, CTX_RA, CTX_EPC slot, because the CTX_PTPR 280 // and CTX_PTAB slots have been initialised in boot code) 281 // The 4 Kbytes idle stack is implemented in the scheduler itself. 282 // - Each processor starts TICK timer, as soon as at least one task 283 // is allocated. 284 // - P[0,0,0] initialises FAT (not done before, because it must 285 // be done after the _ptabs_vaddr[v][x][y] array initialisation, 286 // for V2P translation in _fat_ioc_access() function). 287 //////////////////////////////////////////////////////////////////////////// 288 289 unsigned int sp = ((unsigned int)psched) + 0x2000; 290 unsigned int ra = (unsigned int)(&_ctx_eret); 291 unsigned int epc = (unsigned int)(&_idle_task); 292 293 _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_SP_ID , sp ); 294 _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_RA_ID , ra ); 295 _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_EPC_ID , epc ); 296 297 if (tasks > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE ); 298 299 #if GIET_DEBUG_INIT 300 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes idle_task and starts TICK\n", 301 x, y, p ); 302 #endif 303 304 if ( gpid == 0 ) 261 305 { 262 entry = psched->hwi_vector[irq_id]; 263 if ( entry & 0x80000000 ) hwi_mask = hwi_mask | (1<<irq_id); 264 if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id; 265 266 entry = psched->pti_vector[irq_id]; 267 if ( entry & 0x80000000 ) pti_mask = pti_mask | (1<<irq_id); 268 if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id; 269 270 entry = psched->wti_vector[irq_id]; 271 if ( entry & 0x80000000 ) wti_mask = wti_mask | (1<<irq_id); 272 if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id; 306 _fat_init( 0 ); // no IRQ 307 308 #if GIET_DEBUG_INIT 309 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", 310 x, y, p ); 311 #endif 312 273 313 } 274 314 275 #if GIET_DEBUG_INIT 276 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] sets XCU masks\n" 277 " - ISR_TICK_INDEX = %d\n" 278 " - XCU HWI_MASK = %x\n" 279 " - XCU WTI_MASK = %x\n" 280 " - XCU PTI_MASK = %x\n", 281 x, y, p, 282 isr_switch_index, 283 hwi_mask, wti_mask, pti_mask ); 284 #endif 285 286 unsigned int channel = p * IRQ_PER_PROCESSOR; 287 288 _xcu_set_mask( cluster_xy, channel, hwi_mask, IRQ_TYPE_HWI ); 289 _xcu_set_mask( cluster_xy, channel, wti_mask, IRQ_TYPE_WTI ); 290 _xcu_set_mask( cluster_xy, channel, pti_mask, IRQ_TYPE_PTI ); 291 292 //////////////////////////////////////////////////////////////////////////// 293 // step 4 : Each processor start TICK timer if at least one task 294 295 if (tasks > 0) 296 { 297 // one ISR_TICK must be defined for each proc 298 if (isr_switch_index == 0xFFFFFFFF) 299 { 300 _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n", 301 x, y, p ); 302 _exit(); 303 } 304 305 // start system timer 306 _xcu_timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE ); 307 308 } 309 310 #if GIET_DEBUG_INIT 311 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n", 312 x, y, p ); 313 #endif 314 315 //////////////////////////////////////////////////////////////////////////// 316 // step 5 : each processor updates the idle_task context: 317 // (CTX_SP, CTX_RA, CTX_EPC). 318 // The 4 Kbytes idle stack is implemented in the scheduler. 319 // The PTPR register, the CTX_PTPR and CTX_PTAB slots 320 // have been initialised in boot code. 321 322 unsigned int pstack = ((unsigned int)psched) + 0x2000; 323 324 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_SP_ID, pstack); 325 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int) &_ctx_eret); 326 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_idle_task); 327 328 #if GIET_DEBUG_INIT 329 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes IDLE task\n" 330 " - stack_base = %x\n" 331 " - stack_size = 0x1000\n", 332 x, y, p, pstack - 0x1000 ); 333 #endif 334 315 ///////////////////////////////////////// 335 316 _sqt_barrier_wait( &_all_procs_barrier ); 336 337 //////////////////////////////////////////////////////////////////////////// 338 // step 6 : Each processor compute values for registers SP, SR, PTPR, EPC, 317 ///////////////////////////////////////// 318 319 //////////////////////////////////////////////////////////////////////////// 320 // step 4 : Each processor compute values for registers SP, SR, PTPR, EPC, 339 321 // corresponding to the first allocated task (can be idle task) 340 // and jump to user code when barrier is reached 341 342 if (tasks == 0) 343 { 344 ltid = IDLE_TASK_INDEX; 345 _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n", 346 x, y, p ); 347 } 348 else 349 { 350 ltid = 0; 351 } 322 // and jumps to user code. 323 //////////////////////////////////////////////////////////////////////////// 324 325 if (tasks == 0) _printf("\n[GIET WARNING] No task allocated to P[%d,%d,%d]\n", 326 x, y, p ); 327 328 if (tasks == 0) ltid = IDLE_TASK_INDEX; 329 else ltid = 0; 352 330 353 331 unsigned int sp_value = _get_task_slot( x, y, p, ltid, CTX_SP_ID); … … 356 334 unsigned int epc_value = _get_task_slot( x, y, p, ltid, CTX_EPC_ID); 357 335 358 _sqt_barrier_wait( &_all_procs_barrier );359 360 336 #if GIET_DEBUG_INIT 361 337 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] jumps to user code at cycle %d\n" 362 " sp = %x / sr = %x / ptpr = %x / epc = %x\n",363 x , y, p, _get_proctime(),364 sp_value, sr_value, ptpr_value, epc_value );338 " ltid = %d / sp = %x / sr = %x / ptpr = %x / epc = %x\n", 339 x , y , p , _get_proctime() , 340 ltid , sp_value , sr_value , ptpr_value , epc_value ); 365 341 #endif 366 342 -
soft/giet_vm/giet_kernel/sys_handler.c
r519 r528 61 61 #endif 62 62 63 64 63 //////////////////////////////////////////////////////////////////////////// 65 // Coprocessors loks and synchronisation variables64 // Extern variables 66 65 //////////////////////////////////////////////////////////////////////////// 67 66 68 __attribute__((section(".kdata"))) 69 simple_lock_t _coproc_lock[X_SIZE*Y_SIZE]; 70 71 __attribute__((section(".kdata"))) 72 unsigned int _coproc_done[X_SIZE*Y_SIZE]; 67 // allocated in tty0.c file. 68 extern sqt_lock_t _tty0_sqt_lock; 69 70 // allocated in mwr_driver.c file. 71 extern simple_lock_t _coproc_lock[X_SIZE*Y_SIZE]; 72 extern unsigned int _coproc_done[X_SIZE*Y_SIZE]; 73 74 // allocated in tty_driver.c file. 75 extern unsigned int _tty_rx_full[NB_TTY_CHANNELS]; 76 extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; 73 77 74 78 //////////////////////////////////////////////////////////////////////////// … … 91 95 __attribute__((section(".kdata"))) 92 96 unsigned int _nic_tx_channel_allocator = 0; 93 94 ////////////////////////////////////////////////////////////////////////////95 // These global variables are allocated in tty0.c and tty_driver.c files.96 ////////////////////////////////////////////////////////////////////////////97 98 extern sqt_lock_t _tty0_sqt_lock;99 100 extern unsigned int _tty_rx_full[NB_TTY_CHANNELS];101 102 extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS];103 97 104 98 //////////////////////////////////////////////////////////////////////////// … … 157 151 &_sys_ukn, /* 0x17 */ 158 152 &_sys_ukn, /* 0x18 */ 159 &_ context_switch,/* 0x19 */153 &_sys_context_switch, /* 0x19 */ 160 154 &_sys_vseg_get_vbase, /* 0x1A */ 161 155 &_sys_vseg_get_length, /* 0x1B */ … … 355 349 unsigned int size = desc->buffer_size; 356 350 357 // these variables are used for the v2p translations 358 unsigned int ptab = _get_context_slot(CTX_PTAB_ID); 359 unsigned int ppn; 360 unsigned int flags; 351 // physical addresses 361 352 unsigned long long buffer_paddr; 362 353 unsigned int buffer_lsb; … … 369 360 unsigned int lock_msb; 370 361 362 unsigned int flags; // unused 363 371 364 // compute memory buffer physical address 372 _v2p_translate( (page_table_t*)ptab, 373 desc->buffer_vaddr>>12, 374 &ppn, 375 &flags ); 376 buffer_paddr = (((unsigned long long)ppn) << 12) | 377 (desc->buffer_vaddr & 0x00000FFF); 378 buffer_lsb = (unsigned int)buffer_paddr; 379 buffer_msb = (unsigned int)(buffer_paddr>>32); 365 buffer_paddr = _v2p_translate( desc->buffer_vaddr , &flags ); 366 buffer_lsb = (unsigned int)buffer_paddr; 367 buffer_msb = (unsigned int)(buffer_paddr>>32); 380 368 381 369 // call MWMR_DMA driver … … 385 373 _mwr_set_channel_register( cluster_xy, channel, CHANNEL_BUFFER_MSB, buffer_msb ); 386 374 387 // compute MWMR descriptor and lock physical addresses (if required)388 375 if ( mode == MODE_MWMR ) 389 376 { 390 _v2p_translate( (page_table_t*)ptab, 391 desc->mwmr_vaddr>>12, 392 &ppn, 393 &flags ); 394 mwmr_paddr = (((unsigned long long)ppn) << 12) | 395 (desc->mwmr_vaddr & 0x00000FFF); 377 // compute MWMR descriptor physical address 378 mwmr_paddr = _v2p_translate( desc->mwmr_vaddr , &flags ); 396 379 mwmr_lsb = (unsigned int)mwmr_paddr; 397 380 mwmr_msb = (unsigned int)(mwmr_paddr>>32); 398 399 _v2p_translate( (page_table_t*)ptab,400 desc->lock_vaddr>>12,401 &ppn,402 &flags );403 lock_paddr = (((unsigned long long)ppn) << 12) |404 (desc->lock_vaddr & 0x00000FFF);405 lock_lsb = (unsigned int)lock_paddr;406 lock_msb = (unsigned int)(lock_paddr>>32);407 381 408 382 // call MWMR_DMA driver 409 383 _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_LSB, mwmr_lsb ); 410 384 _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_MSB, mwmr_msb ); 385 386 // compute lock physical address 387 lock_paddr = _v2p_translate( desc->lock_vaddr , &flags ); 388 lock_lsb = (unsigned int)lock_paddr; 389 lock_msb = (unsigned int)(lock_paddr>>32); 390 391 // call MWMR_DMA driver 411 392 _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_LSB, lock_lsb ); 412 393 _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_MSB, lock_msb ); … … 740 721 unsigned long long ker_chbuf_pbase; // kernel chbuf physical address 741 722 742 // These variables are used for the various V2P translation743 unsigned int ptab = _get_context_slot(CTX_PTAB_ID);744 unsigned int ppn;745 unsigned int flags;746 unsigned int vaddr;747 748 723 // allocate one kernel container per cluster in the (xmax / ymax) mesh 749 unsigned int cx; // cluster X coordinate 750 unsigned int cy; // cluster Y coordinate 751 unsigned int index; // container index in chbuf 752 unsigned long long cont_paddr; // container physical address 724 unsigned int cx; // cluster X coordinate 725 unsigned int cy; // cluster Y coordinate 726 unsigned int index; // container index in chbuf 727 unsigned int vaddr; // virtual address 728 unsigned long long cont_paddr; // container physical address 729 730 unsigned int flags; // for _v2p_translate() 753 731 754 732 for ( cx = 0 ; cx < xmax ; cx++ ) … … 770 748 771 749 // compute container physical address 772 _v2p_translate( (page_table_t*)ptab, 773 vaddr>>12, 774 &ppn, 775 &flags ); 776 cont_paddr = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF); 750 cont_paddr = _v2p_translate( vaddr , &flags ); 777 751 778 752 // initialize chbuf entry … … 816 790 if ( is_rx ) vaddr = (unsigned int)( &_nic_rx_chbuf[nic_channel] ); 817 791 else vaddr = (unsigned int)( &_nic_tx_chbuf[nic_channel] ); 818 _v2p_translate( (page_table_t*)ptab, 819 vaddr>>12, 820 &ppn, 821 &flags ); 822 ker_chbuf_pbase = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF); 792 793 ker_chbuf_pbase = _v2p_translate( vaddr , &flags ); 823 794 824 795 #if GIET_DEBUG_NIC … … 965 936 unsigned long long kernel_buffer_paddr; // kernel buffer physical address 966 937 unsigned long long kernel_chbuf_paddr; // kernel chbuf physical address 967 unsigned long long buffer_desc ;// kernel buffer descriptor968 unsigned long long buffer_desc_paddr; // kernel buffer descriptor p hysical address938 unsigned long long buffer_descriptor; // kernel buffer descriptor 939 unsigned long long buffer_desc_paddr; // kernel buffer descriptor paddr 969 940 unsigned int index; // kernel buffer index in chbuf 970 971 // The following variables are used for V2P translation 972 unsigned int ptab = _get_context_slot( CTX_PTAB_ID ); 973 unsigned int ppn; 974 unsigned int flags; 975 unsigned int vaddr; 941 unsigned int flags; // for _v2P_translate 976 942 977 943 // Compute user buffer physical address and check access rights 978 vaddr = (unsigned int)buffer; 979 _v2p_translate( (page_table_t*)ptab, 980 vaddr>>12, 981 &ppn, 982 &flags ); 944 user_buffer_paddr = _v2p_translate( (unsigned int)buffer , &flags ); 983 945 984 946 if ( (flags & PTE_U) == 0 ) … … 987 949 return -1; 988 950 } 989 user_buffer_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);990 951 991 952 #if GIET_DEBUG_NIC … … 995 956 996 957 // compute kernel chbuf physical address (required for sync) 997 vaddr = (unsigned int)chbuf; 998 _v2p_translate( (page_table_t*)ptab, 999 vaddr>>12, 1000 &ppn, 1001 &flags ); 1002 kernel_chbuf_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 958 kernel_chbuf_paddr = _v2p_translate( (unsigned int)chbuf , &flags ); 1003 959 1004 960 // poll local kernel container status until success … … 1011 967 // inval buffer descriptor in L2 before read in L2 1012 968 _mmc_inval( buffer_desc_paddr , 8 ); 1013 buffer_desc = chbuf->buffer[index].desc;969 buffer_descriptor = chbuf->buffer[index].desc; 1014 970 1015 971 #if GIET_DEBUG_NIC 1016 972 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() read buffer descriptor %d\n" 1017 973 " at cycle = %d / paddr = %l / buffer descriptor = %l\n", 1018 thread, index, _get_proctime(), buffer_desc_paddr, buffer_desc );974 thread, index, _get_proctime(), buffer_desc_paddr, buffer_descriptor ); 1019 975 #endif 1020 976 1021 977 // test buffer status and break if found 1022 if ( ( is_rx != 0 ) && (buffer_desc >> 63) == 1 ) break;1023 if ( ( is_rx == 0 ) && (buffer_desc >> 63) == 0 ) break;978 if ( ( is_rx != 0 ) && (buffer_descriptor >> 63) == 1 ) break; 979 if ( ( is_rx == 0 ) && (buffer_descriptor >> 63) == 0 ) break; 1024 980 } 1025 981 1026 982 // compute kernel buffer physical address 1027 kernel_buffer_paddr = buffer_desc & 0x0000FFFFFFFFFFFFULL;983 kernel_buffer_paddr = buffer_descriptor & 0x0000FFFFFFFFFFFFULL; 1028 984 1029 985 // move one container … … 1281 1237 #if NB_CMA_CHANNELS > 0 1282 1238 1283 unsigned int ptab; // page table virtual address1284 1239 unsigned int vaddr; // virtual address 1285 unsigned int flags; // protection flags 1286 unsigned int ppn; // physical page number 1240 unsigned int flags; // for _v2p_translate() 1287 1241 1288 1242 // get channel index … … 1308 1262 1309 1263 // checking user buffers virtual addresses and length alignment 1310 if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 1311 { 1312 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not word aligned\n"); 1313 return -1; 1314 } 1315 1316 // get page table virtual address 1317 ptab = _get_context_slot(CTX_PTAB_ID); 1264 if ( ((unsigned int)vbase0 & 0x3) || 1265 ((unsigned int)vbase1 & 0x3) || 1266 (length & 0x3) ) 1267 { 1268 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not aligned\n"); 1269 return -1; 1270 } 1318 1271 1319 1272 // compute frame buffer physical address and initialize _fbf_chbuf[channel] 1320 vaddr = ((unsigned int)SEG_FBF_BASE); 1321 _v2p_translate( (page_table_t*) ptab, 1322 (vaddr >> 12), 1323 &ppn, 1324 &flags ); 1325 1326 _fbf_chbuf[channel].fbf.desc = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 1273 vaddr = (unsigned int)SEG_FBF_BASE; 1274 _fbf_chbuf[channel].fbf.desc = _v2p_translate( vaddr , &flags ); 1327 1275 1328 1276 // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel] 1329 vaddr = (unsigned int)vbase0; 1330 _v2p_translate( (page_table_t*) ptab, 1331 (vaddr >> 12), 1332 &ppn, 1333 &flags ); 1277 vaddr = (unsigned int)vbase0; 1278 _fbf_chbuf[channel].buf0.desc = _v2p_translate( vaddr , &flags ); 1279 1334 1280 if ((flags & PTE_U) == 0) 1335 1281 { 1336 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 not in user space\n"); 1337 return -1; 1338 } 1339 1340 _fbf_chbuf[channel].buf0.desc = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 1282 _printf("\n[GIET ERROR] in _fbf_cma_start() : buf0 not in user space\n"); 1283 return -1; 1284 } 1341 1285 1342 1286 // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel] 1343 vaddr = (unsigned int)vbase1; 1344 _v2p_translate( (page_table_t*) ptab, 1345 (vaddr >> 12), 1346 &ppn, 1347 &flags ); 1287 vaddr = (unsigned int)vbase1; 1288 _fbf_chbuf[channel].buf1.desc = _v2p_translate( vaddr , &flags ); 1289 1348 1290 if ((flags & PTE_U) == 0) 1349 1291 { 1350 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 not in user space\n"); 1351 return -1; 1352 } 1353 1354 _fbf_chbuf[channel].buf1.desc = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 1292 _printf("\n[GIET ERROR] in _fbf_cma_start() : buf1 not in user space\n"); 1293 return -1; 1294 } 1355 1295 1356 1296 // initializes buffer length … … 1358 1298 1359 1299 // Compute and register physical adress of the fbf_chbuf descriptor 1360 vaddr = (unsigned int)(&_fbf_chbuf[channel]); 1361 _v2p_translate( (page_table_t*) ptab, 1362 (vaddr >> 12), 1363 &ppn, 1364 &flags ); 1300 vaddr = (unsigned int)&_fbf_chbuf[channel]; 1301 _fbf_chbuf_paddr[channel] = _v2p_translate( vaddr , &flags ); 1365 1302 1366 _fbf_chbuf_paddr[channel] = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);1367 1368 1303 if ( USE_IOB ) 1369 1304 { … … 1594 1529 1595 1530 // deschedule 1596 _ context_switch();1531 _sys_context_switch(); 1597 1532 1598 1533 return 0; 1599 1534 } 1600 1535 1601 ////////////////////// 1602 int _ context_switch()1536 ///////////////////////// 1537 int _sys_context_switch() 1603 1538 { 1604 1539 unsigned int save_sr; … … 1755 1690 unsigned int* y ) 1756 1691 { 1757 unsigned int ppn;1758 1692 unsigned int flags; 1759 unsigned int vpn = (((unsigned int)ptr)>>12);1693 unsigned long long paddr = _v2p_translate( (unsigned int)ptr , &flags ); 1760 1694 1761 // get the page table pointer 1762 page_table_t* pt = (page_table_t*)_get_context_slot( CTX_PTAB_ID ); 1763 1764 // compute the physical address 1765 _v2p_translate( pt, vpn, &ppn, &flags ); 1766 1767 *x = (ppn>>24) & 0xF; 1768 *y = (ppn>>20) & 0xF; 1695 *x = (paddr>>36) & 0xF; 1696 *y = (paddr>>32) & 0xF; 1697 1769 1698 return 0; 1770 1699 } -
soft/giet_vm/giet_kernel/sys_handler.h
r519 r528 197 197 int _sys_task_exit( char* string ); 198 198 199 int _ context_switch();199 int _sys_context_switch(); 200 200 201 201 int _sys_local_task_id();
Note: See TracChangeset
for help on using the changeset viewer.