Changeset 624 for trunk/boot/tsar_mips32/boot.c
- Timestamp:
- Mar 12, 2019, 1:37:38 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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" );
Note: See TracChangeset
for help on using the changeset viewer.