- Timestamp:
- Apr 21, 2014, 5:29:40 AM (11 years ago)
- Location:
- soft/giet_vm/giet_kernel
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/ctx_handler.h
r294 r310 69 69 unsigned int pti_vector[32]; // timer interrupt vector 70 70 unsigned int wti_vector[32]; // software interrupt vector 71 unsigned int reserved[30]; // padding to 4 Kbytes 71 72 } static_scheduler_t; 72 73 -
soft/giet_vm/giet_kernel/irq_handler.c
r297 r310 56 56 unsigned int irq_id; 57 57 unsigned int irq_type; 58 char* irq_type_str[] = { "HWI", "WTI", "PTI" };59 58 60 59 // get the highest priority active IRQ index … … 88 87 89 88 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlocks 89 char* irq_type_str[] = { "HWI", "WTI", "PTI" }; 90 90 _puts("\n[IRQS DEBUG] Processor["); 91 91 _putd(x); … … 120 120 else 121 121 { 122 // we don't take the TTY lock to avoid deadlock 123 _puts("\n[GIET ERROR] in _irq_demux() illegal ISR type on processor["); 124 _putd(x); 125 _puts(","); 126 _putd(y); 127 _puts(","); 128 _putd(lpid); 129 _puts("] at cycle "); 130 _putd(_get_proctime() ); 131 _puts("\n "); 132 _puts(irq_type_str[irq_type] ); 133 _puts(" : irq_id = "); 134 _putd(irq_id); 135 _puts(" / isr_type = "); 136 _putd(isr_type); 137 _puts(" / channel = "); 138 _putd(channel); 139 _puts("\n"); 140 _exit(); 122 _printf("\n[GIET ERROR] in _irq_demux() :" 123 " illegal ISR type on processor[%d,%d,%d] at cycle %d\n" 124 " - irq_type = %d\n" 125 " - irq_id = %d\n" 126 " - isr_type = %x\n", 127 x, y, lpid, _get_proctime(), irq_type, irq_id, isr_type ); 141 128 } 142 129 } -
soft/giet_vm/giet_kernel/kernel_init.c
r299 r310 9 9 // This nano-kernel has been written for the MIPS32 processor. 10 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 11 // physicals addresses can have up to 40 bits, and use the (unsigned long long) type. 12 12 // It natively supports clusterised shared mmemory multi-processors architectures, 13 // where each processor is identified by a composite index (cluster_xy, local_id),13 // where each processor is identified by a composite index [x,y,lpid], 14 14 // and where there is one physical memory bank per cluster. 15 15 // 16 // This file contains the _kernel_init() function, that performs the second 17 // phase of system initialisation. The three significant actions are: 18 // 1) processor 0 makes peripherals and system FAT initialisation. 19 // 2) processor 0 awake all other processors by an IPI. 20 // 3) all processors running in parallel perform register initialisation, 21 // from their private scheduler, and jump to user code. 16 // The kernel_init() function is executed in parallel by all procesors, 17 // and 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. 22 47 //////////////////////////////////////////////////////////////////////////////////// 23 48 … … 77 102 unsigned int _init_barrier = 0; 78 103 79 //////////////////////////////////////////////////////////////////////////////////// 80 // This function is the entry point in kernel for all processors. 81 // It is executed in parallel by all procesors, and completes the system 82 // initialisation that has been started by processor 0 in the boot_init() function. 83 // 84 // This kernel code makes the following assuptions, regarding the work bone 85 // by the boot code: 86 // 87 // 1) The page tables associated to the various vspaces have been build 88 // in physical memory, and can be used by the kernel code. 89 // 90 // 2) All schedulers (this include all task contexts) have been initialised, 91 // Both the virtual and the physical base addresses of the page tables 92 // are available in the CTX_PTAB and CTX_PTPR slots. 93 // 94 // 3) The CP0_SCHED register of each processor contains a pointer on its 95 // private scheduler (virtual address). 96 // 97 // 4) The CP2_PTPR register of each processor contains a pointer on 98 // the vspace_0 page table (physical address>>13). 99 // 100 // 5) For all processors, the MMU is activated (CP2_MODE contains 0xF). 101 // 102 // This code must be loaded in .kinit section, in order to control seg_kinit_base, 103 // as this address is used by the boot code to jump into kernel code. 104 //////////////////////////////////////////////////////////////////////////////////// 105 // Each processor performs the following actions: 106 // 1/ contribute to _schedulers_paddr[] array initialisation. 107 // 2/ contribute to _ptabs_paddr[] and _ptabs_vaddr arrays initialisation 108 // 3/ completes task context initialisation for ech allocated task 109 // 4/ compute and set the ICU mask for its private ICU channel 110 // 5/ initialise its private TICK timer (if tasks > 0) 111 // 6/ initialise the "idle" task context in its private scheduler 112 // 7/ initialise SP, SR, PTPR, EPC registers and jump to user code with an eret. 113 //////////////////////////////////////////////////////////////////////////////////// 114 __attribute__((section (".kinit"))) void kernel_parallel_init() 104 /////////////////////////////////////////////////////////////////////////////////// 105 __attribute__((section (".kinit"))) void kernel_init() 115 106 { 116 107 unsigned int global_pid = _get_procid(); … … 119 110 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 120 111 unsigned int lpid = global_pid % NB_PROCS_MAX; 112 unsigned int nprocs = TOTAL_PROCS; 113 unsigned int pid = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + lpid; 114 // unsigned int pid = _get_id(i n_procs ); 115 116 // This last initialisation phase is done sequencially: 117 while( pid != _init_barrier ) asm volatile ( "nop" ); 121 118 122 119 // Step 1 : each processor get its scheduler virtual address … … 129 126 130 127 #if GIET_DEBUG_INIT 131 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] \n"128 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] starts kernel init\n" 132 129 " - scheduler vbase = %x\n" 133 130 " - tasks = %d\n", … … 176 173 177 174 #if GIET_DEBUG_INIT 178 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] update context for task %d\n"175 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] updates context for task %d\n" 179 176 " - ctx_epc = %x\n" 180 177 " - ctx_ra = %x\n", … … 211 208 212 209 #if GIET_DEBUG_INIT 213 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] set XCU masks\n"210 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] sets XCU masks\n" 214 211 " - ICU HWI_MASK = %x\n" 215 212 " - ICU WTI_MASK = %x\n" … … 250 247 251 248 #if GIET_DEBUG_INIT 252 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] start TICK timer\n",249 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] starts TICK timer\n", 253 250 x, y, lpid ); 254 251 #endif … … 269 266 270 267 #if GIET_DEBUG_INIT 271 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] initialize IDLE task\n",268 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] initializes IDLE task\n", 272 269 x, y, lpid ); 273 270 #endif … … 296 293 unsigned int epc_value = _get_task_slot(global_pid, ltid, CTX_EPC_ID); 297 294 298 #if GIET_DEBUG_INIT 299 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] reach barrier at cycle %d\n" 300 " - sp = %x\n" 301 " - sr = %x\n" 302 " - ptpr = %x\n" 303 " - epc = %x\n", 304 x, y, lpid, _get_proctime(), 305 sp_value, sr_value, ptpr_value, epc_value ); 306 #endif 307 295 _printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] reach barrier at cycle %d\n", 296 x, y, lpid, _get_proctime() ); 297 298 /* 308 299 unsigned int* pcount = &_init_barrier; 309 unsigned int nprocs = TOTAL_PROCS;310 300 unsigned int count; 311 301 312 302 // increment barrier counter with atomic LL/SC 313 303 asm volatile ( "_init_barrier_loop: \n" 314 "ll %0, 0(%1) \n" /* count <= *pcount */315 "addi $3, %0, 1 \n" /* $3 <= count + 1 */316 "sc $3, 0(%1) \n" /* *pcount <= $3 */317 "beqz $3, _init_barrier_loop \n" /* retry if failure */304 "ll %0, 0(%1) \n" 305 "addi $3, %0, 1 \n" 306 "sc $3, 0(%1) \n" 307 "beqz $3, _init_barrier_loop \n" 318 308 "nop \n" 319 309 : "=&r"(count) … … 323 313 // busy waiting until all processors synchronized 324 314 while ( *pcount != nprocs ) asm volatile ("nop"); 325 315 */ 316 317 // increment barrier counter 318 _init_barrier++; 319 320 // busy waiting until all processors synchronized 321 while ( _init_barrier != nprocs ) asm volatile ("nop"); 322 323 /* 326 324 _printf("\n[GIET] Processor[%d,%d,%d] jumps to user code at cycle %d\n", 327 325 x, y, lpid, _get_proctime() ); 326 */ 328 327 329 328 // set registers and jump to user code … … 338 337 : "$29" ); 339 338 340 } // end kernel_ parallel_init()339 } // end kernel_init() 341 340 342 341
Note: See TracChangeset
for help on using the changeset viewer.