- Timestamp:
- Mar 12, 2019, 1:37:38 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 49 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/boot/tsar_mips32/Makefile
r572 r624 13 13 # always out-of-date, need to be regenerated everytime they are called 14 14 .PHONY: compile \ 15 ../../hard_config.h 15 ../../hard_config.h \ 16 16 dirs \ 17 build/boot.elf \ 18 19 # Macros to be processed by the C preprocessor. 20 MACROS = -DARCHINFO_PATHNAME="\"arch_info.bin\"" \ 21 -DKERNEL_PATHNAME="\"/bin/kernel/kernel.elf\"" 17 build/boot.elf 22 18 23 19 # Objects to be linked for boot.elf generation -
trunk/boot/tsar_mips32/boot.c
r623 r624 25 25 /**************************************************************************** 26 26 * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture. * 27 * * 28 * It supports a clusterised, shared memory, multi-processor architecture, * 27 * that is a clusterised, shared memory, multi-processor architecture, * 29 28 * where each processor core is identified by a composite index [cxy,lid] * 30 29 * with one physical memory bank per cluster. * … … 86 85 // the Boot Page Table contains two PTE1, and should be aligned on 8 Kbytes 87 86 88 uint32_t boot_pt[2] __attribute__((aligned( 2048)));87 uint32_t boot_pt[2] __attribute__((aligned(0x2000))); 89 88 90 89 // synchronization variables. … … 101 100 uint32_t seg_kdata_base; // kdata segment base address 102 101 uint32_t seg_kdata_size; // kdata segment size (bytes) 103 uint32_t seg_kentry_base; // kcode segment base address 104 uint32_t seg_kentry_size; // kcode segment size (bytes) 105 106 uint32_t kernel_entry; // kernel entry point 102 103 uint32_t kernel_entry; // kernel_init() function 107 104 108 105 // Functions … … 147 144 static void boot_archinfo_load( void ) 148 145 { 149 archinfo_header_t * header = (archinfo_header_t*)ARCHINFO_BASE;146 archinfo_header_t * header = (archinfo_header_t*)ARCHINFO_BASE; 150 147 151 148 // Load file into memory 152 149 if (boot_fat32_load(ARCHINFO_PATHNAME, ARCHINFO_BASE, ARCHINFO_MAX_SIZE)) 153 150 { 154 boot_printf("\n[BOOT ERROR]: boot_archinfo_load(): " 155 "<%s> file not found\n", 156 ARCHINFO_PATHNAME); 151 boot_printf("\n[BOOT ERROR]in %s : <%s> file not found\n", 152 __FUNCTION__, ARCHINFO_PATHNAME); 157 153 boot_exit(); 158 154 } … … 175 171 /************************************************************************************** 176 172 * This function loads the 'kernel.elf' file into the boot cluster memory buffer, 177 * analyzes it, and places the three kcode, kentry, kdata segments at their final 178 * physical adresses (defined the .elf file). 179 * It set the global variables defining the kernel layout. 173 * analyzes it, and places the kcode and kdata segments at their final physical 174 * adresses (defined the .elf file), and set the kernel layout global variables. 180 175 *************************************************************************************/ 181 176 static void boot_kernel_load( void ) … … 192 187 bool_t kcode_found; // kcode segment found. 193 188 bool_t kdata_found; // kdata segment found. 194 bool_t kentry_found; // kentry segment found.195 189 uint32_t seg_id; // iterator for segments loop. 196 190 … … 233 227 kcode_found = false; 234 228 kdata_found = false; 235 kentry_found = false;236 229 for (seg_id = 0; seg_id < segments_nb; seg_id++) 237 230 { … … 265 258 266 259 // Note: we suppose that the 'kernel.elf' file contains exactly 267 // three loadable segments ktext, kentry, & kdata: 268 // - the kcode segment is read-only and base == KCODE_BASE 269 // - the kentry segment is read-only and base == KENTRY_BASE 270 271 if( ((program_header[seg_id].p_flags & PF_W) == 0) && 272 (program_header[seg_id].p_paddr == KCODE_BASE) ) // kcode segment 260 // two loadable segments : kcode & kdata 261 262 if( program_header[seg_id].p_paddr == KCODE_BASE ) // kcode segment 273 263 { 274 264 if( kcode_found ) … … 283 273 seg_kcode_base = seg_paddr; 284 274 seg_kcode_size = seg_memsz; 285 }286 else if( program_header[seg_id].p_paddr == KENTRY_BASE ) // kentry segment287 {288 if( kentry_found )289 {290 boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"291 " two kentry segments found\n",292 __FUNCTION__ , KERNEL_PATHNAME );293 boot_exit();294 }295 296 kentry_found = true;297 seg_kentry_base = seg_paddr;298 seg_kentry_size = seg_memsz;299 275 } 300 276 else // kdata segment … … 322 298 boot_exit(); 323 299 } 324 if( kentry_found == false )325 {326 boot_printf("\n[BOOT_ERROR] in %s for file %s : seg_kentry not found\n",327 __FUNCTION__ , KERNEL_PATHNAME );328 boot_exit();329 }330 300 if( kdata_found == false ) 331 301 { … … 336 306 337 307 // check segments sizes 338 if( seg_kentry_size > KENTRY_MAX_SIZE )339 {340 boot_printf("\n[BOOT_ERROR] in %s for file %s : seg_kentry too large\n",341 __FUNCTION__ , KERNEL_PATHNAME );342 boot_exit();343 }344 345 308 if( (seg_kcode_size + seg_kdata_size) > KCODE_MAX_SIZE ) 346 309 { … … 386 349 boot_device_t * boot_dev; 387 350 388 // get pointer on ARCHINFO header and on the four arch_info arrays 351 #if DEBUG_BOOT_INFO 352 boot_printf("\n[BOOT INFO] %s : enter at cycle %d\n", 353 __FUNCTION__ , boot_get_proctime() ); 354 #endif 355 356 // get pointer on ARCHINFO header and on the four arch_info arrays 389 357 header = (archinfo_header_t*)ARCHINFO_BASE; 390 358 core_base = archinfo_get_core_base (header); … … 406 374 boot_info->kdata_base = seg_kdata_base; 407 375 boot_info->kdata_size = seg_kdata_size; 408 boot_info->kentry_base = seg_kentry_base;409 boot_info->kentry_size = seg_kentry_size;410 376 411 377 // loop on arch_info clusters to build cluster_info[][] array … … 806 772 if (cxy == 0) 807 773 { 808 boot_printf("\n[BOOT] core[%x,%d] entersat cycle %d\n",809 cxy , lid, boot_get_proctime() );774 boot_printf("\n[BOOT] core[%x,%d] active at cycle %d\n", 775 cxy, lid, boot_get_proctime() ); 810 776 811 777 // Initialize IOC driver … … 858 824 boot_check_core(boot_info, lid); 859 825 860 // TO BE DONE 861 // core[0][0] identity maps two big pages for the boot and kernel code, 862 // boot_page_table_init( 0 ); 863 864 // TO BE DONE 865 // core[0][0] activates the instruction MMU to use the local copy of boot code 866 // boot_activate_ins_mmu( 0 ); 826 // identity maps two big pages for the boot and kernel code, 827 boot_page_table_init( 0 ); 828 829 // activate the instruction MMU to use the local copy of boot code 830 boot_activate_ins_mmu( 0 ); 867 831 868 832 // Activate other core[cxy][0] / get number of activated cores … … 889 853 // but all cores must access the code stored in cluster 0 890 854 891 // Each CP0 copies the boot code (data and instructions) 855 #if DEBUG_BOOT_MULTI 856 boot_printf("\n[BOOT] core[%x,%d] active at cycle %d\n", 857 cxy, lid, boot_get_proctime() ); 858 #endif 859 // Each core[cxy][0] copies the boot code (data and instructions) 892 860 // from the cluster 0 to the local cluster. 893 861 boot_remote_memcpy( XPTR( cxy , BOOT_BASE ), … … 899 867 cxy , lid , boot_get_proctime() ); 900 868 901 // TO BE DONE 902 // Each core identity maps two big pages for the boot and kernel code, 903 // boot_page_table_init( cxy ); 904 905 // Each core activates the instruction MMU to use the local copy of boot code 906 // boot_activate_ins_mmu( cxy ); 869 // identity maps two big pages for the boot and kernel code, 870 boot_page_table_init( cxy ); 871 872 // activate the instruction MMU to use the local copy of boot code 873 boot_activate_ins_mmu( cxy ); 907 874 908 875 // Each CP0 copies the arch_info.bin into the local memory. … … 914 881 cxy , lid , boot_get_proctime() ); 915 882 916 // Each CP0 copiesthe kcode segment into local memory883 // copy the kcode segment into local memory 917 884 boot_remote_memcpy( XPTR( cxy , seg_kcode_base ), 918 885 XPTR( BOOT_CORE_CXY , seg_kcode_base ), … … 924 891 seg_kdata_size ); 925 892 926 // [TO BE REMOVED<D-°>927 // Each CP0 copies the kentry segment into local memory928 boot_remote_memcpy( XPTR( cxy , seg_kentry_base ),929 XPTR( BOOT_CORE_CXY , seg_kentry_base ),930 seg_kentry_size );931 932 893 boot_printf("\n[BOOT] core[%x,%d] replicated kernel code at cycle %d\n", 933 894 cxy , lid , boot_get_proctime() ); … … 965 926 **********************************************************************/ 966 927 967 // TO BE DONE 968 // each core activate the instruction MMU to use the local copy of the boot code 969 // boot_activate_ins_mmu( cxy ); 928 #if DEBUG_BOOT_MULTI 929 boot_printf("\n[BOOT] core[%x,%d] active at cycle %d\n", 930 cxy, lid, boot_get_proctime() ); 931 #endif 932 // activate the instruction MMU to use the local copy of the boot code 933 boot_activate_ins_mmu( cxy ); 970 934 971 935 // Get local boot_info_t structure base address. … … 979 943 } 980 944 981 // the "kernel_entry" global variable, set by boot_kernel_load() define982 // the adress of the kernel_init() function.945 // All cores enter the kernel_init() function. The address is contained in 946 // the "kernel_entry" global variable, set by boot_kernel_load() function. 983 947 // Each core initialise the following registers before jumping to kernel: 984 948 // - gr_29 : stack pointer / kernel stack allocated in idle thread descriptor, 985 949 // - c0_sr : status register / reset BEV bit 986 950 // - gr_04 : kernel_init() argument / pointer on boot_info structure 987 // - c0_ebase : kentry_base988 989 // compute "sp" from base address of idle thread descriptors array and lid.990 951 // The array of idle-thread descriptors is allocated in the kdata segment, 991 952 // just after the boot_info structure. 953 954 #if DEBUG_BOOT_MULTI 955 boot_printf("\n[BOOT] core[%x,%d] jump to kernel_init = %x at cycle %d\n", 956 cxy, lid, __FUNCTION__, kernel_entry, boot_get_proctime() ); 957 #endif 958 992 959 uint32_t base; 993 960 uint32_t offset = sizeof( boot_info_t ); … … 998 965 uint32_t sp = base + ((lid + 1) * CONFIG_THREAD_DESC_SIZE) - 16; 999 966 1000 // get "ebase" from kerneL_info1001 uint32_t ebase = boot_info->kentry_base;1002 1003 // TO BE DONE1004 // The cp0_ebase will not be set by the assenbly code below1005 // when the kentry segment will be removed => done in kernel init1006 1007 967 asm volatile( "mfc0 $27, $12 \n" 1008 968 "lui $26, 0xFFBF \n" … … 1012 972 "move $4, %0 \n" 1013 973 "move $29, %1 \n" 1014 "mtc0 %2, $15, 1 \n" 1015 "jr %3 \n" 974 "jr %2 \n" 1016 975 : 1017 976 : "r"(boot_info) , 1018 977 "r"(sp) , 1019 "r"(ebase) ,1020 978 "r"(kernel_entry) 1021 979 : "$26" , "$27" , "$29" , "$4" ); -
trunk/boot/tsar_mips32/boot.ld
r610 r624 6 6 /* define the boot code base address */ 7 7 8 boot_code_base = 0x 100000;8 boot_code_base = 0x200000; 9 9 10 10 /* Set the entry point of the boot-loader */ … … 18 18 { 19 19 . = boot_code_base; 20 . text:20 .code : 21 21 { 22 22 *(.text) … … 27 27 { 28 28 *(.data*) 29 }30 .bss :31 {32 29 *(.bss) 30 *(.scommon) 33 31 } 34 32 } -
trunk/boot/tsar_mips32/boot_config.h
r572 r624 7 7 8 8 // Debug options 9 #define DEBUG_BOOT_MULTI 0 9 10 #define DEBUG_BOOT_INFO 0 10 11 #define DEBUG_BOOT_ELF 0 … … 13 14 #define DEBUG_BOOT_FAT32 0 14 15 15 // Core identifier format16 #define USE_FIXED_FORMAT 116 // Boot cluster definition 17 #define BOOT_CLUSTER_CXY 0 17 18 18 19 // cache line 19 20 #define CACHE_LINE_SIZE 64 20 21 21 // Preloader temporary segment 22 // paths for kernel.elf and arch_info.bin files 23 #define ARCHINFO_PATHNAME "arch_info.bin" 24 #define KERNEL_PATHNAME "bin/kernel/kernel.elf" 25 26 // Preloader segment 22 27 #define PRELOADER_BASE 0x00000000 // 'preloader' physical base address 23 28 #define PRELOADER_MAX_SIZE 0x00004000 // 'preloader' max size 24 29 25 // kentry segment26 #define KENTRY_BASE 0x00004000 // 'kentry' segment physical base address27 #define KENTRY_MAX_SIZE 0x00004000 // 'kentry' segment max size28 29 30 // kcode segment 30 #define KCODE_BASE 0x0000 8000 // 'kcode' segment physical base address31 #define KCODE_MAX_SIZE 0x000F 8000 // 'kcode' + 'kdata' segments max size31 #define KCODE_BASE 0x00004000 // 'kcode' segment physical base address 32 #define KCODE_MAX_SIZE 0x000FC000 // 'kcode' + 'kdata' segments max size 32 33 33 34 // boot.elf file temporary buffer 34 #define BOOT_BASE 0x00 100000 // 'boot.elf' file physical base address35 #define BOOT_MAX_SIZE 0x00010000 // 'boot.elf' file max size 35 #define BOOT_BASE 0x00200000 // 'boot.elf' file physical base address 36 #define BOOT_MAX_SIZE 0x00010000 // 'boot.elf' file max size (64 Kbytes) 36 37 37 38 // arch_info file temporary buffer 38 #define ARCHINFO_BASE 0x00 200000 // 'arch_info.bin' file physical base address39 #define ARCHINFO_MAX_SIZE 0x00010000 // 'arch_info.bin' file max size 39 #define ARCHINFO_BASE 0x00300000 // 'arch_info.bin' file physical base address 40 #define ARCHINFO_MAX_SIZE 0x00010000 // 'arch_info.bin' file max size (64 Kbytes) 40 41 41 42 // kernel.elf file temporary buffer 42 #define KERN_BASE 0x00 300000 // 'kernel.elf' file base address43 #define KERN_BASE 0x00400000 // 'kernel.elf' file base address 43 44 #define KERN_MAX_SIZE 0x00200000 // 'kernel.elf' file max size 44 45 45 46 // Temporary stacks segments 46 #define BOOT_STACK_BASE 0x00 504000 // Boot stack base address47 #define BOOT_STACK_BASE 0x00600000 // Boot stack base address 47 48 #define BOOT_STACK_SIZE 0x00004000 // Boot stack size (16Kb) 48 49 -
trunk/hal/generic/hal_gpt.h
r623 r624 56 56 #define GPT_CACHABLE 0x0020 /*! PTE can be cached */ 57 57 #define GPT_USER 0x0040 /*! PTE is user accessible */ 58 #define GPT_DIRTY 0x0080 /*! PTE has been "recently" written*/58 #define GPT_DIRTY 0x0080 /*! PTE has been written */ 59 59 #define GPT_ACCESSED 0x0100 /*! PTE has been "recently" accessed */ 60 60 #define GPT_GLOBAL 0x0200 /*! PTE is kept in TLB at context switch */ … … 142 142 143 143 /**************************************************************************************** 144 * This function unmaps a page table entry identified by the <vpn> argument in the145 * local GPTidentified by the <gpt> argument.146 * It does NOT release the physical memory allocated for the unmapped page .147 **************************************************************************************** 148 * @ gpt 149 * @ vpn : [in] virtual page number144 * This function unmaps all pages identified by the <vpn> argument from the local GPT 145 * identified by the <gpt> argument. 146 * It does NOT release the physical memory allocated for the unmapped pages. 147 **************************************************************************************** 148 * @ gpt : [in] pointer on the local page table 149 * @ vpn : [in] page index in virtual space 150 150 ***************************************************************************************/ 151 151 void hal_gpt_reset_pte( gpt_t * gpt, -
trunk/hal/generic/hal_special.h
r623 r624 46 46 47 47 /***************************************************************************************** 48 * This function initializes - for architectures requiring it - the MMU registers 49 * as required by the target architecture to execute the kernel threads attached 50 * to kernel process zero. It is called by all cores in the kernel_init() function. 48 * This function initializes - for architectures requiring it - the MMU registers of the 49 * calling core to use the the kernel page table identified by the <gpt> argument for 50 * all threads attached to kernel process_zero. 51 * It is called by all cores in the kernel_init() function. 51 52 ***************************************************************************************** 52 53 * @ gpt : local pointer on the kernel page table descriptor. -
trunk/hal/tsar_mips32/core/hal_gpt.c
r623 r624 174 174 } // end hal_gpt_create() 175 175 176 177 176 /////////////////////////////////// 178 177 void hal_gpt_destroy( gpt_t * gpt ) … … 334 333 335 334 336 /////////////////////////////////////////////////////////////////////////////////////337 // FOr the TSAR architecture, this function allocates a first level PT1 (8 Kbytes),338 // and maps one single big page for the kerne code segment in slot[0].339 /////////////////////////////////////////////////////////////////////////////////////340 void hal_gpt_build_kpt( cxy_t cxy,341 gpt_t * gpt )342 {343 error_t error;344 345 // allocate memory for one gpt346 error = hal_gpt_create( gpt );347 348 if( error )349 {350 printk("\n[PANIC] in %s : cannot allocate kernel GPT in cluster %x\n",351 __FUNCTION__ , cxy );352 hal_core_sleep();353 }354 355 // compute attr and ppn for one PTE1356 uint32_t attr = 0xCA800000; // bits : V,T,C,X,G357 uint32_t ppn = (cxy << 20) >> 9;358 359 // set PTE1360 error = hal_gpt_set_pte( XPTR( cxy , gpt ) , 0 , attr , ppn );361 362 if( error )363 {364 printk("\n[PANIC] in %s : cannot initialize kernel GPT in cluster %x\n",365 __FUNCTION__ , cxy );366 hal_core_sleep();367 }368 }369 370 335 ////////////////////////////////////////// 371 336 error_t hal_gpt_set_pte( xptr_t gpt_xp, … … 617 582 } // end hal_gpt_reset_pte() 618 583 584 585 /* unused until now (march 2019) [AG] 586 587 ////////////////////////////////////// 588 void hal_gpt_reset_range( gpt * gpt, 589 vpn_t vpn_min, 590 vpn_t vpn_max ) 591 { 592 vpn_t vpn; // current vpn 593 594 uint32_t * pt1; // PT1 base address 595 uint32_t pte1; // PT1 entry value 596 597 ppn_t pt2_ppn; // PPN of PT2 598 uint32_t * pt2; // PT2 base address 599 600 uint32_t ix1; // index in PT1 601 uint32_t ix2; // index in PT2 602 603 // get PT1 604 pt1 = gpt->ptr; 605 606 // initialize current index 607 vpn = vpn_min; 608 609 // loop on pages 610 while( vpn <= vpn_max ) 611 { 612 // get ix1 index from vpn 613 ix1 = TSAR_MMU_IX1_FROM_VPN( vpn ); 614 615 // get PTE1 616 pte1 = pt1[ix1] 617 618 if( (pte1 & TSAR_MMU_MAPPED) == 0 ) // PT1[ix1] unmapped 619 { 620 // update vpn (next big page) 621 (vpn = ix1 + 1) << 9; 622 } 623 if( (pte1 & TSAR_MMU_SMALL) == 0 ) // it's a PTE1 (big page) 624 { 625 // unmap the big page 626 pt1[ix1] = 0; 627 hal_fence(); 628 629 // update vpn (next big page) 630 (vpn = ix1 + 1) << 9; 631 } 632 else // it's a PTD1 (small page) 633 { 634 // compute PT2 base address 635 pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 ); 636 pt2 = GET_PTR( ppm_ppn2base( pt2_ppn ) ); 637 638 // get ix2 index from vpn 639 ix2 = TSAR_MMU_IX2_FROM_VPN( vpn ); 640 641 // unmap the small page 642 pt2[2*ix2] = 0; 643 hal_fence(); 644 645 // update vpn (next small page) 646 vpn++; 647 } 648 } 649 } // hal_gpt_reset_range() 650 */ 651 619 652 ////////////////////////////////////// 620 653 error_t hal_gpt_lock_pte( gpt_t * gpt, -
trunk/hal/tsar_mips32/core/hal_special.c
r623 r624 263 263 void hal_core_sleep( void ) 264 264 { 265 thread_t * this = CURRENT_THREAD; 266 267 printk("\n*** thread[%x,%x] on core[%x,%d]/n" 268 " sr = %X / sp = %X / ra = %X\n", 269 this->process->pid, this->trdid, local_cxy, this->core->lid, 270 hal_get_sr(), hal_get_sp(), hal_get_ra() ); 271 272 while( 1 ) asm volatile ("nop"); 265 while( 1 ) asm volatile ("wait"); 273 266 } 274 267 -
trunk/hal/tsar_mips32/core/hal_vmm.c
r623 r624 27 27 #include <hal_gpt.h> 28 28 #include <process.h> 29 #include <thread.h> 29 30 #include <vseg.h> 30 31 #include <xlist.h> … … 41 42 42 43 // extern global variables 43 extern process_t process_zero; 44 extern process_t process_zero; 45 extern chdev_directory_t chdev_dir; 44 46 45 47 ////////////////////////////////////////////////////////////////////////////////////////// 46 48 // This function is called by the process_zero_init() function during kernel_init. 47 49 // It initializes the VMM of the kernel proces_zero (containing all kernel threads) 48 // in the local cluster. 50 // in the local cluster: it registers one "kcode" vseg in kernel VSL, and registers 51 // one big page in slot[0] of kernel GPT. 49 52 ////////////////////////////////////////////////////////////////////////////////////////// 50 53 error_t hal_vmm_kernel_init( boot_info_t * info ) … … 68 71 } 69 72 73 #if DEBUG_HAL_VMM 74 thread_t * this = CURRENT_THREAD; 75 printk("\n[%s] thread[%x,%x] enter in cluster %x / gpt %x\n", 76 __FUNCTION__, this->process->pid, this->trdid, local_cxy, gpt ); 77 #endif 78 70 79 // compute attr and ppn for one PTE1 71 uint32_t attr = 0x8A800000; // bits : V,C,X,G72 uint32_t ppn = (cxy << 20) >> 9; // physical page index is 073 74 // set PTE1 in slot[0]80 uint32_t attr = GPT_MAPPED | GPT_READABLE | GPT_CACHABLE | GPT_EXECUTABLE | GPT_GLOBAL; 81 uint32_t ppn = cxy << 20; 82 83 // register PTE1 in slot[0] of kernel GPT 75 84 error = hal_gpt_set_pte( XPTR( cxy , gpt ) , 0 , attr , ppn ); 76 85 … … 81 90 hal_core_sleep(); 82 91 } 92 93 #if DEBUG_HAL_VMM 94 printk("\n[%s] thread[%x,%x] created PT1[0] : ppn %x / attr %x\n", 95 __FUNCTION__, this->process->pid, this->trdid, ppn, attr ); 96 #endif 83 97 84 98 // create kcode vseg and register it in kernel VSL 85 99 vseg_t * vseg = vmm_create_vseg( &process_zero, 86 VSEG_TYPE_ CODE,100 VSEG_TYPE_KCODE, 87 101 info->kcode_base, 88 102 info->kcode_size, … … 97 111 } 98 112 99 } // end hal_vmm_init() 113 #if DEBUG_HAL_VMM 114 printk("\n[%s] thread[%x,%x] registered kcode vseg[%x,%x]\n", 115 __FUNCTION__, this->process->pid, this->trdid, info->kcode_base, info->kcode_size ); 116 hal_vmm_display( &process_zero , true ); 117 #endif 118 119 return 0; 120 121 } // end hal_kernel_vmm_init() 100 122 101 123 ////////////////////////////////////////////////////////////////////////////////////////// … … 111 133 uint32_t ppn; 112 134 113 // TODO check ppn value in kernel GPT (must be 0) 135 #if DEBUG_HAL_VMM 136 thread_t * this = CURRENT_THREAD; 137 printk("\n[%s] thread[%x,%x] enter in cluster %x \n", 138 __FUNCTION__, this->process->pid, this->trdid, local_cxy ); 139 hal_vmm_display( process , true ); 140 hal_vmm_display( &process_zero , true ); 141 #endif 114 142 115 143 // get cluster identifier 116 144 cxy_t cxy = local_cxy; 117 145 146 // get extended pointer on kernel GPT 147 xptr_t k_gpt_xp = XPTR( cxy , &process_zero.vmm.gpt ); 148 149 // get ppn and attributes from slot[0] of kernel GPT 150 hal_gpt_get_pte( k_gpt_xp , 0 , &attr , &ppn ); 151 152 #if DEBUG_HAL_VMM 153 printk("\n[%s] thread[%x,%x] get PT1[0] ( ppn %x / attr %x ) from kernel GPT\n", 154 __FUNCTION__, this->process->pid, this->trdid, ppn, attr ); 155 #endif 156 118 157 // get extended pointer on user GPT 119 xptr_t gpt_xp = XPTR( cxy , &process->vmm.gpt ); 120 121 // get ppn and attributes from slot[0] in kernel GPT 122 hal_gpt_get_pte( gpt_xp , 0 , &attr , &ppn ); 123 124 // check ppn and attributes 125 assert( (attr == 0x8A800000) && (ppn == ((cxy << 20) >> 9)), __FUNCTION__, 126 "bad ppn = %x or attr = %x in slot[0] of kernel GPT\n", ppn , attr ); 127 158 xptr_t u_gpt_xp = XPTR( cxy , &process->vmm.gpt ); 159 128 160 // update user GPT : set PTE1 in slot[0] 129 error = hal_gpt_set_pte( gpt_xp , 0 , attr , ppn );161 error = hal_gpt_set_pte( u_gpt_xp , 0 , attr , ppn ); 130 162 131 163 if( error ) 132 164 { 133 printk("\n[ERROR] in %s : cannot update GPT in cluster %x\n",165 printk("\n[ERROR] in %s : cannot update user GPT in cluster %x\n", 134 166 __FUNCTION__ , cxy ); 135 167 return -1; 136 168 } 137 169 170 #if DEBUG_HAL_VMM 171 printk("\n[%s] thread[%x,%x] registered PT1[0] ( ppn %x / attr %x ) to user GPT\n", 172 __FUNCTION__, this->process->pid, this->trdid, ppn, attr ); 173 #endif 174 138 175 // get pointer on the unique vseg registered in kernel VSL 139 xptr_t root_xp = XPTR( cxy , &process_zero.vmm.vsegs_root ); 140 vseg_t * vseg = XLIST_FIRST( root_xp , vseg_t , xlist ); 176 xptr_t root_xp = XPTR( cxy , &process_zero.vmm.vsegs_root ); 177 xptr_t vseg_xp = XLIST_FIRST( root_xp , vseg_t , xlist ); 178 vseg_t * vseg = GET_PTR( vseg_xp ); 141 179 142 180 // check vsegs_nr 143 assert( (process_zero.vmm.vsegs_nr == 1 ) , __FUNCTION__,144 "bad vsegs number in kernel VSL \n");181 assert( (process_zero.vmm.vsegs_nr == 1 ) , 182 "bad vsegs number in kernel VSL = %d\n", process_zero.vmm.vsegs_nr ); 145 183 146 184 // update user VSL : register one new vseg for kcode … … 154 192 if( new == NULL ) 155 193 { 156 printk("\n[ERROR] in %s : cannot update VSL in cluster %x\n",194 printk("\n[ERROR] in %s : cannot update user VSL in cluster %x\n", 157 195 __FUNCTION__ , cxy ); 158 196 return -1; 159 197 } 160 } 161 162 198 199 #if DEBUG_HAL_VMM 200 printk("\n[%s] thread[%x,%x] created vseg %s ( base %x / size %x ) to user VSL\n", 201 __FUNCTION__, this->process->pid, this->trdid, 202 vseg_type_str(vseg->type) , vseg->min, (vseg->max - vseg->min) ); 203 hal_vmm_display( process , true ); 204 #endif 205 206 return 0; 207 208 } // end hal_vmm_kernel_update() 209 210 ////////////////////////////////////////// 211 void hal_vmm_display( process_t * process, 212 bool_t mapping ) 213 { 214 vmm_t * vmm = &process->vmm; 215 gpt_t * gpt = &vmm->gpt; 216 217 // get pointers on TXT0 chdev 218 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 219 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 220 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 221 222 // get extended pointer on remote TXT0 lock 223 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 224 225 // get locks protecting the VSL and the GPT 226 remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->vsegs_lock ) ); 227 remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->gpt_lock ) ); 228 229 // get TXT0 lock 230 remote_busylock_acquire( lock_xp ); 231 232 nolock_printk("\n***** VSL and GPT for process %x in cluster %x\n", 233 process->pid , local_cxy ); 234 235 // scan the list of vsegs 236 xptr_t root_xp = XPTR( local_cxy , &vmm->vsegs_root ); 237 xptr_t iter_xp; 238 xptr_t vseg_xp; 239 vseg_t * vseg; 240 XLIST_FOREACH( root_xp , iter_xp ) 241 { 242 vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist ); 243 vseg = GET_PTR( vseg_xp ); 244 245 nolock_printk(" - %s : base = %X / size = %X / npages = %d\n", 246 vseg_type_str( vseg->type ) , vseg->min , vseg->max - vseg->min , vseg->vpn_size ); 247 248 if( mapping ) 249 { 250 vpn_t vpn = vseg->vpn_base; 251 vpn_t vpn_max = vpn + vseg->vpn_size; 252 ppn_t ppn; 253 uint32_t attr; 254 255 while( vpn < vpn_max ) 256 { 257 hal_gpt_get_pte( XPTR( local_cxy , gpt ) , vpn , &attr , &ppn ); 258 259 if( attr & GPT_MAPPED ) 260 { 261 if( attr & GPT_SMALL ) 262 { 263 nolock_printk(" . SMALL : vpn = %X / attr = %X / ppn = %X\n", 264 vpn , attr , ppn ); 265 vpn++; 266 } 267 else 268 { 269 nolock_printk(" . BIG : vpn = %X / attr = %X / ppn = %X\n", 270 vpn , attr , ppn ); 271 vpn += 512; 272 } 273 } 274 else 275 { 276 vpn++; 277 } 278 } 279 } 280 } 281 282 // release TXT0 lock 283 remote_busylock_release( lock_xp ); 284 285 // release the VSK and GPT locks 286 remote_rwlock_rd_release( XPTR( local_cxy , &vmm->vsegs_lock ) ); 287 remote_rwlock_rd_release( XPTR( local_cxy , &vmm->gpt_lock ) ); 288 289 } // hal_vmm_display() 290 -
trunk/hal/tsar_mips32/kernel.ld
r623 r624 1 1 /*************************************************************************************** 2 2 * This is the linker script for the ALMOS-MKH kernel code on the TSAR architecture. 3 * It describes the memory layout for the "kernel.elf" binary file, containing th ree3 * It describes the memory layout for the "kernel.elf" binary file, containing the two 4 4 * loadable segments, that MUST be identity mapped for the TSAR architecture. 5 5 * 6 * WARNING : the seg_k entry_base and seg_kcode_base defined below must be coherent6 * WARNING : the seg_kcode_base defined below must be coherent 7 7 * with the values defined in the boot_config.h file used by the TSAR bootloader. 8 8 **************************************************************************************/ … … 10 10 /* Define the kernel code base addresses */ 11 11 12 seg_kcode_base = 0x00008000; 13 seg_kentry_base = 0x00004000; 12 seg_kcode_base = 0x00004000; 14 13 15 /* Set the entry point (e_entry field in the "kernel.elf" file header) */14 /* Define the e_entry field in the "kernel.elf" file header) */ 16 15 17 16 ENTRY(kernel_init) … … 24 23 seg_kcode : 25 24 { 25 *(.kentry) 26 *(.switch) 26 27 *(.text) 27 28 *(.rodata*) … … 35 36 *(.kidle) 36 37 *(.kdata*) 38 *(.scommon) 39 *(.bss) 40 *(.eh*) 37 41 *(.data*) 38 42 } 39 40 . = seg_kentry_base;41 seg_kentry :42 {43 *(.kentry)44 *(.switch)45 }46 43 } -
trunk/kernel/fs/devfs.c
r623 r624 263 263 if( chdev_cxy != local_cxy ) 264 264 { 265 printk("\ d[PANIC] in %s : illegal DMA chdev in cluster %x\n",265 printk("\n[PANIC] in %s : illegal DMA chdev in cluster %x\n", 266 266 __FUNCTION__, local_cxy ); 267 267 hal_core_sleep(); -
trunk/kernel/kern/kernel_init.c
r623 r624 97 97 process_t process_zero CONFIG_CACHE_LINE_ALIGNED; 98 98 99 // This variable defines extended pointers on the distributed chdevs99 // This variable defines a set of extended pointers on the distributed chdevs 100 100 __attribute__((section(".kdata"))) 101 101 chdev_directory_t chdev_dir CONFIG_CACHE_LINE_ALIGNED; … … 125 125 vfs_ctx_t fs_context[FS_TYPES_NR] CONFIG_CACHE_LINE_ALIGNED; 126 126 127 // kernel_init is the entry point defined in hal/tsar_mips32/kernel.ld128 // It is used by the bootloader to tranfer control to kernel.129 extern void kernel_init( boot_info_t * info );130 131 127 // This array is used for debug, and describes the kernel locks usage, 132 128 // It must be kept consistent with the defines in kernel_config.h file. 129 __attribute__((section(".kdata"))) 133 130 char * lock_type_str[] = 134 131 { … … 229 226 230 227 // intrumentation variables : cumulated costs per syscall type in cluster 228 229 #if CONFIG_INSTRUMENTATION_SYSCALLS 230 __attribute__((section(".kdata"))) 231 231 uint32_t syscalls_cumul_cost[SYSCALLS_NR]; 232 232 233 // intrumentation variables : number of syscalls per syscal type in cluster 233 __attribute__((section(".kdata"))) 234 234 uint32_t syscalls_occurences[SYSCALLS_NR]; 235 #endif 235 236 236 237 /////////////////////////////////////////////////////////////////////////////////////////// … … 978 979 #if DEBUG_KERNEL_INIT 979 980 if( (core_lid == 0) & (local_cxy == 0) ) 980 printk("\n[%s] :exit barrier 1 : TXT0 initialized / cycle %d\n",981 printk("\n[%s] exit barrier 1 : TXT0 initialized / cycle %d\n", 981 982 __FUNCTION__, (uint32_t)hal_get_cycles() ); 982 983 #endif … … 1011 1012 #if DEBUG_KERNEL_INIT 1012 1013 if( (core_lid == 0) & (local_cxy == 0) ) 1013 printk("\n[%s] :exit barrier 2 : cluster manager initialized / cycle %d\n",1014 printk("\n[%s] exit barrier 2 : cluster manager initialized / cycle %d\n", 1014 1015 __FUNCTION__, (uint32_t)hal_get_cycles() ); 1015 1016 #endif 1016 1017 1017 1018 ///////////////////////////////////////////////////////////////////////////////// 1018 // STEP 3 : core[0] initializes the process_zero descriptor, 1019 // STEP 3 : all cores initialize the idle thread descriptor. 1020 // core[0] initializes the process_zero descriptor, 1019 1021 // including the kernel VMM (both GPT and VSL) 1020 1022 ///////////////////////////////////////////////////////////////////////////////// … … 1024 1026 core = &cluster->core_tbl[core_lid]; 1025 1027 1028 // all cores update the register(s) defining the kernel 1029 // entry points for interrupts, exceptions and syscalls, 1030 // this must be done before VFS initialisation, because 1031 // kernel_init() uses RPCs requiring IPIs... 1032 hal_set_kentry(); 1033 1034 // all cores initialize the idle thread descriptor 1035 thread_idle_init( thread, 1036 THREAD_IDLE, 1037 &thread_idle_func, 1038 NULL, 1039 core_lid ); 1040 1026 1041 // core[0] initializes the process_zero descriptor, 1027 1042 if( core_lid == 0 ) process_zero_create( &process_zero , info ); … … 1035 1050 #if DEBUG_KERNEL_INIT 1036 1051 if( (core_lid == 0) & (local_cxy == 0) ) 1037 printk("\n[%s] :exit barrier 3 : kernel processs initialized / cycle %d\n",1052 printk("\n[%s] exit barrier 3 : kernel processs initialized / cycle %d\n", 1038 1053 __FUNCTION__, (uint32_t)hal_get_cycles() ); 1039 1054 #endif … … 1058 1073 #if DEBUG_KERNEL_INIT 1059 1074 if( (core_lid == 0) & (local_cxy == 0) ) 1060 printk("\n[%s] :exit barrier 4 : MMU and IOPIC initialized / cycle %d\n",1075 printk("\n[%s] exit barrier 4 : MMU and IOPIC initialized / cycle %d\n", 1061 1076 __FUNCTION__, (uint32_t)hal_get_cycles() ); 1062 1077 #endif … … 1091 1106 #if DEBUG_KERNEL_INIT 1092 1107 if( (core_lid == 0) & (local_cxy == 0) ) 1093 printk("\n[%s] : exit barrier 5 : allchdevs initialised / cycle %d\n",1108 printk("\n[%s] exit barrier 5 : chdevs initialised / cycle %d\n", 1094 1109 __FUNCTION__, (uint32_t)hal_get_cycles() ); 1095 1110 #endif … … 1101 1116 1102 1117 ///////////////////////////////////////////////////////////////////////////////// 1103 // STEP 6 : All cores enable IPI (Inter Procesor Interrupt),1104 // Alh cores initialize IDLE thread.1105 // Onlycore[0] in cluster[0] creates the VFS root inode.1118 // STEP 6 : all cores enable IPI (Inter Procesor Interrupt), 1119 // all cores unblock the idle thread, and register it in scheduler. 1120 // core[0] in cluster[0] creates the VFS root inode. 1106 1121 // It access the boot device to initialize the file system context. 1107 1122 ///////////////////////////////////////////////////////////////////////////////// … … 1111 1126 hal_enable_irq( &status ); 1112 1127 1113 // all cores initialize the idle thread descriptor 1114 thread_idle_init( thread, 1115 THREAD_IDLE, 1116 &thread_idle_func, 1117 NULL, 1118 core_lid ); 1119 1120 // all cores unblock idle thread, and register it in scheduler 1128 // all cores unblock the idle thread, and register it in scheduler 1121 1129 thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL ); 1122 1130 core->scheduler.idle = thread; … … 1171 1179 cxy_t vfs_root_cxy = GET_CXY( vfs_root_inode_xp ); 1172 1180 vfs_inode_t * vfs_root_ptr = GET_PTR( vfs_root_inode_xp ); 1173 hal_remote_s32( XPTR( vfs_root_cxy , &vfs_root_ptr-> extend), INODE_TYPE_DIR );1181 hal_remote_s32( XPTR( vfs_root_cxy , &vfs_root_ptr->type ), INODE_TYPE_DIR ); 1174 1182 hal_remote_spt( XPTR( vfs_root_cxy , &vfs_root_ptr->extend ), 1175 1183 (void*)(intptr_t)root_dir_cluster ); … … 1208 1216 #if DEBUG_KERNEL_INIT 1209 1217 if( (core_lid == 0) & (local_cxy == 0) ) 1210 printk("\n[%s] :exit barrier 6 : VFS root (%x,%x) in cluster 0 / cycle %d\n",1218 printk("\n[%s] exit barrier 6 : VFS root (%x,%x) in cluster 0 / cycle %d\n", 1211 1219 __FUNCTION__, GET_CXY(process_zero.vfs_root_xp), 1212 1220 GET_PTR(process_zero.vfs_root_xp), (uint32_t)hal_get_cycles() ); … … 1278 1286 #if DEBUG_KERNEL_INIT 1279 1287 if( (core_lid == 0) & (local_cxy == 1) ) 1280 printk("\n[%s] :exit barrier 7 : VFS root (%x,%x) in cluster 1 / cycle %d\n",1288 printk("\n[%s] exit barrier 7 : VFS root (%x,%x) in cluster 1 / cycle %d\n", 1281 1289 __FUNCTION__, GET_CXY(process_zero.vfs_root_xp), 1282 1290 GET_PTR(process_zero.vfs_root_xp), (uint32_t)hal_get_cycles() ); … … 1328 1336 #if DEBUG_KERNEL_INIT 1329 1337 if( (core_lid == 0) & (local_cxy == 0) ) 1330 printk("\n[%s] :exit barrier 8 : DEVFS root initialized in cluster 0 / cycle %d\n",1338 printk("\n[%s] exit barrier 8 : DEVFS root initialized in cluster 0 / cycle %d\n", 1331 1339 __FUNCTION__, (uint32_t)hal_get_cycles() ); 1332 1340 #endif 1333 1341 1334 1342 ///////////////////////////////////////////////////////////////////////////////// 1335 // STEP 9 : All core[0]s complete in parallel theDEVFS initialization.1343 // STEP 9 : In all clusters in parallel, core[0] completes DEVFS initialization. 1336 1344 // Each core[0] get the "dev" and "external" extended pointers from 1337 // values stored in cluster 0. 1338 // Then each core[0] in cluster(i) creates the DEVFS "internal" directory, 1339 // and creates the pseudo-files for all chdevs in cluster (i). 1345 // values stored in cluster(0), creates the DEVFS "internal" directory, 1346 // and creates the pseudo-files for all chdevs in local cluster. 1340 1347 ///////////////////////////////////////////////////////////////////////////////// 1341 1348 … … 1365 1372 #if DEBUG_KERNEL_INIT 1366 1373 if( (core_lid == 0) & (local_cxy == 0) ) 1367 printk("\n[%s] :exit barrier 9 : DEVFS initialized in cluster 0 / cycle %d\n",1374 printk("\n[%s] exit barrier 9 : DEVFS initialized in cluster 0 / cycle %d\n", 1368 1375 __FUNCTION__, (uint32_t)hal_get_cycles() ); 1369 1376 #endif … … 1384 1391 process_init_create(); 1385 1392 } 1393 1394 #if DEBUG_KERNEL_INIT 1395 if( (core_lid == 0) & (local_cxy == 0) ) 1396 printk("\n[%s] exit barrier 10 : process_init created in cluster 0 / cycle %d\n", 1397 __FUNCTION__, (uint32_t)hal_get_cycles() ); 1398 #endif 1386 1399 1387 1400 #if (DEBUG_KERNEL_INIT & 1) … … 1444 1457 #endif 1445 1458 1446 // each core updates the register(s) definig the kernel1447 // entry points for interrupts, exceptions and syscalls...1448 hal_set_kentry();1449 1450 1459 // each core activates its private TICK IRQ 1451 1460 dev_pic_enable_timer( CONFIG_SCHED_TICK_MS_PERIOD ); -
trunk/kernel/kern/process.c
r623 r624 1209 1209 1210 1210 // check th_nr value 1211 assert( (count > 0) , "process th_nr cannot be 0 \n" );1211 assert( (count > 0) , "process th_nr cannot be 0" ); 1212 1212 1213 1213 // remove thread from th_tbl[] … … 1249 1249 // check parent process is the reference process 1250 1250 assert( (parent_process_xp == ref_xp ) , 1251 "parent process must be the reference process \n" );1251 "parent process must be the reference process" ); 1252 1252 1253 1253 #if DEBUG_PROCESS_MAKE_FORK … … 1352 1352 // check main thread LTID 1353 1353 assert( (LTID_FROM_TRDID(thread->trdid) == 0) , 1354 "main thread must have LTID == 0 \n" );1354 "main thread must have LTID == 0" ); 1355 1355 1356 1356 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) … … 1552 1552 #endif 1553 1553 1554 // get pointer on VMM 1555 vmm_t * vmm = &process->vmm; 1556 1554 1557 // get PID from local cluster manager for this kernel process 1555 1558 error = cluster_pid_alloc( process , &pid ); … … 1571 1574 process->term_state = 0; 1572 1575 1573 // initialise kernel GPT and VSL, depending on architecture 1574 hal_vmm_kernel_init( info ); 1576 // initilise VSL as empty 1577 vmm->vsegs_nr = 0; 1578 xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) ); 1579 remote_rwlock_init( XPTR( local_cxy , &vmm->vsegs_lock ) , LOCK_VMM_VSL ); 1580 1581 // initialise GPT as empty 1582 error = hal_gpt_create( &vmm->gpt ); 1583 1584 if( error ) 1585 { 1586 printk("\n[PANIC] in %s : cannot create empty GPT\n", __FUNCTION__ ); 1587 hal_core_sleep(); 1588 } 1589 1590 // initialize GPT lock 1591 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT ); 1592 1593 // create kernel vsegs in GPT and VSL, as required by the hardware architecture 1594 error = hal_vmm_kernel_init( info ); 1595 1596 if( error ) 1597 { 1598 printk("\n[PANIC] in %s : cannot create kernel vsegs in VMM\n", __FUNCTION__ ); 1599 hal_core_sleep(); 1600 } 1575 1601 1576 1602 // reset th_tbl[] array and associated fields … … 1629 1655 // check memory allocator 1630 1656 assert( (process != NULL), 1631 "no memory for process descriptor in cluster %x \n", local_cxy );1657 "no memory for process descriptor in cluster %x", local_cxy ); 1632 1658 1633 1659 // set the CWD and VFS_ROOT fields in process descriptor … … 1640 1666 // check PID allocator 1641 1667 assert( (error == 0), 1642 "cannot allocate PID in cluster %x \n", local_cxy );1668 "cannot allocate PID in cluster %x", local_cxy ); 1643 1669 1644 1670 // check PID value 1645 1671 assert( (pid == 1) , 1646 "process INIT must be first process in cluster 0 \n" );1672 "process INIT must be first process in cluster 0" ); 1647 1673 1648 1674 // initialize process descriptor / parent is local process_zero … … 1669 1695 1670 1696 assert( (error == 0), 1671 "failed to open file <%s> \n", CONFIG_PROCESS_INIT_PATH );1697 "failed to open file <%s>", CONFIG_PROCESS_INIT_PATH ); 1672 1698 1673 1699 #if(DEBUG_PROCESS_INIT_CREATE & 1) … … 1682 1708 1683 1709 assert( (error == 0), 1684 "cannot access .elf file <%s> \n", CONFIG_PROCESS_INIT_PATH );1710 "cannot access .elf file <%s>", CONFIG_PROCESS_INIT_PATH ); 1685 1711 1686 1712 #if(DEBUG_PROCESS_INIT_CREATE & 1) … … 1726 1752 1727 1753 assert( (error == 0), 1728 "cannot create main thread for <%s> \n", CONFIG_PROCESS_INIT_PATH );1754 "cannot create main thread for <%s>", CONFIG_PROCESS_INIT_PATH ); 1729 1755 1730 1756 assert( (thread->trdid == 0), 1731 "main thread must have index 0 for <%s> \n", CONFIG_PROCESS_INIT_PATH );1757 "main thread must have index 0 for <%s>", CONFIG_PROCESS_INIT_PATH ); 1732 1758 1733 1759 #if(DEBUG_PROCESS_INIT_CREATE & 1) … … 1816 1842 1817 1843 assert( (txt_file_xp != XPTR_NULL) , 1818 "process must be attached to one TXT terminal \n" );1844 "process must be attached to one TXT terminal" ); 1819 1845 1820 1846 // get TXT_RX chdev pointers … … 2012 2038 // check owner cluster 2013 2039 assert( (process_cxy == CXY_FROM_PID( process_pid )) , 2014 "process descriptor not in owner cluster \n" );2040 "process descriptor not in owner cluster" ); 2015 2041 2016 2042 // get extended pointer on stdin pseudo file … … 2067 2093 // check owner cluster 2068 2094 assert( (process_cxy == CXY_FROM_PID( process_pid )) , 2069 "process descriptor not in owner cluster \n" );2095 "process descriptor not in owner cluster" ); 2070 2096 2071 2097 // get extended pointer on stdin pseudo file … … 2198 2224 pid_t process_pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ) ); 2199 2225 assert( (process_cxy == CXY_FROM_PID( process_pid )) , 2200 "process descriptor not in owner cluster \n" );2226 "process descriptor not in owner cluster" ); 2201 2227 2202 2228 // get extended pointer on stdin pseudo file -
trunk/kernel/kern/rpc.c
r623 r624 81 81 &rpc_vmm_create_vseg_server, // 27 82 82 &rpc_vmm_set_cow_server, // 28 83 &rpc_ vmm_display_server, // 2983 &rpc_hal_vmm_display_server, // 29 84 84 }; 85 85 … … 2729 2729 2730 2730 ///////////////////////////////////////////// 2731 void rpc_ vmm_display_client( cxy_t cxy,2731 void rpc_hal_vmm_display_client( cxy_t cxy, 2732 2732 process_t * process, 2733 2733 bool_t detailed ) … … 2765 2765 2766 2766 //////////////////////////////////////// 2767 void rpc_ vmm_display_server( xptr_t xp )2767 void rpc_hal_vmm_display_server( xptr_t xp ) 2768 2768 { 2769 2769 #if DEBUG_RPC_VMM_DISPLAY … … 2787 2787 2788 2788 // call local kernel function 2789 vmm_display( process , detailed );2789 hal_vmm_display( process , detailed ); 2790 2790 2791 2791 #if DEBUG_RPC_VMM_DISPLAY -
trunk/kernel/kern/rpc.h
r623 r624 683 683 * @ detailed : [in] detailed display if true. 684 684 **********************************************************************************/ 685 void rpc_ vmm_display_client( cxy_t cxy,685 void rpc_hal_vmm_display_client( cxy_t cxy, 686 686 struct process_s * process, 687 687 bool_t detailed ); 688 688 689 void rpc_ vmm_display_server( xptr_t xp );689 void rpc_hal_vmm_display_server( xptr_t xp ); 690 690 691 691 -
trunk/kernel/kern/scheduler.c
r619 r624 488 488 489 489 #if (DEBUG_SCHED_YIELD & 0x1) 490 if( sched->trace ) 490 // if( sched->trace ) 491 if( (uint32_t)hal_get_cycles() > DEBUG_SCHED_YIELD ) 491 492 sched_display( lid ); 492 493 #endif … … 541 542 542 543 #if DEBUG_SCHED_YIELD 543 if( sched->trace ) 544 // if( sched->trace ) 545 if( (uint32_t)hal_get_cycles() > DEBUG_SCHED_YIELD ) 544 546 printk("\n[%s] core[%x,%d] / cause = %s\n" 545 547 " thread %x (%s) (%x,%x) => thread %x (%s) (%x,%x) / cycle %d\n", … … 558 560 559 561 #if (DEBUG_SCHED_YIELD & 1) 560 if( sched->trace ) 562 // if( sched->trace ) 563 if(uint32_t)hal_get_cycles() > DEBUG_SCHED_YIELD ) 561 564 printk("\n[%s] core[%x,%d] / cause = %s\n" 562 565 " thread %x (%s) (%x,%x) continue / cycle %d\n", … … 601 604 602 605 nolock_printk("\n***** threads on core[%x,%d] / current %x / rpc_threads %d / cycle %d\n", 603 local_cxy , core->lid, sched->current, LOCAL_CLUSTER->rpc_threads[lid],606 local_cxy , lid, sched->current, LOCAL_CLUSTER->rpc_threads[lid], 604 607 (uint32_t)hal_get_cycles() ); 605 608 -
trunk/kernel/kern/thread.c
r623 r624 389 389 printk("\n[%s] CPU & FPU contexts created\n", 390 390 __FUNCTION__, thread->trdid ); 391 vmm_display( process , true );391 hal_vmm_display( process , true ); 392 392 #endif 393 393 … … 689 689 printk("\n[%s] thread[%x,%x] set CPU context & jump to user code / cycle %d\n", 690 690 __FUNCTION__, process->pid, thread->trdid, cycle ); 691 vmm_display( process , true );691 hal_vmm_display( process , true ); 692 692 #endif 693 693 … … 1352 1352 "hold %d busylock(s) / cycle %d\n", 1353 1353 func_str, thread->process->pid, thread->trdid, 1354 thread->busylocks , (uint32_t)hal_get_cycles() );1354 thread->busylocks - 1, (uint32_t)hal_get_cycles() ); 1355 1355 1356 1356 #if DEBUG_BUSYLOCK -
trunk/kernel/kernel_config.h
r623 r624 40 40 41 41 #define DEBUG_BUSYLOCK 0 42 #define DEBUG_BUSYLOCK_THREAD_XP 0x0ULL // selected thread xptr 42 #define DEBUG_BUSYLOCK_PID 0x10001 // thread pid (when detailed debug) 43 #define DEBUG_BUSYLOCK_TRDID 0x10000 // thread trdid (when detailed debug) 43 44 44 45 #define DEBUG_CHDEV_CMD_RX 0 … … 84 85 #define DEBUG_FATFS_MOVE_PAGE 0 85 86 #define DEBUG_FATFS_NEW_DENTRY 0 86 #define DEBUG_FATFS_RELEASE_INODE 187 #define DEBUG_FATFS_RELEASE_INODE 0 87 88 #define DEBUG_FATFS_REMOVE_DENTRY 0 88 89 #define DEBUG_FATFS_SYNC_FAT 0 … … 91 92 #define DEBUG_FATFS_UPDATE_DENTRY 0 92 93 94 #define DEBUG_HAL_EXCEPTIONS 0 93 95 #define DEBUG_HAL_GPT_SET_PTE 0 94 96 #define DEBUG_HAL_GPT_COPY 0 95 97 #define DEBUG_HAL_GPT_CREATE 0 96 98 #define DEBUG_HAL_GPT_DESTROY 0 97 #define DEBUG_HAL_USPACE 0 99 #define DEBUG_HAL_IOC_RX 0 100 #define DEBUG_HAL_IOC_TX 0 101 #define DEBUG_HAL_IRQS 0 98 102 #define DEBUG_HAL_KENTRY 0 99 #define DEBUG_HAL_EXCEPTIONS 0100 #define DEBUG_HAL_IRQS 0101 103 #define DEBUG_HAL_TXT_RX 0 102 104 #define DEBUG_HAL_TXT_TX 0 103 #define DEBUG_HAL_ IOC_RX0104 #define DEBUG_HAL_ IOC_TX0105 #define DEBUG_HAL_USPACE 0 106 #define DEBUG_HAL_VMM 0 105 107 106 108 #define DEBUG_KCM 0 … … 162 164 163 165 #define DEBUG_SCHED_HANDLE_SIGNALS 2 164 #define DEBUG_SCHED_YIELD 2 // must be activated by the trace() syscall166 #define DEBUG_SCHED_YIELD 0 165 167 #define DEBUG_SCHED_RPC_ACTIVATE 0 166 168 … … 236 238 #define DEBUG_VFS_OPENDIR 0 237 239 #define DEBUG_VFS_STAT 0 238 #define DEBUG_VFS_UNLINK 1240 #define DEBUG_VFS_UNLINK 0 239 241 240 242 #define DEBUG_VMM_CREATE_VSEG 0 … … 407 409 408 410 //////////////////////////////////////////////////////////////////////////////////////////// 409 // 411 // 32 bits USER SPACE SEGMENTATION / all values are numbers of pages 410 412 //////////////////////////////////////////////////////////////////////////////////////////// 411 413 412 414 #define CONFIG_VMM_VSPACE_SIZE 0x100000 // virtual space : 4 Gbytes 413 415 414 #define CONFIG_VMM_ KENTRY_BASE 0x000004 // UTILS zone base : 16 Kbytes416 #define CONFIG_VMM_UTILS_BASE 0x000200 // UTILS zone base : 2 Mbytes 415 417 #define CONFIG_VMM_ELF_BASE 0x000400 // ELF zone base : 4 Mbytes 416 418 #define CONFIG_VMM_HEAP_BASE 0x002000 // HEAP zone base : 32 Mbytes 417 419 #define CONFIG_VMM_STACK_BASE 0x0C0000 // STACK zone base : 3 Gbytes 418 420 419 #define CONFIG_VMM_KENTRY_SIZE 0x000004 // kentry vseg size : 16 Kbytes420 421 #define CONFIG_VMM_ARGS_SIZE 0x000004 // args vseg size : 16 Kbytes 421 422 #define CONFIG_VMM_ENVS_SIZE 0x000008 // envs vseg size : 32 Kbytes -
trunk/kernel/libk/busylock.c
r600 r624 2 2 * busylock.c - local kernel-busy waiting lock implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 76 76 77 77 #if DEBUG_BUSYLOCK 78 if( (lock->type != LOCK_CHDEV_TXT0) && 79 ((uint32_t)hal_get_cycles() > DEBUG_BUSYLOCK) ) 78 if( lock->type != LOCK_CHDEV_TXT0 ) 80 79 { 80 // update thread list of busylocks 81 81 xptr_t root_xp = XPTR( local_cxy , &this->busylocks_root ); 82 83 // update thread list of busylocks84 82 xlist_add_last( root_xp , XPTR( local_cxy , &lock->xlist ) ); 85 83 } 86 84 #endif 87 85 88 #if( DEBUG_BUSYLOCK & & DEBUG_BUSYLOCK_THREAD_XP)86 #if( DEBUG_BUSYLOCK & 1 ) 89 87 if( (lock->type != LOCK_CHDEV_TXT0) && 90 (XPTR( local_cxy , this ) == DEBUG_BUSYLOCK_THREAD_XP) ) 88 (this->process->pid == DEBUG_BUSYLOCK_PID) && 89 (this->trdid == DEBUG_BUSYLOCK_TRDID) ) 91 90 { 92 // get cluster and local pointer of target thread93 cxy_t thread_cxy = GET_CXY( DEBUG_BUSYLOCK_THREAD_XP );94 thread_t * thread_ptr = GET_PTR( DEBUG_BUSYLOCK_THREAD_XP );95 96 // display message on kernel TXT097 91 printk("\n[%s] thread[%x,%x] ACQUIRE lock %s\n", 98 92 __FUNCTION__, this->process->pid, this->trdid, lock_type_str[lock->type] ); … … 120 114 121 115 #if DEBUG_BUSYLOCK 122 if( (lock->type != LOCK_CHDEV_TXT0) && 123 ((uint32_t)hal_get_cycles() > DEBUG_BUSYLOCK) ) 116 if( lock->type != LOCK_CHDEV_TXT0 ) 124 117 { 125 118 // remove lock from thread list of busylocks … … 128 121 #endif 129 122 130 #if( DEBUG_BUSYLOCK & & DEBUG_BUSYLOCK_THREAD_XP)123 #if( DEBUG_BUSYLOCK & 1 ) 131 124 if( (lock->type != LOCK_CHDEV_TXT0) && 132 (XPTR( local_cxy , this ) == DEBUG_BUSYLOCK_THREAD_XP) ) 125 (this->process->pid == DEBUG_BUSYLOCK_PID) && 126 (this->trdid == DEBUG_BUSYLOCK_TRDID) ) 133 127 { 134 // get cluster and local pointer of target thread135 cxy_t thread_cxy = GET_CXY( DEBUG_BUSYLOCK_THREAD_XP );136 thread_t * thread_ptr = GET_PTR( DEBUG_BUSYLOCK_THREAD_XP );137 138 // display message on kernel TXT0139 128 printk("\n[%s] thread[%x,%x] RELEASE lock %s\n", 140 129 __FUNCTION__, this->process->pid, this->trdid, lock_type_str[lock->type] ); -
trunk/kernel/libk/busylock.h
r623 r624 2 2 * busylock.h: local kernel busy-waiting lock definition. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 34 34 * a shared object located in a given cluster, made by thread(s) running in same cluster. 35 35 * It uses a busy waiting policy when the lock is taken by another thread, and should 36 * be used to execute very short actions, such as accessing basic allocators ,or higher36 * be used to execute very short actions, such as accessing basic allocators or higher 37 37 * level synchronisation objects (barriers, queuelocks, or rwlocks). 38 * WARNING: a thread cannot yield when it is owning a busylock.39 38 * 40 39 * - To acquire the lock, we use a ticket policy to avoid starvation: the calling thread … … 42 41 * value until current == ticket. 43 42 * 44 * - To release the lock, the owner thread increments the "current" value, 45 * decrements its busylocks counter. 43 * - To release the lock, the owner thread increments the "current" value. 46 44 * 47 * - When a thread takes a busylock, it enters a critical section: the busylock_acquire()45 * - When a thread takes a busylock, it enters a critical section: the acquire() 48 46 * function disables the IRQs, takes the lock, increments the thread busylocks counter, 49 * andsave the SR in lock descriptor and returns.47 * save the SR in lock descriptor and returns. 50 48 * 51 * - The busylock_release() function releases the lock, decrements the thread busylock52 * counter, restores the SR to exit the critical section, and returns 49 * - The release() function releases the lock, decrements the thread busylock 50 * counter, restores the SR to exit the critical section, and returns. 53 51 * 54 * - If a thread owning a busylock (local or remote) tries to deschedule, the scheduler 55 * signals a kernel panic. 52 * WARNING: a thread cannot yield when it is holding a busylock (local or remote). 53 * 54 * This rule is checked by all functions containing a thread_yield() AND by the scheduler, 55 * thanks to the busylocks counter stored in the calling thread descriptor. 56 * 1) all functions call "thread_assert_can_yield()" before calling "thread_yield()". 57 * 2) The scheduler checks that the calling thread does not hold any busylock. 58 * In case of violation the core goes to sleep after a [PANIC] message on TXT0. 56 59 ******************************************************************************************/ 57 60 58 61 /******************************************************************************************* 59 62 * This structure defines a busylock. 60 * The < type> and <xlist> fields are used for debug.61 * The typedefines the lock usage as detailed in the kernel_config.h file.63 * The <xlist> field is only used when DEBUG_BUSYLOCK is set. 64 * The <type> field defines the lock usage as detailed in the kernel_config.h file. 62 65 ******************************************************************************************/ 63 66 -
trunk/kernel/libk/remote_busylock.c
r619 r624 2 2 * remote_busylock.c - remote kernel busy-waiting lock implementation. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 87 87 #if DEBUG_BUSYLOCK 88 88 uint32_t type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->type ) ); 89 if( (type != LOCK_CHDEV_TXT0) && 90 ((uint32_t)hal_get_cycles() > DEBUG_BUSYLOCK) ) 89 if( type != LOCK_CHDEV_TXT0 ) 91 90 { 91 // update thread list of busyslocks 92 92 xptr_t root_xp = XPTR( local_cxy , &this->busylocks_root ); 93 94 // update thread list of busyslocks95 93 xlist_add_last( root_xp , XPTR( lock_cxy , &lock_ptr->xlist ) ); 96 94 } 97 95 #endif 98 96 99 #if( DEBUG_BUSYLOCK & & DEBUG_BUSYLOCK_THREAD_XP)97 #if( DEBUG_BUSYLOCK & 1 ) 100 98 if( (type != LOCK_CHDEV_TXT0) && 101 (XPTR( local_cxy , this ) == DEBUG_BUSYLOCK_THREAD_XP) ) 99 (this->process->pid == DEBUG_BUSYLOCK_PID) && 100 (this->trdid == DEBUG_BUSYLOCK_TRDID) ) 102 101 { 103 102 printk("\n[%s] thread[%x,%x] ACQUIRE lock %s\n", … … 131 130 #if DEBUG_BUSYLOCK 132 131 uint32_t type = hal_remote_l32( XPTR( lock_cxy , &lock_ptr->type ) ); 133 if( (type != LOCK_CHDEV_TXT0) && 134 (XPTR( local_cxy , this ) == DEBUG_BUSYLOCK_THREAD_XP) && 135 ((uint32_t)hal_get_cycles() > DEBUG_BUSYLOCK) ) 132 if( type != LOCK_CHDEV_TXT0 ) 136 133 { 137 134 // remove lock from thread list of busyslocks … … 140 137 #endif 141 138 142 #if (DEBUG_BUSYLOCK && DEBUG_BUSYLOCK_THREAD_XP)139 #if( DEBUG_BUSYLOCK & 1 ) 143 140 if( (type != LOCK_CHDEV_TXT0) && 144 (XPTR( local_cxy , this ) == DEBUG_BUSYLOCK_THREAD_XP) ) 141 (this->process->pid == DEBUG_BUSYLOCK_PID) && 142 (this->trdid == DEBUG_BUSYLOCK_TRDID) ) 145 143 { 146 144 printk("\n[%s] thread[%x,%x] RELEASE lock %s\n", -
trunk/kernel/libk/remote_busylock.h
r619 r624 2 2 * remote_busylock.h: remote kernel busy-waiting lock definition. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 37 37 * higher level synchronisation objects, such as remote_queuelock and remote_rwlock. 38 38 * 39 * WARNING: a thread cannot yield when it is owning a busylock (local or remote).40 *41 39 * - To acquire the lock, we use a ticket policy to avoid starvation: the calling thread 42 40 * makes an atomic increment on a "ticket" allocator, and keep polling the "current" 43 41 * value until current == ticket. 44 42 * 45 * - To release the lock, the owner thread increments the "current" value, 46 * decrements its busylocks counter. 43 * - To release the lock, the owner thread increments the "current" value. 47 44 * 48 * - When a thread takes a busylock, it enters a critical section: the busylock_acquire()45 * - When a thread takes a busylock, it enters a critical section: the acquire() 49 46 * function disables the IRQs, takes the lock, increments the thread busylocks counter, 50 * 47 * save the SR in the lock descriptor and returns. 51 48 * 52 * - The busylock_release() function decrements the thread busylock counter,53 * restores the SR to exit the critical section, and returns49 * - The release() function releases the lock, decrements the thread busylock 50 * counter, restores the SR to exit the critical section, and returns. 54 51 * 55 * - If a thread owning a busylock (local or remote) tries to deschedule, the scheduler 56 * signals a kernel panic. 52 * WARNING: a thread cannot yield when it is holding a busylock (local or remote). 53 * 54 * This rule is checked by all functions containing a thread_yield() AND by the scheduler, 55 * thanks to the busylocks counter stored in the calling thread descriptor. 56 * 1) all functions call "thread_assert_can_yield()" before calling "thread_yield()". 57 * 2) The scheduler checks that the calling thread does not hold any busylock. 58 * In case of violation the core goes to sleep after a [PANIC] message on TXT0. 57 59 ******************************************************************************************/ 58 60 -
trunk/kernel/mm/mapper.c
r623 r624 440 440 ppm_page_do_dirty( page_xp ); 441 441 hal_copy_from_uspace( map_ptr , buf_ptr , page_count ); 442 443 putb(" in mapper_move_user()" , map_ptr , page_count );444 445 442 } 446 443 -
trunk/kernel/mm/vmm.c
r623 r624 76 76 vmm_t * vmm = &process->vmm; 77 77 78 // initialize local list of vsegs78 // initialize VSL (empty) 79 79 vmm->vsegs_nr = 0; 80 80 xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) ); 81 81 remote_rwlock_init( XPTR( local_cxy , &vmm->vsegs_lock ) , LOCK_VMM_VSL ); 82 82 83 assert( ((CONFIG_VMM_KENTRY_SIZE + CONFIG_VMM_ARGS_SIZE + CONFIG_VMM_ENVS_SIZE) 84 <= CONFIG_VMM_ELF_BASE) , "UTILS zone too small\n" ); 85 86 assert( (CONFIG_THREADS_MAX_PER_CLUSTER <= 32) , 87 "no more than 32 threads per cluster for a single process\n"); 83 assert( ((CONFIG_VMM_ARGS_SIZE + CONFIG_VMM_ENVS_SIZE) <= 84 (CONFIG_VMM_ELF_BASE - CONFIG_VMM_UTILS_BASE)) , 85 "UTILS zone too small\n" ); 88 86 89 87 assert( ((CONFIG_VMM_STACK_SIZE * CONFIG_THREADS_MAX_PER_CLUSTER) <= … … 92 90 93 91 // register args vseg in VSL 94 base = (CONFIG_VMM_KENTRY_BASE + 95 CONFIG_VMM_KENTRY_SIZE ) << CONFIG_PPM_PAGE_SHIFT; 92 base = CONFIG_VMM_UTILS_BASE << CONFIG_PPM_PAGE_SHIFT; 96 93 size = CONFIG_VMM_ARGS_SIZE << CONFIG_PPM_PAGE_SHIFT; 97 94 … … 114 111 115 112 // register the envs vseg in VSL 116 base = (CONFIG_VMM_KENTRY_BASE + 117 CONFIG_VMM_KENTRY_SIZE + 118 CONFIG_VMM_ARGS_SIZE ) << CONFIG_PPM_PAGE_SHIFT; 113 base = (CONFIG_VMM_UTILS_BASE + CONFIG_VMM_ARGS_SIZE) << CONFIG_PPM_PAGE_SHIFT; 119 114 size = CONFIG_VMM_ENVS_SIZE << CONFIG_PPM_PAGE_SHIFT; 120 115 … … 148 143 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT ); 149 144 150 // update process VMM with kernel vsegs 145 // update process VMM with kernel vsegs as required by the hardware architecture 151 146 error = hal_vmm_kernel_update( process ); 152 147 … … 185 180 } // end vmm_init() 186 181 187 //////////////////////////////////////188 void vmm_display( process_t * process,189 bool_t mapping )190 {191 vmm_t * vmm = &process->vmm;192 gpt_t * gpt = &vmm->gpt;193 194 printk("\n***** VSL and GPT(%x) for process %x in cluster %x\n\n",195 process->vmm.gpt.ptr , process->pid , local_cxy );196 197 // get lock protecting the VSL and the GPT198 remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->vsegs_lock ) );199 remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->gpt_lock ) );200 201 // scan the list of vsegs202 xptr_t root_xp = XPTR( local_cxy , &vmm->vsegs_root );203 xptr_t iter_xp;204 xptr_t vseg_xp;205 vseg_t * vseg;206 XLIST_FOREACH( root_xp , iter_xp )207 {208 vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist );209 vseg = GET_PTR( vseg_xp );210 211 printk(" - %s : base = %X / size = %X / npages = %d\n",212 vseg_type_str( vseg->type ) , vseg->min , vseg->max - vseg->min , vseg->vpn_size );213 214 if( mapping )215 {216 vpn_t vpn;217 ppn_t ppn;218 uint32_t attr;219 vpn_t base = vseg->vpn_base;220 vpn_t size = vseg->vpn_size;221 for( vpn = base ; vpn < (base+size) ; vpn++ )222 {223 hal_gpt_get_pte( XPTR( local_cxy , gpt ) , vpn , &attr , &ppn );224 if( attr & GPT_MAPPED )225 {226 printk(" . vpn = %X / attr = %X / ppn = %X\n", vpn , attr , ppn );227 }228 }229 }230 }231 232 // release the locks233 remote_rwlock_rd_release( XPTR( local_cxy , &vmm->vsegs_lock ) );234 remote_rwlock_rd_release( XPTR( local_cxy , &vmm->gpt_lock ) );235 236 } // vmm_display()237 182 238 183 ////////////////////////////////////////// … … 248 193 // update vseg descriptor 249 194 vseg->vmm = vmm; 195 196 // increment vsegs number 197 vmm->vsegs_nr++; 250 198 251 199 // add vseg in vmm list … … 735 683 736 684 // copy base addresses from parent VMM to child VMM 737 child_vmm->kent_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->kent_vpn_base));738 685 child_vmm->args_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->args_vpn_base)); 739 686 child_vmm->envs_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->envs_vpn_base)); … … 773 720 #if (DEBUG_VMM_DESTROY & 1 ) 774 721 if( DEBUG_VMM_DESTROY < cycle ) 775 vmm_display( process , true );722 hal_vmm_display( process , true ); 776 723 #endif 777 724 … … 785 732 // (don't use a FOREACH for item deletion in xlist) 786 733 787 uint32_t count = 0; 788 789 while( !xlist_is_empty( root_xp ) && (count < 10 ) ) 734 while( !xlist_is_empty( root_xp ) ) 790 735 { 791 736 // get pointer on first vseg in VSL … … 801 746 __FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size ); 802 747 #endif 803 804 count++;805 748 806 749 } … … 1093 1036 // check collisions 1094 1037 vseg = vmm_check_conflict( process , vpn_base , vpn_size ); 1038 1095 1039 if( vseg != NULL ) 1096 1040 { … … 1162 1106 xptr_t lock_xp; // extended pointer on lock protecting forks counter 1163 1107 uint32_t forks; // actual number of pendinf forks 1164 uint32_t type;// vseg type1108 uint32_t vseg_type; // vseg type 1165 1109 1166 1110 #if DEBUG_VMM_DELETE_VSEG … … 1197 1141 1198 1142 // get relevant vseg infos 1199 type= vseg->type;1200 vpn_min = vseg->vpn_base;1201 vpn_max = vpn_min + vseg->vpn_size;1143 vseg_type = vseg->type; 1144 vpn_min = vseg->vpn_base; 1145 vpn_max = vpn_min + vseg->vpn_size; 1202 1146 1203 1147 // loop to invalidate all vseg PTEs in GPT 1204 1148 for( vpn = vpn_min ; vpn < vpn_max ; vpn++ ) 1205 1149 { 1206 // get GPT entry1150 // get ppn and attr from GPT entry 1207 1151 hal_gpt_get_pte( XPTR( local_cxy , gpt ) , vpn , &attr , &ppn ); 1208 1152 … … 1217 1161 hal_gpt_reset_pte( gpt , vpn ); 1218 1162 1219 // the allocated page is not released to KMEMfor kernel vseg1220 if( ( type != VSEG_TYPE_KCODE) &&1221 ( type != VSEG_TYPE_KDATA) &&1222 ( type != VSEG_TYPE_KDEV ) )1163 // the allocated page is not released to for kernel vseg 1164 if( (vseg_type != VSEG_TYPE_KCODE) && 1165 (vseg_type != VSEG_TYPE_KDATA) && 1166 (vseg_type != VSEG_TYPE_KDEV ) ) 1223 1167 { 1224 1225 // FIXME This code must be completely re-written, as the actual release must depend on1226 // - the vseg type1227 // - the reference cluster1228 // - the page refcount and/or the forks counter1229 1230 1168 // get extended pointer on physical page descriptor 1231 1169 page_xp = ppm_ppn2page( ppn ); … … 1233 1171 page_ptr = GET_PTR( page_xp ); 1234 1172 1173 // FIXME This code must be re-written, as the actual release depends on vseg type, 1174 // the reference cluster, the page refcount and/or the forks counter... 1175 1235 1176 // get extended pointers on forks and lock fields 1236 1177 forks_xp = XPTR( page_cxy , &page_ptr->forks ); … … 1245 1186 if( forks ) // decrement pending forks counter 1246 1187 { 1188 // update forks counter 1247 1189 hal_remote_atomic_add( forks_xp , -1 ); 1190 1191 // release the lock protecting the page 1192 remote_busylock_release( lock_xp ); 1248 1193 } 1249 1194 else // release physical page to relevant cluster 1250 1195 { 1196 // release the lock protecting the page 1197 remote_busylock_release( lock_xp ); 1198 1199 // release the page to kmem 1251 1200 if( page_cxy == local_cxy ) // local cluster 1252 1201 { … … 1266 1215 } 1267 1216 1268 // release the lock protecting the page1269 remote_busylock_release( lock_xp );1270 1217 } 1271 1218 } -
trunk/kernel/mm/vmm.h
r623 r624 121 121 uint32_t pgfault_nr; /*! page fault counter (instrumentation) */ 122 122 123 vpn_t kent_vpn_base; /*! kentry vseg first page */124 123 vpn_t args_vpn_base; /*! args vseg first page */ 125 vpn_t envs_vpn_base; /*! envs zonefirst page */126 vpn_t heap_vpn_base; /*! envs zonefirst page */127 vpn_t code_vpn_base; /*! code zonefirst page */128 vpn_t data_vpn_base; /*! datazone first page */124 vpn_t envs_vpn_base; /*! envs vseg first page */ 125 vpn_t code_vpn_base; /*! code vseg first page */ 126 vpn_t data_vpn_base; /*! data vseg first page */ 127 vpn_t heap_vpn_base; /*! heap zone first page */ 129 128 130 129 intptr_t entry_point; /*! main thread entry point */ … … 157 156 * @ mapping : detailed mapping if true. 158 157 ********************************************************************************************/ 159 void vmm_display( struct process_s * process,158 void hal_vmm_display( struct process_s * process, 160 159 bool_t mapping ); 161 160 -
trunk/kernel/syscalls/sys_barrier.c
r619 r624 74 74 printk("\n[ERROR] in %s : unmapped barrier %x / thread %x / process %x\n", 75 75 __FUNCTION__ , vaddr , this->trdid , process->pid ); 76 vmm_display( process , false );76 hal_vmm_display( process , false ); 77 77 #endif 78 78 this->errno = error; … … 95 95 printk("\n[ERROR] in %s : unmapped barrier attributes %x / thread %x / process %x\n", 96 96 __FUNCTION__ , attr , this->trdid , process->pid ); 97 vmm_display( process , false );97 hal_vmm_display( process , false ); 98 98 #endif 99 99 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_condvar.c
r566 r624 2 2 * sys_condvar.c - Access a POSIX condvar. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 24 24 #include <hal_kernel_types.h> 25 25 #include <hal_special.h> 26 #include <hal_vmm.h> 26 27 #include <errno.h> 27 28 #include <thread.h> … … 75 76 printk("\n[ERROR] in %s : unmapped condvar %x / thread %x / process %x\n", 76 77 __FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid ); 77 vmm_display( process , false );78 hal_vmm_display( process , false ); 78 79 #endif 79 80 this->errno = error; -
trunk/kernel/syscalls/sys_display.c
r623 r624 2 2 * sys_display.c - display the current state of a kernel structure on TXT0 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018, 2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 24 24 #include <hal_kernel_types.h> 25 25 #include <hal_uspace.h> 26 #include <hal_vmm.h> 26 27 #include <errno.h> 27 28 #include <vmm.h> … … 167 168 if( cxy == local_cxy ) 168 169 { 169 vmm_display( process , true );170 hal_vmm_display( process , true ); 170 171 } 171 172 else 172 173 { 173 rpc_ vmm_display_client( cxy , process , true );174 rpc_hal_vmm_display_client( cxy , process , true ); 174 175 } 175 176 -
trunk/kernel/syscalls/sys_get_config.c
r566 r624 66 66 printk("\n[ERROR] in %s : x_size buffer unmapped / thread %x / process %x\n", 67 67 __FUNCTION__ , (intptr_t)x_size , this->trdid , process->pid ); 68 vmm_display( process , false );68 hal_vmm_display( process , false ); 69 69 #endif 70 70 this->errno = EINVAL; … … 81 81 printk("\n[ERROR] in %s : y_size buffer unmapped / thread %x / process %x\n", 82 82 __FUNCTION__ , (intptr_t)y_size , this->trdid , process->pid ); 83 vmm_display( process , false );83 hal_vmm_display( process , false ); 84 84 #endif 85 85 this->errno = EINVAL; … … 96 96 printk("\n[ERROR] in %s : ncores buffer unmapped / thread %x / process %x\n", 97 97 __FUNCTION__ , (intptr_t)ncores , this->trdid , process->pid ); 98 vmm_display( process , false );98 hal_vmm_display( process , false ); 99 99 #endif 100 100 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_get_core.c
r506 r624 55 55 printk("\n[ERROR] in %s : cxy buffer unmapped %x / thread %x / process %x\n", 56 56 __FUNCTION__ , (intptr_t)cxy , this->trdid , process->pid ); 57 vmm_display( process , false );57 hal_vmm_display( process , false ); 58 58 #endif 59 59 this->errno = EFAULT; … … 70 70 printk("\n[ERROR] in %s : lid buffer unmapped %x / thread %x / process %x\n", 71 71 __FUNCTION__ , (intptr_t)lid , this->trdid , process->pid ); 72 vmm_display( process , false );72 hal_vmm_display( process , false ); 73 73 #endif 74 74 this->errno = EFAULT; -
trunk/kernel/syscalls/sys_get_cycle.c
r506 r624 53 53 printk("\n[ERROR] in %s : user buffer unmapped %x / thread %x / process %x\n", 54 54 __FUNCTION__ , (intptr_t)cycle , this->trdid , process->pid ); 55 vmm_display( process , false );55 hal_vmm_display( process , false ); 56 56 #endif 57 57 this->errno = EFAULT; -
trunk/kernel/syscalls/sys_is_fg.c
r566 r624 67 67 printk("\n[ERROR] in %s : unmapped owner buffer %x / thread %x in process %x\n", 68 68 __FUNCTION__ , (intptr_t)is_fg, this->trdid, process->pid ); 69 vmm_display( process , false );69 hal_vmm_display( process , false ); 70 70 #endif 71 71 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_kill.c
r594 r624 74 74 tm_start = hal_get_cycles(); 75 75 if( DEBUG_SYS_KILL < tm_start ) 76 printk("\n[%s] thread[%x,%x] enter / process %x / %s/ cycle %d\n",77 __FUNCTION__, this->process->pid, this->trdid, pid,78 sig_type_str(sig_id), (uint32_t)tm_start );76 printk("\n[%s] thread[%x,%x] enter : %s to process %x / cycle %d\n", 77 __FUNCTION__, this->process->pid, this->trdid, 78 sig_type_str(sig_id), pid, (uint32_t)tm_start ); 79 79 #endif 80 80 … … 86 86 #if (DEBUG_SYS_KILL & 1) 87 87 if( DEBUG_SYS_KILL < tm_start ) 88 printk("\n[%s] thread[%x,%x] get owner process %x incluster %x\n",88 printk("\n[%s] thread[%x,%x] get target process descriptor %x in owner cluster %x\n", 89 89 __FUNCTION__ , this->process->pid, this->trdid, owner_ptr, owner_cxy ); 90 90 #endif … … 108 108 #if (DEBUG_SYS_KILL & 1) 109 109 if( DEBUG_SYS_KILL < tm_start ) 110 printk("\n[% x] thread[%x,%x] get parent process%x in cluster %x\n",110 printk("\n[%s] thread[%x,%x] get parent process descriptor %x in cluster %x\n", 111 111 __FUNCTION__ , this->process->pid, this->trdid, parent_ptr, parent_cxy ); 112 112 #endif … … 128 128 process_sigaction( pid , BLOCK_ALL_THREADS ); 129 129 130 #if (DEBUG_SYS_KILL & 1) 131 if( DEBUG_SYS_KILL < tm_start ) 132 printk("\n[%s] thread[%x,%x] blocked all threads of process %x\n", 133 __FUNCTION__ , this->process->pid, this->trdid, pid ); 134 #endif 130 135 // atomically update owner process termination state 131 136 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , … … 136 141 137 142 // calling thread deschedules when it is itself a target thread 138 if( this->process->pid == pid ) sched_yield("block itself"); 143 if( this->process->pid == pid ) 144 { 145 146 #if (DEBUG_SYS_KILL & 1) 147 if( DEBUG_SYS_KILL < tm_start ) 148 printk("\n[%s] thread[%x,%x] is a target thread => deschedule\n", 149 __FUNCTION__ , this->process->pid, this->trdid ); 150 #endif 151 sched_yield("block itself"); 152 } 139 153 140 154 break; -
trunk/kernel/syscalls/sys_mmap.c
r623 r624 70 70 printk("\n[ERROR] in %s : thread[%x,%x] / mmap attributes unmapped %x\n", 71 71 __FUNCTION__ , process->pid, this->trdid, (intptr_t)attr ); 72 vmm_display( process , false );72 hal_vmm_display( process , false ); 73 73 #endif 74 74 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_munmap.c
r623 r624 67 67 printk("\n[ERROR] in %s : thread[%x,%x] / user buffer unmapped %x\n", 68 68 __FUNCTION__ , process->pid, this->trdid, (intptr_t)vaddr ); 69 vmm_display( process , false );69 hal_vmm_display( process , false ); 70 70 #endif 71 71 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_mutex.c
r566 r624 74 74 printk("\n[ERROR] in %s : mutex unmapped %x / thread %x / process %x\n", 75 75 __FUNCTION__ , (intptr_t)vaddr , this->trdid , process->pid ); 76 vmm_display( process , false );76 hal_vmm_display( process , false ); 77 77 #endif 78 78 this->errno = error; -
trunk/kernel/syscalls/sys_opendir.c
r614 r624 66 66 printk("\n[ERROR] in %s / thread[%x,%x] : DIR buffer %x unmapped\n", 67 67 __FUNCTION__ , process->pid , this->trdid, dirp ); 68 vmm_display( process , false );68 hal_vmm_display( process , false ); 69 69 #endif 70 70 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_read.c
r610 r624 107 107 printk("\n[ERROR] in %s : thread[%x,%x] user buffer unmapped %x\n", 108 108 __FUNCTION__ , process->pid, this->trdid, (intptr_t)vaddr ); 109 vmm_display( process , false );109 hal_vmm_display( process , false ); 110 110 #endif 111 111 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_readdir.c
r612 r624 69 69 printk("\n[ERROR] in %s / thread[%x,%x] : user buffer %x unmapped\n", 70 70 __FUNCTION__ , process->pid , this->trdid, buffer ); 71 vmm_display( process , false );71 hal_vmm_display( process , false ); 72 72 #endif 73 73 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_sem.c
r566 r624 2 2 * sys_sem.c - Acces a POSIX unamed semaphore. 3 3 * 4 * Authors Alain Greiner (2016,2017,2018 )4 * Authors Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 24 24 #include <hal_kernel_types.h> 25 25 #include <hal_uspace.h> 26 #include <hal_vmm.h> 26 27 #include <shared_semaphore.h> 27 28 #include <errno.h> … … 74 75 printk("\n[ERROR] in %s : unmapped semaphore pointer %x / thread %x in process %x / cycle %d\n", 75 76 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid, (uint32_t)hal_get_cycles() ); 76 vmm_display( process , false );77 hal_vmm_display( process , false ); 77 78 #endif 78 79 this->errno = EINVAL; … … 112 113 printk("\n[ERROR] in %s GETVALUE: unmapped buffer %x / thread %x in process %x / cycle %d\n", 113 114 __FUNCTION__ , (intptr_t)current_value, this->trdid, process->pid, (uint32_t)hal_get_cycles() ); 114 vmm_display( process , false );115 hal_vmm_display( process , false ); 115 116 #endif 116 117 this->errno = EINVAL; … … 154 155 printk("\n[ERROR] in %s WAIT: semaphore %x not found / thread %x in process %x / cycle %d\n", 155 156 __FUNCTION__ , (intptr_t)vaddr, this->trdid, process->pid, (uint32_t)hal_get_cycles() ); 156 vmm_display( process , true );157 hal_vmm_display( process , true ); 157 158 #endif 158 159 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_stat.c
r610 r624 2 2 * sys_stat.c - kernel function implementing the "stat" syscall. 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 24 24 #include <hal_kernel_types.h> 25 25 #include <hal_uspace.h> 26 #include <hal_vmm.h> 26 27 #include <hal_special.h> 27 28 #include <errno.h> … … 61 62 printk("\n[ERROR] in %s / thread[%x,%x] : stat structure %x unmapped\n", 62 63 __FUNCTION__ , process->pid , this->trdid, u_stat ); 63 vmm_display( process , false );64 hal_vmm_display( process , false ); 64 65 #endif 65 66 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_thread_create.c
r619 r624 2 2 * sys_thread_create.c - creates a new user thread 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 25 25 #include <hal_kernel_types.h> 26 26 #include <hal_uspace.h> 27 #include <hal_vmm.h> 27 28 #include <printk.h> 28 29 #include <errno.h> … … 82 83 printk("\n[ERROR] in %s : thread[%x,%x] / trdid buffer %x unmapped %x\n", 83 84 __FUNCTION__, process->pid, parent->trdid, (intptr_t)trdid_ptr ); 84 vmm_display( process , false );85 hal_vmm_display( process , false ); 85 86 #endif 86 87 parent->errno = EINVAL; … … 99 100 printk("\n[ERROR] in %s : thread[%x,%x] / user_attr buffer unmapped %x\n", 100 101 __FUNCTION__, process->pid, parent->trdid, (intptr_t)user_attr ); 101 vmm_display( process , false );102 hal_vmm_display( process , false ); 102 103 #endif 103 104 parent->errno = EINVAL; … … 117 118 printk("\n[ERROR] in %s : thread[%x,%x] / start_func unmapped %x\n", 118 119 __FUNCTION__, process->pid, parent->trdid, (intptr_t)start_func ); 119 vmm_display( process , false );120 hal_vmm_display( process , false ); 120 121 #endif 121 122 parent->errno = EINVAL; … … 134 135 printk("\n[ERROR] in %s : thread[%x,%x] / start_args buffer unmapped %x\n", 135 136 __FUNCTION__, process->pid, parent->trdid, (intptr_t)start_args ); 136 vmm_display( process , false );137 hal_vmm_display( process , false ); 137 138 #endif 138 139 parent->errno = EINVAL; -
trunk/kernel/syscalls/sys_timeofday.c
r506 r624 2 2 * sys_timeofday.c - Get current time 3 3 * 4 * Author Alain Greiner (2016,2017,2018 )4 * Author Alain Greiner (2016,2017,2018,2019) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 24 24 #include <hal_kernel_types.h> 25 25 #include <hal_uspace.h> 26 #include <hal_vmm.h> 26 27 #include <thread.h> 27 28 #include <printk.h> … … 70 71 printk("\n[ERROR] in %s : user buffer tz unmapped / thread %x / process %x\n", 71 72 __FUNCTION__ , (intptr_t)tz , this->trdid , process->pid ); 72 vmm_display( process , false );73 hal_vmm_display( process , false ); 73 74 #endif 74 75 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_wait.c
r566 r624 25 25 #include <hal_uspace.h> 26 26 #include <hal_irqmask.h> 27 #include <hal_vmm.h> 27 28 #include <remote_queuelock.h> 28 29 #include <core.h> … … 68 69 printk("\n[ERROR] in %s : status buffer %x unmapped for thread %x in process %x\n", 69 70 __FUNCTION__ , (intptr_t)status, this->trdid , process->pid ); 70 vmm_display( process , false );71 hal_vmm_display( process , false ); 71 72 #endif 72 73 this->errno = EINVAL; -
trunk/kernel/syscalls/sys_write.c
r623 r624 24 24 #include <kernel_config.h> 25 25 #include <hal_kernel_types.h> 26 #include <hal_vmm.h> 26 27 #include <hal_uspace.h> 27 28 #include <hal_irqmask.h> … … 106 107 printk("\n[ERROR] in %s : thread[%x,%x] user buffer unmapped %x\n", 107 108 __FUNCTION__ , process->pid, this->trdid, (intptr_t)vaddr ); 108 vmm_display( process , false );109 hal_vmm_display( process , false ); 109 110 #endif 110 111 this->errno = EINVAL; -
trunk/libs/mini-libc/stdio.c
r623 r624 52 52 53 53 /////////////////////////////////////////////////// 54 static unsignedint xprintf( char * string,55 unsigned intlength,56 57 58 { 59 unsignedint ps = 0; // write index to the string buffer60 61 #define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return 0xFFFFFFFF; } while(0);54 static int xprintf( char * string, 55 int length, 56 const char * format, 57 va_list * args ) 58 { 59 int ps = 0; // write index to the string buffer 60 61 #define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0); 62 62 63 63 xprintf_text: … … 259 259 default: // unsupported argument type 260 260 { 261 return 0xFFFFFFFF;261 return -1; 262 262 } 263 263 } // end switch on argument type … … 326 326 327 327 va_start( args, format ); 328 count = xprintf( string , length , format , &args );328 count = xprintf( string , (int)length , format , &args ); 329 329 va_end( args ); 330 330 … … 398 398 char string[4096]; 399 399 va_list args; 400 unsigned int count; 400 int count; 401 int writen; 401 402 int fd; 402 403 … … 408 409 va_end( args ); 409 410 410 if ( count == 0xFFFFFFFF)411 if ( count < 0 ) 411 412 { 412 413 display_string( "fprintf : xprintf failure" ); … … 421 422 string[count] = 0; 422 423 423 printf("\n[%s] fd = %d for string :\n", __FUNCTION__, fd, string ); 424 425 return write( fd , &string , count ); 424 printf("\n[%s] fd = %d for string : %s\n", __FUNCTION__, fd, string ); 425 426 idbg(); 427 428 // copy string to file 429 writen = write( fd , &string , count ); 430 431 if( writen != count ) 432 { 433 display_string( "fprintf : write failure" ); 434 return -1; 435 } 436 437 idbg(); 438 439 return writen; 426 440 } 427 441 } // end fprintf() -
trunk/params-hard.mk
r623 r624 3 3 ARCH = /users/alain/soc/tsar-trunk-svn-2013/platforms/tsar_generic_iob 4 4 X_SIZE = 1 5 Y_SIZE = 15 Y_SIZE = 2 6 6 NB_PROCS = 1 7 7 NB_TTYS = 3 -
trunk/user/ksh/ksh.c
r623 r624 14 14 // 15 15 // The children processes are created by the <load> command, and are 16 // attached to the same TXT terminal as the KSH process itself.16 // attached to the same TXT terminal as the parent KSH process. 17 17 // A child process can be lauched in foreground or in background: 18 // . when the child process is runningin foreground, the KSH process loses18 // . when the child process is launched in foreground, the KSH process loses 19 19 // the TXT terminal ownership, that is transfered to the child process. 20 // . when the child process is running in background:the KSH process keeps20 // . when the child process is launched in background, the KSH process keeps 21 21 // the TXT terminal ownership. 22 22 // … … 58 58 #define DEBUG_INTER 0 59 59 #define DEBUG_PARSE 0 60 #define DEBUG_CMD_CAT 160 #define DEBUG_CMD_CAT 0 61 61 #define DEBUG_CMD_CP 0 62 62 #define DEBUG_CMD_LOAD 0 -
trunk/user/sort/sort.c
r623 r624 305 305 } 306 306 307 printf("\n \n[sort] main starts / %d threads / %d items / pid %x / cycle %d\n",307 printf("\n[sort] main starts / %d threads / %d items / pid %x / cycle %d\n", 308 308 total_threads, ARRAY_LENGTH, getpid(), (unsigned int)start_cycle ); 309 309 … … 467 467 468 468 // register results to file 469 fprintf( stream , "\n----- %s -----\n" 470 " - sequencial : %d cycles\n" 471 " - parallel : %d cycles\n", 472 name, sequencial, parallel ); 469 int ret = fprintf( stream , "\n----- %s -----\n" 470 " - sequencial : %d cycles\n" 471 " - parallel : %d cycles\n", name, sequencial, parallel ); 472 if( ret < 0 ) 473 { 474 printf("\n[sort error] cannot write to instrumentation file <%s>\n", name ); 475 exit(0); 476 } 473 477 474 478 // close instrumentation file
Note: See TracChangeset
for help on using the changeset viewer.