Changeset 203
- Timestamp:
- Aug 13, 2012, 10:52:25 PM (12 years ago)
- Location:
- soft/giet_vm
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/Makefile
r197 r203 57 57 58 58 ### mapping compilation 59 map.bin: map.xml59 map.bin: 1c_4p_four.xml 60 60 $(MAKE) -C xml 61 xml/xml2bin map.xml map.bin61 xml/xml2bin $< $@ 62 62 63 63 ### system compilation -
soft/giet_vm/boot/boot.ld
r189 r203 1 /****************************************************************************2 * Definition of the base address for all virtual segments3 *****************************************************************************/4 1 5 /* 6 The following (virtual) addresses are specific for the boot phase. 7 They must respect identity mapping: physical address = virtual address 8 */ 2 /****************************************************************************/ 3 /* Definition of the base addresses for all vsegs used by the GIET_VM */ 4 /****************************************************************************/ 9 5 10 seg_boot_base = 0xBFC00000; /* boot code */ 6 INCLUDE giet_vsegs.ld 11 7 12 seg_boot_stack_base = 0xBFC08000; /* boot temporary stack */ 13 14 seg_mapping_base = 0xBFC0C000; /* boot mapping_info */ 15 16 /* 17 The following (virtual) addresse are defined and used by the kernel. 18 They are not constrained to respect identity mapping. 19 */ 20 21 seg_kernel_init_base = 0x80090000; /* system init entry */ 22 23 seg_tty_base = 0x90000000; /* TTY device */ 24 seg_timer_base = 0x91000000; /* Timer device */ 25 seg_ioc_base = 0x92000000; /* Block device */ 26 seg_dma_base = 0x93000000; /* DMA device */ 27 seg_gcd_base = 0x95000000; /* GCD device */ 28 seg_fb_base = 0x96000000; /* FrameBuffer device */ 29 seg_iob_base = 0x9E000000; /* IO Bridge device */ 30 seg_icu_base = 0x9F000000; /* ICU or XICU device */ 31 32 /* 33 Grouping sections into segments for boot code and data 34 */ 8 /****************************************************************************/ 9 /* Grouping sections into virtual segment for boot code and data */ 10 /****************************************************************************/ 35 11 36 12 SECTIONS 37 13 { 38 /* contain both data and code sections */ 39 . = seg_boot_base; 40 seg_boot : 14 . = seg_boot_code_base; 15 seg_boot_code : 41 16 { 42 17 *(.boot) … … 55 30 } 56 31 } 32 -
soft/giet_vm/boot/boot_init.c
r200 r203 800 800 } 801 801 802 // checking Rnumber of clusters802 // checking number of clusters 803 803 if ( header->clusters != NB_CLUSTERS ) 804 804 { … … 820 820 } 821 821 822 // checking har ware822 // checking hardware 823 823 unsigned int periph_id; 824 824 unsigned int cluster_id; … … 851 851 boot_exit(); 852 852 } 853 if ( periph[periph_id].channels >NB_TTYS )854 { 855 boot_puts("\n[BOOT ERROR] Too much TTY terminalsin cluster ");853 if ( periph[periph_id].channels != NB_TTYS ) 854 { 855 boot_puts("\n[BOOT ERROR] Wrong NB_TTYS in cluster "); 856 856 boot_putw( cluster_id ); 857 857 boot_puts(" : ttys = "); … … 870 870 boot_exit(); 871 871 } 872 if ( periph[periph_id].channels >NB_NICS )873 { 874 boot_puts("\n[BOOT ERROR] Too much NIC channelsin cluster ");872 if ( periph[periph_id].channels != NB_NICS ) 873 { 874 boot_puts("\n[BOOT ERROR] Wrong NB_NICS in cluster "); 875 875 boot_putw( cluster_id ); 876 876 boot_puts(" : nics = "); … … 884 884 if ( periph[periph_id].type == PERIPH_TYPE_TIM ) 885 885 { 886 if ( periph[periph_id].channels > NB_TIMERS_MAX)886 if ( periph[periph_id].channels != (NB_PROCS_MAX + NB_TIMERS_MAX) ) 887 887 { 888 888 boot_puts("\n[BOOT ERROR] Too much user timers in cluster "); … … 897 897 if ( periph[periph_id].type == PERIPH_TYPE_DMA ) 898 898 { 899 if ( periph[periph_id].channels >NB_DMAS_MAX )899 if ( periph[periph_id].channels != NB_DMAS_MAX ) 900 900 { 901 901 boot_puts("\n[BOOT ERROR] Too much DMA channels in cluster "); … … 1198 1198 //////////////////////////////////////////////////////////////////////////////// 1199 1199 // This function intializes the periherals and coprocessors, as specified 1200 // tsuch as the IOB component 1201 // (I/O bridge, containing the IOMMU, the IOC (external disk controller), 1202 // the NIC (external network controller), the FBDMA (frame buffer controller), 1200 // in the mapping_info file. 1203 1201 //////////////////////////////////////////////////////////////////////////////// 1204 1202 void boot_peripherals_init() … … 1306 1304 1307 1305 } // end for periphs 1308 1306 /* 1309 1307 for ( coproc_id = cluster[cluster_id].coproc_offset ; 1310 1308 coproc_id < cluster[cluster_id].coproc_offset + cluster[cluster_id].coprocs ; … … 1358 1356 } 1359 1357 } // end for coprocs 1360 1358 */ 1361 1359 } // end for clusters 1362 1360 } // end boot_peripherals_init() -
soft/giet_vm/giet_config.h
r199 r203 17 17 #define BOOT_DEBUG_SCHED 0 /* display schedulers initialisation on TTY0 */ 18 18 19 #define GIET_DEBUG_INIT 1/* display parallel kernel initialisation on TTY0 */19 #define GIET_DEBUG_INIT 0 /* display parallel kernel initialisation on TTY0 */ 20 20 #define GIET_DEBUG_SWITCH 0 /* display context switchs on TTY0 */ 21 21 … … 39 39 #define GIET_TICK_VALUE 0x4000 /* context switch period (number of cycles) */ 40 40 #define GIET_IOMMU_ACTIVE 0 /* The IOMMU vspace is defined */ 41 #define GIET_USE_XICU 0/* Use the XICU interrupt controler */41 #define GIET_USE_XICU 1 /* Use the XICU interrupt controler */ 42 42 43 43 #endif -
soft/giet_vm/libs/stdio.c
r165 r203 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The stdio.c and stdio.h files are part of the GIET nano-kernel.7 // The stdio.c and stdio.h files are part of the GIET_VM nano-kernel. 8 8 // This library contains all user-level functions that contain a system call 9 9 // to access protected or shared ressources. … … 17 17 #define SYSCALL_TTY_WRITE 0x02 18 18 #define SYSCALL_TTY_READ 0x03 19 #define SYSCALL_TIMER_START 0x04 20 #define SYSCALL_TIMER_STOP 0x05 19 21 #define SYSCALL_GCD_WRITE 0x06 20 22 #define SYSCALL_GCD_READ 0x07 … … 461 463 } 462 464 465 466 ///// TIMER related system calls ////// 467 468 ////////////////////////////////////////////////////////////////////////////////// 469 // giet_timer_start() 470 ////////////////////////////////////////////////////////////////////////////////// 471 // This function activates the private user timer allocated to the calling task 472 // in the boot phase. 473 // - Returns 0 if success, > 0 if error. 474 ////////////////////////////////////////////////////////////////////////////////// 475 unsigned int giet_timer_start() 476 { 477 return sys_call(SYSCALL_TIMER_START, 478 0,0,0,0); 479 } 480 ////////////////////////////////////////////////////////////////////////////////// 481 // giet_timer_stop() 482 ////////////////////////////////////////////////////////////////////////////////// 483 // This function activates the user timer allocated to the calling task. 484 // - Returns 0 if success, > 0 if error. 485 ////////////////////////////////////////////////////////////////////////////////// 486 unsigned int giet_timer_stop() 487 { 488 return sys_call(SYSCALL_TIMER_STOP, 489 0,0,0,0); 490 } 491 463 492 ///// GCD (Greatest Common Divider) related system calls 464 493 -
soft/giet_vm/sys/common.h
r199 r203 19 19 extern _ld_symbol_t seg_iob_base; 20 20 extern _ld_symbol_t seg_icu_base; 21 extern _ld_symbol_t seg_tim er_base;21 extern _ld_symbol_t seg_tim_base; 22 22 extern _ld_symbol_t seg_tty_base; 23 23 extern _ld_symbol_t seg_gcd_base; 24 24 extern _ld_symbol_t seg_dma_base; 25 extern _ld_symbol_t seg_fb _base;25 extern _ld_symbol_t seg_fbf_base; 26 26 extern _ld_symbol_t seg_ioc_base; 27 27 extern _ld_symbol_t seg_mapping_base; -
soft/giet_vm/sys/drivers.c
r199 r203 11 11 // - vci_multi_dma 12 12 // - vci_multi_icu 13 // - vci_xicu 13 // - vci_xicu & vci_multi_icu 14 14 // - vci_gcd 15 15 // - vci_frame_buffer … … 23 23 // - NB_TTYS 24 24 // 25 // The following base addresses must be defined in the sys.ld file:25 // The following virtual base addresses must be defined in the sys.ld file: 26 26 // - seg_icu_base 27 // - seg_tim er_base27 // - seg_tim_base 28 28 // - seg_tty_base 29 29 // - seg_gcd_base 30 30 // - seg_dma_base 31 // - seg_fb _base31 // - seg_fbf_base 32 32 // - seg_ioc_base 33 33 /////////////////////////////////////////////////////////////////////////////////// … … 93 93 #define in_unckdata __attribute__((section (".unckdata"))) 94 94 95 96 95 ////////////////////////////////////////////////////////////////////////////// 97 // VciMultiTimerdriver96 // Timers driver 98 97 ////////////////////////////////////////////////////////////////////////////// 99 // There is one multi_timer (or xicu) component per cluster. 100 // The global index is cluster_id*(NB_PROCS_MAX+NB_TIMERS_MAX) + local_id 98 // The timers can be implemented in a vci_timer component or in a vci_xicu 99 // component (depending on the GIET_USE_XICU parameter). 100 // There is one timer (or xicu) component per cluster. 101 101 // There is two types of timers: 102 102 // - "system" timers : one per processor, used for context switch. 103 103 // local_id in [0, NB_PROCS_MAX-1], 104 104 // - "user" timers : requested by the task in the mapping_info data structure. 105 // local_id in [NB_PROC_MAX, NB_PROCS_MAX+NB_TIMERS_MAX-1], 106 // For each user timer, the tty_id is stored in the context of the task 107 // and must be explicitely defined in the boot code. 108 // These timers can be implemented in a vci_multi_timer component 109 // or in a vci_xicu component (depending on the GIET_USE_XICU parameter). 105 // local_id in [NB_PROC_MAX, NB_PROCS_MAX + NB_TIMERS_MAX - 1] 106 // For each user timer, the timer_id is stored in the context of the task. 107 // The global index is cluster_id * (NB_PROCS_MAX+NB_TIMERS_MAX) + local_id 110 108 ////////////////////////////////////////////////////////////////////////////// 111 109 … … 118 116 119 117 ////////////////////////////////////////////////////////////////////////////// 120 // _timer_ access()121 // This function is the only way to access a timer device.122 // It can be a multi-timer component or an xicu component.123 // It can be used by the kernel to initialise a "system" timer,118 // _timer_start() 119 // This function activates a timer in the vci_timer (or vci_xicu) component 120 // by writing in the proper register the period value. 121 // It can be used by both the kernel to initialise a "system" timer, 124 122 // or by a task (through a system call) to configure an "user" timer. 125 123 // Returns 0 if success, > 0 if error. 126 124 ////////////////////////////////////////////////////////////////////////////// 127 unsigned int _timer_access( unsigned int read, 128 unsigned int cluster_id, 129 unsigned int local_id, 130 unsigned int register_id, 131 unsigned int* buffer ) 125 unsigned int _timer_start( unsigned int cluster_id, 126 unsigned int local_id, 127 unsigned int period ) 132 128 { 133 129 // parameters checking 134 if ( register_id >= TIMER_SPAN) return 1;135 130 if ( cluster_id >= NB_CLUSTERS) return 1; 136 131 if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1; 137 132 138 133 #if GIET_USE_XICU 139 140 unsigned int* timer_address = //TODO 141 134 unsigned int* timer_address = (unsigned int*)&seg_icu_base + 135 (cluster_id * CLUSTER_SPAN); 136 137 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period; 142 138 #else 143 144 unsigned int* timer_address = (unsigned int*)&seg_timer_base + 145 (cluster_id * CLUSTER_SPAN) + 146 (local_id * TIMER_SPAN); 147 #endif 148 149 if (read) *buffer = timer_address[register_id]; // read word 150 else timer_address[register_id] = *buffer; // write word 139 unsigned int* timer_address = (unsigned int*)&seg_tim_base + 140 (cluster_id * CLUSTER_SPAN); 141 142 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; 143 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3; 144 #endif 145 151 146 return 0; 152 147 } 153 148 ////////////////////////////////////////////////////////////////////////////// 154 // _timer_write() 155 // This function implements a write access to a "user" timer register. 156 // It gets the cluster_id and local_id from the global index stored in 157 // the task context and use the timer_access() function to make the write. 149 // _timer_stop() 150 // This function desactivates a timer in the vci_timer (or vci_xicu) component 151 // by writing in the proper register. 158 152 // Returns 0 if success, > 0 if error. 159 153 ////////////////////////////////////////////////////////////////////////////// 160 unsigned int _timer_write( unsigned int register_id, 161 unsigned int value ) 162 { 163 unsigned int buffer = value; 164 unsigned int task_id = _get_current_task_id(); 165 unsigned int timer_id = _get_context_slot(task_id, CTX_TIMER_ID); 166 unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX); 167 unsigned int local_id = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX); 168 169 // checking user timer 170 if ( local_id < NB_PROCS_MAX ) 171 { 172 return 2; 173 } 174 else 175 { 176 return _timer_access ( 0, // write access 177 cluster_id, 178 local_id, 179 register_id, 180 &buffer ); 181 } 154 unsigned int _timer_stop( unsigned int cluster_id, 155 unsigned int local_id ) 156 { 157 // parameters checking 158 if ( cluster_id >= NB_CLUSTERS) return 1; 159 if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1; 160 161 #if GIET_USE_XICU 162 unsigned int* timer_address = (unsigned int*)&seg_icu_base + 163 (cluster_id * CLUSTER_SPAN); 164 165 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0; 166 #else 167 unsigned int* timer_address = (unsigned int*)&seg_tim_base + 168 (cluster_id * CLUSTER_SPAN); 169 170 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0; 171 #endif 172 173 return 0; 182 174 } 183 175 ////////////////////////////////////////////////////////////////////////////// 184 // _timer_read() 185 // This function implements a read access to a "user" timer register. 186 // It gets the cluster_id and local_id from the global index stored in 187 // the task context and use the timer_access() function to make the read. 176 // _timer_reset_irq() 177 // This function acknowlegge a timer interrupt in the vci_timer (or vci_xicu) 178 // component by writing in the proper register the period value. 179 // It can be used by both the isr_switch() for a "system" timer, 180 // or by the _isr_timer() for an "user" timer. 188 181 // Returns 0 if success, > 0 if error. 189 182 ////////////////////////////////////////////////////////////////////////////// 190 unsigned int _timer_read( unsigned int register_id, 191 unsigned int* buffer ) 192 { 193 unsigned int task_id = _get_current_task_id(); 194 unsigned int timer_id = _get_context_slot(task_id, CTX_TIMER_ID); 195 unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX); 196 unsigned int local_id = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX); 197 198 // checking user timer 199 if ( local_id < NB_PROCS_MAX ) 200 { 201 return 2; 202 } 203 else 204 { 205 return _timer_access ( 1, // read access 206 cluster_id, 207 local_id, 208 register_id, 209 buffer ); 210 } 211 } 212 ///////////////////////////////////////////////////////////////////////////////// 213 // _timer_check() 214 ///////////////////////////////////////////////////////////////////////////////// 183 unsigned int _timer_reset_irq( unsigned int cluster_id, 184 unsigned int local_id ) 185 { 186 // parameters checking 187 if ( cluster_id >= NB_CLUSTERS) return 1; 188 if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1; 189 190 #if GIET_USE_XICU 191 unsigned int* timer_address = (unsigned int*)&seg_icu_base + 192 (cluster_id * CLUSTER_SPAN); 193 194 unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)]; 195 #else 196 unsigned int* timer_address = (unsigned int*)&seg_tim_base + 197 (cluster_id * CLUSTER_SPAN); 198 199 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0; 200 #endif 201 202 return 0; 203 } 215 204 216 205 ///////////////////////////////////////////////////////////////////////////////// … … 349 338 // VciMultiIcu and VciXicu drivers 350 339 //////////////////////////////////////////////////////////////////////////////// 351 // There is in principle one vci_multi_icu (or vci_xicu) component per cluster, 352 // and the number of independant ICUs is equal to NB_PROCS_MAX, because there is 353 // one private interrupr controler per processor. 354 //////////////////////////////////////////////////////////////////////////////// 355 356 //////////////////////////////////////////////////////////////////////////////// 357 // _icu_write() 358 // Write a 32-bit word in a memory mapped register of the MULTI_ICU device, 359 // identified by the cluster index, and a processor local index. 360 // Returns 0 if success, > 0 if error. 361 //////////////////////////////////////////////////////////////////////////////// 362 unsigned int _icu_write( unsigned int cluster_index, 363 unsigned int proc_index, 364 unsigned int register_index, 365 unsigned int value ) 366 { 340 // There is one vci_multi_icu (or vci_xicu) component per cluster, 341 // and the number of independant ICUs is equal to NB_PROCS_MAX, 342 // because there is one private interrupr controler per processor. 343 //////////////////////////////////////////////////////////////////////////////// 344 345 //////////////////////////////////////////////////////////////////////////////// 346 // _icu_set_mask() 347 // This function can be used with both the vci_xicu & vci_multi_icu components. 348 // It set the mask register for the ICU channel identified by the cluster index 349 // and the processor index: all '1' bits are set / all '0' bits are not modified. 350 // Returns 0 if success, > 0 if error. 351 //////////////////////////////////////////////////////////////////////////////// 352 unsigned int _icu_set_mask( unsigned int cluster_id, 353 unsigned int proc_id, 354 unsigned int value, 355 unsigned int is_timer ) 356 { 357 // parameters checking 358 if ( cluster_id >= NB_CLUSTERS) return 1; 359 if ( proc_id >= NB_PROCS_MAX ) return 1; 360 361 unsigned int* icu_address = (unsigned int*)&seg_icu_base + 362 (cluster_id * CLUSTER_SPAN); 367 363 #if GIET_USE_XICU 368 364 if ( is_timer ) icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value; 365 else icu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value; 369 366 #else 370 367 icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 368 #endif 369 370 return 0; 371 } 372 //////////////////////////////////////////////////////////////////////////////// 373 // _icu_get_index() 374 // This function can be used with both the vci_xicu & vci_multi_icu components. 375 // It returns the index of the highest priority (smaller index) active HWI. 376 // The ICU channel is identified by the cluster index and the processor index. 377 // Returns 0 if success, > 0 if error. 378 //////////////////////////////////////////////////////////////////////////////// 379 unsigned int _icu_get_index( unsigned int cluster_id, 380 unsigned int proc_id, 381 unsigned int* buffer ) 382 { 371 383 // parameters checking 372 if ( register_index >= ICU_SPAN) return 1; 373 if ( cluster_index >= NB_CLUSTERS) return 1; 374 if ( proc_index >= NB_PROCS_MAX ) return 1; 375 376 unsigned int *icu_address = (unsigned int*)&seg_icu_base + 377 (cluster_index * CLUSTER_SPAN) + 378 (proc_index * ICU_SPAN); 379 380 icu_address[register_index] = value; // write word 384 if ( cluster_id >= NB_CLUSTERS) return 1; 385 if ( proc_id >= NB_PROCS_MAX ) return 1; 386 387 unsigned int* icu_address = (unsigned int*)&seg_icu_base + 388 (cluster_id * CLUSTER_SPAN); 389 #if GIET_USE_XICU 390 unsigned int prio = icu_address[XICU_REG(XICU_PRIO, proc_id)]; 391 unsigned int pti_ok = (prio & 0x00000001); 392 unsigned int hwi_ok = (prio & 0x00000002); 393 unsigned int swi_ok = (prio & 0x00000004); 394 unsigned int pti_id = (prio & 0x00001F00) >> 8; 395 unsigned int hwi_id = (prio & 0x001F0000) >> 16; 396 unsigned int swi_id = (prio & 0x1F000000) >> 24; 397 if (pti_ok) *buffer = pti_id; 398 else if (hwi_ok) *buffer = hwi_id; 399 else if (swi_ok) *buffer = swi_id; 400 else *buffer = 32; 401 #else 402 *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 403 #endif 404 381 405 return 0; 382 383 #endif384 }385 ////////////////////////////////////////////////////////////////////////////////386 // _icu_read()387 // Read a 32-bit word in a memory mapped register of the MULTI_ICU device,388 // identified by the cluster index and a processor local index.389 // Returns 0 if success, > 0 if error.390 ////////////////////////////////////////////////////////////////////////////////391 unsigned int _icu_read( unsigned int cluster_index,392 unsigned int proc_index,393 unsigned int register_index,394 unsigned int* buffer )395 {396 #if GIET_USE_XICU397 398 #else399 400 // parameters checking401 if ( register_index >= ICU_SPAN) return 1;402 if ( cluster_index >= NB_CLUSTERS) return 1;403 if ( proc_index >= NB_PROCS_MAX ) return 1;404 405 unsigned int *icu_address = (unsigned int*)&seg_icu_base +406 (cluster_index * CLUSTER_SPAN) +407 (proc_index * ICU_SPAN);408 409 *buffer = icu_address[register_index]; // read word410 return 0;411 412 #endif413 406 } 414 407 … … 763 756 else 764 757 { 765 unsigned char *fb_address = (unsigned char*)&seg_fb _base + offset;758 unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset; 766 759 memcpy((void*)fb_address, (void*)buffer, length); 767 760 return 0; … … 789 782 else 790 783 { 791 unsigned char *fb_address = (unsigned char*)&seg_fb _base + offset;784 unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset; 792 785 memcpy((void*)buffer, (void*)fb_address, length); 793 786 return 0; … … 833 826 if ( (user_vaddr & 0x3) || (length & 0x3) ) 834 827 { 828 _get_lock(&_tty_put_lock); 835 829 _puts("[GIET ERROR] in _fbdma_access() : user buffer not word aligned\n"); 830 _release_lock(&_tty_put_lock); 836 831 return 1; 837 832 } … … 841 836 842 837 // compute frame buffer pbase address 843 unsigned int fb_vaddr = (unsigned int)&seg_fb _base + offset;838 unsigned int fb_vaddr = (unsigned int)&seg_fbf_base + offset; 844 839 845 840 ko = _v2p_translate( (page_table_t*)user_ptab, … … 851 846 if ( ko ) 852 847 { 848 _get_lock(&_tty_put_lock); 853 849 _puts("[GIET ERROR] in _fbdma_access() : frame buffer unmapped\n"); 850 _release_lock(&_tty_put_lock); 854 851 return 2; 855 852 } … … 864 861 if ( ko ) 865 862 { 863 _get_lock(&_tty_put_lock); 866 864 _puts("[GIET ERROR] in _fbdma_access() : user buffer unmapped\n"); 865 _release_lock(&_tty_put_lock); 867 866 return 3; 868 867 } 869 868 if ( (flags & PTE_U) == 0 ) 870 869 { 870 _get_lock(&_tty_put_lock); 871 871 _puts("[GIET ERROR] in _fbdma_access() : user buffer not in user space\n"); 872 _release_lock(&_tty_put_lock); 872 873 return 4; 873 874 } 874 875 if ( ( (flags & PTE_W) == 0 ) && to_user ) 875 876 { 877 _get_lock(&_tty_put_lock); 876 878 _puts("[GIET ERROR] in _fbdma_access() : user buffer not writable\n"); 879 _release_lock(&_tty_put_lock); 877 880 return 5; 878 881 } -
soft/giet_vm/sys/drivers.h
r189 r203 15 15 extern volatile unsigned char _timer_event[]; 16 16 17 unsigned int _timer_access( unsigned int read, // reas if non 0 18 unsigned int cluster_id, 19 unsigned int local_id, 20 unsigned int register_id, 21 unsigned int* buffer); 17 unsigned int _timer_start( unsigned int cluster_id, 18 unsigned int local_id, 19 unsigned int period ); 22 20 23 unsigned int _timer_ read( unsigned int register_id,24 unsigned int* buffer);21 unsigned int _timer_stop( unsigned int cluster_id, 22 unsigned int local_id ); 25 23 26 unsigned int _timer_write( unsigned int register_id, 27 unsigned int value); 24 25 unsigned int _timer_reset_irq( unsigned int cluster_id, 26 unsigned int local_id ); 28 27 29 28 /////////////////////////////////////////////////////////////////////////////////// … … 48 47 /////////////////////////////////////////////////////////////////////////////////// 49 48 50 unsigned int _icu_ read(unsigned int cluster_id,49 unsigned int _icu_get_index(unsigned int cluster_id, 51 50 unsigned int proc_id, 52 unsigned int register_id, 53 unsigned int* buffer); 51 unsigned int* buffer ); 54 52 55 unsigned int _icu_ write(unsigned int cluster_id,53 unsigned int _icu_set_mask( unsigned int cluster_id, 56 54 unsigned int proc_id, 57 unsigned int register_id,58 unsigned int value);55 unsigned int mask, 56 unsigned int is_timer ); 59 57 60 58 /////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/sys/hwr_mapping.h
r200 r203 65 65 ICU_SPAN = 8, 66 66 }; 67 enum Xicu_registers { 68 XICU_WTI_REG = 0, 69 XICU_PTI_PER = 1, 70 XICU_PTI_VAL = 2, 71 XICU_PTI_ACK = 3, 67 72 73 XICU_MSK_PTI = 4, 74 XICU_MSK_PTI_ENABLE = 5, 75 XICU_MSK_PTI_DISABLE = 6, 76 XICU_PTI_ACTIVE = 6, 77 78 XICU_MSK_HWI = 8, 79 XICU_MSK_HWI_ENABLE = 9, 80 XICU_MSK_HWI_DISABLE = 10, 81 XICU_HWI_ACTIVE = 10, 82 83 XICU_MSK_WTI = 12, 84 XICU_MSK_WTI_ENABLE = 13, 85 XICU_MSK_WTI_DISABLE = 14, 86 XICU_WTI_ACTIVE = 14, 87 88 XICU_PRIO = 15, 89 }; 90 91 #define XICU_REG(func, index) (((func)<<5)|(index)) 92 68 93 /* TIMER */ 69 94 enum TIMER_registers { -
soft/giet_vm/sys/irq_handler.c
r189 r203 42 42 43 43 // get the highest priority active IRQ index 44 45 #if GIET_USE_XICU 46 47 #else 48 49 if ( _icu_read( pid / NB_PROCS_MAX, 50 pid % NB_PROCS_MAX, 51 ICU_IT_VECTOR, 52 &irq_id ) ) 44 if ( _icu_get_index( pid / NB_PROCS_MAX, 45 pid % NB_PROCS_MAX, 46 &irq_id ) ) 53 47 { 54 _puts("\n[GIET ERROR] wrong _icu_read in _irq_demux() function\n"); 55 _exit(); 48 _get_lock(&_tty_put_lock); 49 _puts("\n[GIET ERROR] Strange... Wrong _icu_read in _irq_demux()\n"); 50 _release_lock(&_tty_put_lock); 56 51 } 57 58 #endif59 52 60 53 if ( irq_id < 32 ) // do nothing if no interrupt active … … 74 67 // _isr_default() 75 68 // The default ISR is called when no specific ISR has been installed in the 76 // interrupt vector. It simply displays a message on kernel TTY[0].69 // interrupt vector. It simply displays an error message on kernel TTY[0]. 77 70 /////////////////////////////////////////////////////////////////////////////////// 78 71 void _isr_default() 79 72 { 80 _puts("\n\n!!! Strange... Default ISR activated !!!\n"); 73 _get_lock(&_tty_put_lock); 74 _puts("\n[GIET ERROR] Strange... Default ISR activated for processor "); 75 _putd( _procid() ); 76 _puts("\n"); 77 _release_lock(&_tty_put_lock); 81 78 } 82 79 … … 122 119 unsigned int* ioc_address = (unsigned int*)&seg_ioc_base; 123 120 124 _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; / * save status & reset IRQ */125 _ioc_done = 1; / * signals completion */121 _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; // save status & reset IRQ 122 _ioc_done = 1; // signals completion 126 123 } 127 124 128 125 /////////////////////////////////////////////////////////////////////////////////// 129 126 // _isr_timer() 130 // This ISR handles the IRQs generated by the "user" timers (the IRQs 131 // generatedby the "system" timers should be handled by the _isr_switch().127 // This ISR handles the IRQs generated by the "user" timers (the IRQs generated 128 // by the "system" timers should be handled by the _isr_switch(). 132 129 // These timers are distributed in all clusters, and can be implemented 133 130 // in a vci_multi_timer component, or in a vci_xicu component. 134 // The channel_id argument is the global channel index:135 // channel_id = cluster_id*(NB_TIMERS_MAX+NB_PROCS_MAX) + loc_id131 // The timer_id argument is a global index: 132 // timer_id = cluster_id*(NB_TIMERS_MAX+NB_PROCS_MAX) + local_id 136 133 // The user timer local index is (loc_id - NB_PROCS_MAX). 137 134 // 138 135 // The ISR acknowledges the IRQ and registers the event in the proper entry 139 // of the _timer_event[] array .140 // A log message is displayed on the kernel terminal.141 /////////////////////////////////////////////////////////////////////////////////// 142 void _isr_timer(unsigned int channel_id) 143 { 144 145 unsigned int cluster_id = channel_id / (NB_TIMERS_MAX + NB_PROCS_MAX);146 unsigned int loc_id = channel_id % (NB_TIMERS_MAX + NB_PROCS_MAX); 147 148 if (loc _id < NB_PROCS_MAX )136 // of the _timer_event[] array, and a log message is displayed on kernel terminal. 137 /////////////////////////////////////////////////////////////////////////////////// 138 void _isr_timer(unsigned int timer_id) 139 { 140 141 unsigned int cluster_id = timer_id / (NB_TIMERS_MAX + NB_PROCS_MAX); 142 unsigned int local_id = timer_id % (NB_TIMERS_MAX + NB_PROCS_MAX); 143 144 // checking timer type 145 if (local_id < NB_PROCS_MAX ) 149 146 { 150 _puts("[GIET ERROR] Receiving a user timer IRQ for a system timer\n"); 151 _puts(" cluster = "); 152 _putw(cluster_id); 153 _puts(" / local_id = "); 154 _putw(loc_id); 147 _get_lock(&_tty_put_lock); 148 _puts("[GIET ERROR] Strange... User timer ISR for a system timer\n"); 149 _release_lock(&_tty_put_lock); 155 150 } 156 151 157 #if GIET_USE_XICU 158 159 // TODO 160 161 #else 162 163 // compute Timer address 164 unsigned int* timer_address = (unsigned int*)&seg_timer_base + 165 (loc_id * TIMER_SPAN) + 166 (cluster_id * CLUSTER_SPAN); 167 168 // reset IRQ 169 timer_address[TIMER_RESETIRQ] = 0; 170 171 #endif 152 // aknowledge IRQ 153 _timer_reset_irq( cluster_id, local_id ); 172 154 173 155 #if NB_TIMERS_MAX … … 177 159 178 160 // display a message on TTY 0 179 _puts("[GIET] User Timer IRQ / cluster = "); 180 _putw(cluster_id); 181 _puts(" / timer = "); 182 _putw(loc_id - NB_PROCS_MAX); 161 _get_lock(&_tty_put_lock); 162 _puts("[GIET] User Timer IRQ at cycle "); 163 _putd( _proctime() ); 164 _puts(" / index = "); 165 _putd(timer_id); 183 166 _puts("\n"); 167 _release_lock(&_tty_put_lock); 184 168 } 185 169 … … 219 203 // get cluster index and proc local index 220 204 unsigned int pid = _procid(); 221 unsigned int loc _id= pid % NB_PROCS_MAX;205 unsigned int local_id = pid % NB_PROCS_MAX; 222 206 unsigned int cluster_id = pid / NB_PROCS_MAX; 223 207 224 #if GIET_USE_XICU 225 226 unsigned int* timer_address = // TODO 227 228 #else 229 230 // compute Timer address 231 unsigned int* timer_address = (unsigned int*)&seg_timer_base + 232 (loc_id * TIMER_SPAN) + 233 (cluster_id * CLUSTER_SPAN); 234 235 // reset IRQ 236 timer_address[TIMER_RESETIRQ] = 0; 237 238 #endif 208 // acknowledge IRQ 209 _timer_reset_irq( cluster_id, local_id ); 239 210 240 211 // performs the context switch 241 212 _ctx_switch(); 242 243 } 244 213 } 214 -
soft/giet_vm/sys/kernel_init.c
r199 r203 76 76 77 77 // step 2 : initialise page table addresse arrays 78 // it scans all tasks contexts in the scheduler79 // and get VSID, PTAB and PTPR values78 // each processor scans all tasks contexts in its 79 // private scheduler and get VSID, PTAB and PTPR values 80 80 81 81 unsigned int ltid; … … 87 87 unsigned int ptab_vaddr = _get_context_slot( ltid , CTX_PTAB_ID ); 88 88 unsigned int ptab_paddr = _get_context_slot( ltid , CTX_PTPR_ID ) << 13; 89 89 90 _ptabs_vaddr[vspace_id] = ptab_vaddr; 90 91 _ptabs_paddr[vspace_id] = ptab_paddr; … … 106 107 } 107 108 108 // step 3 : compute and set ICU mask 109 // step 3 : compute and set ICU masks 110 // there is at most 32 interrupts per processor 111 // software interrupts are not supported yet 112 109 113 unsigned int irq_id; 110 unsigned int mask = 0; 114 unsigned int hwi_mask = 0; 115 unsigned int pti_mask = 0; 116 111 117 for ( irq_id = 0 ; irq_id < 32 ; irq_id++ ) 112 118 { 113 unsigned int entry = _get_interrupt_vector_entry(irq_id); 114 if ( entry ) mask = mask | 0x1<< irq_id; 115 } 116 _icu_write( cluster_id, 117 lpid, 118 ICU_MASK_SET, 119 mask ); 119 unsigned int entry = _get_interrupt_vector_entry(irq_id); 120 unsigned int isr = entry & 0x000000FF; 121 122 if ( (isr == ISR_DMA) || (isr == ISR_IOC) || (isr == ISR_TTY) ) 123 { 124 hwi_mask = hwi_mask | 0x1<< irq_id; 125 } 126 else if ( (isr == ISR_SWITCH) || (isr == ISR_TIMER) ) 127 { 128 pti_mask = pti_mask | 0x1<< irq_id; 129 } 130 } 131 _icu_set_mask( cluster_id, lpid, hwi_mask, 0 ); // set HWI_MASK 132 _icu_set_mask( cluster_id, lpid, pti_mask, 1 ); // set PTI_MASK 120 133 121 134 #if GIET_DEBUG_INIT … … 123 136 _puts("\n[GIET DEBUG] step 3 for processor "); 124 137 _putd( proc_id ); 125 _puts(" / ICU mask = "); 126 _putw( mask ); 138 _puts("\n - ICU HWI_MASK = "); 139 _putw( hwi_mask ); 140 _puts("\n - ICU PTI_MASK = "); 141 _putw( pti_mask ); 127 142 _puts("\n"); 128 143 _release_lock(&_tty_put_lock); … … 133 148 if ( tasks > 1 ) 134 149 { 135 unsigned int period = GIET_TICK_VALUE; 136 unsigned int mode = 0x3; 137 _timer_access( 0, // write access 138 cluster_id, 139 proc_id, 140 TIMER_PERIOD, 141 &period ); 142 _timer_access( 0, // write access 143 cluster_id, 144 proc_id, 145 TIMER_MODE, 146 &mode ); 150 _timer_start( cluster_id, 151 proc_id, 152 GIET_TICK_VALUE ); 147 153 148 154 #if GIET_DEBUG_INIT … … 150 156 _puts("\n[GIET DEBUG] Step 4 for processor "); 151 157 _putd( proc_id ); 152 _puts(" / TICKactivated\n");158 _puts(" / context switch activated\n"); 153 159 _release_lock(&_tty_put_lock); 154 160 #endif -
soft/giet_vm/sys/sys.ld
r167 r203 1 /****************************************************************************2 * Definition of the base address for all virtual segments3 *****************************************************************************/4 1 5 /* The vsegs used by the system are mapped in all virtual spaces 6 They can be identity mapping... or not */ 2 /******************************************************************************/ 3 /* Definition of the base addresses for all vsegs used by the GIET_VM */ 4 /******************************************************************************/ 7 5 8 seg_kernel_code_base = 0x80000000; /* system code */ 9 seg_kernel_data_base = 0x80010000; /* system cacheable data */ 10 seg_kernel_uncdata_base = 0x80080000; /* system uncacheable data */ 11 seg_kernel_init_base = 0x80090000; /* system page table */ 12 seg_mapping_base = 0xBFC0C000; /* boot mapping_info */ 6 INCLUDE giet_vsegs.ld 13 7 14 15 /* The peripherals base addresses are referenced by the software drivers and \ 16 must be defined, even if the peripherals are not used in the architecture */ 17 18 seg_tty_base = 0x90000000; /* TTY device */ 19 seg_timer_base = 0x91000000; /* Timer device */ 20 seg_ioc_base = 0x92000000; /* Block device */ 21 seg_dma_base = 0x93000000; /* DMA device */ 22 seg_gcd_base = 0x95000000; /* GCD device */ 23 seg_fb_base = 0x96000000; /* FrameBuffer device */ 24 seg_iob_base = 0x9E000000; /* IOB device */ 25 seg_icu_base = 0x9F000000; /* ICU or XICU device */ 26 27 /* 28 * Grouping sections into segments for system code and data 29 */ 8 /******************************************************************************/ 9 /* Grouping sections into virtual segments for system code and data */ 10 /******************************************************************************/ 30 11 31 12 SECTIONS … … 37 18 *(.text) 38 19 } 20 39 21 . = seg_kernel_data_base; 40 22 seg_kernel_data : … … 53 35 *(.scommon) 54 36 } 37 55 38 . = seg_kernel_uncdata_base; 56 39 seg_kernel_uncdata : -
soft/giet_vm/sys/sys_handler.c
r199 r203 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The sys_handler.c and sys_handler.h files are part of the GIET nano-kernel.7 // The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel. 8 8 // It define the syscall_vector[] (at the end of this file), as well as the 9 9 // associated syscall handlers that are not related to peripherals. … … 26 26 &_tty_write, /* 0x02 */ 27 27 &_tty_read, /* 0x03 */ 28 &_timer_ write, /* 0x04 */29 &_timer_ read, /* 0x05 */28 &_timer_start, /* 0x04 */ 29 &_timer_stop, /* 0x05 */ 30 30 &_gcd_write, /* 0x06 */ 31 31 &_gcd_read, /* 0x07 */ -
soft/giet_vm/xml/xml_parser.c
r202 r203 1078 1078 } 1079 1079 1080 ////////// get ident attribute (optional : 0 if missing) 1081 value = getIntValue(reader,"ident", &ok); 1082 if ( ok ) 1083 { 1084 #if XML_PARSER_DEBUG 1085 printf(" ident = %d\n", value); 1086 #endif 1087 vseg[vseg_index]->ident = value; 1088 } 1089 else 1090 { 1091 vseg[vseg_index]->ident = 0; 1092 } 1093 1080 1094 /////////// get vbase attribute 1081 1095 value = getIntValue(reader,"vbase", &ok); … … 1127 1141 exit(1); 1128 1142 } 1129 1130 ////////// get ident attribute (optional : 0 if missing)1131 value = getIntValue(reader,"ident", &ok);1132 if ( ok )1133 {1134 #if XML_PARSER_DEBUG1135 printf(" ident = %d\n", value);1136 #endif1137 vseg[vseg_index]->ident = value;1138 }1139 else1140 {1141 vseg[vseg_index]->ident = 0;1142 }1143 1143 1144 1144 //////// get mode attribute … … 1257 1257 else 1258 1258 { 1259 printf("[XML ERROR] illegal or missing <startname> attribute for vspace % d\n",1260 vspace _index);1259 printf("[XML ERROR] illegal or missing <startname> attribute for vspace %s\n", 1260 vspace[vspace_index]->name); 1261 1261 exit(1); 1262 1262 } … … 1281 1281 if(index == -1) 1282 1282 { 1283 printf("[XML ERROR] vobj containing the start vector not found %s\n",str); 1283 printf("[XML ERROR] vobj containing start vector not found in vspace %s\n", 1284 vspace[vspace_index]->name); 1284 1285 exit(-1); 1285 1286 }
Note: See TracChangeset
for help on using the changeset viewer.