Changeset 295
- Timestamp:
- Mar 26, 2014, 6:44:44 PM (11 years ago)
- Location:
- soft/giet_vm
- Files:
-
- 9 added
- 47 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/Makefile
r289 r295 11 11 ### partition sectors = 524832 12 12 13 MAP_XML = mappings/4c_ 1p_iob_four.xml13 MAP_XML = mappings/4c_4p_sort_leti_ext.xml 14 14 15 15 ### Objects to be linked for kernel.elf … … 18 18 build/fat32/fat32.o \ 19 19 build/drivers/dma_driver.o \ 20 build/drivers/cma_driver.o \ 20 21 build/drivers/fbf_driver.o \ 21 22 build/drivers/xcu_driver.o \ … … 26 27 build/drivers/sdc_driver.o \ 27 28 build/drivers/spi_driver.o \ 29 build/drivers/rdk_driver.o \ 28 30 build/drivers/iob_driver.o \ 29 31 build/drivers/mmc_driver.o \ … … 32 34 build/drivers/tim_driver.o \ 33 35 build/drivers/tty_driver.o \ 36 build/drivers/pic_driver.o \ 34 37 build/kernel/giet.o \ 35 38 build/kernel/switch.o \ … … 44 47 build/common/vmem.o \ 45 48 build/fat32/fat32.o \ 49 build/drivers/dma_driver.o \ 46 50 build/drivers/tty_driver.o \ 51 build/drivers/pic_driver.o \ 47 52 build/drivers/xcu_driver.o \ 48 build/drivers/dma_driver.o \49 build/drivers/mwr_driver.o \50 53 build/drivers/ioc_driver.o \ 51 54 build/drivers/bdv_driver.o \ 52 build/drivers/hba_driver.o \53 55 build/drivers/sdc_driver.o \ 54 56 build/drivers/spi_driver.o \ 55 build/drivers/ nic_driver.o \57 build/drivers/rdk_driver.o \ 56 58 build/drivers/mmc_driver.o \ 59 build/drivers/mwr_driver.o \ 57 60 build/kernel/ctx_handler.o \ 58 61 build/kernel/switch.o \ … … 96 99 build/libs/barrier.o 97 100 101 ### Objects to be linked for transpose.elf 102 TRANSPOSE_OBJS = build/transpose/main.o \ 103 build/libs/stdio.o \ 104 build/libs/malloc.o \ 105 build/libs/spin_lock.o \ 106 build/libs/barrier.o 98 107 99 108 CFLAGS = -Wall -ffreestanding -mno-gpopt -mips32 … … 123 132 build/gameoflife/gameoflife.elf \ 124 133 build/sort/sort.elf \ 134 build/transpose/transpose.elf \ 125 135 hdd/virt_hdd.dmg 126 136 … … 128 138 ### This requires the generic LINUX/MacOS script "create_dmg" script 129 139 ### written by C.Fuguet. (should be installed in GIET-VM root directory). 130 hdd/virt_hdd.dmg: map.bin \ 131 build/boot/boot.elf \ 132 build/kernel/kernel.elf \ 133 build/display/display.elf \ 134 build/hello/hello.elf \ 135 build/pgcd/pgcd.elf \ 136 build/router/router.elf \ 137 build/dhrystone/dhrystone.elf \ 138 build/gameoflife/gameoflife.elf 140 hdd/virt_hdd.dmg: map.bin \ 141 build/boot/boot.elf \ 142 build/kernel/kernel.elf \ 143 build/display/display.elf \ 144 build/hello/hello.elf \ 145 build/pgcd/pgcd.elf \ 146 build/router/router.elf \ 147 build/dhrystone/dhrystone.elf \ 148 build/gameoflife/gameoflife.elf \ 149 build/sort/sort.elf \ 150 build/transpose/transpose.elf 151 139 152 ### remove all content of virtual disk virt_hdd 140 153 rm -rf hdd/virt_hdd/* … … 162 175 163 176 ### drivers compilation 177 build/drivers/cma_driver.o: giet_drivers/cma_driver.c \ 178 giet_drivers/cma_driver.h \ 179 giet_config.h \ 180 $(MAP_XML) 181 $(CC) $(GIET_INCLUDE) $(CFLAGS) -c -o $@ $< 182 164 183 build/drivers/dma_driver.o: giet_drivers/dma_driver.c \ 165 184 giet_drivers/dma_driver.h \ … … 216 235 $(CC) $(GIET_INCLUDE) $(CFLAGS) -c -o $@ $< 217 236 237 build/drivers/rdk_driver.o: giet_drivers/rdk_driver.c \ 238 giet_drivers/rdk_driver.h \ 239 giet_config.h \ 240 $(MAP_XML) 241 $(CC) $(GIET_INCLUDE) $(CFLAGS) -c -o $@ $< 242 218 243 build/drivers/iob_driver.o: giet_drivers/iob_driver.c \ 219 244 giet_drivers/iob_driver.h \ … … 248 273 build/drivers/tty_driver.o: giet_drivers/tty_driver.c \ 249 274 giet_drivers/tty_driver.h \ 275 giet_config.h \ 276 $(MAP_XML) 277 $(CC) $(GIET_INCLUDE) $(CFLAGS) -c -o $@ $< 278 279 build/drivers/pic_driver.o: giet_drivers/pic_driver.c \ 280 giet_drivers/pic_driver.h \ 250 281 giet_config.h \ 251 282 $(MAP_XML) … … 399 430 400 431 build/sort/main.o: sort/main.c 432 $(CC) $(USER_INCLUDE) $(CFLAGS) -c -o $@ $< 433 434 ### transpose compilation 435 build/transpose/transpose.elf: $(TRANSPOSE_OBJS) transpose/transpose.ld 436 $(LD) -o $@ -T transpose/transpose.ld $(TRANSPOSE_OBJS) 437 $(DU) -D $@ > $@.txt 438 439 build/transpose/main.o: transpose/main.c 401 440 $(CC) $(USER_INCLUDE) $(CFLAGS) -c -o $@ $< 402 441 … … 419 458 rm -rf build/dhrystone/* 420 459 rm -rf build/sort/* 460 rm -rf build/transpose/* 421 461 rm -rf build/map.bin 422 462 rm -rf hdd/virt_hdd/* -
soft/giet_vm/display/main.c
r258 r295 1 #include <stdio.h> 1 #include "stdio.h" 2 #include "hard_config.h" 2 3 3 4 #define NBLOCKS 32 // (128 * 128) / 512 … … 7 8 __attribute__((constructor)) void main() 8 9 { 9 int fd;10 int blocks;11 unsigned int ko;12 unsigned int blocks_to_skip = 8*NBLOCKS;10 int fd; 11 int blocks; 12 unsigned int ko; 13 unsigned int blocks_to_skip = 8*NBLOCKS; 13 14 14 giet_tty_printf("\nStarting task DISPLAY on processor %d at cycle %d\n", 15 giet_procid(), giet_proctime() ); 15 unsigned int procid = giet_procid(); 16 unsigned int cluster_xy = procid/NB_PROCS_MAX; 17 unsigned int lpid = procid%NB_PROCS_MAX; 18 unsigned int x = cluster_xy >> Y_WIDTH; 19 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 20 21 giet_tty_printf( "*** Starting task display on processor[%d,%d,%d] at cycle %d\n\n", 22 x, y, lpid, giet_proctime() ); 16 23 17 24 /////////////////////////////////////////// -
soft/giet_vm/display/main_cma.c
r258 r295 1 #include <stdio.h> 1 #include "stdio.h" 2 #include "hard_config.h" 2 3 3 4 #define NBLOCKS 32 … … 8 9 __attribute__((constructor)) void main(void) 9 10 { 10 unsigned int ko; 11 int blocks; 12 int fd; 13 unsigned int blocks_to_skip = 0; 11 int fd; 12 unsigned int blocks_to_skip = 0; 13 unsigned int procid = giet_procid(); 14 unsigned int cluster_xy = procid/NB_PROCS_MAX; 15 unsigned int lpid = procid%NB_PROCS_MAX; 16 unsigned int x = cluster_xy >> Y_WIDTH; 17 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 14 18 15 giet_tty_printf( "\nStarting task DISPLAY on processor %d at cycle %d\n",16 giet_procid(), giet_proctime() );19 giet_tty_printf( "*** Starting task display on processor[%d,%d,%d] at cycle %d\n\n", 20 x, y, lpid, giet_proctime() ); 17 21 18 22 ////////////////////////////////////////// … … 30 34 } 31 35 32 //////////////////////////////////////////// 33 ko = giet_fb_cma_init( buf0, buf1, 128*128 ); 34 if ( ko ) 35 { 36 giet_tty_printf("\n*** echec giet_cma_init at cycle %d\n", 36 //////////////////////////////////////// 37 giet_fb_cma_init( buf0, buf1, 128*128 ); 38 39 giet_tty_printf("\ngiet_cma_init completed at cycle %d\n", 37 40 giet_proctime() ); 38 giet_exit();39 }40 else41 {42 giet_tty_printf("\ngiet_cma_init completed at cycle %d\n",43 giet_proctime() );44 }45 46 41 47 42 while ( blocks_to_skip < 10 * NBLOCKS ) 48 43 { 49 //////////////////////////////////////////////////////////// 50 blocks = giet_fat_read( fd, buf0, NBLOCKS, blocks_to_skip ); 51 if ( blocks != NBLOCKS ) 52 { 53 giet_tty_printf("\nechec giet_fat_read to buf0 at cycle %d\n", 44 /////////////////////////////////////////////////// 45 giet_fat_read( fd, buf0, NBLOCKS, blocks_to_skip ); 46 47 giet_tty_printf("\ngiet_fat_read to buf0 completed at cycle = %d\n", 54 48 giet_proctime() ); 55 giet_exit(); 56 }57 else58 { 59 giet_tty_printf("\ngiet_fat_read tobuf0 completed at cycle = %d\n",49 50 /////////////////////// 51 giet_fb_cma_write( 0 ); 52 53 giet_tty_printf("giet_cma_write for buf0 completed at cycle = %d\n", 60 54 giet_proctime() ); 61 }62 63 ///////////////////////////64 ko = giet_fb_cma_write( 0 );65 if ( ko )66 {67 giet_tty_printf("echec giet_cma_write for buf0 at cycle %d\n",68 giet_proctime() );69 giet_exit();70 }71 else72 {73 giet_tty_printf("giet_cma_write for buf0 completed at cycle = %d\n",74 giet_proctime() );75 }76 55 77 56 blocks_to_skip = blocks_to_skip + NBLOCKS; 78 57 79 /////////////////////////////////////////////////////// 80 blocks = giet_fat_read( fd, buf1, NBLOCKS, blocks_to_skip ); 81 if ( blocks != NBLOCKS ) 82 { 83 giet_tty_printf("echec giet_fat_read to buf1 at cycle %d\n", 58 /////////////////////////////////////////////////// 59 giet_fat_read( fd, buf1, NBLOCKS, blocks_to_skip ); 60 61 giet_tty_printf("giet_fat_read to buf1 completed at cycle = %d\n", 84 62 giet_proctime() ); 85 giet_exit(); 86 }87 else88 {89 giet_tty_printf("giet_fat_read tobuf1 completed at cycle = %d\n",63 64 /////////////////////// 65 giet_fb_cma_write( 1 ); 66 67 giet_tty_printf("giet_cma_write for buf1 completed at cycle = %d\n", 90 68 giet_proctime() ); 91 }92 69 93 ////////////////////////////94 ko = giet_fb_cma_write( 1 );95 if ( ko )96 {97 giet_tty_printf("echec giet_cma_write for buf1 at cycle %d\n",98 giet_proctime() );99 giet_exit();100 }101 else102 {103 giet_tty_printf("giet_cma_write for buf1 completed at cycle = %d\n",104 giet_proctime() );105 }106 70 blocks_to_skip = blocks_to_skip + NBLOCKS; 107 71 } -
soft/giet_vm/gameoflife/main.c
r263 r295 20 20 21 21 giet_barrier_t barriers[2]; 22 23 unsigned int init_ok = 1; 22 24 23 25 #define NEW 0 … … 80 82 } 81 83 84 ////////////////////////////////////////////////////// 82 85 void compute_new_gen(size_t base_line, size_t nb_line) 83 86 { 84 87 size_t x,y; 85 for (y = base_line; y < base_line + nb_line; y++){ 86 for(x = 0; x < WIDTH ; x++) { 88 for (y = base_line; y < base_line + nb_line; y++) 89 { 90 for(x = 0; x < WIDTH ; x++) 91 { 87 92 world[NEW][y][x] = compute_cell(x,y); 88 93 } … … 90 95 } 91 96 97 //////////////////////////////////////////////////// 92 98 void display_world(size_t base_line, size_t nb_line) 93 99 { … … 100 106 } 101 107 102 if (giet_fb_sync_write(base_line * WIDTH , &world[NEW][base_line][0], nb_line * WIDTH)) 103 { 104 PRINTF("Echec fb_sync_write\n"); 105 giet_exit(); 106 } 107 // TODO COLOR ! 108 /*if (giet_fb_sync_write(base_line * WIDTH + WIDTH*HEIGHT , &world_yuv[base_line][0], nb_line * WIDTH)) 109 { 110 PRINTF("Echec fb_sync_write\n"); 111 giet_exit(); 112 }*/ 108 giet_fb_sync_write( base_line * WIDTH , 109 &world[NEW][base_line][0], 110 nb_line * WIDTH); 113 111 } 114 112 113 ///////////////////////////////////////////////////// 115 114 void grow_old_world(size_t base_line, size_t nb_line) 116 115 { 117 116 size_t x,y; 118 for (y = base_line; y < base_line + nb_line; y++){ 119 for(x = 0; x < WIDTH ; x++) { 117 for (y = base_line; y < base_line + nb_line; y++) 118 { 119 for(x = 0; x < WIDTH ; x++) 120 { 120 121 world[OLD][y][x] = world[NEW][y][x]; 121 122 } 122 123 } 123 124 } 124 125 126 125 127 126 //////////////////////////////////////// … … 131 130 unsigned int nlocal_procs = NB_PROCS_MAX; // processors per cluster 132 131 unsigned int nclusters = X_SIZE*Y_SIZE; // number of clusters 133 unsigned int local_id = proc_id % nlocal_procs; // local processor id134 unsigned int cluster_id = proc_id / nlocal_procs; // cluster id135 132 unsigned int nglobal_procs = nclusters * nlocal_procs; // number of tasks 136 133 size_t i; … … 142 139 143 140 // barriers initialization 144 barrier_init(&barriers[0], nglobal_procs); 145 barrier_init(&barriers[1], nglobal_procs); 141 if ( proc_id == 0 ) 142 { 143 barrier_init(&barriers[0], nglobal_procs); 144 barrier_init(&barriers[1], nglobal_procs); 145 146 init_ok = 0; 147 } 148 else 149 { 150 while ( init_ok == 1 ); 151 } 152 146 153 init_world(base_line, nb_line); 147 154 -
soft/giet_vm/giet_boot/boot.c
r293 r295 68 68 /////////////////////////////////////////////////////////////////////////////////////// 69 69 70 // for vobjs initialisation71 70 #include <giet_config.h> 72 71 #include <mwmr_channel.h> … … 80 79 #include <nic_driver.h> 81 80 #include <ioc_driver.h> 81 #include <pic_driver.h> 82 82 #include <mwr_driver.h> 83 83 #include <ctx_handler.h> … … 874 874 _putx( curr->length ); 875 875 _puts(" / vbase "); 876 _put l( curr->vbase );876 _putx( curr->vbase ); 877 877 _puts(" / pbase "); 878 878 _putl( curr->pbase ); … … 894 894 boot_vspace_pt_build(vspace_id); 895 895 896 _puts("\n[BOOT] Page Table for vspace ");896 _puts("\n[BOOT] Page Table for vspace \""); 897 897 _puts( vspace[vspace_id].name ); 898 _puts(" completed at cycle ");898 _puts("\" completed at cycle "); 899 899 _putd( _get_proctime() ); 900 900 _puts("\n"); … … 1149 1149 mapping_task_t* task = _get_task_base(header); 1150 1150 mapping_vobj_t* vobj = _get_vobj_base(header); 1151 mapping_p roc_t* proc = _get_proc_base(header);1151 mapping_periph_t* periph = _get_periph_base(header); 1152 1152 mapping_irq_t* irq = _get_irq_base(header); 1153 1153 1154 1154 unsigned int cluster_id; // cluster index in mapping_info 1155 unsigned int p roc_id; // processor index in mapping_info1155 unsigned int periph_id; // peripheral index in mapping_info 1156 1156 unsigned int irq_id; // irq index in mapping_info 1157 1157 unsigned int vspace_id; // vspace index in mapping_info … … 1163 1163 // are reserved for the kernel (context switch) 1164 1164 1165 unsigned int alloc_tty_channel = 0; // TTY channel allocator 1166 unsigned int alloc_nic_channel = 0; // NIC channel allocator 1167 unsigned int alloc_cma_channel = 0; // CMA channel allocator 1168 unsigned int alloc_hba_channel = 0; // IOC channel allocator 1169 unsigned int alloc_tim_channel[X_SIZE*Y_SIZE]; // user TIMER allocators 1170 1171 if (NB_TTY_CHANNELS > 1) alloc_tty_channel++; 1165 unsigned int alloc_tty_channel = 1; // TTY channel allocator 1166 unsigned int alloc_nic_channel = 0; // NIC channel allocator 1167 unsigned int alloc_cma_channel = 0; // CMA channel allocator 1168 unsigned int alloc_hba_channel = 0; // HBA channel allocator 1169 unsigned int alloc_tim_channel[X_SIZE*Y_SIZE]; // user TIMER allocators 1172 1170 1173 1171 ///////////////////////////////////////////////////////////////////////// … … 1198 1196 alloc_tim_channel[cluster_id] = NB_PROCS_MAX; 1199 1197 1200 unsigned int lpid; // processor local index in cluster1201 unsigned int sched_vbase; // schedulers segment virtual base address1202 unsigned int sched_length; // schedulers segment length1203 unsigned int nprocs; // number of processors in cluster1204 1205 nprocs = cluster[cluster_id].procs;1206 1207 1198 // checking processors number 1208 if ( nprocs > NB_PROCS_MAX )1199 if ( cluster[cluster_id].procs > NB_PROCS_MAX ) 1209 1200 { 1210 1201 _puts("\n[BOOT ERROR] Too much processors in cluster["); … … 1216 1207 } 1217 1208 1218 // get scheduler array virtual base address and length 1219 boot_get_sched_vaddr( cluster_id, &sched_vbase, &sched_length ); 1220 1221 // each processor scheduler requires 4 Kbytes 1222 if ( sched_length < (nprocs<<12) ) 1223 { 1224 _puts("\n[BOOT ERROR] Schedulers segment too small in cluster["); 1225 _putd( x ); 1226 _puts(","); 1227 _putd( y ); 1228 _puts("]\n"); 1229 _exit(); 1230 } 1231 1232 // loop on processors 1233 for ( proc_id = cluster[cluster_id].proc_offset, lpid = 0 ; 1234 proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs; 1235 proc_id++, lpid++ ) 1236 { 1237 // current processor scheduler pointer : psched 1238 static_scheduler_t* psched = (static_scheduler_t*)(sched_vbase+(lpid<<12)); 1239 1240 // set the schedulers pointers array 1241 _schedulers[cluster_xy * NB_PROCS_MAX + lpid] = psched; 1209 static_scheduler_t* psched; // schedulers array base address in cluster 1210 1211 // no schedulers initialisation if nprocs == 0 1212 if ( cluster[cluster_id].procs > 0 ) 1213 { 1214 // get scheduler array virtual base address and length 1215 unsigned int sched_vbase; // schedulers segment virtual base address 1216 unsigned int sched_length; // schedulers segment length 1217 boot_get_sched_vaddr( cluster_id, &sched_vbase, &sched_length ); 1218 1219 if ( sched_length < (cluster[cluster_id].procs<<12) ) // 4 Kbytes per scheduler 1220 { 1221 _puts("\n[BOOT ERROR] Schedulers segment too small in cluster["); 1222 _putd( x ); 1223 _puts(","); 1224 _putd( y ); 1225 _puts("]\n"); 1226 _exit(); 1227 } 1228 1229 psched = (static_scheduler_t*)sched_vbase; 1230 1231 // scan cluster peripherals to find the ICU/XCU 1232 unsigned int found = 0; 1233 for ( periph_id = cluster[cluster_id].periph_offset ; 1234 periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs; 1235 periph_id++ ) 1236 { 1237 if( (periph[periph_id].type == PERIPH_TYPE_XCU) || 1238 (periph[periph_id].type == PERIPH_TYPE_ICU) ) 1239 { 1240 found = 1; 1241 break; 1242 } 1243 } 1244 if ( found == 0 ) 1245 { 1246 _puts("\n[BOOT ERROR] No ICU / XCU component in cluster["); 1247 _putd( x ); 1248 _puts(","); 1249 _putd( y ); 1250 _puts("]\n"); 1251 _exit(); 1252 } 1253 1254 // loop on schedulers for default values initialisation 1255 unsigned int lpid; 1256 for ( lpid = 0 ; lpid < cluster[cluster_id].procs ; lpid++ ) 1257 { 1258 // set the schedulers pointers array 1259 _schedulers[cluster_xy * NB_PROCS_MAX + lpid] = 1260 (static_scheduler_t*)&psched[lpid]; 1242 1261 1243 1262 #if BOOT_DEBUG_SCHED 1244 _puts("\nProc _");1263 _puts("\nProc["); 1245 1264 _putd( x ); 1246 _puts(" _");1265 _puts(","); 1247 1266 _putd( y ); 1248 _puts(" _");1267 _puts(","); 1249 1268 _putd( lpid ); 1250 _puts(" : scheduler virtual base address = "); 1251 _putx( sched_vbase + (lpid<<12) ); 1252 _puts("\n"); 1253 #endif 1254 1255 // initialise the "tasks" variable : default value is 0 1256 psched->tasks = 0; 1257 1258 // initialise the "current" variable : default value is idle_task 1259 psched->current = IDLE_TASK_INDEX; 1260 1261 // initialise interrupt_vector with default value (valid bit = 0) 1262 unsigned int slot; 1263 for (slot = 0; slot < 32; slot++) psched->interrupt_vector[slot] = 0; 1264 1265 // initialise interrupt vector with the IRQs actually allocated 1266 for (irq_id = proc[proc_id].irq_offset; 1267 irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs; 1268 irq_id++) 1269 _puts("] : scheduler virtual base address = "); 1270 _putx( (unsigned int)&psched[lpid] ); 1271 _puts("\n"); 1272 #endif 1273 // initialise the "tasks" and "current" variables default values 1274 psched[lpid].tasks = 0; 1275 psched[lpid].current = IDLE_TASK_INDEX; 1276 1277 // initialise HWI / PTI / SWI vectors (valid bit = 0) 1278 unsigned int slot; 1279 for (slot = 0; slot < 32; slot++) 1280 { 1281 psched[lpid].hwi_vector[slot] = 0; 1282 psched[lpid].pti_vector[slot] = 0; 1283 psched[lpid].wti_vector[slot] = 0; 1284 } 1285 1286 // initializes the idle_task context in scheduler: 1287 // - the SR slot is 0xFF03 because this task run in kernel mode. 1288 // - it uses the page table of vspace[0] 1289 // - it uses the kernel TTY terminal 1290 // - slots containing addresses (SP, RA, EPC, PTAB, PTPR) 1291 // must be re-initialised by kernel_parallel_init() 1292 1293 psched[lpid].context[IDLE_TASK_INDEX][CTX_CR_ID] = 0; 1294 psched[lpid].context[IDLE_TASK_INDEX][CTX_SR_ID] = 0xFF03; 1295 psched[lpid].context[IDLE_TASK_INDEX][CTX_PTPR_ID] = _ptabs_paddr[0]>>13; 1296 psched[lpid].context[IDLE_TASK_INDEX][CTX_PTAB_ID] = _ptabs_vaddr[0]; 1297 psched[lpid].context[IDLE_TASK_INDEX][CTX_TTY_ID] = 0; 1298 psched[lpid].context[IDLE_TASK_INDEX][CTX_LTID_ID] = IDLE_TASK_INDEX; 1299 psched[lpid].context[IDLE_TASK_INDEX][CTX_VSID_ID] = 0; 1300 psched[lpid].context[IDLE_TASK_INDEX][CTX_RUN_ID] = 1; 1301 } 1302 1303 1304 // loop on irqs for actual HWI / PTI / WTI vectors initialisation 1305 for ( irq_id = periph[periph_id].irq_offset ; 1306 irq_id < periph[periph_id].irq_offset + periph[periph_id].irqs ; 1307 irq_id++ ) 1269 1308 { 1270 unsigned int type = irq[irq_id].type; 1271 unsigned int icu_id = irq[irq_id].icuid; 1272 unsigned int isr_id = irq[irq_id].isr; 1309 unsigned int lpid = irq[irq_id].dstid; 1310 unsigned int dstx = irq[irq_id].dstx; 1311 unsigned int dsty = irq[irq_id].dsty; 1312 if ( (dstx != x) || (dsty != y) ) 1313 { 1314 _puts("\n[BOOT ERROR] Bad IRQ cluster coordinates in cluster["); 1315 _putd( x ); 1316 _puts(","); 1317 _putd( y ); 1318 _puts("]\n - dstx = "); 1319 _putd( dstx ); 1320 _puts("\n - dsty = "); 1321 _putd( dsty ); 1322 _puts("\n - x = "); 1323 _putd( x ); 1324 _puts("\n - y = "); 1325 _putd( y ); 1326 _puts("\n"); 1327 _exit(); 1328 } 1329 if ( lpid >= cluster[cluster_id].procs ) 1330 { 1331 _puts("\n[BOOT ERROR] Bad IRQ processor index in cluster["); 1332 _putd( x ); 1333 _puts(","); 1334 _putd( y ); 1335 _puts("]\n"); 1336 _exit(); 1337 } 1338 unsigned int type = irq[irq_id].srctype; 1339 unsigned int index = irq[irq_id].srcid; 1340 unsigned int isr = irq[irq_id].isr; 1273 1341 unsigned int channel = irq[irq_id].channel; 1274 1342 1275 unsigned int value = ((isr_id & 0xFF) ) | 1276 ((type & 0xFF) << 8) | 1343 unsigned int entry = ((isr & 0xFFFF) ) | 1277 1344 ((channel & 0x7FFF) << 16) | 1278 1345 0x80000000; // Valid entry 1279 1346 1280 psched->interrupt_vector[icu_id] = value; 1347 if (type == IRQ_TYPE_HWI) psched[lpid].hwi_vector[index] = entry; 1348 else if (type == IRQ_TYPE_PTI) psched[lpid].pti_vector[index] = entry; 1349 else if (type == IRQ_TYPE_WTI) psched[lpid].wti_vector[index] = entry; 1281 1350 1282 1351 #if BOOT_DEBUG_SCHED 1283 _puts("- IRQ : icu= ");1284 _putd( icu_id);1285 _puts(" / type= ");1286 _putd( type);1352 _puts("- IRQ : type = "); 1353 _putd( type ); 1354 _puts(" / index = "); 1355 _putd( index ); 1287 1356 _puts(" / isr = "); 1288 _putd( isr_id);1357 _putd( isr ); 1289 1358 _puts(" / channel = "); 1290 _putd(channel); 1291 _puts(" => vector_entry = "); 1292 _putx( value ); 1293 _puts("\n"); 1294 #endif 1295 } 1296 1297 // initializes the idle_task context in scheduler: 1298 // - the SR slot is 0xFF03 because this task run in kernel mode. 1299 // - it uses the page table of vspace[0] 1300 // - it uses the kernel TTY terminal 1301 // - slots containing addresses (SP, RA, EPC, PTAB, PTPR) 1302 // must be re-initialised by kernel_parallel_init() 1303 1304 psched->context[IDLE_TASK_INDEX][CTX_CR_ID] = 0; 1305 psched->context[IDLE_TASK_INDEX][CTX_SR_ID] = 0xFF03; 1306 psched->context[IDLE_TASK_INDEX][CTX_PTPR_ID] = _ptabs_paddr[0]>>13; 1307 psched->context[IDLE_TASK_INDEX][CTX_PTAB_ID] = _ptabs_vaddr[0]; 1308 psched->context[IDLE_TASK_INDEX][CTX_TTY_ID] = 0; 1309 psched->context[IDLE_TASK_INDEX][CTX_LTID_ID] = IDLE_TASK_INDEX; 1310 psched->context[IDLE_TASK_INDEX][CTX_VSID_ID] = 0; 1311 psched->context[IDLE_TASK_INDEX][CTX_RUN_ID] = 1; 1312 1313 } // end for procs 1359 _putd( channel ); 1360 _puts("\n"); 1361 #endif 1362 1363 } // end for irqs 1364 } // end if nprocs > 0 1314 1365 } // end for clusters 1315 1366 1316 1367 /////////////////////////////////////////////////////////////////// 1317 // Step 2 : loop on the vspaces and the tasks 1318 // t o initialise the schedulers and the task contexts.1368 // Step 2 : loop on the vspaces and the tasks to complete 1369 // the schedulers and task contexts initialisation. 1319 1370 1320 1371 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) … … 1329 1380 task_id++) 1330 1381 { 1331 1332 // compute the cluster coordinates 1382 // compute the cluster coordinates & local processor index 1333 1383 unsigned int x = cluster[task[task_id].clusterid].x; 1334 1384 unsigned int y = cluster[task[task_id].clusterid].y; 1335 1385 unsigned int cluster_xy = (x<<Y_WIDTH) + y; 1386 unsigned int lpid = task[task_id].proclocid; 1336 1387 1337 1388 #if BOOT_DEBUG_SCHED … … 1347 1398 #endif 1348 1399 // compute gpid (global processor index) and scheduler base address 1349 unsigned int gpid = cluster_xy * NB_PROCS_MAX + task[task_id].proclocid;1400 unsigned int gpid = cluster_xy * NB_PROCS_MAX + lpid; 1350 1401 static_scheduler_t* psched = _schedulers[gpid]; 1351 1402 … … 1360 1411 1361 1412 // ctx_tty : TTY terminal global index provided by the global allocator 1413 // Each user terminal is a private ressource: the number of 1414 // requested terminal cannot be larger than NB_TTY_CHANNELS. 1362 1415 unsigned int ctx_tty = 0xFFFFFFFF; 1363 1416 if (task[task_id].use_tty) … … 1365 1418 if (alloc_tty_channel >= NB_TTY_CHANNELS) 1366 1419 { 1367 _puts("\n[BOOT ERROR] TTY index too large for task ");1420 _puts("\n[BOOT ERROR] TTY channel index too large for task "); 1368 1421 _puts(task[task_id].name); 1369 1422 _puts(" in vspace "); … … 1373 1426 } 1374 1427 ctx_tty = alloc_tty_channel; 1375 if (NB_TTY_CHANNELS > 1) alloc_tty_channel++; 1376 } 1428 alloc_tty_channel++; 1429 } 1430 1377 1431 // ctx_nic : NIC channel global index provided by the global allocator 1432 // Each channel is a private ressource: the number of 1433 // requested channels cannot be larger than NB_NIC_CHANNELS. 1378 1434 unsigned int ctx_nic = 0xFFFFFFFF; 1379 1435 if (task[task_id].use_nic) … … 1391 1447 alloc_nic_channel++; 1392 1448 } 1449 1393 1450 // ctx_cma : CMA channel global index provided by the global allocator 1451 // Each channel is a private ressource: the number of 1452 // requested channels cannot be larger than NB_NIC_CHANNELS. 1394 1453 unsigned int ctx_cma = 0xFFFFFFFF; 1395 1454 if (task[task_id].use_cma) … … 1407 1466 alloc_cma_channel++; 1408 1467 } 1468 1409 1469 // ctx_hba : HBA channel global index provided by the global allocator 1470 // Each channel is a private ressource: the number of 1471 // requested channels cannot be larger than NB_NIC_CHANNELS. 1410 1472 unsigned int ctx_hba = 0xFFFFFFFF; 1411 1473 if (task[task_id].use_hba) 1412 1474 { 1413 if (alloc_hba_channel >= NB_ HBA_CHANNELS)1475 if (alloc_hba_channel >= NB_IOC_CHANNELS) 1414 1476 { 1415 1477 _puts("\n[BOOT ERROR] IOC channel index too large for task "); … … 1423 1485 alloc_hba_channel++; 1424 1486 } 1425 // ctx_tim : TIM local channel index provided by the cluster allocator 1487 // ctx_tim : TIMER local channel index provided by the cluster allocator 1488 // Each timer is a private ressource 1426 1489 unsigned int ctx_tim = 0xFFFFFFFF; 1427 1490 if (task[task_id].use_tim) … … 1438 1501 _exit(); 1439 1502 } 1440 1441 // checking that there is an ISR_TIMER installed 1442 unsigned int found = 0; 1443 for ( irq_id = 0 ; irq_id < 32 ; irq_id++ ) 1444 { 1445 unsigned int entry = psched->interrupt_vector[irq_id]; 1446 unsigned int isr = entry & 0x000000FF; 1447 unsigned int channel = entry>>16; 1448 if ( (isr == ISR_TIMER) && (channel == alloc_tim_channel[cluster_id]) ) 1449 { 1450 found = 1; 1451 ctx_tim = alloc_tim_channel[cluster_id]; 1452 alloc_tim_channel[cluster_id]++; 1453 break; 1454 } 1455 } 1456 if (!found) 1457 { 1458 _puts("\n[BOOT ERROR] No ISR_TIMER installed for task "); 1459 _puts(task[task_id].name); 1460 _puts(" in vspace "); 1461 _puts(vspace[vspace_id].name); 1462 _puts("\n"); 1463 _exit(); 1464 } 1503 ctx_tim = alloc_tim_channel[cluster_id]; 1504 alloc_tim_channel[cluster_id]++; 1465 1505 } 1466 1506 // ctx_epc : Get the virtual address of the memory location containing … … 1520 1560 _puts("\nTask "); 1521 1561 _putd( task_id ); 1522 _puts(" allocated to processor "); 1523 _putd( gpid ); 1524 _puts("\n - ctx[LTID] = "); 1562 _puts(" allocated to processor["); 1563 _putd( x ) 1564 _puts(","); 1565 _putd( y ) 1566 _puts(","); 1567 _putd( lpid ) 1568 _puts("]\n - ctx[LTID] = "); 1525 1569 _putd( psched->context[ltid][CTX_LTID_ID] ); 1526 1570 _puts("\n - ctx[SR] = "); … … 1533 1577 _putx( psched->context[ltid][CTX_PTPR_ID] ); 1534 1578 _puts("\n - ctx[TTY] = "); 1535 _put d( psched->context[ltid][CTX_TTY_ID] );1579 _putx( psched->context[ltid][CTX_TTY_ID] ); 1536 1580 _puts("\n - ctx[NIC] = "); 1537 _put d( psched->context[ltid][CTX_NIC_ID] );1581 _putx( psched->context[ltid][CTX_NIC_ID] ); 1538 1582 _puts("\n - ctx[CMA] = "); 1539 _put d( psched->context[ltid][CTX_CMA_ID] );1583 _putx( psched->context[ltid][CTX_CMA_ID] ); 1540 1584 _puts("\n - ctx[IOC] = "); 1541 _put d( psched->context[ltid][CTX_HBA_ID] );1585 _putx( psched->context[ltid][CTX_HBA_ID] ); 1542 1586 _puts("\n - ctx[TIM] = "); 1543 _put d( psched->context[ltid][CTX_TIM_ID] );1587 _putx( psched->context[ltid][CTX_TIM_ID] ); 1544 1588 _puts("\n - ctx[PTAB] = "); 1545 1589 _putx( psched->context[ltid][CTX_PTAB_ID] ); 1546 1590 _puts("\n - ctx[GTID] = "); 1547 _put d( psched->context[ltid][CTX_GTID_ID] );1591 _putx( psched->context[ltid][CTX_GTID_ID] ); 1548 1592 _puts("\n - ctx[VSID] = "); 1549 _put d( psched->context[ltid][CTX_VSID_ID] );1593 _putx( psched->context[ltid][CTX_VSID_ID] ); 1550 1594 _puts("\n - ctx[TRDID] = "); 1551 _put d( psched->context[ltid][CTX_TRDID_ID] );1595 _putx( psched->context[ltid][CTX_TRDID_ID] ); 1552 1596 _puts("\n"); 1553 1597 #endif … … 1565 1609 _ioc_init( 0 ); 1566 1610 1567 int fd_id = _fat_open( IOC_BOOT_ PA_MODE,1611 int fd_id = _fat_open( IOC_BOOT_MODE, 1568 1612 "map.bin", 1569 1613 0 ); // no creation … … 1586 1630 if ( offset ) nblocks++; 1587 1631 1588 unsigned int ok = _fat_read( IOC_BOOT_ PA_MODE,1632 unsigned int ok = _fat_read( IOC_BOOT_MODE, 1589 1633 fd_id, 1590 1634 (unsigned int*)( &seg_boot_mapping_base), … … 1781 1825 // The "preloader.elf" file is not loaded, because it has been burned in the ROM. 1782 1826 // The "boot.elf" file is not loaded, because it has been loaded by the preloader. 1783 // Itscans all vobjs defined in the map.bin data structure to collect1827 // This function scans all vobjs defined in the map.bin data structure to collect 1784 1828 // all .elf files pathnames, and calls the load_one_elf_file() function to 1785 1829 // load all loadable segments at the virtual address found in the .elf file. … … 1813 1857 } 1814 1858 1815 load_one_elf_file( IOC_BOOT_ VA_MODE,1859 load_one_elf_file( IOC_BOOT_MODE, 1816 1860 vobj[vobj_id].binpath, 1817 1861 0 ); // vspace 0 1818 1862 1819 _puts("\n[BOOT] File ");1863 _puts("\n[BOOT] File \""); 1820 1864 _puts( vobj[vobj_id].binpath ); 1821 _puts(" loaded at cycle ");1865 _puts("\" loaded at cycle "); 1822 1866 _putd( _get_proctime() ); 1823 1867 _puts("\n"); … … 1852 1896 } 1853 1897 1854 load_one_elf_file( IOC_BOOT_ VA_MODE,1898 load_one_elf_file( IOC_BOOT_MODE, 1855 1899 vobj[vobj_id].binpath, 1856 1900 vspace_id ); 1857 1901 1858 _puts("\n[BOOT] File ");1902 _puts("\n[BOOT] File \""); 1859 1903 _puts( vobj[vobj_id].binpath ); 1860 _puts(" loaded at cycle ");1904 _puts("\" loaded at cycle "); 1861 1905 _putd( _get_proctime() ); 1862 1906 _puts("\n"); … … 1882 1926 mapping_coproc_t * coproc = _get_coproc_base(header); 1883 1927 mapping_cp_port_t * cp_port = _get_cp_port_base(header); 1928 mapping_irq_t * irq = _get_irq_base(header); 1884 1929 1885 1930 unsigned int cluster_id; … … 2001 2046 case PERIPH_TYPE_TTY: // vci_multi_tty component 2002 2047 { 2048 // nothing to do 2003 2049 #if BOOT_DEBUG_PERI 2004 2050 _puts("- TTY / channels = "); … … 2025 2071 _puts("\n"); 2026 2072 #endif 2073 break; 2074 } 2075 case PERIPH_TYPE_PIC: // vci_iopic component 2076 { 2077 2078 #if BOOT_DEBUG_PERI 2079 _puts("- PIC / channels = "); 2080 _putd(channels); 2081 _puts("\n"); 2082 #endif 2083 // scan all HWI IRQs defined in mapping for PIC component, 2084 // and initialises addresses for WTI IRQs 2085 for ( channel_id = periph[periph_id].irq_offset ; 2086 channel_id < periph[periph_id].irq_offset + periph[periph_id].irqs ; 2087 channel_id++ ) 2088 { 2089 unsigned int hwi_id = irq[channel_id].srcid; // HWI index in PIC 2090 unsigned int wti_id = irq[channel_id].dstid; // WTI index in XCU 2091 unsigned int x = irq[channel_id].dstx; // XCU X coordinate 2092 unsigned int y = irq[channel_id].dsty; // XCU Y coordinate 2093 unsigned int cluster = (x<<Y_WIDTH) + y; // XCU cluster 2094 unsigned int vaddr; 2095 2096 _xcu_get_wti_address( wti_id, &vaddr ); 2097 2098 _pic_init( hwi_id, vaddr, cluster ); 2099 #if BOOT_DEBUG_PERI 2100 _puts(" hwi_index = "); 2101 _putd( hwi_id ); 2102 _puts(" / wti_index = "); 2103 _putd( wti_id ); 2104 _puts(" / vaddr = "); 2105 _putx( vaddr ); 2106 _puts(" in cluster["); 2107 _putd( x ); 2108 _puts(","); 2109 _putd( y ); 2110 _puts("]\n"); 2111 #endif 2112 } 2027 2113 break; 2028 2114 } … … 2089 2175 void boot_init() 2090 2176 { 2091 mapping_header_t* header = (mapping_header_t *) & seg_boot_mapping_base; 2092 unsigned int gpid = _get_procid(); 2093 unsigned int cluster_xy = gpid / NB_PROCS_MAX; 2094 unsigned int lpid = gpid % NB_PROCS_MAX; 2177 mapping_header_t* header = (mapping_header_t *) & seg_boot_mapping_base; 2178 mapping_cluster_t* cluster = _get_cluster_base(header); 2179 unsigned int gpid = _get_procid(); 2095 2180 2096 2181 if ( gpid == 0 ) // only Processor 0 does it … … 2103 2188 boot_mapping_init(); 2104 2189 2105 _puts("\n[BOOT] Mapping ");2190 _puts("\n[BOOT] Mapping \""); 2106 2191 _puts( header->name ); 2107 _puts(" loaded at cycle ");2192 _puts("\" loaded at cycle "); 2108 2193 _putd(_get_proctime()); 2109 2194 _puts("\n"); … … 2111 2196 // Building all page tables 2112 2197 boot_pt_init(); 2113 2114 _puts("\n[BOOT] Page Tables initialisation completed at cycle ");2115 _putd(_get_proctime());2116 _puts("\n");2117 2198 2118 2199 // Activating proc 0 MMU … … 2134 2215 boot_schedulers_init(); 2135 2216 2136 _puts("\n[BOOT] All schedulers initialised at cycle ");2217 _puts("\n[BOOT] Schedulers initialised at cycle "); 2137 2218 _putd(_get_proctime()); 2138 2219 _puts("\n"); … … 2144 2225 boot_peripherals_init(); 2145 2226 2146 _puts("\n[BOOT] Allperipherals initialised at cycle ");2227 _puts("\n[BOOT] Non replicated peripherals initialised at cycle "); 2147 2228 _putd(_get_proctime()); 2148 2229 _puts("\n"); … … 2151 2232 boot_elf_load(); 2152 2233 2153 _puts("\n[BOOT] All ELF files loaded at cycle ");2154 _putd(_get_proctime());2155 _puts("\n");2156 2157 2234 // P0 starts all other processors 2158 unsigned int x,y,p; 2159 for (x = 0 ; x < X_SIZE ; x++) 2160 { 2161 for (y = 0 ; y < Y_SIZE ; y++) 2235 unsigned int clusterid, p; 2236 2237 for ( clusterid = 0 ; clusterid < X_SIZE*Y_SIZE ; clusterid++ ) 2238 { 2239 unsigned int nprocs = cluster[clusterid].procs; 2240 unsigned int xdest = cluster[clusterid].x; 2241 unsigned int ydest = cluster[clusterid].y; 2242 unsigned int cluster_xy = (xdest<<Y_WIDTH) + ydest; 2243 2244 for ( p = 0 ; p < nprocs; p++ ) 2162 2245 { 2163 for(p = 0; p < NB_PROCS_MAX; p++) 2164 { 2165 if ( (x != 0) || (y != 0) || (p != 0) ) 2166 { 2167 _xcu_send_ipi( (x<<Y_WIDTH) + y, 2168 p, 2169 (unsigned int)boot_init ); 2170 } 2246 if ( (nprocs > 0) && ((clusterid != 0) || (p != 0)) ) 2247 { 2248 _xcu_send_wti( cluster_xy, p, (unsigned int)boot_init ); 2171 2249 } 2172 2250 } 2173 2251 } 2252 2174 2253 } // end monoprocessor boot 2175 2254 … … 2186 2265 _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[0]>>13) ); 2187 2266 _set_mmu_mode( 0xF ); 2188 2189 _tty_get_lock( 0 );2190 _puts("\n[BOOT] Processor[");2191 _putd( cluster_xy >> Y_WIDTH );2192 _puts(",");2193 _putd( cluster_xy & ((1<<Y_WIDTH)-1) );2194 _puts(",");2195 _putd( lpid );2196 _puts("] : MMU activation at cycle ");2197 _putd(_get_proctime());2198 _puts("\n");2199 _tty_release_lock( 0 );2200 2267 } 2201 2268 2202 2269 // all processors jump to kernel_init 2203 2270 unsigned int kernel_entry = (unsigned int)&seg_kernel_init_base; 2204 2205 #if GIET_DEBUG_INIT2206 _tty_get_lock( 0 );2207 _puts("\n[BOOT DEBUG] Processor[");2208 _putd( cluster_xy >> Y_WIDTH );2209 _puts(",");2210 _putd( cluster_xy & ((1<<Y_WIDTH)-1) );2211 _puts(",");2212 _putd( lpid );2213 _puts("] enters kernel at cycle ");2214 _putd( _get_proctime() );2215 _puts(" / kernel entry = ");2216 _putx( kernel_entry );2217 _puts("\n");2218 _tty_release_lock( 0 );2219 #endif2220 2221 2271 asm volatile( "jr %0" ::"r"(kernel_entry) ); 2222 2272 -
soft/giet_vm/giet_common/mips32_registers.h
r268 r295 54 54 #define CP0_PROCID $15,1 55 55 #define CP0_SCHED $4,2 56 #define CP0_SRSAVE $8 56 57 57 58 /* CP2 registers */ -
soft/giet_vm/giet_common/utils.c
r293 r295 47 47 unsigned int size ) // bytes 48 48 { 49 unsigned int* dst =dest;50 const unsigned int* src =source;49 unsigned int* idst = (unsigned int*)dest; 50 unsigned int* isrc = (unsigned int*)source; 51 51 52 52 // word-by-word copy 53 if (!((unsigned int) dst & 3) && !((unsigned int)src & 3))53 if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3)) 54 54 { 55 55 while (size > 3) 56 56 { 57 * dst++ = *src++;57 *idst++ = *isrc++; 58 58 size -= 4; 59 59 } 60 60 } 61 61 62 unsigned char * cdst = (unsigned char *) dst;63 unsigned char * csrc = (unsigned char *) src;62 unsigned char* cdst = (unsigned char*)dest; 63 unsigned char* csrc = (unsigned char*)source; 64 64 65 65 /* byte-by-byte copy */ … … 73 73 // Fill a byte string with a byte value. 74 74 ////////////////////////////////////////////////////////////////////////////////// 75 inline void * _memset( void* d st,75 inline void * _memset( void* dest, 76 76 int value, 77 77 unsigned int count ) 78 78 { 79 char * a = (char *) dst; 79 // word-by-word copy 80 unsigned int* idst = dest; 81 unsigned int data = (((unsigned char)value) ) | 82 (((unsigned char)value) << 8) | 83 (((unsigned char)value) << 16) | 84 (((unsigned char)value) << 24) ; 85 86 if ( ! ((unsigned int)idst & 3) ) 87 { 88 while ( count > 3 ) 89 { 90 *idst++ = data; 91 count -= 4; 92 } 93 } 94 95 // byte-by-byte copy 96 unsigned char* cdst = dest; 80 97 while (count--) 81 98 { 82 *a++ = (char)value; 83 } 84 return dst; 99 *cdst++ = (unsigned char)value; 100 } 101 return dest; 102 } 103 104 ////////////////////////////////////////////////////////////////////////////////// 105 // This function implements an interactive break for debug. 106 // Execution continue when typing any character on TTY0. 107 // The "str" argument is supposed to indicate the break location. 108 ////////////////////////////////////////////////////////////////////////////////// 109 inline void _break( char* string ) 110 { 111 char byte; 112 113 _printf("\n[GIET DEBUG] break from %s / continue ?\n", string ); 114 _getc( &byte ); 85 115 } 86 116 … … 90 120 inline void _exit() 91 121 { 122 unsigned int procid = _get_procid(); 123 unsigned int lpid = procid % NB_PROCS_MAX; 124 unsigned int cluster_xy = procid / NB_PROCS_MAX; 125 unsigned int x = cluster_xy >> Y_WIDTH; 126 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 127 128 129 _printf("\n[GIET PANIC] processor[%d,%d,%d] suicide...\n", x, y, lpid ); 130 92 131 while (1) { asm volatile ("nop"); } 93 132 } … … 103 142 { 104 143 unsigned int ret; 105 asm volatile("mfc0 %0, $4, 2\n" : "=r"(ret) ); 144 asm volatile( "mfc0 %0, $4,2 \n" 145 : "=r"(ret) ); 106 146 return ret; 107 147 } … … 112 152 { 113 153 unsigned int ret; 114 asm volatile("mfc2 %0, $0" : "=r"(ret)); 154 asm volatile( "mfc2 %0, $0 \n" 155 : "=r"(ret) ); 115 156 return ret; 116 157 } 117 158 /////////////////////////////////////////////////////////////////////////////////// 159 // Returns MODE register content. 160 /////////////////////////////////////////////////////////////////////////////////// 161 inline unsigned int _get_mmu_mode() 162 { 163 unsigned int ret; 164 asm volatile( "mfc2 %0, $1 \n" 165 : "=r"(ret) ); 166 return ret; 167 } 168 /////////////////////////////////////////////////////////////////////////////////// 118 169 // Returns EPC register content. 119 170 /////////////////////////////////////////////////////////////////////////////////// … … 121 172 { 122 173 unsigned int ret; 123 asm volatile("mfc0 %0, $14" : "=r"(ret)); 174 asm volatile( "mfc0 %0, $14 \n" 175 : "=r"(ret) ); 124 176 return ret; 125 177 } … … 130 182 { 131 183 unsigned int ret; 132 asm volatile("mfc0 %0, $8" : "=r"(ret)); 184 asm volatile( "mfc0 %0, $8 \n" 185 : "=r"(ret)); 133 186 return ret; 134 187 } … … 139 192 { 140 193 unsigned int ret; 141 asm volatile("mfc0 %0, $13" : "=r"(ret)); 194 asm volatile( "mfc0 %0, $13 \n" 195 : "=r"(ret)); 142 196 return ret; 143 197 } … … 148 202 { 149 203 unsigned int ret; 150 asm volatile("mfc0 %0, $12" : "=r"(ret)); 204 asm volatile( "mfc0 %0, $12 \n" 205 : "=r"(ret)); 151 206 return ret; 152 207 } … … 156 211 inline void _set_sr(unsigned int val) 157 212 { 158 asm volatile("mtc0 %0, $12" ::"r" (val)); 159 } 160 ////////////////////////////////////////////////////////////////////////////////// 213 asm volatile( "mtc0 %0, $12 \n" 214 : 215 :"r" (val) ); 216 } 217 ////////////////////////////////////////////////////////////////////////////// 161 218 // Returns processor index 162 ////////////////////////////////////////////////////////////////////////////// ////219 ////////////////////////////////////////////////////////////////////////////// 163 220 inline unsigned int _get_procid() 164 221 { 165 222 unsigned int ret; 166 asm volatile ("mfc0 %0, $15, 1":"=r" (ret)); 223 asm volatile ( "mfc0 %0, $15, 1 \n" 224 :"=r" (ret) ); 167 225 return (ret & 0x3FF); 168 226 } 169 ////////////////////////////////////////////////////////////////////////////// /////227 ////////////////////////////////////////////////////////////////////////////// 170 228 // Returns local time (32 bits value) 171 229 // boot_proctime() 172 ////////////////////////////////////////////////////////////////////////////// /////230 ////////////////////////////////////////////////////////////////////////////// 173 231 inline unsigned int _get_proctime() 174 232 { 175 233 unsigned int ret; 176 asm volatile ("mfc0 %0, $9":"=r" (ret)); 234 asm volatile ( "mfc0 %0, $9 \n" 235 :"=r" (ret) ); 177 236 return ret; 178 237 } 179 ////////////////////////////////////////////////////////////////////////////// /////180 // Returns index of the currently running task from the sheduler.181 ////////////////////////////////////////////////////////////////////////////// /////182 unsigned int _get_ proc_task_id()238 ////////////////////////////////////////////////////////////////////////////// 239 // Returns index of the currently running task from the processor scheduler. 240 ////////////////////////////////////////////////////////////////////////////// 241 unsigned int _get_current_task_id() 183 242 { 184 243 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); … … 186 245 } 187 246 188 /////////////////////////////////////////////////////////////////////////////////// 189 // Disables IRQs 190 /////////////////////////////////////////////////////////////////////////////////// 191 inline void _it_disable() 192 { 193 asm volatile( 194 "li $3, 0xFFFFFFFE \n" 195 "mfc0 $4, $12 \n" 196 "and $3, $3, $4 \n" 197 "mtc0 $3, $12 \n" 198 ::: "$3", "$4"); 199 } 200 /////////////////////////////////////////////////////////////////////////////////// 247 ////////////////////////////////////////////////////////////////////////////// 248 // Save SR value into save_sr_ptr variable and disable IRQs. 249 ////////////////////////////////////////////////////////////////////////////// 250 inline void _it_disable( unsigned int * save_sr_ptr) 251 { 252 unsigned int sr; 253 asm volatile( "li $3, 0xFFFFFFFE \n" 254 "mfc0 %0, $12 \n" 255 "and $3, $3, %0 \n" 256 "mtc0 $3, $12 \n" 257 : "=r"(sr) 258 : 259 : "$3" ); 260 *save_sr_ptr = sr; 261 } 262 ////////////////////////////////////////////////////////////////////////////// 201 263 // Enables IRQs 202 ////////////////////////////////////////////////////////////////////////////// /////264 ////////////////////////////////////////////////////////////////////////////// 203 265 inline void _it_enable() 204 266 { 205 asm volatile( 206 "li $3, 0x00000001 \n" 207 "mfc0 $4, $12 \n" 208 "or $3, $3, $4 \n" 209 "mtc0 $3, $12 \n" 210 ::: "$3", "$4"); 267 asm volatile( "li $3, 0x00000001 \n" 268 "mfc0 $4, $12 \n" 269 "or $3, $3, $4 \n" 270 "mtc0 $3, $12 \n" 271 ::: "$3", "$4" ); 272 } 273 274 ////////////////////////////////////////////////////////////////////////////// 275 // Restores previous SR value. 276 ////////////////////////////////////////////////////////////////////////////// 277 inline void _it_restore( unsigned int * save_sr_ptr ) 278 { 279 unsigned int sr = *save_sr_ptr; 280 asm volatile( "mtc0 %0, $12 \n" 281 : 282 : "r"(sr) ); 211 283 } 212 284 … … 216 288 inline void _set_mmu_ptpr(unsigned int val) 217 289 { 218 asm volatile ("mtc2 %0, $0"::"r" (val)); 290 asm volatile ( "mtc2 %0, $0 \n" 291 : 292 :"r" (val) ); 219 293 } 220 294 ////////////////////////////////////////////////////////////////////////////// … … 223 297 inline void _set_mmu_mode(unsigned int val) 224 298 { 225 asm volatile ("mtc2 %0, $1"::"r" (val)); 299 asm volatile ( "mtc2 %0, $1 \n" 300 : 301 :"r" (val) ); 226 302 } 227 303 ////////////////////////////////////////////////////////////////////////////// … … 231 307 inline void _set_sched(unsigned int val) 232 308 { 233 asm volatile ("mtc0 %0, $4, 2"::"r" (val)); 309 asm volatile ( "mtc0 %0, $4, 2 \n" 310 : 311 :"r" (val) ); 234 312 } 235 313 … … 249 327 250 328 asm volatile( 329 "li $3, 0xFFFFFFFE \n" 330 "mfc0 $2, $12 \n" 331 "and $3, $2, $3 \n" 332 "mtc0 $3, $12 \n" /* IRQ disabled */ 333 251 334 "mfc2 $2, $1 \n" /* $2 <= MMU_MODE */ 252 335 "andi $3, $2, 0xb \n" … … 258 341 259 342 "mtc2 $2, $1 \n" /* restore MMU_MODE */ 343 344 "li $3, 0x00000001 \n" 345 "mfc0 $2, $12 \n" 346 "or $3, $3, $2 \n" 347 "mtc0 $3, $12 \n" /* IRQ enabled */ 260 348 : "=r" (value) 261 349 : "r" (lsb), "r" (msb) … … 268 356 //////////////////////////////////////////////////////////////////////////// 269 357 inline void _physical_write( unsigned long long paddr, 270 unsigned int value )358 unsigned int value ) 271 359 { 272 360 unsigned int lsb = (unsigned int)paddr; … … 274 362 275 363 asm volatile( 364 "li $3, 0xFFFFFFFE \n" 365 "mfc0 $2, $12 \n" 366 "and $3, $2, $3 \n" 367 "mtc0 $3, $12 \n" /* IRQ disabled */ 368 276 369 "mfc2 $2, $1 \n" /* $2 <= MMU_MODE */ 277 370 "andi $3, $2, 0xb \n" … … 283 376 284 377 "mtc2 $2, $1 \n" /* restore MMU_MODE */ 378 379 "li $3, 0x00000001 \n" 380 "mfc0 $2, $12 \n" 381 "or $3, $3, $2 \n" 382 "mtc0 $3, $12 \n" /* IRQ enabled */ 285 383 : 286 384 : "r" (value), "r" (lsb), "r" (msb) 287 385 : "$2", "$3"); 386 } 387 388 /////////////////////////////////////////////////////////////////////////////////// 389 // This function is used by all drivers (_xxx_set_register() function) 390 // If the MMU is not activated, the virtual address is extended using 391 // X_IO and Y_IO to reach the cluster_io. 392 /////////////////////////////////////////////////////////////////////////////////// 393 inline void _io_extended_write( unsigned int* vaddr, 394 unsigned int value ) 395 { 396 unsigned long long paddr; 397 398 if ( _get_mmu_mode() & 0x4 ) // MMU activated : use virtual address 399 { 400 *vaddr = value; 401 } 402 else // use paddr extension for IO 403 { 404 paddr = (unsigned long long)(unsigned int)vaddr + 405 (((unsigned long long)((X_IO<<Y_WIDTH) + Y_IO))<<32); 406 _physical_write( paddr, value ); 407 } 408 asm volatile("sync" ::: "memory"); 409 } 410 411 /////////////////////////////////////////////////////////////////////////////////// 412 // This function is used by all drivers (_xxx_get_register() function) 413 // If the MMU is not activated, the virtual address is extended using 414 // X_IO and Y_IO to reach the cluster_io. 415 /////////////////////////////////////////////////////////////////////////////////// 416 inline unsigned int _io_extended_read( unsigned int* vaddr ) 417 { 418 unsigned long long paddr; 419 420 if ( _get_mmu_mode() & 0x4 ) // MMU activated : use virtual address 421 { 422 return *(volatile unsigned int*)vaddr; 423 } 424 else // use paddr extension for IO 425 { 426 paddr = (unsigned long long)(unsigned int)vaddr + 427 (((unsigned long long)((X_IO<<Y_WIDTH) + Y_IO))<<32); 428 return _physical_read( paddr ); 429 } 288 430 } 289 431 … … 323 465 :"$2", "$3", "$4"); 324 466 } 467 325 468 /////////////////////////////////////////////////////////////////////////////////// 326 469 // Release a previouly taken lock. … … 328 471 inline void _release_lock(unsigned int * plock) 329 472 { 330 asm volatile ( "sync\n" ); // necessary because of the TSAR consistency model 473 asm volatile ( "sync\n" ::: "memory" ); 474 // sync is necessary because of the TSAR consistency model 331 475 *plock = 0; 332 476 } 333 477 334 478 /////////////////////////////////////////////////////////////////////////////////// 335 // Display a string on TTY0 / used for system code debug and log.336 // It does not use the TTY driver, but uses the seg_tty_base variable...337 ///////////////////////////////////////////////////////////////////////////////////338 void _puts(char * buffer)339 {340 unsigned int n;341 for (n = 0; n < 1000; n++)342 {343 if (buffer[n] == 0) break;344 }345 _tty_write( buffer, n, 0 ); // last argument is TTY channel346 }347 348 ///////////////////////////////////////////////////////////////////////////////////349 479 // Access functions to system terminal TTY0 350 480 /////////////////////////////////////////////////////////////////////////////////// 351 481 352 482 /////////////////////////////////////////////////////////////////////////////////// 353 // Display a 32 bits unsigned int as an hexadecimal string on TTY0 354 /////////////////////////////////////////////////////////////////////////////////// 355 void _putx(unsigned int val) 483 // Display "string" argument on TTY0. 484 // It uses the low level access functions from TTY driver, using a busy waiting 485 // policy if TTY buffer is full. 486 // The exclusive access lock should be taken by the caller. 487 /////////////////////////////////////////////////////////////////////////////////// 488 void _puts( char* string ) 489 { 490 unsigned int n = 0; 491 492 while ( string[n] > 0 ) 493 { 494 // test status register 495 while ( (_tty_get_register( 0, TTY_STATUS ) & 0x2) ); 496 497 // write one byte 498 _tty_set_register( 0, TTY_WRITE, (unsigned int)string[n] ); 499 n++; 500 } 501 } 502 503 /////////////////////////////////////////////////////////////////////////////////// 504 // Display a 32 bits unsigned int as an hexadecimal string on TTY0. 505 /////////////////////////////////////////////////////////////////////////////////// 506 void _putx( unsigned int val ) 356 507 { 357 508 static const char HexaTab[] = "0123456789ABCDEF"; … … 368 519 val = val >> 4; 369 520 } 370 _puts( buf);371 } 372 373 /////////////////////////////////////////////////////////////////////////////////// 374 // Display a 64 bits unsigned long as an hexadecimal string on TTY0 375 /////////////////////////////////////////////////////////////////////////////////// 376 void _putl( unsigned long long val)521 _puts( buf ); 522 } 523 524 /////////////////////////////////////////////////////////////////////////////////// 525 // Display a 64 bits unsigned long as an hexadecimal string on TTY0. 526 /////////////////////////////////////////////////////////////////////////////////// 527 void _putl( unsigned long long val ) 377 528 { 378 529 static const char HexaTab[] = "0123456789ABCDEF"; … … 389 540 val = val >> 4; 390 541 } 391 _puts( buf);392 } 393 394 /////////////////////////////////////////////////////////////////////////////////// 395 // Display a 32 bits unsigned int as a decimal string on TTY0 396 /////////////////////////////////////////////////////////////////////////////////// 397 void _putd( unsigned int val)542 _puts( buf ); 543 } 544 545 /////////////////////////////////////////////////////////////////////////////////// 546 // Display a 32 bits unsigned int as a decimal string on TTY0. 547 /////////////////////////////////////////////////////////////////////////////////// 548 void _putd( unsigned int val ) 398 549 { 399 550 static const char DecTab[] = "0123456789"; … … 414 565 val /= 10; 415 566 } 416 _puts(&buf[first]); 567 _puts( &buf[first] ); 568 } 569 570 /////////////////////////////////////////////////////////////////////////////////// 571 // Display a format on TTY0. 572 // To provide an atomic display, this function takes the lock protecting 573 // exclusive access to TTY0, entering a critical section until the lock 574 // is released. 575 // Only a limited number of formats are supported: 576 // - %d : 32 bits signed decimal 577 // - %u : 32 bits unsigned decimal 578 // - %x : 32 bits unsigned hexa 579 // - %l : 64 bits unsigned hexa 580 // - %c : char 581 // - %s : string 582 /////////////////////////////////////////////////////////////////////////////////// 583 void _printf( char * format, ... ) 584 { 585 va_list ap; 586 va_start(ap, format); 587 unsigned int save_sr; // used to save the SR value in critical section 588 589 // get TTY0 lock 590 _tty_get_lock( 0, &save_sr ); 591 592 printf_text: 593 594 while (*format) 595 { 596 unsigned int i; 597 for (i = 0 ; format[i] && (format[i] != '%') ; i++); 598 if (i) 599 { 600 if ( _tty_write( format, i, 0 ) != i ) goto return_error; 601 format += i; 602 } 603 if (*format == '%') 604 { 605 format++; 606 goto printf_arguments; 607 } 608 } 609 610 // release TTY0 lock 611 _tty_release_lock( 0, &save_sr ); 612 613 va_end(ap); 614 return; 615 616 printf_arguments: 617 618 { 619 char buf[20]; 620 char * pbuf; 621 unsigned int len = 0; 622 static const char HexaTab[] = "0123456789ABCDEF"; 623 unsigned int i; 624 625 switch (*format++) 626 { 627 case ('c'): /* char conversion */ 628 { 629 int val = va_arg( ap, int ); 630 len = 1; 631 buf[0] = val; 632 pbuf = &buf[0]; 633 break; 634 } 635 case ('d'): /* 32 bits decimal signed */ 636 { 637 int val = va_arg( ap, int ); 638 if (val < 0) 639 { 640 val = -val; 641 if ( _tty_write( "-" , 1, 0 ) != 1 ) goto return_error; 642 } 643 for(i = 0; i < 10; i++) 644 { 645 buf[9 - i] = HexaTab[val % 10]; 646 if (!(val /= 10)) break; 647 } 648 len = i + 1; 649 pbuf = &buf[9 - i]; 650 break; 651 } 652 case ('u'): /* 32 bits decimal unsigned */ 653 { 654 unsigned int val = va_arg( ap, unsigned int ); 655 for(i = 0; i < 10; i++) 656 { 657 buf[9 - i] = HexaTab[val % 10]; 658 if (!(val /= 10)) break; 659 } 660 len = i + 1; 661 pbuf = &buf[9 - i]; 662 break; 663 } 664 case ('x'): /* 32 bits hexadecimal unsigned */ 665 { 666 unsigned int val = va_arg( ap, unsigned int ); 667 if ( _tty_write( "0x" , 2, 0 ) != 2 ) goto return_error; 668 for(i = 0; i < 8; i++) 669 { 670 buf[7 - i] = HexaTab[val % 16]; 671 if (!(val /= 16)) break; 672 } 673 len = i + 1; 674 pbuf = &buf[7 - i]; 675 break; 676 } 677 case ('l'): /* 64 bits hexadecimal unsigned */ 678 { 679 unsigned long long val = va_arg( ap, unsigned long long ); 680 if ( _tty_write( "0x" , 2, 0 ) != 2 ) goto return_error; 681 for(i = 0; i < 16; i++) 682 { 683 buf[15 - i] = HexaTab[val % 16]; 684 if (!(val /= 16)) break; 685 } 686 len = i + 1; 687 pbuf = &buf[15 - i]; 688 break; 689 } 690 case ('s'): /* string */ 691 { 692 char* str = va_arg( ap, char* ); 693 while (str[len]) 694 { 695 len++; 696 } 697 pbuf = str; 698 break; 699 } 700 default: 701 goto return_error; 702 } 703 704 if ( _tty_write( pbuf, len, 0 ) != len ) goto return_error; 705 706 goto printf_text; 707 } 708 709 return_error: 710 711 { 712 unsigned int procid = _get_procid(); 713 unsigned int lpid = procid % NB_PROCS_MAX; 714 unsigned int cluster_xy = procid / NB_PROCS_MAX; 715 unsigned int x = cluster_xy >> Y_WIDTH; 716 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 717 718 _puts("\n\n[GIET ERROR] in _printf() for processor["); 719 _putd( x ); 720 _puts(","); 721 _putd( y ); 722 _puts(","); 723 _putd( lpid ); 724 _puts("]\n"); 725 726 // release TTY0 lock 727 _tty_release_lock( 0, &save_sr ); 728 729 _exit(); 730 } 731 } 732 733 /////////////////////////////////////////////////////////////////////////////////// 734 // Get a character from TTY0. 735 /////////////////////////////////////////////////////////////////////////////////// 736 void _getc( char* byte ) 737 { 738 // test status register 739 while ( _tty_get_register( 0, TTY_STATUS ) == 0 ); 740 741 // read one byte 742 *byte = (char)_tty_get_register( 0, TTY_READ ); 417 743 } 418 744 … … 452 778 // register, to be more processor independant. 453 779 /////////////////////////////////////////////////////////////////////////////////// 454 void _dcache_buf_invalidate( constvoid * buffer,780 void _dcache_buf_invalidate( void * buffer, 455 781 unsigned int size) 456 782 { -
soft/giet_vm/giet_common/utils.h
r268 r295 23 23 typedef struct _ld_symbol_s _ld_symbol_t; 24 24 25 // peripheral base addresses25 // non replicated peripherals 26 26 extern _ld_symbol_t seg_iob_base; 27 27 extern _ld_symbol_t seg_nic_base; 28 extern _ld_symbol_t seg_cma_base; 29 extern _ld_symbol_t seg_tty_base; 30 extern _ld_symbol_t seg_fbf_base; 31 extern _ld_symbol_t seg_pic_base; 32 extern _ld_symbol_t seg_ioc_base; 33 extern _ld_symbol_t seg_sim_base; 34 35 // replicated peripherals 28 36 extern _ld_symbol_t seg_icu_base; 29 37 extern _ld_symbol_t seg_xcu_base; 30 38 extern _ld_symbol_t seg_tim_base; 31 extern _ld_symbol_t seg_tty_base;32 extern _ld_symbol_t seg_gcd_base;33 39 extern _ld_symbol_t seg_dma_base; 34 extern _ld_symbol_t seg_fbf_base;35 extern _ld_symbol_t seg_ioc_base;36 40 extern _ld_symbol_t seg_mmc_base; 37 extern _ld_symbol_t seg_cma_base;38 extern _ld_symbol_t seg_hba_base;39 extern _ld_symbol_t seg_sim_base;40 41 41 42 // for replicated peripherals … … 70 71 extern _ld_symbol_t seg_kernel_init_size; 71 72 72 73 extern _ld_symbol_t seg_ram_disk_base; 74 extern _ld_symbol_t seg_ram_disk_size; 75 76 extern _ld_symbol_t seg_reset_code_base; 77 extern _ld_symbol_t seg_reset_code_size; 73 78 74 79 /////////////////////////////////////////////////////////////////////////////////// … … 85 90 86 91 /////////////////////////////////////////////////////////////////////////////////// 92 // Break function 93 /////////////////////////////////////////////////////////////////////////////////// 94 95 extern void _break( char* str); 96 97 /////////////////////////////////////////////////////////////////////////////////// 87 98 // Suicide function 88 99 /////////////////////////////////////////////////////////////////////////////////// … … 102 113 extern unsigned int _get_sched(void); 103 114 extern unsigned int _get_mmu_ptpr(void); 115 extern unsigned int _get_mmu_mode(void); 104 116 extern unsigned int _get_epc(void); 105 117 extern unsigned int _get_bvar(void); … … 108 120 extern unsigned int _get_procid(void); 109 121 extern unsigned int _get_proctime(void); 110 extern unsigned int _get_ proc_task_id(void);111 112 extern void _it_disable( void);122 extern unsigned int _get_current_task_id(void); 123 124 extern void _it_disable( unsigned int* save_sr_ptr ); 113 125 extern void _it_enable(void); 126 extern void _it_restore( unsigned int* save_sr_ptr ); 114 127 115 128 extern void _set_mmu_ptpr(unsigned int value); … … 127 140 unsigned int value ); 128 141 142 extern unsigned int _io_extended_read( unsigned int* vaddr ); 143 144 extern void _io_extended_write( unsigned int* vaddr, 145 unsigned int value ); 146 129 147 /////////////////////////////////////////////////////////////////////////////////// 130 148 // Locks access functions … … 135 153 136 154 /////////////////////////////////////////////////////////////////////////////////// 137 // Display functions 138 /////////////////////////////////////////////////////////////////////////////////// 139 140 extern void _puts(char *string); // display a string 141 extern void _putx(unsigned int val); // display a 32 bits value (hexa) 142 extern void _putd(unsigned int val); // display a 32 bits value (dec) 143 extern void _putl(unsigned long long val); // display a 64 bits value (hexa) 155 // TTY0 access functions 156 /////////////////////////////////////////////////////////////////////////////////// 157 158 extern void _puts( char* string ); 159 160 extern void _putx( unsigned int val ); 161 162 extern void _putd( unsigned int val ); 163 164 extern void _putl( unsigned long long val ); 165 166 extern void _printf(char* format, ...); 167 168 extern void _getc( char* byte ); 144 169 145 170 /////////////////////////////////////////////////////////////////////////////////// … … 158 183 /////////////////////////////////////////////////////////////////////////////////// 159 184 160 extern void _dcache_buf_invalidate( constvoid * buffer,185 extern void _dcache_buf_invalidate( void * buffer, 161 186 unsigned int size ); 162 187 -
soft/giet_vm/giet_common/vmem.c
r258 r295 25 25 // _iommu_add_pte2() 26 26 ////////////////////////////////////////////////////////////////////////////// 27 void _iommu_add_pte2( 28 unsigned int ix1, 29 unsigned int ix2, 30 unsigned int ppn, 31 unsigned int flags) 27 void _iommu_add_pte2( unsigned int ix1, 28 unsigned int ix2, 29 unsigned int ppn, 30 unsigned int flags ) 32 31 { 33 32 unsigned int ptba; … … 41 40 if ((pt->pt1[ix1] & PTE_V) == 0) 42 41 { 43 _tty_get_lock( 0 ); 44 _puts("\n[GIET ERROR] in iommu_add_pte2 function\n"); 45 _puts("the IOMMU PT1 entry is not mapped / ix1 = "); 46 _putx( ix1 ); 47 _puts("\n"); 48 _tty_release_lock( 0 ); 42 _printf("\n[GIET ERROR] in iommu_add_pte2() : " 43 "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 ); 49 44 _exit(); 50 45 } … … 63 58 // _iommu_inval_pte2() 64 59 ////////////////////////////////////////////////////////////////////////////// 65 void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) { 60 void _iommu_inval_pte2( unsigned int ix1, 61 unsigned int ix2 ) 62 { 66 63 unsigned int ptba; 67 64 unsigned int * pt_flags; … … 73 70 if ((pt->pt1[ix1] & PTE_V) == 0) 74 71 { 75 _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n"); 76 _puts("the IOMMU PT1 entry is not mapped / ix1 = "); 77 _putx( ix1 ); 78 _puts("\n"); 72 _printf("\n[GIET ERROR] in iommu_inval_pte2() " 73 "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 ); 79 74 _exit(); 80 75 } … … 95 90 unsigned int vpn, 96 91 unsigned int* ppn, 97 unsigned int* flags )92 unsigned int* flags ) 98 93 { 99 94 unsigned long long ptba; -
soft/giet_vm/giet_config.h
r289 r295 23 23 24 24 #define GIET_DEBUG_INIT 0 /* trace parallel kernel initialisation */ 25 26 25 #define GIET_DEBUG_FAT 0 /* trace fat accesses */ 27 #define GIET_DEBUG_SWITCH 0 /* trace context switchs */ 26 #define GIET_DEBUG_SWITCH 0 /* trace context switchs */ 27 #define GIET_DEBUG_IRQS 0 /* trace interrupts */ 28 28 #define GIET_DEBUG_IOC_DRIVER 0 /* trace IOC accesses */ 29 #define GIET_DEBUG_BDV_DRIVER 0 /* trace BDV accesses */ 30 #define GIET_DEBUG_TTY_DRIVER 0 /* trace TTY accesses */ 29 31 #define GIET_DEBUG_DMA_DRIVER 0 /* trace DMA accesses */ 30 32 #define GIET_DEBUG_FBF_DRIVER 0 /* trace FBF accesses */ … … 34 36 /* software parameters */ 35 37 36 #define GIET_IDLE_TASK_PERIOD 10000000 /* Idle Task message period */ 37 #define GIET_IDLE_TASK_VERBOSITY 1 38 38 #define GIET_IDLE_TASK_PERIOD 0xFFFFFFFF /* Idle Task message period */ 39 39 #define GIET_MAX_ELF_FILES 20 /* max .elf files loaded by boot-loader */ 40 40 #define GIET_OPEN_FILES_MAX 16 /* max simultaneously open files */ 41 41 #define GIET_NB_VSPACE_MAX 64 /* max number of virtual spaces */ 42 #define GIET_TICK_VALUE 100000/* context switch period (number of cycles) */42 #define GIET_TICK_VALUE 0x8000 /* context switch period (number of cycles) */ 43 43 #define GIET_USE_IOMMU 0 /* IOMMU activated when non zero */ 44 44 #define GIET_NO_HARD_CC 0 /* No hard cache coherence when non zero */ -
soft/giet_vm/giet_drivers/bdv_driver.c
r289 r295 10 10 // a single channel, block oriented, external storage contrÃŽler. 11 11 // 12 // It can exist only one block-device controler in the architecture. 13 // 14 // The _bdv_read() and _bdv_write() functions use the _bdv_access() function, 15 // that is always blocking, but can be called in 4 modes: 16 // 17 // - In BOOT_PA mode, the _bdv_access() function uses a polling policy on the 18 // IOC_STATUS register to detect transfer completion, as hardware interrupts 19 // are not activated. This mode is used by the boot code to load the map.bin 20 // file into memory. 21 // 22 // - In BOOT_VA mode, the _bdv_access() function uses a polling policy on 23 // IOC_STATUS register to detect transfer completion. This mode is used by 24 // the boot code to load the various .elf files into memory. 25 // 26 // - In KERNEL mode, the _bdv_access() function uses a descheduling strategy: 12 // The _bdv_read() and _bdv_write() functions are always blocking. 13 // They can be called in 3 modes: 14 // 15 // - In BOOT mode, these functions use a polling policy on the BDV STATUS 16 // register to detect transfer completion, as interrupts are not activated. 17 // This mode is used by the boot code to load the map.bin file into memory 18 // (before MMU activation), or to load the .elf files (after MMU activation). 19 // 20 // - In KERNEL mode, these functions use a descheduling strategy: 27 21 // The ISR executed when transfer completes should restart the calling task. 28 // There is no checking of user access right to the memory buffer. This mode29 // must be used to access IOC, for an "open" system call.30 // 31 // - In USER mode, the _bdv_access() function usesa descheduling strategy:22 // There is no checking of user access right to the memory buffer. 23 // This mode must be used, for an "open" system call. 24 // 25 // - In USER mode, these functions use a descheduling strategy: 32 26 // The ISR executed when transfer completes should restart the calling task, 33 27 // The user access right to the memory buffer must be checked. 34 // This mode must be used to access IOC,for a "read/write" system call.28 // This mode must be used for a "read/write" system call. 35 29 // 36 30 // As the BDV component can be used by several programs running in parallel, 37 // the _ ioc_lock variable guaranties exclusive access to the device. The31 // the _bdv_lock variable guaranties exclusive access to the device. The 38 32 // _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock. 39 33 // … … 47 41 // if the IOMMU is not activated. 48 42 // An error code is returned if these conditions are not verified. 49 /////////////////////////////////////////////////////////////////////////////////// 50 // The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file. 43 // 44 // The "seg_ioc_base" must be defined in giet_vsegs.ld file. 45 /////////////////////////////////////////////////////////////////////////////////// 46 // Implementation notes: 47 // 48 // 1. In order to share code, the two _bdv_read() and _bdv_write() functions 49 // call the same _bdv_access() function. 50 // 51 // 2. All accesses to BDV registers are done by the two 52 // _bdv_set_register() and _bdv_get_register() low-level functions, 53 // that are handling virtual / physical extended addressing. 51 54 /////////////////////////////////////////////////////////////////////////////////// 52 55 53 56 #include <giet_config.h> 57 #include <bdv_driver.h> 58 #include <xcu_driver.h> 54 59 #include <ioc_driver.h> 55 #include <bdv_driver.h>56 60 #include <utils.h> 57 61 #include <tty_driver.h> … … 59 63 60 64 /////////////////////////////////////////////////////////////////////////////// 61 // _bdv_access() 65 // BDV global variables 66 /////////////////////////////////////////////////////////////////////////////// 67 68 #define in_unckdata __attribute__((section (".unckdata"))) 69 70 in_unckdata unsigned int _bdv_lock = 0; 71 in_unckdata volatile unsigned int _bdv_status = 0; 72 in_unckdata volatile unsigned int _bdv_gtid; 73 74 /////////////////////////////////////////////////////////////////////////////// 75 // This low_level function returns the value contained in register (index). 76 /////////////////////////////////////////////////////////////////////////////// 77 unsigned int _bdv_get_register( unsigned int index ) 78 { 79 unsigned int* vaddr = (unsigned int*)&seg_ioc_base + index; 80 return _io_extended_read( vaddr ); 81 } 82 83 /////////////////////////////////////////////////////////////////////////////// 84 // This low-level function set a new value in register (index). 85 /////////////////////////////////////////////////////////////////////////////// 86 void _bdv_set_register( unsigned int index, 87 unsigned int value ) 88 { 89 unsigned int* vaddr = (unsigned int*)&seg_ioc_base + index; 90 _io_extended_write( vaddr, value ); 91 } 92 93 /////////////////////////////////////////////////////////////////////////////// 62 94 // This function transfer data between a memory buffer and the block device. 63 95 // The buffer lentgth is (count*block_size) bytes. … … 70 102 // Returns 0 if success, > 0 if error. 71 103 /////////////////////////////////////////////////////////////////////////////// 72 static unsigned int _bdv_access( unsigned int to_mem, 73 unsigned int mode, 74 unsigned int lba, 75 paddr_t buf_paddr, 76 unsigned int count) 77 { 78 79 #if GIET_DEBUG_IOC_DRIVER 80 _tty_get_lock( 0 ); 81 _puts("\n[IOC DEBUG] Enter _bdv_access() at cycle "); 82 _putd( _get_proctime() ); 83 _puts(" for processor "); 84 _putd( _get_procid() ); 85 _puts("\n - mode = "); 86 _putd( mode ); 87 _puts("\n - paddr = "); 88 _putx( buf_paddr ); 89 _puts("\n - sectors = "); 90 _putd( count ); 91 _puts("\n - lba = "); 92 _putx( lba ); 93 _puts("\n"); 94 _tty_release_lock( 0 ); 104 static unsigned int _bdv_access( unsigned int to_mem, 105 unsigned int mode, 106 unsigned int lba, 107 unsigned long long buf_paddr, 108 unsigned int count) 109 { 110 111 #if GIET_DEBUG_BDV_DRIVER 112 unsigned int procid = _get_procid(); 113 unsigned int cxy = procid / NB_PROCS_MAX; 114 unsigned int lpid = procid % NB_PROCS_MAX; 115 unsigned int x = cxy >> Y_WIDTH; 116 unsigned int y = cxy & ((1<<Y_WIDTH) - 1); 117 118 _printf("\n[BDV DEBUG] Processor[%d,%d,%d] enters _bdv_access() at cycle %d\n" 119 " - mode = %d\n" 120 " - paddr = %l\n" 121 " - sectors = %x\n" 122 " - lba = %x\n", 123 x, y, lpid, _get_proctime(), mode, buf_paddr, count, lba ); 95 124 #endif 96 125 97 volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ; 98 unsigned int error = 0; 99 100 // get the lock protecting IOC 101 _get_lock(&_ioc_lock); 102 103 // set the _ioc_status polling variable 104 _ioc_status = BLOCK_DEVICE_BUSY; 105 106 ioc_address[BLOCK_DEVICE_BUFFER] = (unsigned int)buf_paddr; 107 ioc_address[BLOCK_DEVICE_BUFFER_EXT] = (unsigned int)(buf_paddr>>32); 108 ioc_address[BLOCK_DEVICE_COUNT] = count; 109 ioc_address[BLOCK_DEVICE_LBA] = lba; 110 111 // There are two policies for transfer completion 112 // detection, depending on the mode argument: 113 114 if ( (mode == IOC_BOOT_PA_MODE) || // We poll directly the IOC_STATUS register 115 (mode == IOC_BOOT_VA_MODE) ) // as IRQs are masked. 126 unsigned int error = 0; 127 128 // get the lock protecting BDV 129 _get_lock(&_bdv_lock); 130 131 // set device registers 132 _bdv_set_register( BLOCK_DEVICE_BUFFER , (unsigned int)buf_paddr ); 133 _bdv_set_register( BLOCK_DEVICE_BUFFER_EXT, (unsigned int)(buf_paddr>>32) ); 134 _bdv_set_register( BLOCK_DEVICE_COUNT , count ); 135 _bdv_set_register( BLOCK_DEVICE_LBA , lba ); 136 137 // In BOOT mode, we launch transfer, and poll the BDV_STATUS 138 // register because IRQs are masked. 139 if ( mode == IOC_BOOT_MODE ) 116 140 { 117 141 // Launch transfert 118 if (to_mem == 0) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;119 else ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;142 if (to_mem == 0) _bdv_set_register( BLOCK_DEVICE_OP, BLOCK_DEVICE_WRITE ); 143 else _bdv_set_register( BLOCK_DEVICE_OP, BLOCK_DEVICE_READ ); 120 144 121 145 unsigned int status; 122 146 do 123 147 { 124 if ( _bdv_get_status( 0, &status ) ) return 1; 125 126 #if GIET_DEBUG_IOC_DRIVER 127 _tty_get_lock( 0 ); 128 _puts("\n[IOC DEBUG] _bdv_access() : ... waiting on IOC_STATUS register ...\n"); 129 _tty_release_lock( 0 ); 148 status = _bdv_get_register( BLOCK_DEVICE_STATUS ); 149 150 #if GIET_DEBUG_BDV_DRIVER 151 _printf("\n[BDV DEBUG] _bdv_access() : ... waiting on BDV_STATUS register ...\n"); 130 152 #endif 131 153 } … … 133 155 (status != BLOCK_DEVICE_READ_ERROR) && 134 156 (status != BLOCK_DEVICE_WRITE_SUCCESS) && 135 (status != BLOCK_DEVICE_WRITE_ERROR) ); 157 (status != BLOCK_DEVICE_WRITE_ERROR) ); // busy waiting 136 158 137 159 // analyse status … … 140 162 141 163 // release lock 142 _release_lock(&_ ioc_lock);164 _release_lock(&_bdv_lock); 143 165 } 144 else // in USER or KERNEL mode, we deschedule the task. 145 // When the task is rescheduled by the ISR, we reset 146 // the _ioc_status variable, and release the lock 166 // in USER or KERNEL mode, we deschedule the task. 167 // When the task is rescheduled, we check the _bdv_status variable, 168 // and release the lock. 169 // We need a critical section, because we must reset the RUN bit 170 // before to launch the transfer, and we don't want to be descheduled 171 // between these two operations. 172 else 147 173 { 148 // We need a critical section, because we must reset the RUN bit 149 // before to launch the transfer, and we want to avoid to be descheduled 150 // between these two operations. 151 152 // Enter critical section 153 _it_disable(); 174 unsigned int save_sr; 175 unsigned int ltid = _get_current_task_id(); 176 unsigned int gpid = _get_procid(); 177 178 // activates BDV interrupts 179 _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 1 ); 180 181 // set the _bdv_status variable 182 _bdv_status = BLOCK_DEVICE_BUSY; 183 184 // enters critical section 185 _it_disable( &save_sr ); 154 186 155 // set _ioc_gtid and reset runnable 156 unsigned int ltid = _get_proc_task_id(); 157 unsigned int pid = _get_procid(); 158 _ioc_gtid = (pid<<16) + ltid; 159 _set_task_slot( pid, ltid, CTX_RUN_ID, 0 ); 187 // set _bdv_gtid and reset runnable 188 _bdv_gtid = (gpid<<16) + ltid; 189 _set_task_slot( gpid, ltid, CTX_RUN_ID, 0 ); 160 190 161 // Launch transfert162 if (to_mem == 0) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;163 else ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;191 // launch transfer 192 if (to_mem == 0) _bdv_set_register( BLOCK_DEVICE_OP, BLOCK_DEVICE_WRITE ); 193 else _bdv_set_register( BLOCK_DEVICE_OP, BLOCK_DEVICE_READ ); 164 194 165 195 // deschedule task 166 196 _ctx_switch(); 167 197 198 // restore SR 199 _it_restore( &save_sr ); 200 168 201 // analyse status 169 error = ( (_ ioc_status == BLOCK_DEVICE_READ_ERROR) ||170 (_ ioc_status == BLOCK_DEVICE_WRITE_ERROR) );171 172 // reset _ ioc_status and release lock173 _ ioc_status = BLOCK_DEVICE_IDLE;174 _release_lock(&_ ioc_lock);202 error = ( (_bdv_status == BLOCK_DEVICE_READ_ERROR) || 203 (_bdv_status == BLOCK_DEVICE_WRITE_ERROR) ); 204 205 // reset _bdv_status and release lock 206 _bdv_status = BLOCK_DEVICE_IDLE; 207 _release_lock(&_bdv_lock); 175 208 } 176 209 177 #if GIET_DEBUG_IOC_DRIVER 178 _tty_get_lock( 0 ); 179 _puts("\n[IOC DEBUG] _bdv_access completed at cycle "); 180 _putd( _get_proctime() ); 181 _puts(" for processor "); 182 _putd( _get_procid() ); 183 _puts(" : error = "); 184 _putd( (unsigned int)error ); 185 _puts("\n"); 186 _tty_release_lock( 0 ); 210 #if GIET_DEBUG_BDV_DRIVER 211 _printf("\n[BDV DEBUG] Processor[%d,%d,%d] exit _bdv_access() at cycle %d\n", 212 x, y, lpid, _get_proctime() ); 187 213 #endif 188 214 … … 191 217 192 218 /////////////////////////////////////////////////////////////////////////////// 193 // _bdv_init() 194 // This function cheks block size, and activates the IOC interrupts. 219 // This function cheks block size, and desactivates the interrupts. 195 220 // Return 0 for success, > 0 if error 196 221 /////////////////////////////////////////////////////////////////////////////// 197 unsigned int _bdv_init( unsigned int channel ) 198 { 199 volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ; 200 201 if ( ioc_address[BLOCK_DEVICE_BLOCK_SIZE] != 512 ) 222 unsigned int _bdv_init() 223 { 224 if ( _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE ) != 512 ) 202 225 { 203 _tty_get_lock( 0 ); 204 _puts("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n"); 205 _tty_release_lock( 0 ); 226 _printf("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n"); 206 227 return 1; 207 228 } 208 229 209 if ( channel != 0 ) 210 { 211 _tty_get_lock( 0 ); 212 _puts("\n[GIET ERROR] in _bdv_init() : illegal channel\n"); 213 _tty_release_lock( 0 ); 214 215 return 1; 216 } 217 218 ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1; 230 _bdv_set_register( BLOCK_DEVICE_IRQ_ENABLE, 0 ); 219 231 return 0; 220 232 } 221 233 222 234 /////////////////////////////////////////////////////////////////////////////// 223 // _bdv_read()224 235 // Transfer data from the block device to a memory buffer. 225 236 // - mode : BOOT / KERNEL / USER … … 229 240 // Returns 0 if success, > 0 if error. 230 241 /////////////////////////////////////////////////////////////////////////////// 231 unsigned int _bdv_read( unsigned int mode,232 unsigned int lba,233 paddr_tbuffer,234 unsigned int count)242 unsigned int _bdv_read( unsigned int mode, 243 unsigned int lba, 244 unsigned long long buffer, 245 unsigned int count) 235 246 { 236 247 return _bdv_access( 1, // read access … … 242 253 243 254 /////////////////////////////////////////////////////////////////////////////// 244 // _bdv_write()245 255 // Transfer data from a memory buffer to the block device. 246 256 // - mode : BOOT / KERNEL / USER … … 250 260 // Returns 0 if success, > 0 if error. 251 261 /////////////////////////////////////////////////////////////////////////////// 252 unsigned int _bdv_write( unsigned int mode,253 unsigned int lba,254 paddr_tbuffer,255 unsigned int count )262 unsigned int _bdv_write( unsigned int mode, 263 unsigned int lba, 264 unsigned long long buffer, 265 unsigned int count ) 256 266 { 257 267 return _bdv_access( 0, // write access … … 263 273 264 274 /////////////////////////////////////////////////////////////////////////////// 265 // _bdv_get_status() 266 // This function returns in the status variable, the transfert status, and 267 // acknowledge the IRQ if the IOC controler is not busy. 268 // Returns 0 if success, > 0 if error 269 /////////////////////////////////////////////////////////////////////////////// 270 unsigned int _bdv_get_status( unsigned int channel, 271 unsigned int* status ) 272 { 273 if ( channel != 0 ) 274 { 275 _tty_get_lock( 0 ); 276 _puts("\n[GIET ERROR] in _bdv_get_status() : illegal channel\n"); 277 _tty_release_lock( 0 ); 278 279 return 1; 280 } 281 282 // get IOC base address 283 volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base; 284 *status = ioc_address[BLOCK_DEVICE_STATUS]; 285 286 return 0; 287 } 288 289 /////////////////////////////////////////////////////////////////////////////// 290 // _bdv_get_block_size() 291 // This function returns the block_size with which the IOC has been configured. 292 /////////////////////////////////////////////////////////////////////////////// 293 unsigned int _bdv_get_block_size() 294 { 295 // get IOC base address 296 volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base; 297 298 return ioc_address[BLOCK_DEVICE_BLOCK_SIZE]; 275 // Returns device status. 276 /////////////////////////////////////////////////////////////////////////////// 277 unsigned int _bdv_get_status() 278 { 279 return _bdv_get_register( BLOCK_DEVICE_STATUS ); 280 } 281 282 /////////////////////////////////////////////////////////////////////////////// 283 // Returns block size. 284 /////////////////////////////////////////////////////////////////////////////// 285 unsigned int _bdv_get_block_size() 286 { 287 return _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE ); 288 } 289 290 /////////////////////////////////////////////////////////////////////////////////// 291 // This ISR save the status, acknowledge the IRQ, 292 // and activates the task waiting on IO transfer. 293 // It can be an HWI or a SWI. 294 // 295 // TODO the _set_task_slot access should be replaced by an atomic LL/SC 296 // when the CTX_RUN bool will be replaced by a bit_vector. 297 /////////////////////////////////////////////////////////////////////////////////// 298 void _bdv_isr( unsigned int irq_type, // HWI / WTI 299 unsigned int irq_id, // index returned by ICU 300 unsigned int channel ) // unused 301 { 302 unsigned int procid = _get_procid(); 303 unsigned int cluster_xy = procid / NB_PROCS_MAX; 304 unsigned int lpid = procid % NB_PROCS_MAX; 305 306 // acknowledge WTI in local XCU if required 307 unsigned int value; 308 if ( irq_type == IRQ_TYPE_WTI ) _xcu_get_wti_value( cluster_xy, irq_id, &value ); 309 310 // save status in _bdv_status variable and reset IRQ 311 _bdv_status = _bdv_get_register( BLOCK_DEVICE_STATUS ); 312 313 // identify task waiting on BDV 314 unsigned int rprocid = _bdv_gtid>>16; 315 unsigned int ltid = _bdv_gtid & 0xFFFF; 316 unsigned int remote_xy = rprocid / NB_PROCS_MAX; 317 318 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlock 319 unsigned int x = cluster_xy >> Y_WIDTH; 320 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 321 unsigned int rx = remote_xy >> Y_WIDTH; 322 unsigned int ry = remote_xy & ((1<<Y_WIDTH)-1); 323 unsigned int rlpid = rprocid % NB_PROCS_MAX; 324 _puts("\n[IRQS DEBUG] Processor["); 325 _putd(x ); 326 _puts(","); 327 _putd(y ); 328 _puts(","); 329 _putd(lpid ); 330 _puts("] enters _bdv_isr() at cycle "); 331 _putd(_get_proctime() ); 332 _puts("\n for task "); 333 _putd(ltid ); 334 _puts(" running on processor["); 335 _putd(rx ); 336 _puts(","); 337 _putd(ry ); 338 _puts(","); 339 _putd(rlpid ); 340 _puts(" / bdv status = "); 341 _putx(_bdv_status ); 342 _puts("\n"); 343 #endif 344 345 // re-activates sleeping task 346 _set_task_slot( rprocid, // global processor index 347 ltid, // local task index on processor 348 CTX_RUN_ID, // CTX_RUN slot 349 1 ); // running 350 351 // requires a context switch for remote processor running the waiting task 352 _xcu_send_wti( remote_xy, // cluster index 353 lpid, // local processor index 354 0 ); // don't force context switch if not idle 299 355 } 300 356 -
soft/giet_vm/giet_drivers/bdv_driver.h
r289 r295 7 7 /////////////////////////////////////////////////////////////////////////////////// 8 8 9 #ifndef _GIET_BDV_DRIVERS_H_ 10 #define _GIET_BDV_DRIVERS_H_ 11 12 #include <mapping_info.h> 9 #ifndef _GIET_BDV_DRIVER_H_ 10 #define _GIET_BDV_DRIVER_H_ 13 11 14 12 /////////////////////////////////////////////////////////////////////////////////// 15 // BDV access functions and variables (vci_block_device)13 // BDV global variables 16 14 /////////////////////////////////////////////////////////////////////////////////// 17 15 18 extern unsigned int _bdv_init( unsigned int channel ); 16 extern unsigned int _bdv_lock; // BDV is a shared ressource 17 extern volatile unsigned int _bdv_status; // required for IRQ signaling 18 extern volatile unsigned int _bdv_gtid; // descheduled task id = gpid<<16 + ltid 19 19 20 extern unsigned int _bdv_write( unsigned int mode, 21 unsigned int lba, 22 paddr_t buffer, 23 unsigned int count ); 20 /////////////////////////////////////////////////////////////////////////////////// 21 // BDV registers, operations and status values 22 /////////////////////////////////////////////////////////////////////////////////// 24 23 25 extern unsigned int _bdv_read( unsigned int mode, 26 unsigned int lba, 27 paddr_t buffer, 28 unsigned int count ); 24 enum BDV_registers 25 { 26 BLOCK_DEVICE_BUFFER, 27 BLOCK_DEVICE_LBA, 28 BLOCK_DEVICE_COUNT, 29 BLOCK_DEVICE_OP, 30 BLOCK_DEVICE_STATUS, 31 BLOCK_DEVICE_IRQ_ENABLE, 32 BLOCK_DEVICE_SIZE, 33 BLOCK_DEVICE_BLOCK_SIZE, 34 BLOCK_DEVICE_BUFFER_EXT, 35 }; 29 36 30 extern unsigned int _bdv_get_status( unsigned int channel, 31 unsigned int* status ); 37 enum BDV_operations 38 { 39 BLOCK_DEVICE_NOOP, 40 BLOCK_DEVICE_READ, 41 BLOCK_DEVICE_WRITE, 42 }; 43 44 enum BDV_status 45 { 46 BLOCK_DEVICE_IDLE, 47 BLOCK_DEVICE_BUSY, 48 BLOCK_DEVICE_READ_SUCCESS, 49 BLOCK_DEVICE_WRITE_SUCCESS, 50 BLOCK_DEVICE_READ_ERROR, 51 BLOCK_DEVICE_WRITE_ERROR, 52 BLOCK_DEVICE_ERROR, 53 }; 54 55 /////////////////////////////////////////////////////////////////////////////////// 56 // BDV access functions (vci_block_device) 57 /////////////////////////////////////////////////////////////////////////////////// 58 59 extern unsigned int _bdv_init(); 60 61 extern unsigned int _bdv_write( unsigned int mode, 62 unsigned int lba, 63 unsigned long long buffer, 64 unsigned int count ); 65 66 extern unsigned int _bdv_read( unsigned int mode, 67 unsigned int lba, 68 unsigned long long buffer, 69 unsigned int count ); 70 71 extern unsigned int _bdv_get_status(); 32 72 33 73 extern unsigned int _bdv_get_block_size(); 74 75 extern void _bdv_isr( unsigned irq_type, 76 unsigned irq_id, 77 unsigned channel ); 34 78 35 79 /////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_drivers/cma_driver.h
r258 r295 29 29 }; 30 30 31 /////////////////////////////////////////////////////////////////////////////////// 32 // CMA (vci_chbuf_dma) low-level access functions 33 /////////////////////////////////////////////////////////////////////////////////// 34 35 extern unsigned int _cma_get_register( unsigned int channel, 36 unsigned int index ); 37 38 extern void _cma_set_register( unsigned int channel, 39 unsigned int index, 40 unsigned int value ); 41 42 extern void _cma_isr( unsigned int irq_type, 43 unsigned int irq_id, 44 unsigned int channel ); 45 46 /////////////////////////////////////////////////////////////////////////////////// 47 31 48 #endif 32 49 -
soft/giet_vm/giet_drivers/dma_driver.c
r267 r295 196 196 unsigned int procid = _get_procid(); 197 197 unsigned int cluster_xy = procid/NB_PROCS_MAX; 198 unsigned int x = cluster_xy >> Y_WIDTH; 199 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 198 200 unsigned int channel_id = procid%NB_PROCS_MAX; 199 201 … … 203 205 204 206 #if GIET_DEBUG_DMA_DRIVER 205 _tty_get_lock( 0 ); 206 _puts("\n[DMA DEBUG] Enter _dma_copy() at cycle "); 207 _putd( _get_proctime() ); 208 _puts("\n - vspace_id = "); 209 _putx( vspace_id ); 210 _puts("\n - cluster_xy = "); 211 _putx( cluster_xy ); 212 _puts("\n - channel_id = "); 213 _putx( channel_id ); 214 _puts("\n - dest = "); 215 _putx( (unsigned int)dest ); 216 _puts("\n - source = "); 217 _putx( (unsigned int)source ); 218 _puts("\n - bytes = "); 219 _putd( size ); 220 _tty_release_lock( 0 ); 207 unsigned int x = cluster_xy >> Y_WIDTH; 208 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 209 210 _printf("\n[DMA DEBUG] Processor[%d,%d,%d] enters _dma_copy() at cycle %d\n" 211 " - vspace_id = %d\n" 212 " - cluster_xy = %x\n" 213 " - channel_id = %d\n" 214 " - dest = %x\n" 215 " - source = %x\n" 216 " - bytes = %x\n", 217 x, y, channel_id, _get_proctime(), vspace_id, cluster_xy, 218 (unsigned int)dest, (unsigned int)source, size ); 221 219 #endif 222 220 … … 226 224 (size & 0x3) ) 227 225 { 228 _tty_get_lock( 0 ); 229 _puts("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n"); 230 _tty_release_lock( 0 ); 226 _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n"); 231 227 _exit(); 232 228 } … … 242 238 if ( ko ) 243 239 { 244 _tty_get_lock( 0 ); 245 _puts("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n"); 246 _tty_release_lock( 0 ); 240 _printf("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n"); 247 241 _exit(); 248 242 } … … 257 251 if ( ko ) 258 252 { 259 _tty_get_lock( 0 ); 260 _puts("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n"); 261 _tty_release_lock( 0 ); 253 _printf("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n"); 262 254 _exit(); 263 255 } … … 266 258 267 259 #if GIET_DEBUG_DMA_DRIVER 268 _tty_get_lock( 0 ); 269 _puts("\n - src_paddr = "); 270 _putl( src_paddr ); 271 _puts("\n - dst_paddr = "); 272 _putl( dst_paddr ); 273 _puts("\n"); 274 _tty_release_lock( 0 ); 260 _printf(" - src_paddr = %llx\n" 261 " - dst_paddr = %llx\n", 262 src_paddr, dst_paddr ); 275 263 #endif 276 264 … … 282 270 if ( ko ) 283 271 { 284 _tty_get_lock( 0 ); 285 _puts("\n[GIET ERROR] in _dma_copy() : cannot start transfer\n"); 286 _tty_release_lock( 0 ); 272 _printf("\n[GIET ERROR] in _dma_copy() : cannot start transfer\n"); 287 273 _exit(); 288 274 } … … 297 283 298 284 #if GIET_DEBUG_DMA_DRIVER 299 _tty_get_lock( 0 ); 300 _puts("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register ...\n"); 301 _tty_release_lock( 0 ); 285 _printf("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register ...\n"); 302 286 #endif 303 287 … … 307 291 if( status != DMA_SUCCESS ) 308 292 { 309 _tty_get_lock( 0 ); 310 _puts("\n[GIET ERROR] in _dma_copy() : DMA_STATUS error = "); 311 _putd( status ); 312 _puts("\n"); 313 _tty_release_lock( 0 ); 293 _printf("\n[GIET ERROR] in _dma_copy() : DMA_STATUS = %x\n", status ); 314 294 _exit(); 315 295 } … … 318 298 319 299 #if GIET_DEBUG_DMA_DRIVER 320 _tty_get_lock( 0 ); 321 _puts("\n[DMA DEBUG] _dma_copy() completed at cycle "); 322 _putd( _get_proctime() ); 323 _puts("\n"); 324 _tty_release_lock( 0 ); 300 _printf("\n[DMA DEBUG] _dma_copy() completed at cycle %d\n", _get_proctime() ); 325 301 #endif 326 302 327 303 #else // NB_DMA_CHANNELS == 0 328 _tty_get_lock( 0 ); 329 _puts("\n[GIET ERROR] in _dma_copy() : NB_DMA_CHANNELS = 0 !\n"); 330 _tty_release_lock( 0 ); 304 _printf("\n[GIET ERROR] in _dma_copy() : NB_DMA_CHANNELS = 0 !\n"); 331 305 _exit(); 332 306 #endif -
soft/giet_vm/giet_drivers/fbf_driver.c
r275 r295 7 7 // The fbf_driver.c and fbf_driver.h files are part ot the GIET-VM kernel. 8 8 // This driver supports the SoCLib vci_framebuffer component. 9 //10 // It can exist only one frame buffer in the architecture.11 9 // 12 10 // There exist two methods to access the VciFrameBuffer device: … … 59 57 unsigned int length) 60 58 { 61 char* fb_address = (char *)&seg_fbf_base + offset; 62 _memcpy( fb_address, buffer, length); 59 char* fbf_address = (char *)&seg_fbf_base + offset; 60 61 _memcpy( fbf_address, buffer, length); 62 63 63 return 0; 64 64 } … … 74 74 unsigned int length) 75 75 { 76 char* fb_address = (char *)&seg_fbf_base + offset; 77 _memcpy( buffer, fb_address, length); 76 char* fbf_address = (char *)&seg_fbf_base + offset; 77 78 _memcpy( buffer, fbf_address, length); 79 78 80 return 0; 79 81 } … … 145 147 if ( channel_id >= NB_CMA_CHANNELS ) 146 148 { 147 _tty_get_lock( 0 ); 148 _puts("\n[GIET ERROR] in _fb_cma_init() : CMA channel index too large\n"); 149 _tty_release_lock( 0 ); 149 _printf("\n[GIET ERROR] in _fb_cma_init() : CMA channel index too large\n"); 150 150 return 1; 151 151 } … … 154 154 if ( sizeof(fb_cma_channel_t) != 32 ) 155 155 { 156 _tty_get_lock( 0 ); 157 _puts("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel size\n"); 158 _tty_release_lock( 0 ); 156 _printf("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel size\n"); 159 157 return 1; 160 158 } … … 163 161 if ( (unsigned int)(&_fb_cma_channel[channel_id]) & 0x1F ) 164 162 { 165 _tty_get_lock( 0 ); 166 _puts("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel alignment\n"); 167 _tty_release_lock( 0 ); 163 _printf("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel alignment\n"); 168 164 return 1; 169 165 } … … 172 168 if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 173 169 { 174 _tty_get_lock( 0 ); 175 _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer not word aligned\n"); 176 _tty_release_lock( 0 ); 170 _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer not word aligned\n"); 177 171 return 1; 178 172 } … … 189 183 if (ko) 190 184 { 191 _tty_get_lock( 0 ); 192 _puts("\n[GIET ERROR] in _fb_cma_init() : frame buffer unmapped\n"); 193 _tty_release_lock( 0 ); 185 _printf("\n[GIET ERROR] in _fb_cma_init() : frame buffer unmapped\n"); 194 186 return 1; 195 187 } … … 204 196 if (ko) 205 197 { 206 _tty_get_lock( 0 ); 207 _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 0 unmapped\n"); 208 _tty_release_lock( 0 ); 198 _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer 0 unmapped\n"); 209 199 return 1; 210 200 } 211 201 if ((flags & PTE_U) == 0) 212 202 { 213 _tty_get_lock( 0 ); 214 _puts("[GIET ERROR] in _fb_cma_init() : user buffer 0 not in user space\n"); 215 _tty_release_lock( 0 ); 203 _printf("[GIET ERROR] in _fb_cma_init() : user buffer 0 not in user space\n"); 216 204 return 1; 217 205 } … … 226 214 if (ko) 227 215 { 228 _tty_get_lock( 0 ); 229 _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 1 unmapped\n"); 230 _tty_release_lock( 0 ); 216 _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer 1 unmapped\n"); 231 217 return 1; 232 218 } 233 219 if ((flags & PTE_U) == 0) 234 220 { 235 _tty_get_lock( 0 ); 236 _puts("[GIET ERROR] in _fb_cma_init() : user buffer 1 not in user space\n"); 237 _tty_release_lock( 0 ); 221 _printf("[GIET ERROR] in _fb_cma_init() : user buffer 1 not in user space\n"); 238 222 return 1; 239 223 } … … 251 235 if (ko) 252 236 { 253 _tty_get_lock( 0 ); 254 _puts("\n[GIET ERROR] in _fb_cma_init() : channel descriptor unmapped\n"); 255 _tty_release_lock( 0 ); 237 _printf("\n[GIET ERROR] in _fb_cma_init() : channel descriptor unmapped\n"); 256 238 return 1; 257 239 } … … 262 244 263 245 #if GIET_DEBUG_FBF_DRIVER 264 _tty_get_lock( 0 ); 265 _puts("\n[CMA DEBUG] fb_cma_init()"); 266 _puts("\n - fbf pbase = "); 267 _putl( _fb_cma_channel[channel_id].fbf ); 268 _puts("\n - buf0 pbase = "); 269 _putl( _fb_cma_channel[channel_id].buf0 ); 270 _puts("\n - buf1 pbase = "); 271 _putl( _fb_cma_channel[channel_id].buf1 ); 272 _puts("\n - channel pbase = "); 273 _putl( _fb_cma_desc_paddr[channel_id] ); 274 _puts("\n"); 275 _tty_release_lock( 0 ); 246 _printf("\n[CMA DEBUG] enters _fb_cma_init()\n" 247 " - fbf pbase = %l\n" 248 " - buf0 pbase = %l\n" 249 " - buf1 pbase = %l\n" 250 " - channel pbase = %l\n" 251 _fb_cma_channel[channel_id].fbf, 252 _fb_cma_channel[channel_id].buf0, 253 _fb_cma_channel[channel_id].buf1, 254 _fb_cma_desc_paddr[channel_id] ); 276 255 #endif 277 256 … … 283 262 284 263 // CMA channel activation 285 unsigned int* cma_vbase = (unsigned int *)&seg_cma_base; 286 unsigned int offset = channel_id * CHBUF_CHANNEL_SPAN; 287 288 cma_vbase[offset + CHBUF_SRC_DESC] = (unsigned int)(desc_paddr & 0xFFFFFFFF); 289 cma_vbase[offset + CHBUF_SRC_EXT] = (unsigned int)(desc_paddr >> 32); 290 cma_vbase[offset + CHBUF_SRC_NBUFS] = 2; 291 cma_vbase[offset + CHBUF_DST_DESC] = (unsigned int)(desc_paddr & 0xFFFFFFFF) + 16; 292 cma_vbase[offset + CHBUF_DST_EXT] = (unsigned int)(desc_paddr >> 32); 293 cma_vbase[offset + CHBUF_DST_NBUFS] = 1; 294 cma_vbase[offset + CHBUF_BUF_SIZE] = length; 295 cma_vbase[offset + CHBUF_PERIOD] = 300; 296 cma_vbase[offset + CHBUF_RUN] = 1; 297 264 _cma_set_register( channel_id, CHBUF_SRC_DESC , (unsigned int)(desc_paddr & 0xFFFFFFFF) ); 265 _cma_set_register( channel_id, CHBUF_SRC_EXT , (unsigned int)(desc_paddr >> 32) ); 266 _cma_set_register( channel_id, CHBUF_SRC_NBUFS, 2 ); 267 _cma_set_register( channel_id, CHBUF_DST_DESC , (unsigned int)(desc_paddr & 0xFFFFFFFF) + 16 ); 268 _cma_set_register( channel_id, CHBUF_DST_EXT , (unsigned int)(desc_paddr >> 32) ); 269 _cma_set_register( channel_id, CHBUF_DST_NBUFS, 1 ); 270 _cma_set_register( channel_id, CHBUF_BUF_SIZE , length ); 271 _cma_set_register( channel_id, CHBUF_PERIOD , 300 ); 272 _cma_set_register( channel_id, CHBUF_RUN , 1 ); 298 273 return 0; 299 274 300 275 #else 301 302 _tty_get_lock( 0 ); 303 _puts("\n[GIET ERROR] in _fb_cma_init() : no CMA channel allocated\n"); 304 _tty_release_lock( 0 ); 305 276 _printf("\n[GIET ERROR] in _fb_cma_init() : no CMA channel allocated\n"); 306 277 return 1; 307 278 #endif 308 279 } 280 309 281 //////////////////////////////////////////////////////////////////////////////////// 310 282 // _fb_cma_write() … … 330 302 331 303 volatile paddr_t buf_paddr; 332 unsigned int buf_length;333 304 unsigned int full = 1; 334 305 … … 339 310 340 311 #if GIET_DEBUG_FBF_DRIVER 341 _tty_get_lock( 0 ); 342 _puts("\n[CMA DEBUG] fb_cma_write() for CMA channel "); 343 _putd( channel_id ); 344 _puts(" / buf_id = "); 345 _putd( buffer_id ); 346 _puts("\n"); 347 _tty_release_lock( 0 ); 312 _printf("\n[CMA DEBUG] _fb_cma_write() for CMA channel %d / bufid = %d at cycle %d\n", 313 channel_id, buffer_id, _get_proctime() ); 348 314 #endif 349 315 … … 357 323 358 324 // INVAL L1 cache for the channel descriptor, 359 _dcache_buf_invalidate( &_fb_cma_channel[channel_id], 32 );325 _dcache_buf_invalidate( (void*)&_fb_cma_channel[channel_id], 32 ); 360 326 } 361 327 … … 367 333 count++; 368 334 if ( count == 10 ) _exit(); 369 370 #if GIET_DEBUG_FBF_DRIVER371 _tty_get_lock( 0 );372 _puts(" - buffer descriptor = ");373 _putl( buf_paddr );374 _puts(" at cycle ");375 _putd( _get_proctime() );376 _puts("\n");377 _tty_release_lock( 0 );378 #endif379 380 335 } 381 336 … … 408 363 #else 409 364 410 _tty_get_lock( 0 ); 411 _puts("\n[GIET ERROR] in _fb_cma_channel() : no CMA channel allocated\n"); 412 _tty_release_lock( 0 ); 365 _printf("\n[GIET ERROR] in _fb_cma_channel() : no CMA channel allocated\n"); 413 366 return 1; 414 367 … … 427 380 unsigned int channel_id = _get_context_slot(CTX_CMA_ID); 428 381 382 #if GIET_DEBUG_FBF_DRIVER 383 _printf("\n[CMA DEBUG] _fb_cma_stop() for CMA channel %d at cycle %d\n", 384 channel_id, _get_proctime() ); 385 #endif 386 429 387 // CMA channel desactivation 430 unsigned int* cma_vbase = (unsigned int *)&seg_cma_base; 431 unsigned int offset = channel_id * CHBUF_CHANNEL_SPAN; 432 cma_vbase[offset + CHBUF_RUN] = 0; 388 _cma_set_register( channel_id, CHBUF_RUN, 0 ); 389 433 390 return 0; 434 391 435 392 #else 436 393 437 _tty_get_lock( 0 ); 438 _puts("\n[GIET ERROR] in _fb_cma_stop() : no CMA channel allocated\n"); 439 _tty_release_lock( 0 ); 394 _printf("\n[GIET ERROR] in _fb_cma_stop() : no CMA channel allocated\n"); 440 395 return 1; 441 396 -
soft/giet_vm/giet_drivers/hba_driver.c
r289 r295 2 2 // File : hba_driver.c 3 3 // Date : 23/11/2013 4 // Author : alain greiner and zhang4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// … … 9 9 // block oriented, external storage contrÃŽler, respecting the AHCI standard. 10 10 // 11 // It can exist only one ahci-device controler in the architecture. 11 // The seg_ioc_base (standard HBA virtual base address) and seg_ioc_base_bis 12 // (backup HBA virtual base address) must be defined in giet_vsegs.ld file. 13 ////////////////////////////////////////////////////////////////////////////////// 14 // Implementation notes: 12 15 // 13 // The _ioc_read() and _ioc_write() functions use the _ioc_access() function,14 // that is always blocking, but can be called in 4 modes:16 // 1. In order to share code, the two _hba_read() and _hba_write() functions 17 // call the same _hba_set_cmd() function. 15 18 // 16 // - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address 17 // as a physical address (as the page tables are not build) and use a polling 18 // policy on the IOC_STATUS register to detect transfer completion, as 19 // hardware interrupts are not activated. This mode is used by the 20 // boot code to load the map.bin file into memory. 21 // 22 // - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to 23 // compute the buffer physical address, and use a polling policy on IOC_STATUS 24 // register to detect transfer completion. This mode is used by the boot code 25 // to load the various .elf files into memory. 26 // 27 // - In KERNEL mode, the _ioc_access() function makes a V2P translation to 28 // compute the buffer physical address, and use a descheduling strategy: 29 // The ISR executed when transfer completes should restart the calling task. 30 // There is no checking of user access right to the memory buffer. 31 // This mode must be used to access IOC, for an "open" system call. 32 // 33 // - In USER mode, the _ioc_access() function makes a V2P translation to 34 // compute the buffer physical address, and use a descheduling strategy: 35 // The ISR executed when transfer completes should restart the calling task, 36 // The user access right to the memory buffer must be checked. 37 // This mode must be used to access IOC, for a "read/write" system call. 38 // 39 // As the IOC component can be used by several programs running in parallel, 40 // the _ioc_lock variable guaranties exclusive access to the device. The 41 // _ioc_read() and _ioc_write() functions use atomic LL/SC to get the lock. 42 // 43 // The IOMMU can be activated or not: 44 // 45 // 1) When the IOMMU is used, a fixed size 2Mbytes vseg is allocated to 46 // the IOC peripheral, in the I/O virtual space, and the user buffer is 47 // dynamically remapped in the IOMMU page table. The corresponding entry 48 // in the IOMMU PT1 is defined by the kernel _ioc_iommu_ix1 variable. 49 // The number of pages to be unmapped is stored in the _ioc_npages variable. 50 // The number of PT2 entries is dynamically computed and stored in the 51 // kernel _ioc_iommu_npages variable. It cannot be larger than 512. 52 // The user buffer is unmapped by the _ioc_completed() function when 53 // the transfer is completed. 54 // 55 // 2/ If the IOMMU is not used, we check that the user buffer is mapped to a 56 // contiguous physical buffer (this is generally true because the user space 57 // page tables are statically constructed to use contiguous physical memory). 58 // 59 // Finally, the memory buffer must fulfill the following conditions: 60 // - The buffer must be word aligned, 61 // - The buffer must be mapped in user space for an user access, 62 // - The buffer must be writable in case of (to_mem) access, 63 // - The total number of physical pages occupied by the user buffer cannot 64 // be larger than 512 pages if the IOMMU is activated, 65 // - All physical pages occupied by the user buffer must be contiguous 66 // if the IOMMU is not activated. 67 // An error code is returned if these conditions are not verified. 68 /////////////////////////////////////////////////////////////////////////////////// 69 // The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file. 19 // 2. All accesses to HBA registers are done by the two 20 // _hba_set_register() and _hba_get_register() low-level functions, 21 // that are handling virtual / physical extended addressing. 70 22 /////////////////////////////////////////////////////////////////////////////////// 71 23 … … 80 32 #include <vmem.h> 81 33 82 #if !defined( NB_HBA_CHANNELS ) 83 # error: You must define NB_HBA_CHANNELS in the hard_config.h file 84 #endif 85 86 #if ( NB_HBA_CHANNELS > 8 ) 87 # error: NB_HBA_CHANNELS cannot be larger than 8 88 #endif 89 90 #if !defined( USE_IOB ) 91 # error: You must define USE_IOB in the hard_config.h file 92 #endif 93 94 #if !defined(GIET_USE_IOMMU) 95 # error: You must define GIET_USE_IOMMU in the giet_config.h file 34 #if !defined( NB_IOC_CHANNELS ) 35 # error: You must define NB_IOC_CHANNELS in the hard_config.h file 36 #endif 37 38 #if ( NB_IOC_CHANNELS > 8 ) 39 # error: NB_IOC_CHANNELS cannot be larger than 8 96 40 #endif 97 41 … … 103 47 104 48 // command list array (one per channel) 105 hba_cmd_list_t hba_cmd_list[NB_ HBA_CHANNELS] __attribute__((aligned(0x1000)));49 hba_cmd_list_t hba_cmd_list[NB_IOC_CHANNELS] __attribute__((aligned(0x1000))); 106 50 107 51 // command tables array (32 command tables per channel) 108 hba_cmd_table_t hba_cmd_table[NB_ HBA_CHANNELS][32] __attribute__((aligned(0x1000)));52 hba_cmd_table_t hba_cmd_table[NB_IOC_CHANNELS][32] __attribute__((aligned(0x1000))); 109 53 110 54 // command list physical addresses array (one per channel) 111 paddr_t hba_cmd_list_paddr[NB_ HBA_CHANNELS];55 paddr_t hba_cmd_list_paddr[NB_IOC_CHANNELS]; 112 56 113 57 // command tables physical addresses array (32 command tables per channel) 114 paddr_t hba_cmd_table_paddr[NB_ HBA_CHANNELS][32];58 paddr_t hba_cmd_table_paddr[NB_IOC_CHANNELS][32]; 115 59 116 60 // command list pointer array (one per channel) 117 unsigned int hba_cmd_slot[NB_HBA_CHANNELS]; 118 119 ////////////////////////////////////////////////////////////////// 120 // This function returns the status of a given channel. 121 // return 0 if success, >0 if error 122 ////////////////////////////////////////////////////////////////// 123 unsigned int _hba_get_status( unsigned int channel, 124 unsigned int* status ) 125 { 126 volatile unsigned int* hba_address; 127 hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN*channel); 128 129 if( channel >= NB_HBA_CHANNELS ) 130 { 131 _tty_get_lock( 0 ); 132 _puts("\n[GIET ERROR] in _hba_get_status() : illegal channel\n"); 133 _tty_release_lock( 0 ); 134 return 1; 135 } 136 else 137 { 138 *status = hba_address[HBA_PXIS]; 139 return 0; 140 } 141 } 142 ////////////////////////////////////////////////////////////////// 143 // This function reset the status resgister for a given channel. 144 // return 0 if success, >0 if error 145 ////////////////////////////////////////////////////////////////// 146 unsigned int _hba_reset_status( unsigned int channel ) 147 { 148 volatile unsigned int* hba_address; 149 hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN*channel); 150 151 if( channel >= NB_HBA_CHANNELS ) 152 { 153 _tty_get_lock( 0 ); 154 _puts("\n[GIET ERROR] in _hba_reset_status() : illegal channel\n"); 155 _tty_release_lock( 0 ); 156 return 1; 157 } 158 else 159 { 160 hba_address[HBA_PXIS] = 0; 161 return 0; 162 } 163 } 61 unsigned int hba_cmd_slot[NB_IOC_CHANNELS]; 62 63 ////////////////////////////////////////////////////////////////////////////// 64 // This low level function returns the value of register (channel / index) 65 ////////////////////////////////////////////////////////////////////////////// 66 unsigned int _hba_get_register( unsigned int channel, 67 unsigned int index ) 68 { 69 unsigned int* vaddr = (unsigned int*)&seg_ioc_base + channel*HBA_SPAN + index; 70 return _io_extended_read( vaddr ); 71 } 72 73 ////////////////////////////////////////////////////////////////////////////// 74 // This low level function set a new value in register (channel / index) 75 ////////////////////////////////////////////////////////////////////////////// 76 void _hba_set_register( unsigned int channel, 77 unsigned int index, 78 unsigned int value ) 79 { 80 unsigned int* vaddr = (unsigned int*)&seg_ioc_base + channel*HBA_SPAN + index; 81 _io_extended_write( vaddr, value ); 82 } 83 84 164 85 /////////////////////////////////////////////////////////////////////////////// 165 86 // This function register a command in both the command list … … 171 92 // return 0 if success, > 0 if error 172 93 /////////////////////////////////////////////////////////////////////////////// 173 unsigned int _hba_cmd_set( unsigned int is_read, // to memory 94 unsigned int _hba_cmd_set( unsigned int channel, // channel index 95 unsigned int is_read, // to memory 174 96 unsigned int lba, // logic block address 175 unsigned int buf_vaddr, // buffer virtual address97 paddr_t buffer, // buffer physical address 176 98 unsigned int count ) // number of blocks 177 99 { 178 volatile unsigned int *hba_address;179 180 100 unsigned int block_size; // defined by the block device (bytes) 181 unsigned int channel_id; // channel index182 101 unsigned int pxci; // command list status 183 102 unsigned int cmd_id; // command index in command list 184 unsigned int buf_id; // for physical buffers covering user buffer 185 unsigned int user_pt_vbase; // user page table virtual base address 186 unsigned int vpn; // for all pages covering the userbuffer 187 unsigned int vpn_min; // first virtual page index for user buffer 188 unsigned int vpn_max; // last virtual page index for user buffer 189 unsigned int offset; // unaligned bytes in page frame: buf_vaddr & 0xFFF 190 unsigned int offset_last; // unaligned bytes in last frame 103 191 104 hba_cmd_desc_t* cmd_desc; // command descriptor pointer 192 105 hba_cmd_table_t* cmd_table; // command table pointer … … 195 108 196 109 // check buffer alignment 197 if( buf_vaddr & (block_size-1) ) 198 { 199 _tty_get_lock( 0 ); 200 _puts("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n"); 201 _tty_release_lock( 0 ); 110 if( buffer & (block_size-1) ) 111 { 112 _printf("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n"); 202 113 return 1; 203 114 } 204 115 205 // get channel index 206 channel_id = _get_context_slot(CTX_HBA_ID); 207 if ( channel_id == 0xFFFFFFFF ) 208 { 209 _tty_get_lock( 0 ); 210 _puts("\n[GIET ERROR] in _hba_set_cmd() : no HBA channel allocated\n"); 211 _tty_release_lock( 0 ); 116 // get command list status from PXCI register 117 pxci = _hba_get_register( channel, HBA_PXCI ); 118 119 // get command index and return error if command list full 120 cmd_id = hba_cmd_slot[channel]; 121 if( pxci & (1<<cmd_id ) ) 122 { 123 _printf("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel %d\n", 124 channel ); 212 125 return 1; 213 126 } 214 127 215 // get hba device address216 hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN * channel_id);217 218 // get command list status219 pxci = hba_address[HBA_PXCI];220 221 // get command index and return error if command list full222 cmd_id = hba_cmd_slot[channel_id];223 if( pxci & (1<<cmd_id ) )224 {225 _tty_get_lock( 0 );226 _puts("\n[GIET ERROR] in _hba_set_cmd() : command list full in channel \n");227 _putd( channel_id );228 _puts("\n");229 _tty_release_lock( 0 );230 return 1;231 }232 233 128 // compute pointers on command descriptor and command table 234 cmd_desc = (hba_cmd_desc_t*)(&(hba_cmd_list[channel_id].desc[cmd_id])); 235 cmd_table = (hba_cmd_table_t*)(&(hba_cmd_table[channel_id][cmd_id])); 129 cmd_desc = (hba_cmd_desc_t*)(&(hba_cmd_list[channel].desc[cmd_id])); 130 cmd_table = (hba_cmd_table_t*)(&(hba_cmd_table[channel][cmd_id])); 131 132 // set buffer descriptor in command table 133 cmd_table->entry[0].dba = (unsigned int)(buffer); 134 cmd_table->entry[0].dbau = (unsigned int)(buffer >> 32); 135 cmd_table->entry[0].dbc = count * block_size; 136 137 // initialize command table header 138 cmd_table->header.lba0 = (char)lba; 139 cmd_table->header.lba1 = (char)(lba>>8); 140 cmd_table->header.lba2 = (char)(lba>>16); 141 cmd_table->header.lba3 = (char)(lba>>24); 142 cmd_table->header.lba4 = 0; 143 cmd_table->header.lba5 = 0; 144 145 // initialise command descriptor 146 cmd_desc->prdtl[0] = 1; 147 cmd_desc->prdtl[1] = 0; 148 cmd_desc->ctba = (unsigned int)(hba_cmd_table_paddr[channel][cmd_id]); 149 cmd_desc->ctbau = (unsigned int)(hba_cmd_table_paddr[channel][cmd_id]>>32); 150 if( is_read ) cmd_desc->flag[0] = 0x00; 151 else cmd_desc->flag[0] = 0x40; 152 153 // update PXCI register 154 _hba_set_register( channel, HBA_PXCI, (1<<cmd_id) ); 155 156 // update command pointer 157 hba_cmd_slot[channel] = (cmd_id + 1)%32; 158 159 return 0; 160 } 161 162 /* This can be used for a future use with buffer in virtual space 236 163 237 164 // get user space page table virtual address … … 262 189 if ( ko ) 263 190 { 264 _tty_get_lock( 0 ); 265 _puts("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n"); 266 _tty_release_lock( 0 ); 191 _printf("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n"); 267 192 return 1; 268 193 } 269 194 if ((flags & PTE_U) == 0) 270 195 { 271 _tty_get_lock( 0 ); 272 _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n"); 273 _tty_release_lock( 0 ); 196 _printf("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n"); 274 197 return 1; 275 198 } 276 199 if (((flags & PTE_W) == 0 ) && (is_read == 0) ) 277 200 { 278 _tty_get_lock( 0 ); 279 _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n"); 280 _tty_release_lock( 0 ); 201 _printf("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n"); 281 202 return 1; 282 203 } … … 285 206 if( buf_id > 245 ) 286 207 { 287 _tty_get_lock( 0 ); 288 _puts("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n"); 289 _tty_release_lock( 0 ); 208 _printf("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n"); 290 209 return 1; 291 210 } … … 301 220 302 221 #if GIET_DEBUG_HBA_DRIVER 303 _p uts("\n- buf_index = ");222 _printf("\n- buf_index = "); 304 223 _putd( buf_id ); 305 _p uts(" / paddr = ");224 _printf(" / paddr = "); 306 225 _putl( paddr ); 307 _p uts(" / count = ");226 _printf(" / count = "); 308 227 _putd( count ); 309 _p uts("\n");228 _printf("\n"); 310 229 #endif 311 230 buf_id++; … … 320 239 321 240 #if GIET_DEBUG_HBA_DRIVER 322 _p uts("\n- buf_index = ");241 _printf("\n- buf_index = "); 323 242 _putd( buf_id ); 324 _p uts(" / paddr = ");243 _printf(" / paddr = "); 325 244 _putl( paddr ); 326 _p uts(" / count = ");245 _printf(" / count = "); 327 246 _putd( count ); 328 _p uts("\n");247 _printf("\n"); 329 248 #endif 330 249 buf_id++; … … 340 259 341 260 #if GIET_DEBUG_HBA_DRIVER 342 _p uts("\n- buf_index = ");261 _printf("\n- buf_index = "); 343 262 _putd( buf_id ); 344 _p uts(" / paddr = ");263 _printf(" / paddr = "); 345 264 _putl( paddr ); 346 _p uts(" / count = ");265 _printf(" / count = "); 347 266 _putd( count ); 348 _p uts("\n");267 _printf("\n"); 349 268 #endif 350 269 buf_id++; … … 357 276 358 277 #if GIET_DEBUG_HBA_DRIVER 359 _p uts("\n- buf_index = ");278 _printf("\n- buf_index = "); 360 279 _putd( buf_id ); 361 _p uts(" / paddr = ");280 _printf(" / paddr = "); 362 281 _putl( paddr ); 363 _p uts(" / count = ");282 _printf(" / count = "); 364 283 _putd( count ); 365 _p uts("\n");284 _printf("\n"); 366 285 #endif 367 286 buf_id++; … … 376 295 377 296 #if GIET_DEBUG_HBA_DRIVER 378 _p uts("\n- buf_index = ");297 _printf("\n- buf_index = "); 379 298 _putd( buf_id ); 380 _p uts(" / paddr = ");299 _printf(" / paddr = "); 381 300 _putl( paddr ); 382 _p uts(" / count = ");301 _printf(" / count = "); 383 302 _putd( count ); 384 _p uts("\n");303 _printf("\n"); 385 304 #endif 386 305 buf_id++; 387 306 } 388 307 } 389 390 // initialize command table header 391 cmd_table->header.lba0 = (char)lba; 392 cmd_table->header.lba1 = (char)(lba>>8); 393 cmd_table->header.lba2 = (char)(lba>>16); 394 cmd_table->header.lba3 = (char)(lba>>24); 395 396 // initialise command descriptor 397 cmd_desc->prdtl[0] = (unsigned char)(buf_id); 398 cmd_desc->prdtl[1] = (unsigned char)(buf_id>>8); 399 cmd_desc->ctba = (unsigned int)(hba_cmd_table_paddr[channel_id][cmd_id]); 400 cmd_desc->ctbau = (unsigned int)(hba_cmd_table_paddr[channel_id][cmd_id]>>32); 401 if( is_read ) cmd_desc->flag[0] = 0x00; 402 else cmd_desc->flag[0] = 0x40; 403 404 // update PXCI register 405 hba_address[HBA_PXCI] = (1<<cmd_id); 406 407 // update command pointer 408 hba_cmd_slot[channel_id] = (cmd_id + 1)%32; 409 410 return 0; 411 } 308 */ 309 310 412 311 /////////////////////////////////////////////////////////////////// 413 312 // Register a write command in Command List and Command Table 414 // for a single buffer.313 // for a single physical buffer. 415 314 // Returns 0 if success, > 0 if error. 416 315 /////////////////////////////////////////////////////////////////// 417 unsigned int _hba_write( unsigned int mode, 316 unsigned int _hba_write( unsigned int channel, 317 unsigned int mode, 418 318 unsigned int lba, 419 void*buffer,319 paddr_t buffer, 420 320 unsigned int count ) 421 321 { 422 return _hba_cmd_set( 0, lba, (unsigned int)buffer, count ); 322 return _hba_cmd_set( channel, 323 0, // write 324 lba, 325 buffer, 326 count ); 423 327 } 424 328 425 329 /////////////////////////////////////////////////////////////////// 426 330 // Register a read command in Command List and Command Table 427 // for a single buffer.331 // for a single physical buffer. 428 332 // Returns 0 if success, > 0 if error. 429 333 /////////////////////////////////////////////////////////////////// 430 unsigned int _hba_read( unsigned int mode, 334 unsigned int _hba_read( unsigned int channel, 335 unsigned int mode, 431 336 unsigned int lba, 432 void*buffer,337 paddr_t buffer, 433 338 unsigned int count ) 434 339 { 435 return _hba_cmd_set( 1, lba, (unsigned int)buffer, count ); 436 } 340 return _hba_cmd_set( channel, 341 1, // read 342 lba, 343 buffer, 344 count ); 345 } 346 437 347 ////////////////////////////////////////////////////////////////// 438 348 // This function initializes for a given channel … … 453 363 unsigned int pt = _get_context_slot(CTX_PTAB_ID); 454 364 455 // HBA registers 456 unsigned int* hba_address; 457 hba_address = (unsigned int*)&seg_ioc_base + HBA_SPAN * channel; 458 459 hba_address[HBA_PXCLB] = (unsigned int)(&hba_cmd_list[channel]); 460 hba_address[HBA_PXCLBU] = 0; 461 hba_address[HBA_PXIE] = 0x40000001; 462 hba_address[HBA_PXIS] = 0; 463 hba_address[HBA_PXCI] = 0; 464 hba_address[HBA_PXCMD] = 1; 365 // HBA registers TODO: ne faut_il pas un V2P pour PXCLB/PXCLBU ? (AG) 366 _hba_set_register( channel, HBA_PXCLB , (unsigned int)&hba_cmd_list[channel] ); 367 _hba_set_register( channel, HBA_PXCLBU, 0 ); 368 _hba_set_register( channel, HBA_PXIE , 0x40000001 ); 369 _hba_set_register( channel, HBA_PXIS , 0 ); 370 _hba_set_register( channel, HBA_PXCI , 0 ); 371 _hba_set_register( channel, HBA_PXCMD , 1 ); 465 372 466 373 // command list pointer … … 475 382 if ( fail ) 476 383 { 477 _tty_get_lock( 0 ); 478 _puts("[GIET ERROR] in _hba_init() : command list unmapped\n"); 479 _tty_release_lock( 0 ); 384 _printf("[GIET ERROR] in _hba_init() : command list unmapped\n"); 480 385 return 1; 481 386 } … … 492 397 if ( fail ) 493 398 { 494 _tty_get_lock( 0 ); 495 _puts("[GIET ERROR] in _hba_init() : command table unmapped\n"); 496 _tty_release_lock( 0 ); 399 _printf("[GIET ERROR] in _hba_init() : command table unmapped\n"); 497 400 return 1; 498 401 } … … 513 416 } 514 417 418 ///////////////////////////////////////////////////////////////////////////////////// 419 // This function returns the content of the HBA_PXIS register for a given channel, 420 // and reset this register to acknoledge IRQ. 421 // return 0 if success, > 0 if error 422 ///////////////////////////////////////////////////////////////////////////////////// 423 unsigned int _hba_get_status( unsigned int channel ) 424 { 425 426 if( channel >= NB_IOC_CHANNELS ) 427 { 428 _printf("\n[GIET ERROR] in _hba_get_status() : illegal channel\n"); 429 _exit(); 430 } 431 432 // get HBA_PXIS value 433 unsigned int status = _hba_get_register( channel, HBA_PXIS ); 434 435 // reset HBA_PXIS 436 _hba_set_register( channel, HBA_PXIS, 0 ); 437 438 return status; 439 } 515 440 516 441 // Local Variables: -
soft/giet_vm/giet_drivers/hba_driver.h
r289 r295 59 59 } hba_cmd_entry_t; 60 60 61 typedef struct hba_cmd_table_s // size = 256 bytes61 typedef struct hba_cmd_table_s // size = 4096 bytes 62 62 { 63 63 … … 97 97 /////////////////////////////////////////////////////////////////////////////////// 98 98 99 unsigned int _hba_write( unsigned int mode, 100 unsigned int lba, // logic bloc address on device 101 void* buffer, // memory buffer base address 102 unsigned int count ); // number of blocs 99 extern unsigned int _hba_init ( unsigned int channel ); 103 100 104 unsigned int _hba_read ( unsigned int mode, 105 unsigned int lba, // logic bloc address on device 106 void* buffer, // memory buffer base address 107 unsigned int count ); // number of blocks 101 extern unsigned int _hba_write( unsigned int channel, // channel index 102 unsigned int mode, // BOOT / KERNEL / USER 103 unsigned int lba, // logic bloc address on device 104 unsigned long long paddr, // memory buffer base address 105 unsigned int count ); // number of blocs 108 106 109 unsigned int _hba_init ( unsigned int channel ); 107 extern unsigned int _hba_read ( unsigned int channel, // channel index 108 unsigned int mode, // BOOT / KERNEL / USER 109 unsigned int lba, // logic bloc address on device 110 unsigned long long paddr, // memory buffer base address 111 unsigned int count ); // number of blocks 110 112 111 unsigned int _hba_get_status( unsigned int channel, 112 unsigned int* status ); 113 extern unsigned int _hba_get_status( unsigned int channel ); 113 114 114 unsigned int _hba_reset_status( unsigned int channel ); 115 116 unsigned int _hba_get_block_size (); 115 extern unsigned int _hba_get_block_size (); 117 116 118 117 -
soft/giet_vm/giet_drivers/icu_driver.c
r263 r295 70 70 71 71 #if USE_XICU 72 _p uts("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");72 _printf("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n"); 73 73 return 1; 74 74 #else … … 98 98 99 99 #if USE_XICU 100 _p uts("[GIET ERROR] _icu_get_index() should not be used if USE_XICU is set\n");100 _printf("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n"); 101 101 return 1; 102 102 #else -
soft/giet_vm/giet_drivers/ioc_driver.c
r289 r295 7 7 /////////////////////////////////////////////////////////////////////////////////// 8 8 // The ioc_driver.c and ioc_driver.h files are part ot the GIET-VM kernel. 9 // This driver supports the SocLib vci_block_device component, that is 10 // a single channel, block oriented, external storage contrÃŽler. 11 // 12 // It can exist only one block-device controler in the architecture. 13 // 14 // The _ioc_read() and _ioc_write() functions use the _ioc_access() function, 15 // that is always blocking. The _ioc_access function will call the read or 16 // write function in the driver of the choosen IOC peripheral, which can be for 17 // now: BDV, HBA and SPI. This function can be called in 4 modes: 18 // 19 // - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address 20 // as a physical address (as the page tables are not build). This mode is 21 // used by the boot code to load the map.bin file into memory. 22 // 23 // - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to 24 // compute the buffer physical address. This mode is used by the boot code to 25 // load the various .elf files into memory. 26 // 27 // - In KERNEL mode, the _ioc_access() function makes a V2P translation to 28 // compute the buffer physical address. There is no checking of user access 29 // right to the memory buffer. This mode must be used to access IOC, for an 30 // "open" system call. 31 // 32 // - In USER mode, the _ioc_access() function makes a V2P translation to 33 // compute the buffer physical address. The user access right to the memory 34 // buffer must be checked. This mode must be used to access IOC, for a 35 // "read/write" system call. 9 // 10 // This abstact driver define a generic API, supporting various physical 11 // block device controlers, including: 12 // - vci_block_device : single channel) => bdv_driver 13 // - vci_ahci : multi channels => hba_driver 14 // - sd_card : single channel => sdc_driver 15 // - ramdisk (single channel meory mapped virtual disk) => rdk_driver 16 // 17 // It can exist only one block-device type in the architecture, that must be 18 // defined by one of the following configuration variables in hard_config.h file: 19 // USE_IOC_BDV, USE_IOC_SDC, USE_IOC_HBA, USE_IOC_RDK. 20 // 21 // Any physical driver xxx must provide the following API: 22 // - _xxx_init() 23 // - _xxx_read() 24 // - _xxx_write() 25 // - _xxx_get_status() 26 // - _xxx_get_block_size() 27 // The "channel" parameter is no transmited to single channel devices. 28 // 29 // The _ioc_read() and _ioc_write() functions are always blocking for 30 // the calling user program. 31 // 32 // These functions compute the physical address of the memory buffer before 33 // calling the proper physical device. They can be called in 3 modes: 34 // 35 // - In BOOT mode, these functions use the buffer virtual address 36 // as a physical address if the MMU is not activated. 37 // They make a V2P translation if the MMU is activated. 38 // This mode is used to load the map.bin file (before memory activation), 39 // or to load the various .elf files (after MMU activation). 40 // 41 // - In KERNEL mode, these functions make a V2P translation to 42 // compute the buffer physical address. 43 // There is no checking of user access right to the memory buffer. 44 // This mode must be used for an "open" system call. 45 // 46 // - In USER mode, these functions make a V2P translation to 47 // compute the buffer physical address. 48 // The user access right to the memory buffer are checked. 49 // This mode must be used for a "read" or "write" system call. 36 50 // 37 51 // The IOMMU can be activated or not: … … 60 74 // if the IOMMU is not activated. 61 75 // An error code is returned if these conditions are not verified. 76 // 77 // The "seg_ioc_base" virtual base address of the segment containing the 78 // memory-mapped registers of the device must be defined in the giet_vsegs.ld file. 79 // If the RAMDISK is used, an extra memory segment with virtual base address 80 // "seg_ramdisk_base" must be defined in the giet_vsegs.ld file. 62 81 /////////////////////////////////////////////////////////////////////////////////// 63 // The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file. 82 // Implementation note: 83 // In order to share the code, the two _ioc_read() and _ioc_write() functions 84 // call the same _ioc_access() function. 64 85 /////////////////////////////////////////////////////////////////////////////////// 65 86 66 87 #include <giet_config.h> 67 88 #include <ioc_driver.h> 89 #include <bdv_driver.h> 90 #include <hba_driver.h> 91 #include <sdc_driver.h> 92 #include <rdk_driver.h> 68 93 #include <utils.h> 69 94 #include <tty_driver.h> … … 81 106 #endif 82 107 83 #if (USE_ BDV + USE_SPI + USE_HBA) != 184 # error: You must use only one IOC controller (BDV or SPI or HBA)85 #endif 86 87 #if USE_ BDV108 #if (USE_IOC_BDV + USE_IOC_SPI + USE_IOC_HBA + USE_IOC_RDK) != 1 109 # error: You must use only one IOC controller type (BDV or SPI or HBA or RDK) 110 #endif 111 112 #if USE_IOC_BDV 88 113 # include <bdv_driver.h> 89 114 #endif 90 115 91 #if USE_ SPI116 #if USE_IOC_SPI 92 117 # include <sdc_driver.h> 93 118 #endif 94 119 95 #if USE_ HBA120 #if USE_IOC_HBA 96 121 # include <hba_driver.h> 97 122 #endif 98 123 124 #if USE_IOC_RDK 125 # include <rdk_driver.h> 126 #endif 127 128 /////////////////////////////////////////////////////////////////////////////// 129 // IOC global variables 130 /////////////////////////////////////////////////////////////////////////////// 99 131 100 132 #define in_unckdata __attribute__((section (".unckdata"))) 101 133 102 ///////////////////// IOC global variables103 104 in_unckdata unsigned int _ioc_lock = 0;105 in_unckdata unsigned int _ioc_status = 0;106 in_unckdata volatile unsigned int _ioc_gtid;107 134 in_unckdata volatile unsigned int _ioc_iommu_ix1 = 0; 108 135 in_unckdata volatile unsigned int _ioc_iommu_npages; 109 136 110 137 /////////////////////////////////////////////////////////////////////////////// 111 // _ioc_access()112 138 // This function transfer data between a memory buffer and the block device. 113 139 // The buffer lentgth is (count*block_size) bytes. 114 140 // Arguments are: 115 141 // - to_mem : from external storage to memory when non 0. 116 // - kernel : kernel buffer with identity mapping when non 0.142 // - mode : BOOT_PA / BOOT_VA / KERNEL / USER 117 143 // - lba : first block index on the external storage. 118 144 // - buf_vaddr : virtual base address of the memory buffer. … … 121 147 /////////////////////////////////////////////////////////////////////////////// 122 148 static unsigned int _ioc_access( unsigned int to_mem, 149 unsigned int channel, 123 150 unsigned int mode, 124 151 unsigned int lba, … … 128 155 129 156 #if GIET_DEBUG_IOC_DRIVER 130 _tty_get_lock( 0 ); 131 _puts("\n[IOC DEBUG] Enter _ioc_access() at cycle "); 132 _putd( _get_proctime() ); 133 _puts(" for processor "); 134 _putd( _get_procid() ); 135 _puts("\n - mode = "); 136 _putd( mode ); 137 _puts("\n - vaddr = "); 138 _putx( buf_vaddr ); 139 _puts("\n - sectors = "); 140 _putd( count ); 141 _puts("\n - lba = "); 142 _putx( lba ); 143 _puts("\n"); 144 _tty_release_lock( 0 ); 157 unsigned int procid = _get_procid(); 158 unsigned int cid = procid / NB_PROCS_MAX; 159 unsigned int lpid = procid % NB_PROCS_MAX; 160 unsigned int x = cid >> Y_WIDTH; 161 unsigned int y = cid & ((1<<Y_WIDTH) - 1); 162 163 _printf("\n[IOC DEBUG] Processor[%d,%d,%d] enters _ioc_access() at cycle %d\n" 164 " - channel = %d\n" 165 " - mode = %d\n" 166 " - vaddr = %d\n" 167 " - sectors = %d\n" 168 " - lba = %d\n", 169 x, y, lpid, _get_proctime(), channel, mode, buf_vaddr, count, lba ); 145 170 #endif 146 171 … … 160 185 if ((unsigned int) buf_vaddr & 0x3) 161 186 { 162 _tty_get_lock( 0 ); 163 _puts("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n"); 164 _tty_release_lock( 0 ); 165 return 1; 187 _printf("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n"); 188 _exit(); 189 } 190 191 // check channel 192 if ( (USE_IOC_HBA == 0) && (channel > 0) ) 193 { 194 _printf("\n[GIET ERROR] in _ioc_access() : channel must be 0 when HBA not used\n"); 195 _exit(); 166 196 } 167 197 168 198 unsigned int length = count << 9; // count * 512 bytes 169 199 170 // computing targetbuffer physical address171 if ( mode == IOC_BOOT_PA_MODE )// identity mapping200 // computing memory buffer physical address 201 if ( (mode == IOC_BOOT_MODE) && ((_get_mmu_mode() & 0x4) == 0) ) // identity mapping 172 202 { 173 203 buf_paddr = (paddr_t)buf_vaddr; 174 204 } 175 else // V2P translation205 else // V2P translation required 176 206 { 177 207 // get page table virtual address 178 208 pt_vbase = _get_context_slot(CTX_PTAB_ID); 179 vpn_min = buf_vaddr >> 12;180 vpn_max = (buf_vaddr + length - 1) >> 12;209 vpn_min = buf_vaddr >> 12; 210 vpn_max = (buf_vaddr + length - 1) >> 12; 181 211 182 212 // loop on all virtual pages covering the user buffer 183 for (vpn = vpn_min, ix2 = 0 ; 184 vpn <= vpn_max ; 185 vpn++, ix2++ ) 213 for (vpn = vpn_min, ix2 = 0 ; vpn <= vpn_max ; vpn++, ix2++ ) 186 214 { 187 215 // get ppn and flags for each vpn … … 193 221 if ( ko ) 194 222 { 195 _tty_get_lock( 0 ); 196 _puts("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n"); 197 _tty_release_lock( 0 ); 223 _printf("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n"); 198 224 return 1; 199 225 } … … 201 227 if ( (mode == IOC_USER_MODE) && ((flags & PTE_U) == 0) ) 202 228 { 203 _tty_get_lock( 0 ); 204 _puts("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n"); 205 _tty_release_lock( 0 ); 229 _printf("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n"); 206 230 return 1; 207 231 } … … 209 233 if ( ((flags & PTE_W) == 0 ) && to_mem ) 210 234 { 211 _tty_get_lock( 0 ); 212 _puts("\n[GIET ERROR] in _ioc_access() : buffer not writable\n"); 213 _tty_release_lock( 0 ); 235 _printf("\n[GIET ERROR] in _ioc_access() : buffer not writable\n"); 214 236 return 1; 215 237 } … … 223 245 if (ix2 > 511) // check buffer length < 2 Mbytes 224 246 { 225 _tty_get_lock( 0 ); 226 _puts("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n"); 227 _tty_release_lock( 0 ); 247 _printf("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n"); 228 248 return 1; 229 249 } … … 242 262 if ((ppn - ppn_first) != ix2) 243 263 { 244 _tty_get_lock( 0 ); 245 _puts("[GIET ERROR] in _ioc_access() : split physical buffer\n"); 246 _tty_release_lock( 0 ); 264 _printf("[GIET ERROR] in _ioc_access() : split physical buffer\n"); 247 265 return 1; 248 266 } … … 272 290 else // memory read : update data caches 273 291 { 274 // L1 cache : nothing to do ifL1 write-through292 // L1 cache : nothing to do for L1 write-through 275 293 276 294 // L2 cache (only if IOB used) … … 280 298 if ( GIET_USE_IOMMU ) buf_paddr = (paddr_t) buf_xaddr; 281 299 282 #if USE_BDV 283 if (to_mem) error = _bdv_read (mode, lba, buf_paddr, count); 284 else error = _bdv_write(mode, lba, buf_paddr, count); 285 #elif USE_SPI 286 if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count); 287 else error = _sdc_write(mode, lba, buf_paddr, count); 288 #elif USE_HBA 289 if (to_mem) error = _hba_read (mode, lba, buf_paddr, count); 290 else error = _hba_write(mode, lba, buf_paddr, count); 300 /////////////////////////////////////////// 301 // select the proper physical device 302 /////////////////////////////////////////// 303 304 #if ( USE_IOC_BDV ) 305 306 #if GIET_DEBUG_IOC_DRIVER 307 _printf("\n[IOC DEBUG] Calling BDV driver\n"); 308 #endif 309 if (to_mem) error = _bdv_read ( mode, lba, buf_paddr, count); 310 else error = _bdv_write( mode, lba, buf_paddr, count); 311 312 #elif ( USE_IOC_SPI ) 313 314 #if GIET_DEBUG_IOC_DRIVER 315 _printf("\n[IOC DEBUG] Calling SPI driver\n"); 316 #endif 317 if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count); 318 else error = _sdc_write(mode, lba, buf_paddr, count); 319 320 #elif ( USE_IOC_HBA ) 321 322 #if GIET_DEBUG_IOC_DRIVER 323 _printf("\n[IOC DEBUG] Calling HBA driver\n"); 324 #endif 325 if (to_mem) error = _hba_read (channel, mode, lba, buf_paddr, count); 326 else error = _hba_write(channel, mode, lba, buf_paddr, count); 327 328 #elif ( USE_IOC_RDK ) 329 330 #if GIET_DEBUG_IOC_DRIVER 331 _printf("\n[IOC DEBUG] Calling RDK driver\n"); 332 #endif 333 if (to_mem) error = _rdk_read (lba, buf_vaddr, count); 334 else error = _rdk_write(lba, buf_vaddr, count); 335 291 336 #endif 292 337 … … 295 340 296 341 /////////////////////////////////////////////////////////////////////////////// 297 // _ioc_init()298 342 // This function cheks block size, and activates the IOC interrupts. 299 343 // Return 0 for success. … … 301 345 unsigned int _ioc_init( unsigned int channel ) 302 346 { 303 #if USE_BDV 304 return _bdv_init( channel ); 305 #elif USE_SPI 306 return _sdc_init( channel ); 307 #elif USE_HBA 347 348 #if ( USE_IOC_BDV ) 349 350 return _bdv_init(); 351 352 #elif ( USE_IOC_SPI ) 353 354 return _sdc_init(); 355 356 #elif ( USE_IOC_HBA ) 357 308 358 return _hba_init( channel ); 309 #endif 359 360 #elif ( USE_IOC_RDK ) 361 362 return _rdk_init(); 363 364 #endif 365 310 366 } 311 367 312 368 /////////////////////////////////////////////////////////////////////////////// 313 // _ioc_read()314 369 // Transfer data from the block device to a memory buffer. 315 // - mode : BOOT / KERNEL / USER370 // - mode : BOOT_PA / BOOT_VA / KERNEL / USER 316 371 // - lba : first block index on the block device 317 372 // - buffer : base address of the memory buffer (must be word aligned) … … 319 374 // Returns 0 if success, > 0 if error. 320 375 /////////////////////////////////////////////////////////////////////////////// 321 unsigned int _ioc_read( unsigned int mode, 376 unsigned int _ioc_read( unsigned int channel, 377 unsigned int mode, 322 378 unsigned int lba, 323 379 void* buffer, … … 325 381 { 326 382 return _ioc_access( 1, // read access 383 channel, 327 384 mode, 328 385 lba, … … 332 389 333 390 /////////////////////////////////////////////////////////////////////////////// 334 // _ioc_write()335 391 // Transfer data from a memory buffer to the block device. 336 // - mode : BOOT / KERNEL / USER392 // - mode : BOOT_PA / BOOT_VA / KERNEL / USER 337 393 // - lba : first block index on the block device 338 394 // - buffer : base address of the memory buffer (must be word aligned) … … 340 396 // Returns 0 if success, > 0 if error. 341 397 /////////////////////////////////////////////////////////////////////////////// 342 unsigned int _ioc_write( unsigned int mode, 398 unsigned int _ioc_write( unsigned int channel, 399 unsigned int mode, 343 400 unsigned int lba, 344 401 const void* buffer, … … 346 403 { 347 404 return _ioc_access( 0, // write access 405 channel, 348 406 mode, 349 407 lba, … … 353 411 354 412 /////////////////////////////////////////////////////////////////////////////// 355 // _ioc_get_status()356 413 // This function returns in the status variable, the transfert status, and 357 414 // acknowledge the IRQ if the IOC controler is not busy. 358 415 // Returns 0 if success, > 0 if error 359 416 /////////////////////////////////////////////////////////////////////////////// 360 unsigned int _ioc_get_status( unsigned int channel, 361 unsigned int* status ) 362 { 363 #if USE_BDV 364 return _bdv_get_status(channel, status); 365 #elif USE_SPI 366 return _sdc_get_status(channel, status); 367 #elif USE_HBA 368 return _hba_get_status(channel, status); 369 #endif 417 unsigned int _ioc_get_status( unsigned int channel ) 418 { 419 420 #if ( USE_IOC_BDV ) 421 422 return _bdv_get_status( ); 423 424 #elif ( USE_IOC_SPI ) 425 426 return _sdc_get_status( ); 427 428 #elif ( USE_IOC_HBA ) 429 430 return _hba_get_status( channel ); 431 432 #elif ( USE_IOC_RDK ) 433 434 _printf("[GIET ERROR] _ioc_get_status() should not be called"); 435 _printf(" when RAMDISK is used...\n"); 436 _exit(); 437 438 return 0; 439 440 #endif 441 370 442 } 371 443 372 444 /////////////////////////////////////////////////////////////////////////////// 373 // _ioc_get_block_size()374 445 // This function returns the block_size with which the IOC has been configured. 375 446 /////////////////////////////////////////////////////////////////////////////// 376 447 unsigned int _ioc_get_block_size() 377 448 { 378 #if USE_BDV 449 450 #if ( USE_IOC_BDV ) 451 379 452 return _bdv_get_block_size(); 380 #elif USE_SPI 453 454 #elif ( USE_IOC_SPI ) 455 381 456 return _sdc_get_block_size(); 382 #elif USE_HBA 457 458 #elif ( USE_IOC_HBA ) 459 383 460 return _hba_get_block_size(); 384 #endif 461 462 #elif ( USE_IOC_RDK ) 463 464 return 512; 465 466 #endif 467 385 468 } 386 469 -
soft/giet_vm/giet_drivers/ioc_driver.h
r289 r295 13 13 /////////////////////////////////////////////////////////////////////////////////// 14 14 15 enum IOC_registers16 {17 BLOCK_DEVICE_BUFFER,18 BLOCK_DEVICE_LBA,19 BLOCK_DEVICE_COUNT,20 BLOCK_DEVICE_OP,21 BLOCK_DEVICE_STATUS,22 BLOCK_DEVICE_IRQ_ENABLE,23 BLOCK_DEVICE_SIZE,24 BLOCK_DEVICE_BLOCK_SIZE,25 BLOCK_DEVICE_BUFFER_EXT,26 };27 enum IOC_operations28 {29 BLOCK_DEVICE_NOOP,30 BLOCK_DEVICE_READ,31 BLOCK_DEVICE_WRITE,32 };33 enum IOC_status34 {35 BLOCK_DEVICE_IDLE,36 BLOCK_DEVICE_BUSY,37 BLOCK_DEVICE_READ_SUCCESS,38 BLOCK_DEVICE_WRITE_SUCCESS,39 BLOCK_DEVICE_READ_ERROR,40 BLOCK_DEVICE_WRITE_ERROR,41 BLOCK_DEVICE_ERROR,42 };43 15 enum IOC_driver_modes 44 16 { 45 IOC_BOOT_PA_MODE, // No V2P translation / Polling IOC_STATUS / no access checking 46 IOC_BOOT_VA_MODE, // V2P translation / Polling IOC_STATUS / no access checking 47 IOC_KERNEL_MODE, // V2P translation / Descheduling + IRQ / no access checking 48 IOC_USER_MODE, // V2P translation / Descheduling + IRQ / access checking 17 IOC_BOOT_MODE = 0, // Polling IOC_STATUS / no access right checking 18 IOC_KERNEL_MODE = 1, // Descheduling + IRQ / no access right checking 19 IOC_USER_MODE = 2, // Descheduling + IRQ / access right checking 49 20 }; 50 21 51 22 /////////////////////////////////////////////////////////////////////////////////// 52 // IOC access functions and variables (vci_block_device)23 // IOC global variables (generic disk controller) 53 24 /////////////////////////////////////////////////////////////////////////////////// 54 25 55 extern unsigned int _ioc_lock;56 extern unsigned int _ioc_status;57 extern volatile unsigned int _ioc_gtid;58 26 extern volatile unsigned int _ioc_iommu_ix1; 59 27 extern volatile unsigned int _ioc_iommu_npages; 60 28 29 /////////////////////////////////////////////////////////////////////////////////// 30 // IOC access functions (generic disk controller) 31 /////////////////////////////////////////////////////////////////////////////////// 32 61 33 extern unsigned int _ioc_init( unsigned int channel ); 62 34 63 extern unsigned int _ioc_write( unsigned int mode, 35 extern unsigned int _ioc_write( unsigned int channel, 36 unsigned int mode, 64 37 unsigned int lba, 65 38 const void* buffer, 66 39 unsigned int count ); 67 40 68 extern unsigned int _ioc_read( unsigned int mode, 41 extern unsigned int _ioc_read( unsigned int channel, 42 unsigned int mode, 69 43 unsigned int lba, 70 44 void* buffer, 71 45 unsigned int count ); 72 46 73 extern unsigned int _ioc_get_status( unsigned int channel, 74 unsigned int* status ); 47 extern unsigned int _ioc_get_status( unsigned int channel ); 75 48 76 49 extern unsigned int _ioc_get_block_size(); -
soft/giet_vm/giet_drivers/mmc_driver.c
r263 r295 57 57 if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 58 58 { 59 _puts("\n[GIET ERROR] in _memc_inval() : illegal cluster index["); 60 _putd( x ); 61 _puts(","); 62 _putd( y ); 63 _puts("]\n"); 64 _puts(" - paddr = "); 65 _putl( buf_paddr ); 66 _puts("\n - cluster_xy = "); 67 _putx( cluster_xy ); 68 _puts("\n"); 59 _printf("\n[GIET ERROR] in _memc_inval() : illegal cluster_xy for paddr %l\n", 60 buf_paddr ); 69 61 _exit(); 70 62 } … … 102 94 if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 103 95 { 104 _puts("\n[GIET ERROR] in _memc_sync() : illegal cluster index["); 105 _putd( x ); 106 _puts(","); 107 _putd( y ); 108 _puts("]\n"); 109 _puts(" - paddr = "); 110 _putl( buf_paddr ); 111 _puts("\n - cluster_xy = "); 112 _putx( cluster_xy ); 113 _puts("\n"); 96 _printf( "\n[GIET ERROR] in _memc_sync() : illegal cluster_xy for paddr %l\n", 97 buf_paddr ); 114 98 _exit(); 115 99 } -
soft/giet_vm/giet_drivers/mwr_driver.c
r263 r295 56 56 paddr_t channel_pbase ) 57 57 { 58 _p uts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");58 _printf(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n"); 59 59 _exit(); 60 60 -
soft/giet_vm/giet_drivers/nic_driver.c
r258 r295 56 56 #define in_unckdata __attribute__((section (".unckdata"))) 57 57 58 /////////////////////////////////////////////////////////////////////////////// 59 // This low_level function returns the value contained in register (index). 60 /////////////////////////////////////////////////////////////////////////////// 61 unsigned int _nic_get_register( unsigned int channel, 62 unsigned int index ) 63 { 64 unsigned int* vaddr = (unsigned int*)&seg_nic_base + 65 NIC_CHANNEL_SPAN*channel + index; 66 return _io_extended_read( vaddr ); 67 } 68 69 /////////////////////////////////////////////////////////////////////////////// 70 // This low-level function set a new value in register (index). 71 /////////////////////////////////////////////////////////////////////////////// 72 void _nic_set_register( unsigned int channel, 73 unsigned int index, 74 unsigned int value ) 75 { 76 unsigned int* vaddr = (unsigned int*)&seg_nic_base + 77 NIC_CHANNEL_SPAN*channel + index; 78 _io_extended_write( vaddr, value ); 79 } 80 58 81 ////////////////////////////////////////////////////////////////////////////////// 59 // _nic_sync_write()60 82 // Transfer data from an memory buffer to the NIC device using a memcpy. 61 83 // - buffer : base address of the memory buffer. … … 65 87 unsigned int length ) 66 88 { 67 _p uts("[GIET ERROR] _nic_sync_write function not implemented\n");89 _printf("[GIET ERROR] _nic_sync_write function not implemented\n"); 68 90 _exit(); 69 91 … … 73 95 } 74 96 ////////////////////////////////////////////////////////////////////////////////// 75 // _nic_sync_read()76 97 // Transfer data from the NIC device to a memory buffer using a memcpy. 77 98 // - buffer : base address of the memory buffer. … … 81 102 unsigned int length ) 82 103 { 83 _p uts("[GIET ERROR] _nic_sync_read function not implemented\n");104 _printf("[GIET ERROR] _nic_sync_read function not implemented\n"); 84 105 _exit(); 85 106 … … 89 110 } 90 111 ////////////////////////////////////////////////////////////////////////////////// 91 // _nic_cma_start()92 112 // Returns 0 if success, > 0 if error. 93 113 ////////////////////////////////////////////////////////////////////////////////// 94 114 unsigned int _nic_cma_start( ) 95 115 { 96 _p uts("[GIET ERROR] _nic_cma_start functionnot implemented\n");116 _printf("[GIET ERROR] _nic_cma_start() not implemented\n"); 97 117 _exit(); 98 118 … … 101 121 } 102 122 ////////////////////////////////////////////////////////////////////////////////// 103 // _nic_cma_stop()104 123 // Returns 0 if success, > 0 if error. 105 124 ////////////////////////////////////////////////////////////////////////////////// 106 125 unsigned int _nic_cma_stop() 107 126 { 108 _p uts("[GIET ERROR] _nic_cma_stop functionnot implemented\n");127 _printf("[GIET ERROR] _nic_cma_stop() not implemented\n"); 109 128 _exit(); 110 129 … … 113 132 } 114 133 134 ////////////////////////////////////////////////////////////////////////////////// 135 // This ISR handles IRQx from a NIC RX channeL 136 ////////////////////////////////////////////////////////////////////////////////// 137 void _nic_rx_isr( unsigned int irq_type, 138 unsigned int irq_id, 139 unsigned int channel ) 140 { 141 _printf("[GIET ERROR] _nic_rx_isr() not implemented\n"); 142 _exit(); 143 } 144 145 ////////////////////////////////////////////////////////////////////////////////// 146 // This ISR handles IRQx from a NIC RX channeL 147 ////////////////////////////////////////////////////////////////////////////////// 148 void _nic_tx_isr( unsigned int irq_type, 149 unsigned int irq_id, 150 unsigned int channel ) 151 { 152 _printf("[GIET ERROR] _nic_tx_isr() not implemented\n"); 153 _exit(); 154 } 115 155 116 156 // Local Variables: -
soft/giet_vm/giet_drivers/nic_driver.h
r258 r295 8 8 #ifndef _GIET_NIC_DRIVERS_H_ 9 9 #define _GIET_NIC_DRIVERS_H_ 10 11 /////////////////////////////////////////////////////////////////////////////////// 12 // NIC Registers (vci_multi_nic) 13 /////////////////////////////////////////////////////////////////////////////////// 14 15 enum SoclibMultiNicHyperviseurRegisters { 16 NIC_G_VIS = 0, // bitfield : bit N = 0 -> channel N disabled 17 NIC_G_ON = 1, // boolean : NIC component activated 18 NIC_G_NB_CHAN = 2, // Number of channels present in this NIC (read only) 19 NIC_G_BC_ENABLE = 3, // boolean : Enable Broadcast if non zero 20 NIC_G_TDM_ENABLE = 4, // boolean : TDM Scheduler if non zero 21 NIC_G_TDM_PERIOD = 5, // TDM time slot value 22 NIC_G_BYPASS_ENABLE = 6, // boolean : Enable bypass for TX packets 23 // alignment 24 NIC_G_MAC_4 = 8, // channel mac address 32 LSB bits array[8] 25 NIC_G_MAC_2 = 16, // channel mac address 16 MSB bits array[8] 26 // alignment 27 NIC_G_NPKT_RX_G2S_RECEIVED = 32, // number of packets received on GMII RX port 28 NIC_G_NPKT_RX_G2S_DISCARDED = 33, // number of RX packets discarded by RX_G2S FSM 29 30 NIC_G_NPKT_RX_DES_SUCCESS = 34, // number of RX packets transmited by RX_DES FSM 31 NIC_G_NPKT_RX_DES_TOO_SMALL = 35, // number of discarded too small RX packets (<60B) 32 NIC_G_NPKT_RX_DES_TOO_BIG = 36, // number of discarded too big RX packets (>1514B) 33 NIC_G_NPKT_RX_DES_MFIFO_FULL = 37, // number of discarded RX packets because fifo full 34 NIC_G_NPKT_RX_DES_CRC_FAIL = 38, // number of discarded RX packets because CRC32 failure 35 36 NIC_G_NPKT_RX_DISPATCH_RECEIVED = 39, // number of packets received by RX_DISPATCH FSM 37 NIC_G_NPKT_RX_DISPATCH_BROADCAST = 40, // number of broadcast RX packets received 38 NIC_G_NPKT_RX_DISPATCH_DST_FAIL = 41, // number of discarded RX packets for DST MAC not found 39 NIC_G_NPKT_RX_DISPATCH_CH_FULL = 42, // number of discarded RX packets for channel full 40 41 NIC_G_NPKT_TX_DISPATCH_RECEIVED = 43, // number of packets received by TX_DISPATCH FSM 42 NIC_G_NPKT_TX_DISPATCH_TOO_SMALL = 44, // number of discarded too small TX packets (<60B) 43 NIC_G_NPKT_TX_DISPATCH_TOO_BIG = 45, // number of discarded too big TX packets (>1514B) 44 NIC_G_NPKT_TX_DISPATCH_SRC_FAIL = 46, // number of discarded TX packets for SRC MAC failed 45 NIC_G_NPKT_TX_DISPATCH_BROADCAST = 47, // number of broadcast TX packets received 46 NIC_G_NPKT_TX_DISPATCH_BYPASS = 48, // number of bypassed TX->RX packets 47 NIC_G_NPKT_TX_DISPATCH_TRANSMIT = 49, // number of transmit TX packets 48 49 NIC_CHANNEL_SPAN = 0x2000, 50 }; 51 52 ///////////////////////////////////////////////////////////////////// 53 // A container descriptor has the following form: 54 // LOW WORD : Container LSB base address 55 // HIGH WORD: Container status (leftmost bit), '1' means full 56 // Base address MSB extension, if needed (right aligned) 57 ////////////////////////////////////////////////////////////////////// 58 enum SoclibMultiNicChannelRegisters 59 { 60 NIC_RX_DESC_LO_0 = 0, // RX_0 descriptor low word (Read/Write) 61 NIC_RX_DESC_HI_0 = 1, // RX_0 descriptor high word (Read/Write) 62 NIC_RX_DESC_LO_1 = 2, // RX_1 descriptor low word (Read/Write) 63 NIC_RX_DESC_HI_1 = 3, // RX_1 descriptor high word (Read/Write) 64 NIC_TX_DESC_LO_0 = 4, // TX_0 descriptor low word (Read/Write) 65 NIC_TX_DESC_HI_0 = 5, // TX_0 descriptor high word (Read/Write) 66 NIC_TX_DESC_LO_1 = 6, // TX_1 descriptor low word (Read/Write) 67 NIC_TX_DESC_HI_1 = 7, // TX_1 descriptor high word (Read/Write) 68 NIC_MAC_4 = 8, // channel mac address 32 LSB bits (Read Only) 69 NIC_MAC_2 = 9, // channel mac address 16 LSB bits (Read Only) 70 NIC_RX_RUN = 10, // RX packets can be received (write_only) 71 NIC_TX_RUN = 11, // TX packets can be transmitted (write_only) 72 }; 10 73 11 74 /////////////////////////////////////////////////////////////////////////////////// … … 23 86 extern unsigned int _nic_cma_stop(); 24 87 88 extern void _nic_rx_isr( unsigned int irq_type, 89 unsigned int irq_id, 90 unsigned int channel ); 91 92 extern void _nic_tx_isr( unsigned int irq_type, 93 unsigned int irq_id, 94 unsigned int channel ); 95 25 96 /////////////////////////////////////////////////////////////////////////////////// 26 97 -
soft/giet_vm/giet_drivers/sdc_driver.c
r289 r295 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 8 #include <sdc_driver.h> 9 #include <tty_driver.h> 8 10 #include <utils.h> 9 11 … … 179 181 if ( sdcard_rsp != 0x01 ) 180 182 { 181 182 _puts("card CMD0 failed "); 183 _printf("[SDC ERROR] card CMD0 failed\n"); 183 184 return sdcard_rsp; 184 185 } … … 196 197 if (!SDCARD_CHECK_R1_VALID(sdcard_rsp)) 197 198 { 198 _p uts("card CMD8 failed");199 _printf("[SDC ERROR] card CMD8 failed\n"); 199 200 return sdcard_rsp; 200 201 } … … 206 207 ersp = (ersp << 8) | _sdc_receive_char(); 207 208 ersp = (ersp << 8) | _sdc_receive_char(); 208 if ((ersp & 0xffff) != 0x0101) { 209 if ((ersp & 0xffff) != 0x0101) 210 { 209 211 // voltage mismatch 210 _puts("card CMD8 mismatch: "); 211 _putx(ersp); 212 _printf("[SDC ERROR] card CMD8 mismatch : ersp = %x\n"); 212 213 return sdcard_rsp; 213 214 } 214 _p uts("v2 or later ");215 _printf("[SDC WARNING] v2 or later "); 215 216 sdcard.sdhc = 1; 216 217 } … … 218 219 { 219 220 // other error 220 _p uts("card CMD8 error");221 _printf("[SDC ERROR] card CMD8 error\n"); 221 222 return sdcard_rsp; 222 223 } … … 249 250 if (sdcard_rsp) 250 251 { 251 _p uts("SD ACMD41 failed");252 _printf("[SDC ERROR] ACMD41 failed\n"); 252 253 return sdcard_rsp; 253 254 } … … 263 264 if (sdcard_rsp) 264 265 { 265 _p uts("SD CMD58 failed");266 _printf("[SDC ERROR] CMD58 failed\n"); 266 267 return sdcard_rsp; 267 268 } … … 272 273 if (ersp & 0x40000000) 273 274 { 274 _puts("SDHC "); 275 } else 275 _printf(" SDHC "); 276 } 277 else 276 278 { 277 279 sdcard.sdhc = 0; … … 279 281 _sdc_disable(); 280 282 } 281 _p uts("card detected");283 _printf("card detected\n"); 282 284 return 0; 283 285 } … … 334 336 // Returns 0 if success, other value if failure 335 337 /////////////////////////////////////////////////////////////////////////////// 336 unsigned int _sdc_init( unsigned int channel)338 unsigned int _sdc_init() 337 339 { 338 340 spi = (struct spi_dev*) &seg_ioc_base; … … 355 357 while(1) 356 358 { 357 _p uts("Trying to initialize SD card...");358 359 sdcard_rsp = _sdc_open( channel );359 _printf("[SDC WARNING] Trying to initialize SD card...\n"); 360 361 sdcard_rsp = _sdc_open( 0 ); // only channel 0 360 362 if (sdcard_rsp == 0) 361 363 { 362 _p uts("OK\n");364 _printf("OK\n"); 363 365 break; 364 366 } 365 367 366 _p uts("KO\n");368 _printf("KO\n"); 367 369 368 370 for (i = 0; i < 1000; i++); … … 370 372 if (++iter >= SDCARD_RESET_ITER_MAX) 371 373 { 372 _puts("\nERROR: During SD card reset to IDLE state\n" 373 "/ card response = "); 374 _putx(sdcard_rsp); 375 _puts("\n"); 374 _printf("\n[SDC ERROR] During SD card reset to IDLE state " 375 "/ card response = %x\n", sdcard_rsp ); 376 376 _exit(); 377 377 } … … 382 382 if (sdcard_rsp) 383 383 { 384 _p uts("ERROR:During SD card blocklen initialization\n");384 _printf("[SDC ERROR] During SD card blocklen initialization\n"); 385 385 _exit(); 386 386 } … … 396 396 ); 397 397 398 _p uts("Finish block deviceinitialization\n\r");398 _printf("[SDC WARNING] Finish SD card initialization\n\r"); 399 399 400 400 return 0; … … 478 478 479 479 /////////////////////////////////////////////////////////////////////////////// 480 // _sdc_get_status()481 480 // Transfer data from memory buffer to SD card device. 482 481 // - channel: channel index … … 484 483 // Returns 0 if success, > 0 if error. 485 484 /////////////////////////////////////////////////////////////////////////////// 486 unsigned int _sdc_get_status( unsigned int channel , 487 unsigned int* status ) 488 { 489 *status = BLOCK_DEVICE_IDLE; 490 491 return 0; 492 } 493 494 /////////////////////////////////////////////////////////////////////////////// 495 // _sdc_get_block_size() 485 unsigned int _sdc_get_status() 486 { 487 _printf("[SDC ERROR] function _sdc_get_status() should not be called\n"); 488 _exit(); 489 490 return 0; // to avoid a warning 491 } 492 493 /////////////////////////////////////////////////////////////////////////////// 496 494 // Returns the block size in bytes of the SD card 497 495 /////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_drivers/sdc_driver.h
r289 r295 36 36 }; 37 37 38 unsigned int _sdc_init( unsigned int channel ); 39 38 unsigned int _sdc_init(); 40 39 41 40 unsigned int _sdc_read( unsigned int mode, … … 50 49 unsigned int count); 51 50 51 unsigned int _sdc_get_status(); 52 52 53 unsigned int _sdc_get_block_size(); 53 54 unsigned int _sdc_get_status( unsigned int channel ,55 unsigned int* status );56 54 57 55 -
soft/giet_vm/giet_drivers/tim_driver.c
r263 r295 18 18 // The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id 19 19 // 20 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in the 21 // hard_config.h file. 22 // 23 // The register offsets must be defined in the hwr_mapping.h file. 20 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file. 24 21 ///////////////////////////////////////////////////////////////////////////////////// 25 22 // The virtual base address of the segment associated to a channel is: … … 33 30 #include <giet_config.h> 34 31 #include <tim_driver.h> 32 #include <xcu_driver.h> 33 #include <tty_driver.h> 35 34 #include <utils.h> 36 35 … … 68 67 69 68 #if (NB_TIM_CHANNELS > 0) 70 in_unckdata volatile unsigned char _user_timer_event[ X_SIZE*Y_SIZE*NB_TIM_CHANNELS]71 = { [0 ... ((X_SIZE*Y_SIZE*NB_TIM_CHANNELS) - 1)] = 0 };69 in_unckdata volatile unsigned char _user_timer_event[(1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS] 70 = { [0 ... (((1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS) - 1)] = 0 }; 72 71 #endif 73 72 74 73 //////////////////////////////////////////////////////////////////////////////////// 75 // _timer_start()76 74 // This function activates a timer in the vci_timer component 77 75 // by writing in the proper register the period value. 78 76 // It can be used by both the kernel to initialise a "system" timer, 79 77 // or by a task (through a system call) to configure an "user" timer. 80 // Returns 0 if success, > 0 if error. 81 ////////////////////////////////////////////////////////////////////////////// 82 unsigned int _timer_start( unsigned int cluster_xy, 83 unsigned int local_id, 84 unsigned int period) 85 { 86 // parameters checking 87 unsigned int x = cluster_xy >> Y_WIDTH; 88 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 89 if (x >= X_SIZE) return 1; 90 if (y >= Y_SIZE) return 1; 91 if (local_id >= NB_TIM_CHANNELS) return 1; 78 /////////////////////////////////////////////////////////////////////////////////// 79 void _timer_start( unsigned int cluster_xy, 80 unsigned int local_id, 81 unsigned int period) 82 { 83 #if NB_TIM_CHANNELS 84 85 // parameters checking 86 unsigned int x = cluster_xy >> Y_WIDTH; 87 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 88 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 89 { 90 _printf("[GIET ERROR] in _timer_start()\n"); 91 _exit(); 92 } 92 93 93 94 unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + … … 96 97 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; 97 98 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3; 98 return 0; 99 } 100 101 ////////////////////////////////////////////////////////////////////////////// 102 // _timer_stop() 99 100 #else 101 _printf("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n"); 102 _exit(); 103 #endif 104 } 105 106 ////////////////////////////////////////////////////////////////////////////// 103 107 // This function desactivates a timer in the vci_timer component 104 108 // by writing in the proper register. 105 109 // Returns 0 if success, > 0 if error. 106 110 ////////////////////////////////////////////////////////////////////////////// 107 unsigned int _timer_stop( unsigned int cluster_xy, 108 unsigned int local_id) 109 { 110 // parameters checking 111 unsigned int x = cluster_xy >> Y_WIDTH; 112 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 113 if (x >= X_SIZE) return 1; 114 if (y >= Y_SIZE) return 1; 115 if (local_id >= NB_TIM_CHANNELS) return 1; 111 void _timer_stop( unsigned int cluster_xy, 112 unsigned int local_id) 113 { 114 #if NB_TIM_CHANNELS 115 116 // parameters checking 117 unsigned int x = cluster_xy >> Y_WIDTH; 118 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 119 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 120 { 121 _printf("[GIET ERROR] in _timer_stop()\n"); 122 _exit(); 123 } 116 124 117 125 unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + … … 119 127 120 128 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0; 121 return 0; 122 } 123 124 ////////////////////////////////////////////////////////////////////////////// 125 // _timer_reset_irq() 129 130 #else 131 _printf("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n"); 132 _exit(); 133 #endif 134 } 135 136 ////////////////////////////////////////////////////////////////////////////// 126 137 // This function acknowlegge a timer interrupt in the vci_timer 127 138 // component by writing in the proper register. … … 130 141 // Returns 0 if success, > 0 if error. 131 142 ////////////////////////////////////////////////////////////////////////////// 132 unsigned int _timer_reset_irq( unsigned int cluster_xy, 133 unsigned int local_id ) 134 { 135 // parameters checking 136 unsigned int x = cluster_xy >> Y_WIDTH; 137 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 138 if (x >= X_SIZE) return 1; 139 if (y >= Y_SIZE) return 1; 140 if (local_id >= NB_TIM_CHANNELS) return 1; 143 void _timer_reset_irq( unsigned int cluster_xy, 144 unsigned int local_id ) 145 { 146 #if NB_TIM_CHANNELS 147 148 // parameters checking 149 unsigned int x = cluster_xy >> Y_WIDTH; 150 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 151 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 152 { 153 _printf("[GIET ERROR] in _timer_reset_irq()\n"); 154 _exit(); 155 } 141 156 142 157 unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + … … 144 159 145 160 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0; 146 return 0; 161 162 #else 163 _printf("[GIET ERROR] _timer_reset_irq() should not be called when NB_TIM_CHANNELS is 0\n"); 164 _exit(); 165 #endif 147 166 } 148 167 149 168 ///////////////////////////////////////////////////////////////////////////// 150 // _timer_reset_cpt()151 169 // This function resets the timer counter. To do so, we re-write the period 152 170 // in the proper register, what causes the count to restart. … … 156 174 // This function is called during a context switch (user or preemptive) 157 175 //////////////////////////////////////////////////////////////////////i////// 158 unsigned int _timer_reset_cpt( unsigned int cluster_xy, 159 unsigned int local_id) 160 { 161 // parameters checking 162 unsigned int x = cluster_xy >> Y_WIDTH; 163 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 164 if (x >= X_SIZE) return 1; 165 if (y >= Y_SIZE) return 1; 166 if (local_id >= NB_TIM_CHANNELS) return 1; 176 void _timer_reset_cpt( unsigned int cluster_xy, 177 unsigned int local_id) 178 { 179 #if NB_TIM_CHANNELS 180 181 // parameters checking 182 unsigned int x = cluster_xy >> Y_WIDTH; 183 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 184 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 185 { 186 _printf("[GIET ERROR in _timer_reset_cpt()\n"); 187 _exit(); 188 } 167 189 168 190 // We suppose that the TIMER_MODE register value is 0x3 … … 172 194 unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD]; 173 195 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; 174 return 0; 175 } 196 197 #else 198 _printf("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n"); 199 _exit(); 200 #endif 201 } 202 203 /////////////////////////////////////////////////////////////////////////////////// 204 // This ISR handles the IRQs generated by the "user" timers that are 205 // replicated in all clusters. 206 // The IRQs generated by the "system" timers should be handled by _isr_switch(). 207 // It can be a HWI or a PTI. 208 // The channel argument is the user timer local index. 209 // timer_global_id = cluster_id*(NB_TIM_CHANNELS) + channel 210 // The ISR acknowledges the IRQ and registers the event in the proper entry 211 // of the _user_timer_event[] array, and a log message is displayed on TTY0. 212 /////////////////////////////////////////////////////////////////////////////////// 213 void _timer_isr( unsigned int irq_type, // HWI / PTI 214 unsigned int irq_id, // index returned by XCU 215 unsigned int channel ) // user timer index 216 { 217 #if NB_TIM_CHANNELS 218 219 unsigned int cluster_xy = _get_procid() / NB_PROCS_MAX; 220 221 // acknowledge IRQ depending on type 222 if ( irq_type == IRQ_TYPE_HWI ) _timer_reset_irq( cluster_xy, channel ); 223 else _xcu_timer_reset_irq( cluster_xy, irq_id ); 224 225 // register the event 226 _user_timer_event[cluster_xy * NB_TIM_CHANNELS + channel] = 1; 227 228 // display a message on TTY 0 229 _printf("\n[GIET WARNING] User Timer IRQ at cycle %d / cluster = %x / channel = %d\n", 230 _get_proctime(), cluster_xy, channel ); 231 232 #else 233 _printf("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n"); 234 _exit(); 235 #endif 236 } 237 176 238 177 239 -
soft/giet_vm/giet_drivers/tim_driver.h
r263 r295 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 8 #ifndef _GIET_TIM_DRIVER S_H_9 #define _GIET_TIM_DRIVER S_H_8 #ifndef _GIET_TIM_DRIVER_H_ 9 #define _GIET_TIM_DRIVER_H_ 10 10 11 11 /////////////////////////////////////////////////////////////////////////////////// … … 27 27 /////////////////////////////////////////////////////////////////////////////////// 28 28 29 extern volatile unsigned char _timer_event[]; 29 extern void _timer_start( unsigned int cluster_xy, 30 unsigned int local_id, 31 unsigned int period ); 30 32 31 extern unsigned int _timer_start( unsigned int cluster_xy, 32 unsigned int local_id, 33 unsigned int period ); 33 extern void _timer_stop( unsigned int cluster_xy, 34 unsigned int local_id ); 34 35 35 extern unsigned int _timer_stop( unsigned int cluster_xy,36 36 extern void _timer_reset_irq( unsigned int cluster_xy, 37 unsigned int local_id ); 37 38 38 extern unsigned int _timer_reset_irq( unsigned int cluster_xy,39 unsigned int local_id);39 extern void _timer_reset_cpt( unsigned int cluster_xy, 40 unsigned int local_id); 40 41 41 extern unsigned int _timer_reset_cpt( unsigned int cluster_xy, 42 unsigned int local_id); 42 extern void _timer_isr( unsigned int irq_type, 43 unsigned int irq_id, 44 unsigned int channel ); 43 45 44 46 /////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_drivers/tty_driver.c
r258 r295 8 8 // This driver supports the SocLib vci_multi_tty component. 9 9 // 10 // It can exist only one multi_tty controler in the architecture.11 //12 10 // The total number of TTY terminals must be defined by the configuration 13 11 // parameter NB_TTY_CHANNELS in the hard_config.h file. 14 //15 // The register offsets must be defined in the hwr_mapping.h file.16 12 // 17 13 // The "system" terminal is TTY[0]. … … 19 15 // as defined in the mapping_info data structure. The corresponding tty_id must 20 16 // be stored in the context of the task by the boot code. 21 ///////////////////////////////////////////////////////////////////////////////////22 // The virtual base address of the segment associated to a channel is:23 17 // 24 // seg_tty_base + TTY_SPAN * channel_id 25 // 26 // The seg_tty_base virtual base addresses must be defined in giet_vsegs.ld file. 18 // The seg_tty_base must be defined in giet_vsegs.ld file. 19 /////////////////////////////////////////////////////////////////////////////////// 20 // Implementation note: 21 // 22 // All physical accesses to device registers are done by the two 23 // _tty_get_register(), _tty_set_register() low-level functions, 24 // that are handling virtual / physical addressing. 27 25 /////////////////////////////////////////////////////////////////////////////////// 28 26 29 27 #include <giet_config.h> 30 28 #include <tty_driver.h> 29 #include <xcu_driver.h> 31 30 #include <ctx_handler.h> 32 31 #include <utils.h> … … 42 41 #define in_unckdata __attribute__((section (".unckdata"))) 43 42 44 ///////////////// TTY global variables 45 in_unckdata volatile unsigned char _tty_get_buf[NB_TTY_CHANNELS]; 46 in_unckdata volatile unsigned char _tty_get_full[NB_TTY_CHANNELS] 43 ////////////////////////////////////////////////////////////////////////////// 44 // TTY global variables 45 ////////////////////////////////////////////////////////////////////////////// 46 47 in_unckdata volatile unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; 48 in_unckdata volatile unsigned int _tty_rx_full[NB_TTY_CHANNELS] 47 49 = { [0 ... NB_TTY_CHANNELS - 1] = 0 }; 50 51 ////////////////////////////////////////////////////////////////////////////// 52 // This low level function returns the value of register (channel / index) 53 ////////////////////////////////////////////////////////////////////////////// 54 unsigned int _tty_get_register( unsigned int channel, 55 unsigned int index ) 56 { 57 unsigned int* vaddr = (unsigned int*)&seg_tty_base + channel*TTY_SPAN + index; 58 return _io_extended_read( vaddr ); 59 } 60 61 ////////////////////////////////////////////////////////////////////////////// 62 // This low level function set a new value in register (channel / index) 63 ////////////////////////////////////////////////////////////////////////////// 64 void _tty_set_register( unsigned int channel, 65 unsigned int index, 66 unsigned int value ) 67 { 68 unsigned int* vaddr = (unsigned int*)&seg_tty_base + channel*TTY_SPAN + index; 69 _io_extended_write( vaddr, value ); 70 } 48 71 49 72 ///////////////////////////////////////////////////////////////////////////////// 50 73 // This non-blocking function writes a character string from a fixed-length 51 // buffer to the TTY_WRITE register of a TTY terminal identified by the 52 // channel argument. If the channel argument is 0xFFFFFFFF, the channel 53 // index is obtained from the current taxk context. 54 // It doesn't use any interrupt. 74 // buffer to a TTY terminal identified by the channel argument. 75 // This function is intended to be used to handle a system call, and should 76 // not be used by the kernel for log messages on TTY 0. 77 // protecting exclusive access to the selected terminal. 78 // If channel argument is 0xFFFFFFFF, the TTY index is found in the task context. 55 79 // This is a non blocking call: it tests the TTY_STATUS register, and stops 56 80 // the transfer as soon as the TTY_STATUS[WRITE] bit is set. … … 62 86 unsigned int channel) // channel index 63 87 { 64 unsigned int nwritten; 65 unsigned int tty_id; 66 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 67 68 // compute tty channel 69 if( channel == 0xFFFFFFFF ) 70 { 71 tty_id = _get_context_slot(CTX_TTY_ID); 72 } 73 else 74 { 75 tty_id = (unsigned int)channel; 76 } 88 unsigned int nwritten; 89 90 // compute and check tty channel 91 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 92 if( channel >= NB_TTY_CHANNELS ) return -1; 77 93 78 94 // write string to TTY channel … … 80 96 { 81 97 // check tty's status 82 if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) break; 83 _tty_write_data( tty_id, buffer[nwritten] ); 84 } 98 if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 ) break; 99 100 // write one byte 101 _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] ); 102 } 103 85 104 return nwritten; 86 105 } … … 92 111 // It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been 93 112 // filled by the TTY_ISR. 94 // It test the _tty_ get_full[tty_id] register, read the _tty_get_buf[tty_id]113 // It test the _tty_rx_full[tty_id] variable, read the _tty_rx_buf[tty_id] 95 114 // buffer, writes this character to the target buffer, and resets the 96 // _tty_ get_full[tty_id] register.115 // _tty_rx_full[tty_id] register. 97 116 // The length argument is not used. 98 117 ////////////////////////////////////////////////////////////////////////////// … … 103 122 unsigned int channel) // channel index 104 123 { 105 106 unsigned int tty_id; 107 108 // compute tty channel 109 if( channel == 0xFFFFFFFF ) 110 { 111 tty_id = _get_context_slot(CTX_TTY_ID); 112 } 113 else 114 { 115 tty_id = (unsigned int)channel; 116 } 124 // compute and check tty channel 125 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 126 if( channel >= NB_TTY_CHANNELS ) return -1; 117 127 118 128 // read one character from TTY channel 119 if (_tty_ get_full[tty_id] == 0)129 if (_tty_rx_full[channel] == 0) 120 130 { 121 131 return 0; … … 123 133 else 124 134 { 125 *buffer = _tty_ get_buf[tty_id];126 _tty_ get_full[tty_id] = 0;135 *buffer = _tty_rx_buf[channel]; 136 _tty_rx_full[channel] = 0; 127 137 return 1; 128 138 } 129 139 } 130 ////////////////////////////////////////////////////////////////////////////// 131 132 ////////////////////////////////////////////////////////////////////////////// 133 // This function try to take the hardwired lock protecting exclusive access 134 // to TTY terminal identified by the channel argument. 140 141 ////////////////////////////////////////////////////////////////////////////// 142 // This function try to take the hardwired lock protecting 143 // exclusive access to TTY terminal identified by the "channel" argument. 144 // It enters a critical section before taking the lock, and save the SR value 145 // at address defined by the "save_sr_ptr" argument. 135 146 // It returns only when the lock has been successfully taken. 136 147 ////////////////////////////////////////////////////////////////////////////// 137 void _tty_get_lock( unsigned int channel )138 { 139 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 140 141 if( channel >= NB_TTY_CHANNELS )142 {143 _puts("[GIET ERROR] in _tty_get_lock() : illegal TTY index\n"); 144 _exit(); 145 } 146 147 while ( tty_address[channel * TTY_SPAN + TTY_CONFIG] ); 148 } 149 150 ////////////////////////////////////////////////////////////////////////////// 151 // This function releases the hardwired lock protecting exclusive access 152 // to TTY terminal identified by the channel argument. 153 ////////////////////////////////////////////////////////////////////////////// 154 void _tty_release_lock( unsigned int channel ) 155 { 156 unsigned int* tty_address = (unsigned int *) &seg_tty_base;157 158 if( channel >= NB_TTY_CHANNELS ) 159 { 160 _puts("[GIET ERROR] in _tty_release_lock() : illegal TTY index\n"); 161 _exit(); 162 } 163 164 tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0; 165 } 166 167 ////////////////////////////////////////////////////////////////////////////// 168 // This function returns the content of the TTY_READ register in the 169 // TTY terminal identified by the channel argument. 170 ////////////////////////////////////////////////////////////////////////////// 171 unsigned int _tty_read_data( unsigned int channel ) 172 { 173 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 174 175 if( channel >= NB_TTY_CHANNELS )176 {177 _ puts("[GIET ERROR] in _tty_read_data() : illegal TTY index\n");178 _exit();179 }180 181 return tty_address[channel * TTY_SPAN + TTY_READ];182 } 183 184 ////////////////////////////////////////////////////////////////////////////// 185 // This function returns the content of the TTY_STATUS register in the 186 // TTY terminal identified by the channel argument. 187 ////////////////////////////////////////////////////////////////////////////// 188 unsigned int _tty_get_status( unsigned int channel ) 189 { 190 unsigned int* tty_address = (unsigned int *) &seg_tty_base;191 192 if( channel >= NB_TTY_CHANNELS ) 193 { 194 _puts("[GIET ERROR] in _tty_get_status() : illegal TTY index\n");195 _exit(); 196 } 197 198 return tty_address[channel * TTY_SPAN + TTY_STATUS]; 199 } 200 201 ////////////////////////////////////////////////////////////////////////////// 202 // This function writes one character in the TTY_WRITE register in the 203 // TTY terminal identified by the channel argument. 204 ////////////////////////////////////////////////////////////////////////////// 205 void _tty_write_data( unsigned int channel, 206 char byte ) 207 { 208 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 209 210 if( channel >= NB_TTY_CHANNELS ) 211 { 212 _puts("[GIET ERROR] in _tty_write_data() : illegal TTY index\n"); 213 _exit();214 }215 216 tty_address[channel * TTY_SPAN + TTY_WRITE] = (unsigned int) byte;217 } 218 148 void _tty_get_lock( unsigned int channel, 149 unsigned int * save_sr_ptr ) 150 { 151 if( channel >= NB_TTY_CHANNELS ) _exit(); 152 _it_disable( save_sr_ptr ); 153 while ( _tty_get_register( channel, TTY_CONFIG ) ); // busy waiting 154 } 155 156 ////////////////////////////////////////////////////////////////////////////// 157 // This function releases the hardwired lock protecting 158 // exclusive access to TTY terminal identified by the channel argument. 159 // It exit the critical section after lock release, and restore SR value 160 // from address defined by the "save_sr_ptr" argument. 161 ////////////////////////////////////////////////////////////////////////////// 162 void _tty_release_lock( unsigned int channel, 163 unsigned int * save_sr_ptr ) 164 { 165 if( channel >= NB_TTY_CHANNELS ) _exit(); 166 167 _tty_set_register( channel, TTY_CONFIG, 0 ); 168 _it_restore( save_sr_ptr ); 169 } 170 171 /////////////////////////////////////////////////////////////////////////////////// 172 // This ISR handles the IRQ signaling that the RX buffer is full. 173 // IT can be an HWI or an SWI. 174 // There is one single multi_tty component controling all channels. 175 // There is one communication buffer _tty_rx_buf[i] and one synchronisation 176 // variable _tty_rx_full[i] per channel. 177 // A character is lost if the buffer is full when the ISR is executed. 178 /////////////////////////////////////////////////////////////////////////////////// 179 void _tty_rx_isr( unsigned int irq_type, // HWI / WTI 180 unsigned int irq_id, // index returned by XCU 181 unsigned int channel ) // TTY channel 182 { 183 unsigned int cluster_xy = _get_procid() / NB_PROCS_MAX; 184 185 if ( irq_type == IRQ_TYPE_WTI ) // reset SWI in XCU if required 186 { 187 unsigned int value; 188 _xcu_get_wti_value( cluster_xy, irq_id, &value ); 189 } 190 191 // get character and reset TTY IRQ 192 _tty_rx_buf[channel] = _tty_get_register( channel, TTY_READ ); 193 194 #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlock 195 unsigned int x = cluster_xy >> Y_WIDTH; 196 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 197 unsigned int lpid = _get_procid() % NB_PROCS_MAX; 198 _puts("\n[IRQS DEBUG] Processor["); 199 _putd(x ); 200 _puts(","); 201 _putd(y ); 202 _puts(","); 203 _putd(lpid ); 204 _puts("] enters _tty_rx_isr() at cycle "); 205 _putd(_get_proctime() ); 206 _puts("\n read byte = "); 207 _putx(_tty_rx_buf[channel] ); 208 _puts("\n"); 209 #endif 210 211 // signals character available 212 _tty_rx_full[channel] = 1; 213 } 214 215 /////////////////////////////////////////////////////////////////////////////////// 216 // This ISR handles the IRQ signaling that the TX buffer is empty. 217 // IT can be an HWI or an SWI. 218 // There is one single multi_tty component controling all channels. 219 // There is one communication buffer _tty_rx_buf[i] and one synchronisation 220 // variable _tty_rx_full[i] per channel. 221 // A character is lost if the buffer is full when the ISR is executed. 222 /////////////////////////////////////////////////////////////////////////////////// 223 void _tty_tx_isr( unsigned int irq_type, // HWI / WTI 224 unsigned int irq_id, // index returned by XCU 225 unsigned int channel ) // TTY channel 226 { 227 _puts("\n[GIET ERROR] the _tty_tx_isr() is not implemented\n"); 228 _exit(); 229 } 219 230 220 231 // Local Variables: -
soft/giet_vm/giet_drivers/tty_driver.h
r258 r295 24 24 25 25 /////////////////////////////////////////////////////////////////////////////////// 26 // TTY access functions andvariables26 // TTY variables 27 27 /////////////////////////////////////////////////////////////////////////////////// 28 28 … … 31 31 extern volatile unsigned char _tty_get_full[]; 32 32 33 /////// rather high level access functions /////////////////////////////////////// 33 ////////////////////////////////////////////////////////////////////////////////// 34 // TTY access functions 35 ////////////////////////////////////////////////////////////////////////////////// 34 36 35 37 extern unsigned int _tty_write( const char* buffer, 36 unsigned int length, // number of characters37 unsigned int channel ); // channel index38 unsigned int length, 39 unsigned int channel ); 38 40 39 41 extern unsigned int _tty_read( char* buffer, 40 unsigned int length, // unused41 unsigned int channel ); // channel index42 unsigned int length, 43 unsigned int channel ); 42 44 43 /////// very low level access functions ////////////////////////////////////////// 45 extern void _tty_get_lock( unsigned int channel, 46 unsigned int* save_sr_ptr ); 44 47 45 extern void _tty_write_data( unsigned int channel, char byte ); 48 extern void _tty_release_lock( unsigned int channel, 49 unsigned int* save_sr_ptr ); 46 50 47 extern unsigned int _tty_read_data( unsigned int channel ); 51 extern void _tty_rx_isr( unsigned int irq_type, 52 unsigned int irq_id, 53 unsigned int channel ); 48 54 49 extern unsigned int _tty_get_status( unsigned int channel ); 50 51 extern void _tty_get_lock( unsigned int channel ); 52 53 extern void _tty_release_lock( unsigned int channel ); 55 extern void _tty_tx_isr( unsigned int irq_type, 56 unsigned int irq_id, 57 unsigned int channel ); 54 58 55 59 /////////////////////////////////////////////////////////////////////////////////// 60 // low-level access functions 61 /////////////////////////////////////////////////////////////////////////////////// 56 62 63 extern unsigned int _tty_get_register( unsigned int channel, 64 unsigned int index ); 65 66 extern void _tty_set_register( unsigned int channel, 67 unsigned int index, 68 unsigned int value ); 57 69 58 70 #endif -
soft/giet_vm/giet_drivers/xcu_driver.c
r281 r295 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel.8 // This driver supports the SoCLib vci_xicu, that is a vectorised interrupt9 // controler supporting IPI (Inter Processor Interrupts) and integrated timers.10 //11 // It can exist several interrupt controller unit in the architecture12 // (one per cluster), and each one can contain several channels.13 // The number of XICU channels is equal to NB_PROCS_MAX, because there is14 // one private XICU channel per processor in a cluster.15 ////////////////////////////////////////////////////////////////////////////////16 // The virtual base address of the segment associated to the component is:17 //18 // seg_xcu_base + cluster_xy * vseg_cluster_increment19 //20 // The seg_xcu_base and vseg_cluster_increment values must be defined21 // in giet_vsegs.ld file.22 ////////////////////////////////////////////////////////////////////////////////23 7 24 8 #include <giet_config.h> … … 52 36 #endif 53 37 54 //////////////////////////////////////////////////////////////////////////////// 55 // _xcu_set_mask() 56 // This function set the mask register for the XICU channel identified by the 57 // cluster index and the processor index multiplied by the number of IRQ per 58 // processor. 38 39 //////////////////////////////////////////////////////////////////////////////// 40 // This function set the mask register for the IRQ type defined by "irq_type", 41 // and for the channel identified by the "cluster_xy" and "channel" arguments. 59 42 // All '1' bits are set / all '0' bits are not modified. 60 // Returns 0 if success, > 0 if error. 61 //////////////////////////////////////////////////////////////////////////////// 62 unsigned int _xcu_set_mask( unsigned int cluster_xy, 63 unsigned int irq_index, 64 unsigned int value, 65 unsigned int irq_type ) 66 { 67 // parameters checking 68 unsigned int x = cluster_xy >> Y_WIDTH; 69 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 70 if (x >= X_SIZE) return 1; 71 if (y >= Y_SIZE) return 1; 72 if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1; 73 74 #if USE_XICU 43 //////////////////////////////////////////////////////////////////////////////// 44 void _xcu_set_mask( unsigned int cluster_xy, 45 unsigned int channel, 46 unsigned int value, 47 unsigned int irq_type ) 48 { 49 #if USE_XICU 50 // parameters checking 51 unsigned int x = cluster_xy >> Y_WIDTH; 52 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 53 if (x >= X_SIZE) _exit(); 54 if (y >= Y_SIZE) _exit(); 55 if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 56 75 57 volatile unsigned int* xcu_address = 76 58 (unsigned int *) ((unsigned int)&seg_xcu_base + … … 79 61 unsigned int func; 80 62 if (irq_type == IRQ_TYPE_PTI) func = XICU_MSK_PTI_ENABLE; 81 else if (irq_type == IRQ_TYPE_SWI) func = XICU_MSK_WTI_ENABLE; 82 else func = XICU_MSK_HWI_ENABLE; 83 xcu_address[XICU_REG(func,irq_index)] = value; 84 return 0; 85 #else 86 _tty_get_lock( 0 ); 87 _puts("[GIET ERROR] _xcu_set_mask should not be used if USE_XICU is not set\n"); 88 _tty_release_lock( 0 ); 89 return 1; 90 #endif 91 } 92 93 //////////////////////////////////////////////////////////////////////////////// 94 // _xcu_get_index() 95 // This function returns the index of the highest priority (smaller index) 96 // - active HWI (Hardware Interrupt), or 97 // - active PTI (Timer Interrupt), or 98 // - active SWI (Software Interrupt). 99 // The ICU channel is identified by the cluster index and the processor index 100 // multiplied by the number of IRQ per processor. 101 // Returns 0 if success, > 0 if error. 102 //////////////////////////////////////////////////////////////////////////////// 103 unsigned int _xcu_get_index( unsigned int cluster_xy, 104 unsigned int irq_index, 105 unsigned int * buffer) 106 { 107 // parameters checking 108 unsigned int x = cluster_xy >> Y_WIDTH; 109 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 110 if (x >= X_SIZE) return 1; 111 if (y >= Y_SIZE) return 1; 112 if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1; 113 114 #if USE_XICU 115 volatile unsigned int* xcu_address = 116 (unsigned int *) ((unsigned int)&seg_xcu_base + 117 (cluster_xy * (unsigned int)&vseg_cluster_increment)); 118 119 unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,irq_index)]; 63 else if (irq_type == IRQ_TYPE_WTI) func = XICU_MSK_WTI_ENABLE; 64 else if (irq_type == IRQ_TYPE_HWI) func = XICU_MSK_HWI_ENABLE; 65 else 66 { 67 _printf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n"); 68 _exit(); 69 } 70 71 xcu_address[XICU_REG(func,channel)] = value; 72 73 #else 74 _printf("[GIET ERROR] _xcu_set_mask() should not be used if USE_XICU not set\n"); 75 _exit(); 76 #endif 77 } 78 79 //////////////////////////////////////////////////////////////////////////////// 80 // This function returns the index and the type of the highest priority 81 // - active PTI (Timer Interrupt), then 82 // - active HWI (Hardware Interrupt), then 83 // - active WTI (Software Interrupt) 84 // As the hardware can define more than one IRQ per processor, but the GIET 85 // use only one, channel = lpid * IRQ_PER_PROCESSOR. 86 //////////////////////////////////////////////////////////////////////////////// 87 void _xcu_get_index( unsigned int cluster_xy, 88 unsigned int channel, 89 unsigned int * index, 90 unsigned int * irq_type ) 91 { 92 #if USE_XICU 93 // parameters checking 94 unsigned int x = cluster_xy >> Y_WIDTH; 95 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 96 if (x >= X_SIZE) _exit(); 97 if (y >= Y_SIZE) _exit(); 98 if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 99 100 volatile unsigned int* xcu_address = 101 (unsigned int *) ((unsigned int)&seg_xcu_base + 102 (cluster_xy * (unsigned int)&vseg_cluster_increment)); 103 104 unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,channel)]; 120 105 unsigned int pti_ok = (prio & 0x00000001); 121 106 unsigned int hwi_ok = (prio & 0x00000002); 122 unsigned int swi_ok = (prio & 0x00000004);107 unsigned int wti_ok = (prio & 0x00000004); 123 108 unsigned int pti_id = (prio & 0x00001F00) >> 8; 124 109 unsigned int hwi_id = (prio & 0x001F0000) >> 16; 125 unsigned int swi_id = (prio & 0x1F000000) >> 24; 126 if (pti_ok) *buffer = pti_id; 127 else if (hwi_ok) *buffer = hwi_id; 128 else if (swi_ok) *buffer = swi_id; 129 else *buffer = 32; 130 return 0; 131 #else 132 _tty_get_lock( 0 ); 133 _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n"); 134 _tty_release_lock( 0 ); 135 return 1; 136 #endif 137 } 138 139 //////////////////////////////////////////////////////////////////////////////// 140 // _xcu_send_ipi() 141 // This function can be used only in an architecture using XICU components. 142 // It writes the "wdata" value in the mailbox defined by the cluster index 143 // and the processor index. 144 // Giet-VM supports at most NB_PROCS_MAX mailboxes: 145 // (0 <= wti_index <= NB_PROCS_MAX-1) 146 // Returns 0 if success, > 0 if error. 147 //////////////////////////////////////////////////////////////////////////////// 148 unsigned int _xcu_send_ipi( unsigned int cluster_xy, 149 unsigned int wti_index, 150 unsigned int wdata ) 110 unsigned int wti_id = (prio & 0x1F000000) >> 24; 111 if (pti_ok) 112 { 113 *index = pti_id; 114 *irq_type = IRQ_TYPE_PTI; 115 } 116 else if (hwi_ok) 117 { 118 *index = hwi_id; 119 *irq_type = IRQ_TYPE_HWI; 120 } 121 else if (wti_ok) 122 { 123 *index = wti_id; 124 *irq_type = IRQ_TYPE_WTI; 125 } 126 else 127 { 128 *index = 32; 129 } 130 131 #else 132 _printf("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n"); 133 _exit(); 134 #endif 135 } 136 137 //////////////////////////////////////////////////////////////////////////////// 138 // This function writes the "wdata" value in the mailbox defined 139 // by the "cluster_xy" and "wti_index" arguments. 140 //////////////////////////////////////////////////////////////////////////////// 141 void _xcu_send_wti( unsigned int cluster_xy, 142 unsigned int wti_index, 143 unsigned int wdata ) 151 144 { 152 // parameters checking 153 unsigned int x = cluster_xy >> Y_WIDTH;154 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);155 if (x >= X_SIZE) return 1;156 if ( y >= Y_SIZE) return 1;157 if ( wti_index >= NB_PROCS_MAX) return 1;158 159 #if USE_XICU 145 #if USE_XICU 146 // parameters checking 147 unsigned int x = cluster_xy >> Y_WIDTH; 148 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 149 if (x >= X_SIZE) _exit(); 150 if (y >= Y_SIZE) _exit(); 151 if (wti_index >= 32) _exit(); 152 160 153 volatile unsigned int* xcu_address = 161 154 (unsigned int *) ((unsigned int)&seg_xcu_base + … … 163 156 164 157 xcu_address[XICU_REG(XICU_WTI_REG,wti_index)] = wdata; 165 return 0; 166 #else 167 _tty_get_lock( 0 ); 168 _puts("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n"); 169 _tty_release_lock( 0 ); 170 return 1; 158 159 #else 160 _printf("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n"); 161 _exit(); 171 162 #endif 172 163 } 173 164 174 165 //////////////////////////////////////////////////////////////////////////////// 175 // _xcu_timer_start() 166 // This function returns the value contained in a WTI mailbox defined by 167 // the cluster_xy and "wti_index" arguments. This value is written in 168 // the "value" argument, and the corresponding WTI is acknowledged. 169 // returns 0 if success, > 0 if error. 170 //////////////////////////////////////////////////////////////////////////////// 171 void _xcu_get_wti_value( unsigned int cluster_xy, 172 unsigned int wti_index, 173 unsigned int * value ) 174 { 175 #if USE_XICU 176 // parameters checking 177 unsigned int x = cluster_xy >> Y_WIDTH; 178 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 179 if (x >= X_SIZE) _exit(); 180 if (y >= Y_SIZE) _exit(); 181 if (wti_index >= 32) _exit(); 182 183 volatile unsigned int* xcu_address = 184 (unsigned int *) ((unsigned int)&seg_xcu_base + 185 (cluster_xy * (unsigned int)&vseg_cluster_increment)); 186 187 *value = xcu_address[XICU_REG(XICU_WTI_REG, wti_index)]; 188 189 #else 190 _printf("[GIET ERROR] in _xcu_get_wti_value() USE_XICU is not set\n"); 191 _exit(); 192 #endif 193 } 194 195 //////////////////////////////////////////////////////////////////////////////// 196 // This function returns the address of a WTI mailbox defined by 197 // the "wti_index" argument, in the unsigned int "address" argument. 198 // It is used by the GIET to configurate the IOPIC component. 199 // There is no access to a specific XCU component in a specific cluster. 200 // returns 0 if success, > 0 if error. 201 //////////////////////////////////////////////////////////////////////////////// 202 void _xcu_get_wti_address( unsigned int wti_index, 203 unsigned int * address ) 204 { 205 #if USE_XICU 206 if (wti_index >= 32) _exit(); 207 208 unsigned int xcu_address = (unsigned int)&seg_xcu_base; 209 *address = xcu_address + (XICU_REG(XICU_WTI_REG, wti_index)<<2); 210 211 #else 212 _printf("[GIET ERROR] in _xcu_get_wti_address() USE_XICU is not set\n"); 213 _exit(); 214 #endif 215 } 216 217 //////////////////////////////////////////////////////////////////////////////// 176 218 // This function activates a timer contained in XICU by writing in the 177 219 // proper register the period value. 178 // Returns 0 if success, > 0 if error. 179 //////////////////////////////////////////////////////////////////////////////// 180 unsigned int _xcu_timer_start( unsigned int cluster_xy, 181 unsigned int pti_index, 182 unsigned int period ) 183 { 184 // parameters checking 185 unsigned int x = cluster_xy >> Y_WIDTH; 186 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 187 if (x >= X_SIZE) return 1; 188 if (y >= Y_SIZE) return 1; 189 190 #if USE_XICU 220 //////////////////////////////////////////////////////////////////////////////// 221 void _xcu_timer_start( unsigned int cluster_xy, 222 unsigned int pti_index, 223 unsigned int period ) 224 { 225 #if USE_XICU 226 // parameters checking 227 unsigned int x = cluster_xy >> Y_WIDTH; 228 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 229 if (x >= X_SIZE) _exit(); 230 if (y >= Y_SIZE) _exit(); 231 191 232 volatile unsigned int* xcu_address = 192 233 (unsigned int *) ((unsigned int)&seg_xcu_base + … … 194 235 195 236 xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period; 196 return 0; 197 #else 198 _tty_get_lock( 0 ); 199 _puts("[GIET ERROR] _xcu_timer_start should not be used if USE_XICU is not set\n"); 200 _tty_release_lock( 0 ); 201 return 1; 202 #endif 203 } 204 205 ////////////////////////////////////////////////////////////////////////////// 206 // _xcu_timer_stop() 237 238 #else 239 _printf("[GIET ERROR] in _xcu_timer_start() USE_XICU is not set\n"); 240 _exit(); 241 #endif 242 } 243 244 ////////////////////////////////////////////////////////////////////////////// 207 245 // This function desactivates a timer in XICU component 208 246 // by writing in the proper register. 209 // Returns 0 if success, > 0 if error. 210 ////////////////////////////////////////////////////////////////////////////// 211 unsigned int _xcu_timer_stop( unsigned int cluster_xy, 212 unsigned int pti_index) 213 { 214 // parameters checking 215 unsigned int x = cluster_xy >> Y_WIDTH; 216 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 217 if (x >= X_SIZE) return 1; 218 if (y >= Y_SIZE) return 1; 219 220 #if USE_XICU 247 ////////////////////////////////////////////////////////////////////////////// 248 void _xcu_timer_stop( unsigned int cluster_xy, 249 unsigned int pti_index) 250 { 251 #if USE_XICU 252 // parameters checking 253 unsigned int x = cluster_xy >> Y_WIDTH; 254 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 255 if (x >= X_SIZE) _exit(); 256 if (y >= Y_SIZE) _exit(); 257 221 258 volatile unsigned int * xcu_address = 222 259 (unsigned int *) ((unsigned int)&seg_xcu_base + … … 224 261 225 262 xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0; 226 return 0; 227 #else 228 _tty_get_lock( 0 ); 229 _puts("[GIET ERROR] _xcu_timer_stop should not be used if USE_XICU is not set\n"); 230 _tty_release_lock( 0 ); 231 return 1; 232 #endif 233 } 234 235 ////////////////////////////////////////////////////////////////////////////// 236 // _xcu_timer_reset_irq() 263 264 #else 265 _printf("[GIET ERROR] in _xcu_timer_stop() USE_XICU is not set\n"); 266 _exit(); 267 #endif 268 } 269 270 ////////////////////////////////////////////////////////////////////////////// 237 271 // This function acknowlegge a timer interrupt in XICU 238 272 // component by reading in the proper register. 239 273 // It can be used by both the isr_switch() for a "system" timer, 240 274 // or by the _isr_timer() for an "user" timer. 241 // Returns 0 if success, > 0 if error. 242 ////////////////////////////////////////////////////////////////////////////// 243 unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 244 unsigned int pti_index ) 245 { 246 // parameters checking 247 unsigned int x = cluster_xy >> Y_WIDTH; 248 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 249 if (x >= X_SIZE) return 1; 250 if (y >= Y_SIZE) return 1; 251 252 #if USE_XICU 275 ////////////////////////////////////////////////////////////////////////////// 276 void _xcu_timer_reset_irq( unsigned int cluster_xy, 277 unsigned int pti_index ) 278 { 279 #if USE_XICU 280 // parameters checking 281 unsigned int x = cluster_xy >> Y_WIDTH; 282 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 283 if (x >= X_SIZE) _exit(); 284 if (y >= Y_SIZE) _exit(); 285 253 286 volatile unsigned int * xcu_address = 254 287 (unsigned int *) ((unsigned int)&seg_xcu_base + … … 256 289 257 290 xcu_address[XICU_REG(XICU_PTI_ACK, pti_index)]; 258 return 0; 259 #else 260 _tty_get_lock( 0 ); 261 _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n"); 262 _tty_release_lock( 0 ); 263 return 1; 264 #endif 265 } 266 267 ////////////////////////////////////////////////////////////////////////////// 268 // _xcu_timer_reset_cpt() 291 292 #else 293 _printf("[GIET ERROR] in _xcu_timer_reset_irq() USE_XICU is not set\n"); 294 _exit(); 295 #endif 296 } 297 298 ////////////////////////////////////////////////////////////////////////////// 269 299 // This function resets a timer counter. To do so, we re-write the period 270 300 // in the proper register, what causes the count to restart. 271 301 // The period value is read from the same (TIMER_PERIOD) register, 272 302 // this is why in appearance we do nothing useful (read a value 273 // from a register and write this value in the same register) 303 // from a register and write this value in the same register). 274 304 // This function is called during a context switch (user or preemptive) 275 305 ///////////////////////////////////////////////////////////////////////////// 276 unsigned int_xcu_timer_reset_cpt( unsigned int cluster_xy,277 278 { 279 // parameters checking 280 unsigned int x = cluster_xy >> Y_WIDTH;281 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);282 if (x >= X_SIZE) return 1;283 if ( y >= Y_SIZE) return 1;284 285 #if USE_XICU 306 void _xcu_timer_reset_cpt( unsigned int cluster_xy, 307 unsigned int pti_index ) 308 { 309 #if USE_XICU 310 // parameters checking 311 unsigned int x = cluster_xy >> Y_WIDTH; 312 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 313 if (x >= X_SIZE) _exit(); 314 if (y >= Y_SIZE) _exit(); 315 286 316 volatile unsigned int * xcu_address = 287 317 (unsigned int *) ((unsigned int) &seg_xcu_base + … … 294 324 xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0; 295 325 xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period; 296 return 0; 297 #else 298 _tty_get_lock( 0 ); 299 _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n"); 300 _tty_release_lock( 0 ); 301 return 1; 326 327 #else 328 _printf("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XICU is not set\n"); 329 _exit(); 302 330 #endif 303 331 } -
soft/giet_vm/giet_drivers/xcu_driver.h
r281 r295 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel. 8 // This driver supports the SoCLib vci_xicu, that is a vectorised interrupt 9 // controler supporting IPI (Inter Processor Interrupts) and integrated timers. 10 // 11 // It can exist several interrupt controller unit in the architecture 12 // (one per cluster), and each one can contain several channels. 13 // The number of XICU channels is equal to NB_PROCS_MAX, because there is 14 // one private XICU channel per processor in a cluster. 15 //////////////////////////////////////////////////////////////////////////////// 16 // The virtual base address of the segment associated to the component is: 17 // 18 // seg_xcu_base + cluster_xy * vseg_cluster_increment 19 // 20 // The seg_xcu_base and vseg_cluster_increment values must be defined 21 // in giet_vsegs.ld file. 22 //////////////////////////////////////////////////////////////////////////////// 7 23 8 24 #ifndef _GIET_XCU_DRIVER_H_ … … 44 60 /////////////////////////////////////////////////////////////////////////////////// 45 61 46 extern unsigned int _xcu_get_index( unsigned int cluster_xy, 47 unsigned int irq_index, 48 unsigned int * buffer ); 62 extern void _xcu_set_mask( unsigned int cluster_xy, 63 unsigned int channel, 64 unsigned int mask, 65 unsigned int irq_type ); 49 66 50 extern unsigned int _xcu_set_mask( unsigned int cluster_xy,51 unsigned int irq_index,52 unsigned int mask,53 unsigned int is_timer);67 extern void _xcu_get_index( unsigned int cluster_xy, 68 unsigned int channel, 69 unsigned int * index, 70 unsigned int * irq_type ); 54 71 55 extern unsigned int _xcu_send_ipi( unsigned int cluster_xy,56 57 72 extern void _xcu_send_wti( unsigned int cluster_xy, 73 unsigned int wti_index, 74 unsigned int wdata ); 58 75 59 extern unsigned int _xcu_timer_start( unsigned int cluster_xy,60 unsigned int pti_index,61 unsigned int period );76 extern void _xcu_get_wti_value( unsigned int cluster_xy, 77 unsigned int wti_index, 78 unsigned int * value ); 62 79 63 extern unsigned int _xcu_timer_stop( unsigned int cluster_xy,64 unsigned int pti_index );80 extern void _xcu_get_wti_address( unsigned int wti_index, 81 unsigned int * address ); 65 82 66 extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 67 unsigned int pti_index ); 83 extern void _xcu_timer_start( unsigned int cluster_xy, 84 unsigned int pti_index, 85 unsigned int period ); 68 86 69 extern unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy, 70 unsigned int pti_index ); 87 extern void _xcu_timer_stop( unsigned int cluster_xy, 88 unsigned int pti_index ); 89 90 extern void _xcu_timer_reset_irq( unsigned int cluster_xy, 91 unsigned int pti_index ); 92 93 extern void _xcu_timer_reset_cpt( unsigned int cluster_xy, 94 unsigned int pti_index ); 71 95 72 96 /////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_fat32/fat32.c
r291 r295 17 17 // 2. This FAT32 library uses a FAT cache whose storage capacity is one 18 18 // sector (512 bytes, or 128 cluster indexes in FAT) 19 // 3. This FAT32 library can be used in three modes: BOOT/KERNEL/USER20 // defining threedifferent behaviours for the IOC driver.19 // 3. This FAT32 library can be used in four modes: BOOT_PA/BOOT_VA/KERNEL/USER 20 // defining different behaviours for the IOC driver. 21 21 ////////////////////////////////////////////////////////////////////////////////// 22 22 … … 46 46 temp[8] = 0; 47 47 48 _tty_get_lock( 0 ); 49 _puts("\n*********************** fat_cache_lba = "); 50 _putx( fat.cache_lba ); 51 _puts(" **************************\n"); 48 _printf("\n*********************** fat_cache_lba = %x *****************************\n", 49 fat.cache_lba ); 52 50 53 51 for ( line=0 ; line<16 ; line++ ) 54 52 { 55 53 // display address 56 _putx( (fat.cache_lba<<9) + (line<<5) ); 57 _puts(" : "); 54 _printf( "%x : ", (fat.cache_lba<<9) + (line<<5) ); 58 55 59 56 // display data hexa … … 65 62 (fat.fat_cache[byte+2]<< 8) | 66 63 (fat.fat_cache[byte+3]); 67 _putx( hexa ); 68 _puts(" | "); 64 _printf("%x | ", hexa ); 69 65 70 66 // prepare display ascii … … 76 72 77 73 // display data ascii 78 _puts( (char*)temp ); 79 _puts("\n"); 80 } 81 _puts("***************************************************************************\n"); 82 _tty_release_lock( 0 ); 74 _printf( (char*)temp ); 75 _printf("\n"); 76 } 77 _printf("**************************************************************************\n"); 83 78 } // end display_fat_cache() 84 79 #endif … … 202 197 203 198 // access fat 204 if( _ioc_read( mode, // mode for IOC driver 199 if( _ioc_read( 0, // channel 200 mode, // mode for IOC driver 205 201 lba, // sector index 206 202 fat.fat_cache, // fat cache 207 203 1 ) ) // one sector 208 204 { 209 _tty_get_lock( 0 ); 210 _puts("[FAT_ERROR] in get_next cluster_id() cannot read block "); 211 _putd( lba ); 212 _puts("\n"); 213 _tty_release_lock( 0 ); 205 _printf("[FAT_ERROR] in get_next cluster_id() " 206 "cannot read block %x\n", lba ); 214 207 return 1; 215 208 } … … 271 264 272 265 #if GIET_DEBUG_FAT 273 _tty_get_lock( 0 ); 274 _puts("\n[FAT DEBUG] filename "); 275 _puts( string ); 276 _tty_release_lock( 0 ); 266 _printf("\n[FAT DEBUG] filename %s", string ); 277 267 #endif 278 268 … … 282 272 283 273 #if GIET_DEBUG_FAT 284 _tty_get_lock( 0 ); 285 _puts(" converted to 8.3 SFN format : "); 286 _puts( sfn_string ); 287 _puts("\n"); 288 _tty_release_lock( 0 ); 274 _printf(" converted to 8.3 SFN format : %s\n", sfn_string ); 289 275 #endif 290 276 … … 298 284 299 285 #if GIET_DEBUG_FAT 300 _tty_get_lock( 0 ); 301 _puts(" converted to 8.3 SFN format : "); 302 _puts( string ); 303 _puts("\n"); 304 _tty_release_lock( 0 ); 286 _printf(" converted to 8.3 SFN format : %s\n", sfn_string ); 305 287 #endif 306 288 … … 358 340 359 341 #if GIET_DEBUG_FAT 360 _tty_get_lock( 0 ); 361 _puts(" converted to 8.3 SFN format : "); 362 _puts( sfn_string ); 363 _puts("\n"); 364 _tty_release_lock( 0 ); 342 _printf(" converted to 8.3 SFN format : %s\n", sfn_string ); 365 343 #endif 366 344 … … 524 502 is_sfn = is_short( file_name, sfn ); 525 503 526 if ( _ioc_read( IOC_KERNEL_MODE, // mode for IOC driver 504 if ( _ioc_read( 0, // channel 505 IOC_KERNEL_MODE, // mode for IOC driver 527 506 lba, // sector index 528 507 fat.fat_cache, // buffer address 529 508 1 ) ) // one sector 530 509 { 531 _tty_get_lock( 0 ); 532 _puts("[FAT ERROR] in update_entry() cannot read sector "); 533 _putd( lba ); 534 _puts("\n"); 535 _tty_release_lock( 0 ); 510 _printf("[FAT ERROR] in update_entry() cannot read sector %x\n", lba ); 536 511 return 1; 537 512 } … … 562 537 else if (ord == NO_MORE_ENTRY ) // end of directory : return 563 538 { 564 _tty_get_lock( 0 ); 565 _puts("[FAT ERROR] in update_entry() end of directory reaches "); 566 _puts("\n"); 567 _tty_release_lock( 0 ); 539 _printf("[FAT ERROR] in update_entry() : reaches end of directory\n"); 568 540 return 1; 569 541 } … … 591 563 else if (ord == NO_MORE_ENTRY ) // end of directory : return 592 564 { 593 _tty_get_lock( 0 ); 594 _puts("[FAT ERROR] in update_entry() end of directory reaches "); 595 _puts("\n"); 596 _tty_release_lock( 0 ); 565 _printf("[FAT ERROR] in update_entry() reaches end of directory\n"); 597 566 return 1; 598 567 } … … 643 612 } 644 613 645 return _ioc_write( IOC_KERNEL_MODE, 646 lba, 647 fat.fat_cache, 648 1 ); 649 } 650 ////////////////////////////////////////////////////////////////////////////////// 651 // This function update FS_INFO, for new last cluster allocated and number of free 652 // cluster. 614 return _ioc_write( 0, // channel 615 IOC_KERNEL_MODE, // mode 616 lba, // sector index 617 fat.fat_cache, // source buffer 618 1 ); // one sector 619 } 620 ////////////////////////////////////////////////////////////////////////////////// 621 // This function update FS_INFO: 622 // last cluster allocated and number of free cluster. 653 623 // Return 0 in case of success, > 0 if failure. 654 624 ////////////////////////////////////////////////////////////////////////////////// … … 658 628 659 629 #if GIET_DEBUG_FAT 660 _tty_get_lock( 0 ); 661 _puts("\n[FAT DEBUG] Enter in update_fs_info()\n"); 662 _tty_release_lock( 0 ); 630 _printf("\n[FAT DEBUG] Enter update_fs_info()\n"); 663 631 #endif 664 632 … … 670 638 else // miss cache 671 639 { 672 if ( _ioc_read( IOC_KERNEL_MODE, // mode for IOC driver 640 if ( _ioc_read( 0, // channel 641 IOC_KERNEL_MODE, // mode for IOC driver 673 642 lba, // sector index 674 fat.fat_cache, // fat cache643 fat.fat_cache, // source buffer 675 644 1 ) ) // one sector 676 645 { 677 _tty_get_lock( 0 ); 678 _puts("[FAT_ERROR] in update_fat() cannot read block "); 679 _putd( lba ); 680 _puts("\n"); 681 _tty_release_lock( 0 ); 646 _printf("[FAT_ERROR] in update_fat() cannot read block %x\n", lba ); 682 647 return 1; 683 648 } … … 686 651 write_entry( FS_FREE_CLUSTER_HINT, fat.fat_cache, fat.last_cluster_allocated ); 687 652 } 688 return _ioc_write( IOC_KERNEL_MODE, 689 lba, 690 fat.fat_cache, 691 1 ); 653 return _ioc_write( 0, // channel 654 IOC_KERNEL_MODE, // mode 655 lba, // sector index 656 fat.fat_cache, // source buffer 657 1 ); // one sector 692 658 } 693 659 … … 703 669 704 670 #if GIET_DEBUG_FAT 705 _tty_get_lock( 0 ); 706 _puts("\n[FAT DEBUG] Enter in update_fat() :\n"); 707 _puts(" - Cluster to update = "); 708 _putd( cluster ); 709 _puts("\n"); 710 _puts(" - Value to write = "); 711 _putd( value ); 712 _puts("\n"); 713 _tty_release_lock( 0 ); 671 _printf("\n[FAT DEBUG] Enter update_fat() : cluster = %x / value = %x\n", 672 cluster, value ); 714 673 #endif 715 674 … … 720 679 else // miss cache 721 680 { 722 if ( _ioc_read( IOC_KERNEL_MODE, // mode for IOC driver 681 if ( _ioc_read( 0, // channel 682 IOC_KERNEL_MODE, // mode for IOC driver 723 683 lba, // sector index 724 fat.fat_cache, // fat cache684 fat.fat_cache, // source buffer 725 685 1 ) ) // one sector 726 686 { 727 _tty_get_lock( 0 ); 728 _puts("[FAT_ERROR] in update_fat() cannot read block "); 729 _putd( lba ); 730 _puts("\n"); 731 _tty_release_lock( 0 ); 687 _printf("[FAT_ERROR] in update_fat() cannot read block %x\n"); 732 688 return 1; 733 689 } … … 735 691 write_entry( ((cluster % 128) << 2), 4, fat.fat_cache, value ); 736 692 } 737 return _ioc_write( IOC_KERNEL_MODE, 738 lba, 739 fat.fat_cache, 740 1 ); 693 return _ioc_write( 0, // channel 694 IOC_KERNEL_MODE, // mode 695 lba, // sector indexs 696 fat.fat_cache, // source buffer 697 1 ); // one sector 741 698 } 742 699 … … 759 716 if ( get_next_cluster_id( IOC_KERNEL_MODE, free_cluster ) != FREE_CLUSTER) 760 717 { 761 _tty_get_lock( 0 ); 762 _puts("\n[FAT ERROR] in _fat_allocate() : first free_cluster isnt free\n"); 763 _tty_release_lock( 0 ); 718 _printf("\n[FAT ERROR] in _fat_allocate() : first free_cluster not free\n"); 764 719 return -1; 765 720 } … … 767 722 if ( count > fat.number_free_cluster ) 768 723 { 769 _tty_get_lock( 0 ); 770 _puts("\n[FAT ERROR] in _fat_allocate() : Not enough free cluster(s) for this allocation\n"); 771 _tty_release_lock( 0 ); 724 _printf("\n[FAT ERROR] in _fat_allocate() : Not enough free cluster(s)\n"); 772 725 return -1; 773 726 } 774 727 775 728 #if GIET_DEBUG_FAT 776 _tty_get_lock( 0 ); 777 _puts("\n[FAT DEBUG] Enter in _fat_allocate() :\n"); 778 _puts(" - Need to allocate "); 779 _putd( count ); 780 _puts(" cluster(s) for file "); 781 _putd( fd_id ); 782 _puts("\n"); 783 _tty_release_lock( 0 ); 729 _printf("\n[FAT DEBUG] Enter in _fat_allocate() for file %d\n", fd_id ); 784 730 #endif 785 731 … … 795 741 796 742 #if GIET_DEBUG_FAT 797 _tty_get_lock( 0 ); 798 _puts("\n[FAT DEBUG] Cluster to update is : "); 799 _putd( last_cluster_file ); 800 _puts("\n"); 801 _puts("[FAT DEBUG] Free cluster is : "); 802 _putd( free_cluster ); 803 _puts("\n"); 804 _puts("[FAT DEBUG] Number of cluster need to be allocated : "); 805 _putd( cluster_to_allocate ); 806 _puts("\n"); 807 _tty_release_lock( 0 ); 743 _printf("\n[FAT DEBUG] cluster to update = %x / free cluster = %x / clusters required = %d\n", 744 last_cluster_file, free_cluster, cluster_to_allocate ); 808 745 #endif 809 746 … … 812 749 if ( update_fat( last_cluster_file, free_cluster ) ) 813 750 { 814 _tty_get_lock( 0 ); 815 _puts("\n[FAT ERROR] in _fat_allocate() : update fat for file "); 816 _putd( fd_id ); 817 _puts(" failed\n"); 818 _tty_release_lock( 0 ); 751 _printf("\n[FAT ERROR] in _fat_allocate() : update fat failed\n"); 819 752 return -1; 820 753 } … … 831 764 if ( update_fat( last_cluster_file, END_OF_CHAIN_CLUSTER ) ) 832 765 { 833 _tty_get_lock( 0 ); 834 _puts("\n[FAT ERROR] in _fat_allocate() : update fat for file "); 835 _putd( fd_id ); 836 _puts(" failed\n"); 837 _tty_release_lock( 0 ); 766 _printf("\n[FAT ERROR] in _fat_allocate() : update fat failed\n"); 838 767 return -1; 839 768 } … … 845 774 if ( get_next_cluster_id( IOC_KERNEL_MODE, free_cluster ) != FREE_CLUSTER) 846 775 { 847 _tty_get_lock( 0 ); 848 _puts("\n[FAT ERROR] in _fat_allocate() : free_cluster isnt free\n"); 849 _tty_release_lock( 0 ); 776 _printf("\n[FAT ERROR] in _fat_allocate() : free_cluster not free\n"); 850 777 return -1; 851 778 } … … 859 786 if ( update_fs_info() ) 860 787 { 861 _tty_get_lock( 0 ); 862 _puts("\n[FAT ERROR] in _fat_allocate() : update fs_info for file "); 863 _putd( fd_id ); 864 _puts(" failed\n"); 865 _tty_release_lock( 0 ); 788 _printf("\n[FAT ERROR] in _fat_allocate() : update fs_info failed\n"); 866 789 return -1; 867 790 } … … 895 818 896 819 #if GIET_DEBUG_FAT 897 _tty_get_lock( 0 ); 898 _puts("\n[FAT DEBUG] enter _scan_directory() searching dir/file : "); 899 _puts( file_name ); 900 _puts("\n"); 901 _tty_release_lock( 0 ); 820 _printf("\n[FAT DEBUG] enter _scan_directory() searching dir/file %s", filename ); 902 821 #endif 903 822 … … 920 839 // load first cluster sector from DATA region into FAT cache 921 840 // other sectors will be loaded inside loop as required 922 if( _ioc_read( mode, // mode for IOC driver 841 if( _ioc_read( 0, // channel 842 mode, // mode for IOC driver 923 843 lba, // sector index 924 844 fat.fat_cache, // buffer address 925 845 1 ) ) // one sector 926 846 { 927 _tty_get_lock( 0 ); 928 _puts("[FAT ERROR] in scan directory() cannot read sector "); 929 _putd( lba ); 930 _puts("\n"); 931 _tty_release_lock( 0 ); 847 _printf("[FAT ERROR] in scan directory() cannot read sector %x\n", lba ); 932 848 return -1; 933 849 } … … 935 851 fat.cache_lba = lba; 936 852 937 938 939 853 #if GIET_DEBUG_FAT 854 display_fat_cache(); 855 #endif 940 856 941 857 // in this loop we scan all names in directory identified by cluster: … … 961 877 block_id = fat.sectors_per_cluster; 962 878 } 963 if( _ioc_read( mode, // mode for IOC driver 879 if( _ioc_read( 0, // channel 880 mode, // mode for IOC driver 964 881 lba, // sector index 965 882 fat.fat_cache, // buffer address 966 883 1 ) ) // one sector 967 884 { 968 _tty_get_lock( 0 ); 969 _puts("[FAT ERROR] in scan directory() cannot read sector "); 970 _putd( lba ); 971 _puts("\n"); 972 _tty_release_lock( 0 ); 885 _printf("[FAT ERROR] in scan directory() cannot read sector %x\n", lba ); 973 886 return -1; 974 887 } … … 1072 985 *lba_dir_entry = lba; 1073 986 1074 #if GIET_DEBUG_FAT1075 _tty_get_lock( 0 );1076 _puts("\n[FAT DEBUG] FILE FOUND\n");1077 _tty_release_lock( 0 );1078 #endif1079 987 return read_cluster( dir_entry ); 1080 988 } … … 1094 1002 unsigned int dir_cluster ) 1095 1003 { 1096 _tty_get_lock( 0 ); 1097 _puts("\n[FAT ERROR] _fat_create() not implemented\n"); 1098 _tty_release_lock( 0 ); 1004 _printf("\n[FAT ERROR] _fat_create() not implemented\n"); 1099 1005 return 0; 1100 1006 } //end _fat_create() … … 1115 1021 1116 1022 #if GIET_DEBUG_FAT 1117 _tty_get_lock( 0 ); 1118 _puts("\n[FAT DEBUG] Enter _fat_init() / fat_cache_base = "); 1119 _putx( (unsigned int)fat.fat_cache ); 1120 _puts("\n"); 1121 _tty_release_lock( 0 ); 1023 unsigned int procid = _get_procid(); 1024 unsigned int cid = procid / NB_PROCS_MAX; 1025 unsigned int lpid = procid % NB_PROCS_MAX; 1026 unsigned int x = cid >> Y_WIDTH; 1027 unsigned int y = cid & ((1<<Y_WIDTH) - 1); 1028 1029 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] enters _fat_init()\n", 1030 x, y, lpid ); 1122 1031 #endif 1123 1032 1124 1033 // load Master Boot Record (sector 0) into fat cache 1125 if ( _ioc_read( mode, // mode for IOC driver 1034 if ( _ioc_read( 0, // channel 1035 mode, // mode for IOC driver 1126 1036 0, // sector index 1127 1037 fat.fat_cache, // buffer address 1128 1038 1 ) ) // one sector 1129 1039 { 1130 _tty_get_lock( 0 ); 1131 _puts("\n[FAT ERROR] in _fat_init() cannot load Boot Sector\n"); 1132 _tty_release_lock( 0 ); 1040 _printf("\n[FAT ERROR] in _fat_init() cannot load Boot Sector\n"); 1133 1041 return -1; 1134 1042 } 1135 1043 fat.cache_lba = 0; 1136 1044 1045 #if GIET_DEBUG_FAT 1046 display_fat_cache(); 1047 #endif 1048 1137 1049 // checking Boot sector integrity 1138 1050 if( MBR_SIGNATURE_VALUE != read_entry( MBR_SIGNATURE_POSITION, fat.fat_cache, 1)) 1139 1051 { 1140 _tty_get_lock( 0 ); 1141 _puts("\n[FAT ERROR] Boot sector not recognized or corrupt \n"); 1142 _tty_release_lock( 0 ); 1052 _printf("\n[FAT ERROR] Boot sector not recognized or corrupt \n"); 1143 1053 return -1; 1144 1054 } 1145 1055 1146 1056 #if GIET_DEBUG_FAT 1147 _tty_get_lock( 0 ); 1148 _puts("\n[FAT DEBUG] Boot Sector Loaded\n"); 1149 _tty_release_lock( 0 ); 1057 _printf("\n[FAT DEBUG] Boot Sector Loaded\n"); 1150 1058 #endif 1151 1059 … … 1155 1063 1156 1064 // load Partition Boot Record (first partition sector) into fat cache 1157 if ( _ioc_read( mode, // mode for IOC driver 1065 if ( _ioc_read( 0, // channel 1066 mode, // mode for IOC driver 1158 1067 fat.partition_lba, // sector index 1159 1068 fat.fat_cache, // buffer address 1160 1069 1 ) ) // one sector 1161 1070 { 1162 _tty_get_lock( 0 ); 1163 _puts("\n[FAT ERROR] in _fat_init() cannot load block "); 1164 _putd( fat.partition_lba ); 1165 _puts("\n"); 1166 _tty_release_lock( 0 ); 1071 _printf("\n[FAT ERROR] in _fat_init() cannot load block %x\n", fat.partition_lba ); 1167 1072 return -1; 1168 1073 } … … 1170 1075 1171 1076 #if GIET_DEBUG_FAT 1172 _tty_get_lock( 0 ); 1173 _puts("\n[FAT DEBUG] Partition First Sector Loaded\n"); 1174 _tty_release_lock( 0 ); 1077 _printf("\n[FAT DEBUG] Partition First Sector Loaded\n"); 1175 1078 #endif 1176 1079 … … 1179 1082 if( read_entry( BPB_BYTSPERSEC, fat.fat_cache, 1 ) != 512 ) 1180 1083 { 1181 _tty_get_lock( 0 ); 1182 _puts("\n[FAT ERROR] The sector size must be 512 bytes\n"); 1183 _tty_release_lock( 0 ); 1084 _printf("\n[FAT ERROR] The sector size must be 512 bytes\n"); 1184 1085 return -1; 1185 1086 } 1186 1087 if( read_entry( BPB_RSVDSECCNT, fat.fat_cache, 1 ) != 32 ) 1187 1088 { 1188 _tty_get_lock( 0 ); 1189 _puts("\n[FAT ERROR] The RSVD region in FAT32 must be 32 sectors\n"); 1190 _tty_release_lock( 0 ); 1089 _printf("\n[FAT ERROR] The RSVD region in FAT32 must be 32 sectors\n"); 1191 1090 return -1; 1192 1091 } 1193 1092 if( read_entry( BPB_NUMFATS, fat.fat_cache, 1 ) != 1 ) 1194 1093 { 1195 _tty_get_lock( 0 ); 1196 _puts("\n[FAT ERROR] The number of FAT copies in FAT region must be 1\n"); 1197 _tty_release_lock( 0 ); 1094 _printf("\n[FAT ERROR] The number of FAT copies in FAT region must be 1\n"); 1198 1095 return -1; 1199 1096 } 1200 1097 if( (read_entry( BPB_FAT32_FATSZ32, fat.fat_cache, 1 ) & 0xF) != 0 ) 1201 1098 { 1202 _tty_get_lock( 0 ); 1203 _puts("\n[FAT ERROR] The FAT region in FAT32 must be multiple of 32 sectors\n"); 1204 _tty_release_lock( 0 ); 1099 _printf("\n[FAT ERROR] The FAT region in FAT32 must be multiple of 32 sectors\n"); 1205 1100 return -1; 1206 1101 } 1207 1208 1102 if( read_entry( BPB_FAT32_ROOTCLUS, fat.fat_cache, 1 ) != 2 ) 1209 1103 { 1210 _tty_get_lock( 0 ); 1211 _puts("\n[FAT ERROR] The first cluster index must be 2\n"); 1212 _tty_release_lock( 0 ); 1104 _printf("\n[FAT ERROR] The first cluster index must be 2\n"); 1213 1105 return -1; 1214 1106 } … … 1227 1119 1228 1120 #if GIET_DEBUG_FAT 1229 _tty_get_lock( 0 ); 1230 _puts("\n[FAT DEBUG] FS_INFO Sector = "); 1231 _putd(fat.fs_info_lba); 1232 _puts("\n"); 1233 _tty_release_lock( 0 ); 1121 _printf("\n[FAT DEBUG] FS_INFO Sector = %x\n", fat.fs_info_lba ); 1234 1122 #endif 1235 1123 1236 1124 // load FS_INFO into fat cache 1237 if ( _ioc_read( mode, // mode for IOC driver 1125 if ( _ioc_read( 0, // channel 1126 mode, // mode for IOC driver 1238 1127 fat.fs_info_lba, // sector index 1239 1128 fat.fat_cache, // buffer address 1240 1129 1 ) ) // one sector 1241 1130 { 1242 _tty_get_lock( 0 ); 1243 _puts("\n[FAT ERROR] in _fat_init() cannot load FS_INFO Sector\n"); 1244 _tty_release_lock( 0 ); 1131 _printf("\n[FAT ERROR] in _fat_init() cannot load FS_INFO Sector\n"); 1245 1132 return -1; 1246 1133 } … … 1251 1138 1252 1139 #if GIET_DEBUG_FAT 1253 _tty_get_lock( 0 ); 1254 _puts("\n[FAT DEBUG] Number of Free Clusters = "); 1255 _putd(fat.number_free_cluster); 1256 _puts("\n"); 1257 _puts("\n[FAT DEBUG] Last known cluster allocated = "); 1258 _putd(fat.last_cluster_allocated); 1259 _puts("\n"); 1260 _puts("\n[FAT DEBUG] FS_INFO Sector Loaded\n"); 1261 _tty_release_lock( 0 ); 1262 #endif 1263 1264 1265 #if GIET_DEBUG_FAT 1266 _tty_get_lock( 0 ); 1267 _puts("\n[FAT DEBUG] Exit _fat_init()\n"); 1268 _tty_release_lock( 0 ); 1140 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] exit _fat_init() / " 1141 "free clusters = %x / last allocated cluster = %x\n", 1142 fat.number_free_cluster, fat.last_cluster_allocated ); 1269 1143 #endif 1270 1144 … … 1275 1149 void _fat_print() 1276 1150 { 1277 _p uts("\n################################ FAT32 ###############################");1278 _p uts("\nFAT initialised "); _putx(fat.initialised );1279 _p uts("\nSector Size (bytes) "); _putx(fat.sector_size );1280 _p uts("\nSectors per cluster "); _putx(fat.sectors_per_cluster );1281 _p uts("\nPartition size (sectors) "); _putx(fat.partition_sectors );1282 _p uts("\nPartition first lba "); _putx(fat.partition_lba );1283 _p uts("\nData region first lba "); _putx(fat.data_lba );1284 _p uts("\nNumber of sectors for one FAT "); _putx(fat.fat_sectors );1285 _p uts("\n######################################################################\n");1151 _printf("\n########################## FAT32 ###########################"); 1152 _printf("\nFAT initialised %d", fat.initialised ); 1153 _printf("\nSector Size (bytes) %x", fat.sector_size ); 1154 _printf("\nSectors per cluster %x", fat.sectors_per_cluster ); 1155 _printf("\nPartition size (sectors) %x", fat.partition_sectors ); 1156 _printf("\nPartition first lba %x", fat.partition_lba ); 1157 _printf("\nData region first lba %x", fat.data_lba ); 1158 _printf("\nNumber of sectors for one FAT %x", fat.fat_sectors ); 1159 _printf("\n############################################################\n"); 1286 1160 } 1287 1161 … … 1294 1168 // a new file is created and introduced in the directory. 1295 1169 // Finally, it sets a new open file in the file descriptors array. 1170 // The same file can be open several times by differents taks. 1296 1171 /////////////////////////////////////////////////////////////////////////////// 1297 1172 // Returns file descriptor index if success, returns -1 if error. … … 1311 1186 1312 1187 #if GIET_DEBUG_FAT 1313 _tty_get_lock( 0 ); 1314 _puts("\n[FAT DEBUG] enter _fat_open() for file "); 1315 _puts( pathname ); 1316 _puts("\n"); 1317 _tty_release_lock( 0 ); 1318 #endif 1319 1320 // check FAT initialised 1188 unsigned int procid = _get_procid(); 1189 unsigned int cid = procid / NB_PROCS_MAX; 1190 unsigned int lpid = procid % NB_PROCS_MAX; 1191 unsigned int x = cid >> Y_WIDTH; 1192 unsigned int y = cid & ((1<<Y_WIDTH) - 1); 1193 1194 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] enters _fat_open() for file %s\n", 1195 x, y, lpid, pathname ); 1196 #endif 1197 1198 // checking arguments 1199 if ( creat ) 1200 { 1201 _printf("[FAT ERROR] in _fat_open() : create not supported yet\n"); 1202 return -1; 1203 } 1204 1205 // takes the FAT lock for exclusive access 1206 _get_lock( &fat.lock ); 1207 1208 #if GIET_DEBUG_FAT 1209 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] takes the FAT lock\n", 1210 x, y, lpid ); 1211 #endif 1212 1213 // FAT initialisation if required 1321 1214 if( fat.initialised != FAT_INITIALISED ) 1322 1215 { 1323 1216 if ( _fat_init( mode ) ) 1324 1217 { 1325 _puts("[FAT ERROR] Cannot initialize FAT descriptor from Boot Sector\n"); 1326 _exit(); 1327 } 1328 1329 #if GIET_DEBUG_FAT 1330 _tty_get_lock( 0 ); 1331 _puts("\n[FAT DEBUG] FAT initialisation completed at cycle "); 1332 _putd(_get_proctime()); 1333 _puts("\n"); 1218 _printf("[FAT ERROR] in _fat_open() : Cannot initialize FAT descriptor\n"); 1219 1220 // release FAT lock 1221 _release_lock( &fat.lock ); 1222 1223 return -1; 1224 } 1225 1226 #if GIET_DEBUG_FAT 1227 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] initialises FAT descriptor\n", 1228 x, y, lpid ); 1334 1229 _fat_print(); 1335 _tty_release_lock( 0 ); 1336 #endif 1230 #endif 1231 1337 1232 } 1338 1233 … … 1350 1245 1351 1246 #if GIET_DEBUG_FAT 1352 _tty_get_lock( 0 ); 1353 _puts("\n[FAT DEBUG] _fat_open : search dir/file : "); 1354 _puts( name ); 1355 _puts("\n"); 1356 _tty_release_lock( 0 ); 1247 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] search dir/file : %s\n", 1248 x, y, lpid, name ); 1357 1249 #endif 1358 1250 … … 1373 1265 else if ( cluster == END_OF_CHAIN_CLUSTER ) 1374 1266 { 1375 _tty_get_lock( 0 ); 1376 _puts("\n[FAT ERROR] in _fat_open() for file "); 1377 _puts( pathname ); 1378 _puts(" : cannot found name "); 1379 _puts( name ); 1380 _puts("\n"); 1381 _tty_release_lock( 0 ); 1267 _printf("\n[FAT ERROR] in _fat_open() cannot found %s\n", name ); 1268 1269 // release FAT lock 1270 _release_lock( &fat.lock ); 1271 1382 1272 return -1; 1383 1273 } 1384 1274 } 1385 1386 #if GIET_DEBUG_FAT1387 _tty_get_lock( 0 );1388 _puts("\n[FAT DEBUG] File ");1389 _puts( pathname );1390 _puts(" found\n");1391 _tty_release_lock( 0 );1392 #endif1393 1275 1394 1276 // check the next value for cluster index found … … 1414 1296 1415 1297 #if GIET_DEBUG_FAT 1416 _tty_get_lock( 0 ); 1417 _puts("\n[FAT DEBUG] file "); 1418 _puts( pathname ); 1419 _puts(" open with fd_id = "); 1420 _putd( fd_id ); 1421 _puts("\n"); 1422 _tty_release_lock( 0 ); 1423 #endif 1298 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] open file %s with fd = %d\n", 1299 x, y, lpid, pathname, fd_id ); 1300 #endif 1301 1302 // release FAT lock 1303 _release_lock( &fat.lock ); 1424 1304 1425 1305 return fd_id; … … 1427 1307 else 1428 1308 { 1429 _tty_get_lock( 0 ); 1430 _puts("\n[FAT ERROR] in _fat_open() for file "); 1431 _puts( pathname ); 1432 _puts(" : file descriptor array full\n "); 1433 _tty_release_lock( 0 ); 1309 _printf("\n[FAT ERROR] in _fat_open() for file %s : fd array full\n", 1310 pathname ); 1311 1312 // release FAT lock 1313 _release_lock( &fat.lock ); 1314 1434 1315 return -1; 1435 1316 } … … 1437 1318 else 1438 1319 { 1439 _tty_get_lock( 0 ); 1440 _puts("\n[FAT ERROR] in _fat_open() for file "); 1441 _puts( pathname ); 1442 _puts(" : file found, but bad cluster\n"); 1443 _tty_release_lock( 0 ); 1320 _printf("\n[FAT ERROR] in _fat_open() for file %s : bad cluster\n", 1321 pathname ); 1322 1323 // release FAT lock 1324 _release_lock( &fat.lock ); 1325 1444 1326 return -1; 1445 1327 } … … 1461 1343 1462 1344 #if GIET_DEBUG_FAT 1463 _tty_get_lock( 0 ); 1464 _puts("\n[FAT DEBUG] Enter _fat_read() for file "); 1465 _puts( fat.fd[fd_id].name ); 1466 _puts("\n - buffer base = "); 1467 _putx( (unsigned int)buffer ); 1468 _puts("\n - skipped sectors = "); 1469 _putd( offset ); 1470 _puts("\n - read sectors = "); 1471 _putd( count ); 1472 _tty_release_lock( 0 ); 1345 unsigned int procid = _get_procid(); 1346 unsigned int cid = procid / NB_PROCS_MAX; 1347 unsigned int lpid = procid % NB_PROCS_MAX; 1348 unsigned int x = cid >> Y_WIDTH; 1349 unsigned int y = cid & ((1<<Y_WIDTH) - 1); 1350 1351 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] enters _fat_read() for file %s\n", 1352 " - buffer vbase = %x\n" 1353 " - skipped sectors = %x\n" 1354 " - read sectors = %x\n", 1355 x, y, lpid, fat.fd[fd_id].name, (unsigned int)buffer, offset, count ); 1473 1356 #endif 1474 1357 … … 1490 1373 if ( fd_id >= GIET_OPEN_FILES_MAX ) 1491 1374 { 1492 _tty_get_lock( 0 ); 1493 _puts("\n[FAT ERROR] in _fat_read() : illegal file descriptor index\n"); 1494 _tty_release_lock( 0 ); 1375 _printf("\n[FAT ERROR] in _fat_read() : illegal file descriptor index\n"); 1495 1376 return -1; 1496 1377 } 1497 1378 if ( fat.fd[fd_id].used != 1 ) 1498 1379 { 1499 _tty_get_lock( 0 ); 1500 _puts("\n[FAT ERROR] in _fat_read() : file not open\n"); 1501 _tty_release_lock( 0 ); 1380 _printf("\n[FAT ERROR] in _fat_read() : file not open\n"); 1502 1381 return -1; 1503 1382 } 1504 1383 if ( ((unsigned int)buffer & 0x1FF) != 0 ) 1505 1384 { 1506 _tty_get_lock( 0 ); 1507 _puts("\n[FAT ERROR] in _fat_read() : memory buffer not sector aligned\n"); 1508 _tty_release_lock( 0 ); 1385 _printf("\n[FAT ERROR] in _fat_read() : memory buffer not sector aligned\n"); 1509 1386 return -1; 1510 1387 } 1511 1388 if ( offset >= file_sectors ) 1512 1389 { 1513 _tty_get_lock( 0 ); 1514 _puts("\n[FAT ERROR] offset larger than number of sectors in file\n"); 1515 _puts(" - offset = "); 1516 _putd( offset ); 1517 _puts(" - file_sectors = "); 1518 _putd( file_sectors ); 1519 _tty_release_lock( 0 ); 1390 _printf("\n[FAT ERROR] offset larger than number of sectors\n"); 1520 1391 return -1; 1521 1392 } … … 1533 1404 1534 1405 #if GIET_DEBUG_FAT 1535 _tty_get_lock( 0 ); 1536 _puts("\n - first cluster = "); 1537 _putd( cluster ); 1538 _puts("\n - skiped clusters = "); 1539 _putd( clusters_to_skip ); 1540 _puts("\n"); 1541 _tty_release_lock( 0 ); 1406 _printf(" - first cluster = %x\n" 1407 " - skiped clusters = %x\n", 1408 cluster, clusters_to_skip ); 1542 1409 #endif 1543 1410 … … 1568 1435 1569 1436 #if GIET_DEBUG_FAT 1570 _tty_get_lock( 0 ); 1571 _puts("\n[FAT DEBUG] _fat_read() IOC request : buf = "); 1572 _putx( (unsigned int)dst ); 1573 _puts(" / lba = "); 1574 _putd( lba ); 1575 _puts(" / sectors = "); 1576 _putd( iter_sectors ); 1577 _puts("\n"); 1578 _tty_release_lock( 0 ); 1579 #endif 1580 1581 if( _ioc_read( mode, // mode for IOC driver 1437 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] makes an IOC read :" 1438 " buf = %x / lba = %x / sectors = %d\n", 1439 x, y, lpid, (unsigned int)dst, lba, iter_sectors ); 1440 #endif 1441 1442 if( _ioc_read( 0, // channel 1443 mode, // mode for IOC driver 1582 1444 lba, // first sector index 1583 1445 dst, // buffer address 1584 1446 iter_sectors ) ) // number of sectors 1585 1447 { 1586 _tty_get_lock( 0 ); 1587 _puts("\n[FAT ERROR] in _fat_read() cannot load block "); 1588 _putd( lba ); 1589 _puts("\n"); 1590 _tty_release_lock( 0 ); 1448 _printf("\n[FAT ERROR] in _fat_read() cannot load block %x\n", lba ); 1591 1449 return -1; 1592 1450 } … … 1653 1511 1654 1512 #if GIET_DEBUG_FAT 1655 _tty_get_lock( 0);1656 _puts("\n[FAT DEBUG] Enter _fat_write() for file ");1657 _puts( fat.fd[fd_id].name );1658 _puts("\n - buffer base = ");1659 _putx( (unsigned int)buffer);1660 _puts("\n - skipped sectors = "); 1661 _p utd( offset );1662 _puts("\n - write sectors = "); 1663 _putd( count ); 1664 _puts("\n - file size (sectors) = ");1665 _putd( file_sectors ); 1666 _puts("\n - need allocate = ");1667 allocate ? _puts( "True" ) : _puts( "False");1668 _tty_release_lock( 0);1513 unsigned int procid = _get_procid(); 1514 unsigned int cid = procid / NB_PROCS_MAX; 1515 unsigned int lpid = procid % NB_PROCS_MAX; 1516 unsigned int x = cid >> Y_WIDTH; 1517 unsigned int y = cid & ((1<<Y_WIDTH) - 1); 1518 1519 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] enters _fat_write() for file %s\n", 1520 " - buffer vbase = %x\n" 1521 " - skipped sectors = %x\n" 1522 " - write sectors = %x\n" 1523 " - file sectors = %x\n" 1524 " - need allocate = %d\n", 1525 x, y, lpid, fat.fd[fd_id].name, (unsigned int)buffer, 1526 offset, count, file_sectors, allocate ); 1669 1527 #endif 1670 1528 … … 1672 1530 if ( fd_id >= GIET_OPEN_FILES_MAX ) 1673 1531 { 1674 _tty_get_lock( 0 ); 1675 _puts("\n[FAT ERROR] in _fat_write() : illegal file descriptor index\n"); 1676 _tty_release_lock( 0 ); 1532 _printf("\n[FAT ERROR] in _fat_write() : illegal file descriptor index\n"); 1677 1533 return -1; 1678 1534 } 1679 1535 if ( fat.fd[fd_id].used != 1 ) 1680 1536 { 1681 _tty_get_lock( 0 ); 1682 _puts("\n[FAT ERROR] in _fat_write() : file not open\n"); 1683 _tty_release_lock( 0 ); 1537 _printf("\n[FAT ERROR] in _fat_write() : file not open\n"); 1684 1538 return -1; 1685 1539 } 1686 1540 if ( ((unsigned int)buffer & 0x1FF) != 0 ) 1687 1541 { 1688 _tty_get_lock( 0 ); 1689 _puts("\n[FAT ERROR] in _fat_write() : memory buffer not sector aligned\n"); 1690 _tty_release_lock( 0 ); 1542 _printf("\n[FAT ERROR] in _fat_write() : memory buffer not sector aligned\n"); 1691 1543 return -1; 1692 1544 } … … 1696 1548 if ( _fat_allocate( fd_id, (required_cluster - current_cluster) ) < 0 ) 1697 1549 { 1698 _tty_get_lock( 0 ); 1699 _puts("\n[FAT ERROR] in _fat_write() : fat_allocate for file "); 1700 _putd( fd_id ); 1701 _puts(" failed\n"); 1702 _tty_release_lock( 0 ); 1550 _printf("\n[FAT ERROR] in _fat_write() : fat_allocate failed\n"); 1703 1551 return -1; 1704 1552 } … … 1713 1561 1714 1562 #if GIET_DEBUG_FAT 1715 _tty_get_lock( 0 ); 1716 _puts("\n - first cluster = "); 1717 _putd( cluster ); 1718 _puts("\n - skiped clusters = "); 1719 _putd( clusters_to_skip ); 1720 _puts("\n"); 1721 _tty_release_lock( 0 ); 1563 _printf(" - first cluster = %x\n" 1564 " - skiped clusters = %x\n", 1565 cluster, clusters_to_skip ); 1722 1566 #endif 1723 1567 … … 1748 1592 1749 1593 #if GIET_DEBUG_FAT 1750 _tty_get_lock( 0 ); 1751 _puts("\n[FAT DEBUG] _fat_write() IOC request : buf = "); 1752 _putx( (unsigned int)src ); 1753 _puts(" / lba = "); 1754 _putd( lba ); 1755 _puts(" / sectors = "); 1756 _putd( iter_sectors ); 1757 _puts("\n"); 1758 _tty_release_lock( 0 ); 1759 #endif 1760 1761 if( _ioc_write( mode, // mode for IOC driver 1594 _printf("\n[FAT DEBUG] Processor[%d,%d,%d] makes an IOC write : " 1595 "buf = %x / lba = %x / sectors = %x\n", 1596 x, y, lpid, (unsigned int)src, lba, iter_sectors ); 1597 #endif 1598 1599 if( _ioc_write( 0, // channel 1600 mode, // mode for IOC driver 1762 1601 lba, // first sector index 1763 src, // buffer address1602 src, // source buffer address 1764 1603 iter_sectors ) ) // number of sectors 1765 1604 { 1766 _tty_get_lock( 0 ); 1767 _puts("\n[FAT ERROR] in _fat_write() cannot write block "); 1768 _putd( lba ); 1769 _puts("\n"); 1770 _tty_release_lock( 0 ); 1605 _printf("\n[FAT ERROR] in _fat_write() cannot write block %x\n", lba ); 1771 1606 return -1; 1772 1607 } … … 1792 1627 if ( update_entry(fd_id, DIR_FILE_SIZE, fat.fd[fd_id].file_size) ) 1793 1628 { 1794 _tty_get_lock( 0 ); 1795 _puts("\n[FAT ERROR] in _fat_write() update entry for file "); 1796 _putd( fd_id ); 1797 _puts(" failed\n"); 1798 _tty_release_lock( 0 ); 1629 _printf("\n[FAT ERROR] in _fat_write() update entry failed\n"); 1799 1630 return -1; 1800 1631 } … … 1826 1657 else 1827 1658 { 1828 _tty_get_lock( 0 ); 1829 _puts("\n[FAT ERROR] in _fat_fstat() : illegal file descriptor index\n"); 1830 _tty_release_lock( 0 ); 1659 _printf("\n[FAT ERROR] in _fat_fstat() : illegal file descriptor index\n"); 1831 1660 return -1; 1832 1661 } … … 1847 1676 else 1848 1677 { 1849 _tty_get_lock( 0 ); 1850 _puts("\n[FAT ERROR] in _fat_close() : illegal file descriptor index\n"); 1851 _tty_release_lock( 0 ); 1678 _printf("\n[FAT ERROR] in _fat_close() : illegal file descriptor index\n"); 1852 1679 return -1; 1853 1680 } … … 1863 1690 unsigned int flags ) // unused: TODO 1864 1691 { 1865 return _fat_open( IOC_KERNEL_MODE, // we KERNEL_MODE, because1692 return _fat_open( IOC_KERNEL_MODE, // we use KERNEL_MODE, because 1866 1693 pathname, // we need to write into FAT cache 1867 0 ); 1694 0 ); // no creation if not found 1868 1695 } 1869 1696 … … 1909 1736 unsigned int whence ) 1910 1737 { 1911 _tty_get_lock( 0 ); 1912 _puts("[GIET ERROR] _fat_user_lseek function not implemented\n"); 1913 _tty_release_lock( 0 ); 1738 _printf("[GIET ERROR] _fat_user_lseek() not implemented\n"); 1914 1739 _exit(); 1915 1740 return 0; -
soft/giet_vm/giet_fat32/fat32.h
r291 r295 143 143 unsigned int cluster_size; // sector_size * sector_per_cluster (bytes) 144 144 unsigned int fat_sectors; // number of sectors occupied by one FAT copy 145 unsigned int partition_sectors; // total number of sectors (RESVD + FAT +DATA)145 unsigned int partition_sectors; // total number of sectors (RESVD+FAT+DATA) 146 146 unsigned int partition_lba; // lba of first partiton sector 147 147 unsigned int data_lba; // lba of first data sector … … 150 150 unsigned int number_free_cluster; // number of free clusters 151 151 unsigned int fs_info_lba; // lba of fs_info 152 unsigned int lock; // lock protecting exclusive access 152 153 } fat32_fs_t; 153 154 /***************************************************************************************/ -
soft/giet_vm/giet_libs/barrier.c
r258 r295 15 15 16 16 /////////////////////////////////////////////////////////////////////////////////// 17 // barrier_init() 18 // This function makes a cooperative initialisation of the barrier: 19 // several tasks try to initialize the barrier, but the initialisation 20 // is done by only one task, using LL/SC instructions. 17 // This function initializes the barrier: this should be done by a single task. 21 18 /////////////////////////////////////////////////////////////////////////////////// 22 void barrier_init( giet_barrier_t * barrier, unsigned int value) { 23 unsigned int * pinit = (unsigned int *) &barrier->init; 24 unsigned int * pcount = (unsigned int *) &barrier->count; 25 26 // parallel initialisation using atomic instructions LL/SC 27 // inputs : pinit, pcount, value 28 // no output 29 asm volatile ("_barrier_init_test: \n" 30 "ll $2, 0(%0) \n" /* read initial value */ 31 "bnez $2, _barrier_init_done \n" 32 "move $3, %2 \n" 33 "sc $3, 0(%0) \n" /* write initial value */ 34 "beqz $3, _barrier_init_test \n" 35 "move $3, %2 \n" 36 "sw $3, 0(%1) \n" /* write count */ 37 "_barrier_init_done: \n" 38 : 39 : "r"(pinit), "r"(pcount), "r"(value) 40 : "$2", "$3"); 19 void barrier_init( giet_barrier_t* barrier, 20 unsigned int value ) 21 { 22 barrier->init = value; 23 barrier->count = value; 41 24 } 42 25 43 26 44 27 /////////////////////////////////////////////////////////////////////////////////// 45 // barrier_wait()46 28 // This blocking function uses LL/SC to decrement the barrier's counter. 47 29 // Then, it uses a busy_waiting mechanism if it is not the last. 48 // (because the GIET does not support dynamic task scheduling/descheduling)49 30 /////////////////////////////////////////////////////////////////////////////////// 50 void barrier_wait(giet_barrier_t * barrier) { 31 void barrier_wait( giet_barrier_t* barrier ) 32 { 51 33 unsigned int * pcount = (unsigned int *) &barrier->count; 52 34 unsigned int maxcount = barrier->init; … … 56 38 // - input : pointer on the barrier counter 57 39 // - output : counter value 58 asm volatile ("_barrier_decrement: 40 asm volatile ("_barrier_decrement: \n" 59 41 "ll %0, 0(%1) \n" 60 42 "addi $3, %0, -1 \n" … … 68 50 // waking up all other waiting tasks 69 51 70 if (count == 1) { 52 if (count == 1) 53 { 71 54 // last task 72 55 *pcount = maxcount; -
soft/giet_vm/giet_libs/barrier.h
r258 r295 13 13 /////////////////////////////////////////////////////////////////////////////////// 14 14 15 typedef struct giet_barrier_s { 15 typedef struct giet_barrier_s 16 { 16 17 char name[32]; // barrier name 17 18 unsigned int init; // total number of participants … … 23 24 ////////////////////////////////////////////////////////////////////////////// 24 25 25 void barrier_init(giet_barrier_t * barrier, unsigned int value); 26 void barrier_wait(giet_barrier_t * barrier); 26 void barrier_init( giet_barrier_t* barrier, 27 unsigned int value ); // number of tasks 28 29 void barrier_wait( giet_barrier_t* barrier ); 27 30 28 31 #endif -
soft/giet_vm/giet_libs/malloc.h
r258 r295 8 8 #ifndef _MALLOC_H_ 9 9 #define _MALLOC_H_ 10 10 11 //#define DEBUG_MALLOC 1 11 12 -
soft/giet_vm/giet_libs/stdio.c
r289 r295 19 19 20 20 //////////////////////////////////////////////////////////////////////////////////// 21 // giet_procid()22 ////////////////////////////////////////////////////////////////////////////////////23 // This function returns the processor identifier.24 ////////////////////////////////////////////////////////////////////////////////////25 int giet_procid()26 {27 return sys_call( SYSCALL_PROCID,28 0, 0, 0, 0 );29 }30 ////////////////////////////////////////////////////////////////////////////////////31 // giet_proctime()32 ////////////////////////////////////////////////////////////////////////////////////33 // This function returns the local processor time (clock cycles since boot)34 ////////////////////////////////////////////////////////////////////////////////////35 int giet_proctime()36 {37 return sys_call( SYSCALL_PROCTIME,38 0, 0, 0, 0 );39 }40 41 42 ////////////////////////////////////////////////////////////////////////////////////43 21 ///////////////////// TTY device related system calls ///////////////////////////// 44 22 //////////////////////////////////////////////////////////////////////////////////// 45 23 46 //////////////////////////////////////////////////////////////////////////////////// 47 // giet_tty_putc() 48 //////////////////////////////////////////////////////////////////////////////////// 49 // This function displays a single ascii character on a terminal. 50 // The terminal index must be defined in the task context in the boot phase. 51 // It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer. 52 // - Returns 1 if the character has been written, 0 otherwise. 53 //////////////////////////////////////////////////////////////////////////////////// 54 int giet_tty_putc(char byte) 55 { 56 return sys_call(SYSCALL_TTY_WRITE, 57 (unsigned int)(&byte), 58 1, 59 0xFFFFFFFF, 60 0); 61 } 62 //////////////////////////////////////////////////////////////////////////////////// 63 // giet_tty_puts() 64 //////////////////////////////////////////////////////////////////////////////////// 65 // This function displays a string on a terminal. 66 // The terminal index must be defined in the task context in the boot phase. 67 // The string must be terminated by a NUL character. 68 // It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer. 69 // - Returns the number of written characters. 70 //////////////////////////////////////////////////////////////////////////////////// 71 int giet_tty_puts(char * buf) 72 { 73 unsigned int length = 0; 74 while (buf[length] != 0) { length++; } 75 return sys_call(SYSCALL_TTY_WRITE, 76 (unsigned int)buf, 77 length, 78 0xFFFFFFFF, 79 0); 80 } 81 //////////////////////////////////////////////////////////////////////////////////// 82 // giet_tty_putw() 83 //////////////////////////////////////////////////////////////////////////////////// 84 // This function displays the value of a 32-bit word with decimal characters. 85 // The terminal index must be defined in the task context in the boot phase. 86 // It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer. 87 // Returns the number of written characters (should be equal to ten). 88 //////////////////////////////////////////////////////////////////////////////////// 89 int giet_tty_putw(unsigned int val) 90 { 91 char buf[10]; 92 unsigned int i; 93 for (i = 0; i < 10; i++) 94 { 95 buf[9 - i] = (val % 10) + 0x30; 96 val = val / 10; 97 } 98 return sys_call(SYSCALL_TTY_WRITE, 99 (unsigned int)buf, 100 10, 101 0xFFFFFFFF, 102 0); 103 } 104 //////////////////////////////////////////////////////////////////////////////////// 105 // giet_tty_getc() 106 //////////////////////////////////////////////////////////////////////////////////// 107 // This blocking function fetches a single ascii character from a terminal. 108 // The terminal index must be defined in the task context in the boot phase. 109 // It uses the IRQ_GET interrupt, and the associated kernel buffer. 110 // - Returns 0 when completed. 111 //////////////////////////////////////////////////////////////////////////////////// 112 int giet_tty_getc(char * byte) 113 { 114 unsigned int ret = 0; 115 while (ret == 0) 24 //////////////////////////////////////// 25 void giet_tty_printf( char* format, ...) 26 { 27 va_list args; 28 va_start( args, format ); 29 30 int ret; // return value from the syscalls 31 unsigned int channel = 0xFFFFFFFF; 32 33 printf_text: 34 35 while (*format) 36 { 37 unsigned int i; 38 for (i = 0 ; format[i] && (format[i] != '%') ; i++); 39 if (i) 40 { 41 ret = sys_call(SYSCALL_TTY_WRITE, 42 (unsigned int)format, 43 i, 44 channel, 45 0); 46 47 if (ret != i) goto return_error; 48 49 format += i; 50 } 51 if (*format == '%') 52 { 53 format++; 54 goto printf_arguments; 55 } 56 } 57 58 va_end( args ); 59 return; 60 61 printf_arguments: 62 63 { 64 char buf[20]; 65 char * pbuf; 66 unsigned int len = 0; 67 static const char HexaTab[] = "0123456789ABCDEF"; 68 unsigned int i; 69 70 switch (*format++) 71 { 72 case ('c'): /* char conversion */ 73 { 74 int val = va_arg( args, int ); 75 len = 1; 76 buf[0] = val; 77 pbuf = &buf[0]; 78 break; 79 } 80 case ('d'): /* 32 bits decimal signed integer */ 81 { 82 int val = va_arg( args, int ); 83 if (val < 0) 84 { 85 val = -val; 86 ret = sys_call(SYSCALL_TTY_WRITE, 87 (unsigned int)"-", 88 1, 89 channel, 90 0); 91 if (ret != 1) goto return_error; 92 } 93 for(i = 0; i < 10; i++) 94 { 95 buf[9 - i] = HexaTab[val % 10]; 96 if (!(val /= 10)) break; 97 } 98 len = i + 1; 99 pbuf = &buf[9 - i]; 100 break; 101 } 102 case ('u'): /* 32 bits decimal unsigned integer */ 103 { 104 unsigned int val = va_arg( args, unsigned int ); 105 for(i = 0; i < 10; i++) 106 { 107 buf[9 - i] = HexaTab[val % 10]; 108 if (!(val /= 10)) break; 109 } 110 len = i + 1; 111 pbuf = &buf[9 - i]; 112 break; 113 } 114 case ('x'): /* 32 bits hexadecimal integer */ 115 { 116 unsigned int val = va_arg( args, unsigned int ); 117 ret = sys_call(SYSCALL_TTY_WRITE, 118 (unsigned int)"0x", 119 2, 120 channel, 121 0); 122 if (ret != 2) goto return_error; 123 for(i = 0; i < 8; i++) 124 { 125 buf[7 - i] = HexaTab[val % 16]; 126 if (!(val /= 16)) break; 127 } 128 len = i + 1; 129 pbuf = &buf[7 - i]; 130 break; 131 } 132 case ('l'): /* 64 bits hexadecimal unsigned */ 133 { 134 unsigned long long val = va_arg( args, unsigned long long ); 135 ret = sys_call(SYSCALL_TTY_WRITE, 136 (unsigned int)"0x", 137 2, 138 channel, 139 0); 140 if (ret != 2) goto return_error; 141 for(i = 0; i < 16; i++) 142 { 143 buf[15 - i] = HexaTab[val % 16]; 144 if (!(val /= 16)) break; 145 } 146 len = i + 1; 147 pbuf = &buf[15 - i]; 148 break; 149 } 150 case ('s'): /* string */ 151 { 152 char* str = va_arg( args, char* ); 153 while (str[len]) 154 { 155 len++; 156 } 157 pbuf = str; 158 break; 159 } 160 default: 161 goto return_error; 162 } 163 164 ret = sys_call(SYSCALL_TTY_WRITE, 165 (unsigned int)pbuf, 166 len, 167 channel, 168 0); 169 if (ret != len) goto return_error; 170 171 goto printf_text; 172 } 173 174 return_error: 175 176 va_end( args ); 177 giet_exit("error in giet_tty_printf()"); 178 } // end giet_tty_printf() 179 180 //////////////////////////////////////// 181 void giet_shr_printf( char* format, ...) 182 { 183 va_list args; 184 va_start( args, format ); 185 186 int ret; // return value from the syscalls 187 unsigned int channel = 0; 188 unsigned int sr_save; 189 190 sys_call( SYSCALL_TTY_GET_LOCK, 191 channel, 192 (unsigned int)&sr_save, 193 0, 0 ); 194 195 printf_text: 196 197 while (*format) 198 { 199 unsigned int i; 200 for (i = 0 ; format[i] && (format[i] != '%') ; i++); 201 if (i) 202 { 203 ret = sys_call(SYSCALL_TTY_WRITE, 204 (unsigned int)format, 205 i, 206 channel, 207 0); 208 209 if (ret != i) goto return_error; 210 211 format += i; 212 } 213 if (*format == '%') 214 { 215 format++; 216 goto printf_arguments; 217 } 218 } 219 220 sys_call( SYSCALL_TTY_RELEASE_LOCK, 221 channel, 222 (unsigned int)&sr_save, 223 0, 0 ); 224 225 va_end( args ); 226 return; 227 228 printf_arguments: 229 230 { 231 char buf[20]; 232 char * pbuf; 233 unsigned int len = 0; 234 static const char HexaTab[] = "0123456789ABCDEF"; 235 unsigned int i; 236 237 switch (*format++) 238 { 239 case ('c'): /* char conversion */ 240 { 241 int val = va_arg( args, int ); 242 len = 1; 243 buf[0] = val; 244 pbuf = &buf[0]; 245 break; 246 } 247 case ('d'): /* 32 bits decimal signed integer */ 248 { 249 int val = va_arg( args, int ); 250 if (val < 0) 251 { 252 val = -val; 253 ret = sys_call(SYSCALL_TTY_WRITE, 254 (unsigned int)"-", 255 1, 256 channel, 257 0); 258 if (ret != 1) goto return_error; 259 } 260 for(i = 0; i < 10; i++) 261 { 262 buf[9 - i] = HexaTab[val % 10]; 263 if (!(val /= 10)) break; 264 } 265 len = i + 1; 266 pbuf = &buf[9 - i]; 267 break; 268 } 269 case ('u'): /* 32 bits decimal unsigned integer */ 270 { 271 unsigned int val = va_arg( args, unsigned int ); 272 for(i = 0; i < 10; i++) 273 { 274 buf[9 - i] = HexaTab[val % 10]; 275 if (!(val /= 10)) break; 276 } 277 len = i + 1; 278 pbuf = &buf[9 - i]; 279 break; 280 } 281 case ('x'): /* 32 bits hexadecimal integer */ 282 { 283 unsigned int val = va_arg( args, unsigned int ); 284 ret = sys_call(SYSCALL_TTY_WRITE, 285 (unsigned int)"0x", 286 2, 287 channel, 288 0); 289 if (ret != 2) goto return_error; 290 for(i = 0; i < 8; i++) 291 { 292 buf[7 - i] = HexaTab[val % 16]; 293 if (!(val /= 16)) break; 294 } 295 len = i + 1; 296 pbuf = &buf[7 - i]; 297 break; 298 } 299 case ('l'): /* 64 bits hexadecimal unsigned */ 300 { 301 unsigned long long val = va_arg( args, unsigned long long ); 302 ret = sys_call(SYSCALL_TTY_WRITE, 303 (unsigned int)"0x", 304 2, 305 channel, 306 0); 307 if (ret != 2) goto return_error; 308 for(i = 0; i < 16; i++) 309 { 310 buf[15 - i] = HexaTab[val % 16]; 311 if (!(val /= 16)) break; 312 } 313 len = i + 1; 314 pbuf = &buf[15 - i]; 315 break; 316 } 317 case ('s'): /* string */ 318 { 319 char* str = va_arg( args, char* ); 320 while (str[len]) 321 { 322 len++; 323 } 324 pbuf = str; 325 break; 326 } 327 default: 328 goto return_error; 329 } 330 331 ret = sys_call(SYSCALL_TTY_WRITE, 332 (unsigned int)pbuf, 333 len, 334 channel, 335 0); 336 if (ret != len) goto return_error; 337 338 goto printf_text; 339 } 340 341 return_error: 342 343 sys_call( SYSCALL_TTY_RELEASE_LOCK, 344 channel, 345 (unsigned int)&sr_save, 346 0, 0 ); 347 348 va_end( args ); 349 giet_exit("error in giet_shr_printf()"); 350 } // end giet_shr_printf() 351 352 353 ///////////////////////////////// 354 void giet_tty_getc( char * byte ) 355 { 356 int ret; 357 358 do 116 359 { 117 360 ret = sys_call(SYSCALL_TTY_READ, … … 120 363 0xFFFFFFFF, // channel index from task context 121 364 0); 122 } 123 return 0; 124 } 125 //////////////////////////////////////////////////////////////////////////////////// 126 // giet_tty_gets() 127 //////////////////////////////////////////////////////////////////////////////////// 128 // This blocking function fetches a string from a terminal to a fixed length buffer. 129 // The terminal index must be defined in the task context in the boot phase. 130 // It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer. 131 // - Returns 0 when completed. 132 // - Up to (bufsize - 1) characters (including the non printable characters) 133 // will be copied into buffer, and the string is always completed by a NUL 134 // character. 135 // - The <LF> character is interpreted, and the function close the string with a 136 // NUL character if <LF> is read. 137 // - The <DEL> character is interpreted, and the corresponding character(s) are 138 // removed from the target buffer. 139 //////////////////////////////////////////////////////////////////////////////////// 140 int giet_tty_gets( char* buf, 141 unsigned int bufsize) 142 { 143 unsigned int ret; 365 if ( ret < 0 ) giet_exit("error in giet_tty_getc()"); 366 } 367 while (ret != 1); 368 } 369 370 ///////////////////////////////////// 371 void giet_tty_gets( char* buf, 372 unsigned int bufsize ) 373 { 374 int ret; 144 375 unsigned char byte; 145 unsigned int index = 0;146 376 unsigned int index = 0; 377 147 378 while (index < (bufsize - 1)) 148 379 { … … 154 385 0xFFFFFFFF, 155 386 0); 387 if ( ret < 0 ) giet_exit("error in giet_tty_gets()"); 156 388 } 157 389 while (ret != 1); … … 172 404 } 173 405 buf[index] = 0; 174 return 0; 175 } 176 //////////////////////////////////////////////////////////////////////////////////// 177 // giet_tty_getw() 178 //////////////////////////////////////////////////////////////////////////////////// 179 // This blocking function fetches a string of decimal characters (most 180 // significant digit first) to build a 32-bit unsigned integer. 181 // The terminal index must be defined in the task context in the boot phase. 182 // It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer. 183 // - Returns necessarily 0 when completed. 184 // 185 // - The non-blocking system function _tty_read_irq is called several times, 186 // and the decimal characters are written in a 32 characters buffer until a 187 // <LF> character is read. 188 // - The <DEL> character is interpreted, and previous characters can be 189 // cancelled. All others characters are ignored. 190 // - When the <LF> character is received, the string is converted to an 191 // unsigned int value. If the number of decimal digit is too large for the 32 192 // bits range, the zero value is returned. 193 //////////////////////////////////////////////////////////////////////////////////// 194 int giet_tty_getw(unsigned int * val) 406 } 407 408 /////////////////////////////////////// 409 void giet_tty_getw( unsigned int* val ) 195 410 { 196 411 unsigned char buf[32]; 197 unsigned char byte; 198 unsigned int save = 0; 199 unsigned int dec = 0; 200 unsigned int done = 0; 201 unsigned int overflow = 0; 202 unsigned int max = 0; 203 unsigned int i; 204 unsigned int ret; 205 412 unsigned int string_byte = 0x00000000; // string containing one single byte 413 unsigned int string_cancel = 0x00082008; // string containing BS/SPACE/BS 414 unsigned int save = 0; 415 unsigned int dec = 0; 416 unsigned int done = 0; 417 unsigned int overflow = 0; 418 unsigned int length = 0; 419 unsigned int i; 420 unsigned int channel = 0xFFFFFFFF; 421 int ret; // return value from syscalls 422 423 // get characters 206 424 while (done == 0) 207 425 { 426 // read one character 208 427 do 209 428 { 210 ret = sys_call(SYSCALL_TTY_READ, 211 (unsigned int)(&byte), 212 1, 213 0xFFFFFFFF, 214 0); 429 ret = sys_call( SYSCALL_TTY_READ, 430 (unsigned int)(&string_byte), 431 1, 432 channel, 433 0); 434 if ( ret < 0 ) giet_exit("error in giet_tty_getw()"); 215 435 } 216 436 while (ret != 1); 217 437 218 if ((byte > 0x2F) && (byte < 0x3A)) /* decimal character */ 219 { 220 buf[max] = byte; 221 max++; 222 giet_tty_putc(byte); 223 } 224 else if ((byte == 0x0A)) /* LF */ 438 // analyse character 439 if ((string_byte > 0x2F) && (string_byte < 0x3A)) /* decimal character */ 440 { 441 buf[length] = (unsigned char)string_byte; 442 length++; 443 444 // echo 445 ret = sys_call( SYSCALL_TTY_WRITE, 446 (unsigned int)(&string_byte), 447 1, 448 channel, 449 0 ); 450 if ( ret < 0 ) giet_exit("error in giet_tty_gets()"); 451 } 452 else if (string_byte == 0x0A) /* LF character */ 225 453 { 226 454 done = 1; 227 455 } 228 else if (byte == 0x7F) /* DEL */ 229 { 230 if (max > 0) 231 { 232 max--; /* cancel the character */ 233 giet_tty_putc(0x08); 234 giet_tty_putc(0x20); 235 giet_tty_putc(0x08); 236 } 237 } 238 if (max == 32) /* decimal string overflow */ 239 { 240 for (i = 0; i < max; i++) 241 { 242 /* cancel the string */ 243 giet_tty_putc(0x08); 244 giet_tty_putc(0x20); 245 giet_tty_putc(0x08); 246 } 247 giet_tty_putc(0x30); 248 *val = 0; /* return 0 value */ 249 return 0; 250 } 251 } 252 253 /* string conversion */ 254 for (i = 0; i < max; i++) 255 { 256 dec = dec * 10 + (buf[i] - 0x30); 257 if (dec < save) overflow = 1; 258 save = dec; 259 } 260 261 /* check overflow */ 262 if (overflow == 0) 263 { 264 *val = dec; /* return decimal value */ 265 } 266 else 267 { 268 for (i = 0; i < max; i++) 269 { 270 /* cancel the string */ 271 giet_tty_putc(0x08); 272 giet_tty_putc(0x20); 273 giet_tty_putc(0x08); 274 } 275 giet_tty_putc(0x30); 276 *val = 0; /* return 0 value */ 277 } 278 return 0; 279 } 280 //////////////////////////////////////////////////////////////////////////////////// 281 // giet_tty_printf() 282 //////////////////////////////////////////////////////////////////////////////////// 283 // This function is a simplified version of the mutek_printf() function. 284 // The terminal index must be defined in the calling task context. 285 // It doesn't use the IRQ_PUT interrupt, and the associated kernel buffer. 286 // Only a limited number of formats are supported: 287 // - %d : signed decimal 288 // - %u : unsigned decimal 289 // - %x : hexadecimal 290 // - %c : char 291 // - %s : string 292 // - Returns 0 if success, > 0 if error. 293 //////////////////////////////////////////////////////////////////////////////////// 294 int giet_tty_printf(char * format, ...) 295 { 296 va_list ap; 297 va_start(ap, format); 298 unsigned int ret; 299 300 if (NB_TTY_CHANNELS == 1) 301 { 302 ret = sys_call(SYSCALL_TTY_LOCK, 0, 0, 0, 0); // Get TTY lock 303 } 304 305 printf_text: 306 307 while (*format) 308 { 309 unsigned int i; 310 for (i = 0 ; format[i] && (format[i] != '%') ; i++); 311 if (i) 312 { 313 ret = sys_call(SYSCALL_TTY_WRITE, 314 (unsigned int)format, 315 i, 316 0xFFFFFFFF, 317 0); 318 319 if (ret != i) goto return_error; 320 321 format += i; 322 } 323 if (*format == '%') 324 { 325 format++; 326 goto printf_arguments; 327 } 328 } 329 330 if (NB_TTY_CHANNELS == 1) 331 { 332 ret = sys_call(SYSCALL_TTY_LOCK, 1, 0, 0, 0); // Release TTY lock 333 } 334 335 va_end(ap); 336 return 0; 337 338 printf_arguments: 339 340 { 341 int val = va_arg(ap, long); 342 char buf[20]; 343 char * pbuf; 344 unsigned int len = 0; 345 static const char HexaTab[] = "0123456789ABCDEF"; 346 unsigned int i; 347 348 switch (*format++) { 349 case ('c'): /* char conversion */ 350 len = 1; 351 buf[0] = val; 352 pbuf = buf; 353 break; 354 case ('d'): /* decimal signed integer */ 355 if (val < 0) 356 { 357 val = -val; 358 ret = sys_call(SYSCALL_TTY_WRITE, 359 (unsigned int)"-", 360 1, 361 0xFFFFFFFF, 362 0); 363 if (ret != 1) goto return_error; 364 } 365 case ('u'): /* decimal unsigned integer */ 366 for(i = 0; i < 10; i++) 367 { 368 buf[9 - i] = HexaTab[val % 10]; 369 if (!(val /= 10)) break; 370 } 371 len = i + 1; 372 pbuf = &buf[9 - i]; 373 break; 374 case ('x'): /* hexadecimal integer */ 375 ret = sys_call(SYSCALL_TTY_WRITE, 376 (unsigned int)"0x", 377 2, 378 0xFFFFFFFF, 379 0); 380 if (ret != 2) goto return_error; /* return error */ 381 for(i = 0; i < 8; i++) 382 { 383 buf[7 - i] = HexaTab[val % 16U]; 384 if (!(val /= 16U)) break; 385 } 386 len = i + 1; 387 pbuf = &buf[7 - i]; 388 break; 389 case ('s'): /* string */ 390 { 391 char * str = (char *) val; 392 while (str[len]) 393 { 394 len++; 395 } 396 pbuf = (char *) val; 397 } 398 break; 399 default: 400 goto printf_text; 401 } 402 403 ret = sys_call(SYSCALL_TTY_WRITE, 404 (unsigned int)pbuf, 405 len, 406 0xFFFFFFFF, 407 0); 408 if (ret != len) goto return_error; 409 410 goto printf_text; 411 } 412 413 return_error: 414 if (NB_TTY_CHANNELS == 1) 415 { 416 ret = sys_call(SYSCALL_TTY_LOCK, 1, 0, 0, 0); // Release TTY lock 417 } 418 419 return 1; 420 } 421 456 else if ( (string_byte == 0x7F) || /* DEL character */ 457 (string_byte == 0x08) ) /* BS character */ 458 { 459 if ( length > 0 ) 460 { 461 length--; // cancel the character 462 463 ret = sys_call( SYSCALL_TTY_WRITE, 464 (unsigned int)(&string_cancel), 465 3, 466 channel, 467 0 ); 468 if ( ret < 0 ) giet_exit("error in giet_tty_gets()"); 469 } 470 } 471 472 // test buffer overflow 473 if ( length >= 32 ) 474 { 475 overflow = 1; 476 done = 1; 477 } 478 } // end while characters 479 480 // string to int conversion with overflow detection 481 if ( overflow == 0 ) 482 { 483 for (i = 0; (i < length) && (overflow == 0) ; i++) 484 { 485 dec = dec * 10 + (buf[i] - 0x30); 486 if (dec < save) overflow = 1; 487 save = dec; 488 } 489 } 490 491 // final evaluation 492 if ( overflow == 0 ) 493 { 494 // return value 495 *val = dec; 496 } 497 else 498 { 499 // cancel all echo characters 500 for (i = 0; i < length ; i++) 501 { 502 ret = sys_call( SYSCALL_TTY_WRITE, 503 (unsigned int)(&string_cancel), 504 3, 505 channel, 506 0 ); 507 if ( ret < 0 ) giet_exit("error in giet_tty_gets()"); 508 } 509 // echo character '0' 510 string_byte = 0x30; 511 ret = sys_call( SYSCALL_TTY_WRITE, 512 (unsigned int)(&string_byte), 513 1, 514 channel, 515 0 ); 516 if ( ret < 0 ) giet_exit(); 517 518 // return 0 value 519 *val = 0; 520 } 521 } 422 522 423 523 … … 426 526 ////////////////////////////////////////////////////////////////////////////////// 427 527 428 ////////////////////////////////////////////////////////////////////////////////// 429 // giet_timer_start() 430 ////////////////////////////////////////////////////////////////////////////////// 431 // This function activates the private user timer allocated to the calling task 432 // in the boot phase. 433 // - Returns 0 if success, > 0 if error. 434 ////////////////////////////////////////////////////////////////////////////////// 435 int giet_timer_start() 436 { 437 return sys_call( SYSCALL_TIMER_START, 438 0, 0, 0, 0 ); 439 } 440 ////////////////////////////////////////////////////////////////////////////////// 441 // giet_timer_stop() 442 ////////////////////////////////////////////////////////////////////////////////// 443 // This function activates the user timer allocated to the calling task. 444 // - Returns 0 if success, > 0 if error. 445 ////////////////////////////////////////////////////////////////////////////////// 446 int giet_timer_stop() 447 { 448 return sys_call( SYSCALL_TIMER_STOP, 449 0, 0, 0, 0 ); 528 /////////////////////// 529 void giet_timer_start() 530 { 531 if ( sys_call( SYSCALL_TIMER_START, 0, 0, 0, 0 ) ) 532 giet_exit("error in giet_timer_start()"); 533 } 534 535 ////////////////////// 536 void giet_timer_stop() 537 { 538 if ( sys_call( SYSCALL_TIMER_STOP, 0, 0, 0, 0 ) ) 539 giet_exit("error in giet_timer_stop()"); 450 540 } 451 541 … … 455 545 ////////////////////////////////////////////////////////////////////////////////// 456 546 457 ////////////////////////////////////////////////////////////////////////////////// 458 // giet_fb_sync_write() 459 ////////////////////////////////////////////////////////////////////////////////// 460 // This blocking function use a memory copy strategy to transfer data from a 461 // user buffer to the frame buffer device in kernel space. 462 // offset : offset (in bytes) in the frame buffer 463 // buffer : base address of the memory buffer 464 // length : number of bytes to be transfered 465 // - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space). 466 ////////////////////////////////////////////////////////////////////////////////// 467 int giet_fb_sync_write( unsigned int offset, 547 //////////////////////////////////////////// 548 void giet_fb_sync_write( unsigned int offset, 468 549 void * buffer, 469 550 unsigned int length ) 470 551 { 471 return sys_call( SYSCALL_FB_SYNC_WRITE, 472 offset, 473 (unsigned int)buffer, 474 length, 475 0 ); 476 } 477 ////////////////////////////////////////////////////////////////////////////////// 478 // giet_fb_sync_read() 479 ////////////////////////////////////////////////////////////////////////////////// 480 // This blocking function use a memory copy strategy to transfer data from the 481 // frame buffer device in kernel space to an user buffer. 482 // offset : offset (in bytes) in the frame buffer 483 // buffer : base address of the user buffer 484 // length : number of bytes to be transfered 485 // - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space). 486 ////////////////////////////////////////////////////////////////////////////////// 487 int giet_fb_sync_read( unsigned int offset, 488 void * buffer, 489 unsigned int length ) 490 { 491 return sys_call( SYSCALL_FB_SYNC_READ, 492 offset, 493 (unsigned int)buffer, 494 length, 495 0 ); 496 } 497 ////////////////////////////////////////////////////////////////////////////////// 498 // giet_fb_cma_init() 499 ////////////////////////////////////////////////////////////////////////////////// 500 // This function initializes the two chbuf SRC an DST used by the CMA controller 501 // and activates the CMA channel allocated to the calling task. 502 // - buf0 : first user buffer virtual address 503 // - buf0 : second user buffer virtual address 504 // - length : buffer size (bytes) 505 // - Returns 0 if success, > 0 if error. 506 ////////////////////////////////////////////////////////////////////////////////// 507 int giet_fb_cma_init( void * buf0, 508 void * buf1, 509 unsigned int length ) 510 { 511 return sys_call( SYSCALL_FB_CMA_INIT, 512 (unsigned int)buf0, 513 (unsigned int)buf1, 514 length, 515 0 ); 516 } 517 ////////////////////////////////////////////////////////////////////////////////// 518 // giet_fb_cma_write() 519 ////////////////////////////////////////////////////////////////////////////////// 520 // This function set the valid status for one of the SRC user buffer. 521 // and reset the valid status for the DST frame buffer. 522 // - bufffer_id : 0 => buf0 valid is set / not 0 => buf1 valid is set 523 // - Returns 0 if success, > 0 if error. 524 ////////////////////////////////////////////////////////////////////////////////// 525 int giet_fb_cma_write( unsigned int buffer_id ) 526 { 527 return sys_call( SYSCALL_FB_CMA_WRITE, 528 buffer_id, 529 0, 0, 0 ); 530 } 531 ////////////////////////////////////////////////////////////////////////////////// 532 // giet_fb_cma_stop() 533 ////////////////////////////////////////////////////////////////////////////////// 534 // This function desactivates the CMA channel allocated to the calling task. 535 // - Returns 0 if success, > 0 if error. 536 ////////////////////////////////////////////////////////////////////////////////// 537 int giet_fb_cma_stop( ) 538 { 539 return sys_call( SYSCALL_FB_CMA_STOP, 540 0, 0, 0, 0 ); 552 if ( sys_call( SYSCALL_FB_SYNC_WRITE, 553 offset, 554 (unsigned int)buffer, 555 length, 556 0 ) ) giet_exit("error in giet_fb_sync_write()"); 557 } 558 559 /////////////////////////////////////////// 560 void giet_fb_sync_read( unsigned int offset, 561 void * buffer, 562 unsigned int length ) 563 { 564 if ( sys_call( SYSCALL_FB_SYNC_READ, 565 offset, 566 (unsigned int)buffer, 567 length, 568 0 ) ) giet_exit("error in giet_fb_sync_read()"); 569 } 570 571 ///////////////////////////////////////// 572 void giet_fb_cma_init( void * buf0, 573 void * buf1, 574 unsigned int length ) 575 { 576 if ( sys_call( SYSCALL_FB_CMA_INIT, 577 (unsigned int)buf0, 578 (unsigned int)buf1, 579 length, 580 0 ) ) giet_exit("error in giet_fb_cma_init()"); 581 } 582 583 /////////////////////////////////////////////// 584 void giet_fb_cma_write( unsigned int buffer_id ) 585 { 586 if ( sys_call( SYSCALL_FB_CMA_WRITE, 587 buffer_id, 588 0, 0, 0 ) ) giet_exit("error in giet_fb_cma_write()"); 589 } 590 591 //////////////////////// 592 void giet_fb_cma_stop() 593 { 594 if ( sys_call( SYSCALL_FB_CMA_STOP, 595 0, 0, 0, 0 ) ) giet_exit("error in giet_fb_cma_stop()"); 541 596 } 542 597 … … 546 601 ////////////////////////////////////////////////////////////////////////////////// 547 602 548 ////////////////////////////////////////////////////////////////////////////////// 549 // giet_nic_cma_init() 550 ////////////////////////////////////////////////////////////////////////////////// 551 // This function initializes the memory chbuf used by the CMA controller, 552 // activates the NIC channel allocated to the calling task, and the CMA channel. 553 // - tx : RX channel if 0 / TX channel if non 0 554 // - buf0 : first user buffer virtual address 555 // - buf1 : second user buffer virtual address 556 // - length : buffer size (bytes) 557 // - Returns 0 if success, > 0 if error 558 ////////////////////////////////////////////////////////////////////////////////// 559 int giet_nic_cma_start() 560 { 561 return sys_call( SYSCALL_NIC_CMA_START, 562 0, 0, 0, 0 ); 563 } 564 ////////////////////////////////////////////////////////////////////////////////// 565 // giet_nic_cma_stop() 566 ////////////////////////////////////////////////////////////////////////////////// 567 // This function desactivates the NIC channel and the two CMA channels 568 // allocated to the calling task. 569 // - Returns 0 if success, > 0 if error. 570 ////////////////////////////////////////////////////////////////////////////////// 571 int giet_nic_cma_stop( ) 572 { 573 return sys_call( SYSCALL_NIC_CMA_STOP, 574 0, 0, 0, 0 ); 575 } 576 577 578 ////////////////////////////////////////////////////////////////////////////////// 579 ///////////////////// Miscellaneous system calls ///////////////////////////////// 580 ////////////////////////////////////////////////////////////////////////////////// 581 582 /////////////////////////////////////////////////////////////////////////////////// 583 // giet_assert() 584 /////////////////////////////////////////////////////////////////////////////////// 585 // This function uses the giet_tty_puts() and giet_exit() system calls. 586 /////////////////////////////////////////////////////////////////////////////////// 587 void giet_assert( unsigned int condition, 588 char* string ) 589 { 590 if ( condition == 0 ) 591 { 592 giet_tty_puts( string ); 593 giet_exit(); 594 } 595 } 596 ////////////////////////////////////////////////////////////////////////////////// 597 // giet_vobj_get_vbase() 598 ////////////////////////////////////////////////////////////////////////////////// 599 // This function writes in argument (vobj_vaddr) the virtual base address 600 // of a vobj (defined in the mapping_info data structure), identified by 601 // the two arguments (vspace_name and vobj_name). 602 // The (vobj_type) argument is redundant, and used for coherence checking. 603 // - Returns the address if success, 0 if error ( not defined or wrong type ) 604 ////////////////////////////////////////////////////////////////////////////////// 605 int giet_vobj_get_vbase( char* vspace_name, 606 char* vobj_name, 607 unsigned int vobj_type, 608 unsigned int* vobj_vaddr ) 609 { 610 return sys_call( SYSCALL_VOBJ_GET_VBASE, 611 (unsigned int) vspace_name, 612 (unsigned int) vobj_name, 613 (unsigned int) vobj_type, 614 (unsigned int) vobj_vaddr ); 615 } 616 //////////////////////////////////////////////////////////////////////////////////// 617 // giet_proc_number() 618 //////////////////////////////////////////////////////////////////////////////////// 619 // This function returns in the buffer argument the number of processors 620 // in the cluster specified by the cluster_id argument. 621 // - Returns 0 if success, > 0 if error ( cluster index too large ) 622 //////////////////////////////////////////////////////////////////////////////////// 623 int giet_proc_number( unsigned int cluster_id, 624 unsigned int* buffer ) 625 { 626 return sys_call(SYSCALL_PROC_NUMBER, cluster_id, (unsigned int) buffer, 0, 0); 627 } 628 ////////////////////////////////////////////////////////////////////////////////// 629 // giet_exit() 630 ////////////////////////////////////////////////////////////////////////////////// 631 // This function stops execution of the calling task with a TTY message, 632 // the user task is descheduled and becomes not runable. 633 // It does not consume processor cycles anymore. 634 ////////////////////////////////////////////////////////////////////////////////// 635 void giet_exit() 636 { 637 sys_call( SYSCALL_EXIT, 638 0, 0, 0, 0 ); 639 } 640 ////////////////////////////////////////////////////////////////////////////////// 641 // giet_context_switch() 642 ////////////////////////////////////////////////////////////////////////////////// 643 // The user task calling this function is descheduled and 644 // the processor is allocated to another task. 645 ////////////////////////////////////////////////////////////////////////////////// 646 int giet_context_switch() 647 { 648 return sys_call( SYSCALL_CTX_SWITCH, 649 0, 0, 0, 0 ); 650 } 651 ////////////////////////////////////////////////////////////////////////////////// 652 // giet_proc_task_id() 653 ////////////////////////////////////////////////////////////////////////////////// 654 // This functions returns the local task id. 655 // If processor has n tasks the local task index is ranging from 0 to n-1 656 ////////////////////////////////////////////////////////////////////////////////// 657 int giet_proc_task_id() 658 { 659 return sys_call( SYSCALL_LOCAL_TASK_ID, 660 0, 0, 0, 0 ); 661 } 662 ////////////////////////////////////////////////////////////////////////////////// 663 // giet_heap_info() 664 ////////////////////////////////////////////////////////////////////////////////// 665 // This function returns the base address and size of the current task's heap 666 ////////////////////////////////////////////////////////////////////////////////// 667 int giet_heap_info( unsigned int* vaddr, 668 unsigned int* length ) 669 { 670 return sys_call( SYSCALL_HEAP_INFO, 671 (unsigned int)vaddr, 672 (unsigned int)length, 673 0, 0 ); 674 } 675 ////////////////////////////////////////////////////////////////////////////////// 676 // giet_global_task_id() 677 ////////////////////////////////////////////////////////////////////////////////// 678 // This functions returns the global task id, which is unique in all the giet. 679 ////////////////////////////////////////////////////////////////////////////////// 680 int giet_global_task_id() 681 { 682 return sys_call( SYSCALL_GLOBAL_TASK_ID, 683 0, 0, 0, 0 ); 684 } 685 686 ////////////////////////////////////////////////////////////////////////////////// 687 // giet_thread_id() 688 ////////////////////////////////////////////////////////////////////////////////// 689 // This functions returns the thread index of the current task. 690 ////////////////////////////////////////////////////////////////////////////////// 691 int giet_thread_id() 692 { 693 return sys_call( SYSCALL_THREAD_ID, 694 0, 0, 0, 0 ); 603 ///////////////////////// 604 void giet_nic_cma_start() 605 { 606 if ( sys_call( SYSCALL_NIC_CMA_START, 0, 0, 0, 0 ) ) 607 giet_exit("error in giet_nic_cma_start()"); 608 } 609 610 ///////////////////////// 611 void giet_nic_cma_stop() 612 { 613 if ( sys_call( SYSCALL_NIC_CMA_STOP, 0, 0, 0, 0 ) ) 614 giet_exit("error in giet_nic_cma_stop()"); 695 615 } 696 616 … … 699 619 /////////////////////////////////////////////////////////////////////////////////// 700 620 701 /////////////////////////////////////////////////////////////////////////////////// 702 // giet_fat_open() 703 /////////////////////////////////////////////////////////////////////////////////// 704 // Open a file identified by a pathname, and contained in the system FAT. 705 // The read/write flags are not supported yet: no effect. 706 /////////////////////////////////////////////////////////////////////////////////// 621 /////////////////////////////////////////// 707 622 int giet_fat_open( const char* pathname, 708 623 unsigned int flags ) … … 713 628 0, 0 ); 714 629 } 630 631 //////////////////////////////////// 632 void giet_fat_read( unsigned int fd, 633 void* buffer, 634 unsigned int count, 635 unsigned int offset ) 636 { 637 if ( sys_call( SYSCALL_FAT_READ, 638 fd, 639 (unsigned int)buffer, 640 count, 641 offset ) != count ) giet_exit("in giet_fat_read()"); 642 } 643 644 ///////////////////////////////////// 645 void giet_fat_write( unsigned int fd, 646 void* buffer, 647 unsigned int count, 648 unsigned int offset ) 649 { 650 if ( sys_call( SYSCALL_FAT_WRITE, 651 fd, 652 (unsigned int)buffer, 653 count, 654 offset ) != count ) giet_exit("in giet_fat_write()"); 655 } 656 657 /* variant implementing the UNIX spec 715 658 /////////////////////////////////////////////////////////////////////////////////// 716 // giet_fat_read() 659 // This system call writes to a file identified by the "fd" file descriptor. 660 // - "buffer" is the source buffer virtual address (must be word aligned). 661 // - "count" is a number of bytes (must be multiple of 4). 662 // It uses the implicit "lseek" pointer in file descriptor. 717 663 /////////////////////////////////////////////////////////////////////////////////// 718 // Read "count" sectors from a file identified by "fd", skipping "offset" 719 // sectors in file, and writing into the user "buffer". 720 // The user buffer base address shoulb be 64 bytes aligned. 721 /////////////////////////////////////////////////////////////////////////////////// 722 // This system call specification should evolve to the UNIX specification: 723 // - count must be a number of bytes, with no alignment constraint on user buffer. 724 // - offset argument should be removed and replaced by an implicit "lseek" pointer 725 // stored in the file descriptor. 726 // This suppose to implement a sectors cache 727 /////////////////////////////////////////////////////////////////////////////////// 728 int giet_fat_read( unsigned int fd, 729 void* buffer, 730 unsigned int count, 731 unsigned int offset ) 732 { 733 return sys_call( SYSCALL_FAT_READ, 734 fd, 735 (unsigned int)buffer, 736 count, 737 offset ); 738 } 739 /////////////////////////////////////////////////////////////////////////////////// 740 // giet_fat_write() 741 /////////////////////////////////////////////////////////////////////////////////// 742 // Write "count" sectors from a file identified by "fd", skipping "offset" 743 // sectors in file, and reading from the user "buffer". 744 // The user buffer base address shoulb be 64 bytes aligned. 745 /////////////////////////////////////////////////////////////////////////////////// 746 // This system call specification should evolve to the UNIX specification: 747 // - count must be a number of bytes, with no alignment constraint on buffer 748 // - offset argument should be removed and replaced by an implicit "lseek" pointer 749 // stored in the file descriptor. 750 // This suppose to implement a sectors cache 751 /////////////////////////////////////////////////////////////////////////////////// 752 int giet_fat_write( unsigned int fd, 664 void giet_fat_write( unsigned int fd, 753 665 void* buffer, 754 unsigned int count, 755 unsigned int offset ) 666 unsigned int count ) // number of bytes 756 667 { 757 668 return sys_call( SYSCALL_FAT_WRITE, 758 669 fd, 759 670 (unsigned int)buffer, 760 count, 761 offset ); 762 } 763 /////////////////////////////////////////////////////////////////////////////////// 764 // giet_fat_lseek() 765 /////////////////////////////////////////////////////////////////////////////////// 766 // Change the lseek file pointer value for a file identified by "fd". 767 /////////////////////////////////////////////////////////////////////////////////// 768 int giet_fat_lseek( unsigned int fd, 671 count, 0 ); 672 } 673 */ 674 675 ///////////////////////////////////// 676 void giet_fat_lseek( unsigned int fd, 769 677 unsigned int offset, 770 unsigned int whence) 771 { 772 return sys_call( SYSCALL_FAT_LSEEK, 773 fd, 774 offset, 775 whence, 776 0 ); 777 } 778 779 /////////////////////////////////////////////////////////////////////////////////// 780 // giet_fat_fstat() 781 /////////////////////////////////////////////////////////////////////////////////// 782 // Return stats of a file identified by "fd". 783 // (Only the file_size in sectors for this moment) 784 /////////////////////////////////////////////////////////////////////////////////// 785 int giet_fat_fstat( unsigned int fd ) 786 { 787 return sys_call( SYSCALL_FAT_FSTAT, 788 fd, 789 0, 0, 0 ); 790 } 791 792 /////////////////////////////////////////////////////////////////////////////////// 793 // giet_fat_close() 794 /////////////////////////////////////////////////////////////////////////////////// 795 // Close a file identified by "fd". 796 /////////////////////////////////////////////////////////////////////////////////// 797 int giet_fat_close( unsigned int fd ) 798 { 799 return sys_call( SYSCALL_FAT_CLOSE, 800 fd, 801 0, 0, 0 ); 802 } 803 804 805 /////////////////////////////////////////////////////////////////////////////////// 806 ////////////////// Pseudo system calls (no syscall instruction) /////////////////// 807 /////////////////////////////////////////////////////////////////////////////////// 808 809 /////////////////////////////////////////////////////////////////////////////////// 810 // giet_rand() 811 // This function returns a pseudo-random value derived from the processor cycle 812 // count. This value is comprised between 0 & 65535. 813 /////////////////////////////////////////////////////////////////////////////////// 678 unsigned int whence ) 679 { 680 if ( sys_call( SYSCALL_FAT_LSEEK, 681 fd, 682 offset, 683 whence, 684 0 ) ) giet_exit("in giet_fat_lseek()"); 685 } 686 687 ////////////////////////////////////// 688 void giet_fat_fstat( unsigned int fd ) 689 { 690 if ( sys_call( SYSCALL_FAT_FSTAT, 691 fd, 692 0, 0, 0 ) ) giet_exit("in giet_fat_lseek()"); 693 } 694 695 ///////////////////////////////////// 696 void giet_fat_close( unsigned int fd ) 697 { 698 if ( sys_call( SYSCALL_FAT_CLOSE, 699 fd, 700 0, 0, 0 ) ) giet_exit("in giet_fat_close()"); 701 } 702 703 704 ////////////////////////////////////////////////////////////////////////////////// 705 ///////////////////// Miscellaneous system calls ///////////////////////////////// 706 ////////////////////////////////////////////////////////////////////////////////// 707 708 ///////////////// 709 int giet_procid() 710 { 711 return sys_call( SYSCALL_PROCID, 712 0, 0, 0, 0 ); 713 } 714 715 //////////////////// 716 int giet_proctime() 717 { 718 return sys_call( SYSCALL_PROCTIME, 719 0, 0, 0, 0 ); 720 } 721 722 /////////////////////// 723 int giet_proc_task_id() 724 { 725 return sys_call( SYSCALL_LOCAL_TASK_ID, 726 0, 0, 0, 0 ); 727 } 728 729 ///////////////////////// 730 int giet_global_task_id() 731 { 732 return sys_call( SYSCALL_GLOBAL_TASK_ID, 733 0, 0, 0, 0 ); 734 } 735 736 //////////////////// 737 int giet_thread_id() 738 { 739 return sys_call( SYSCALL_THREAD_ID, 740 0, 0, 0, 0 ); 741 } 742 743 /////////////// 814 744 int giet_rand() 815 745 { … … 822 752 } 823 753 } 754 755 ////////////////////////////// 756 void giet_exit( char* string ) 757 { 758 sys_call( SYSCALL_EXIT, 759 (unsigned int)string, 760 0, 0, 0 ); 761 } 762 763 ///////////////////////////////////////// 764 void giet_assert( unsigned int condition, 765 char* string ) 766 { 767 if ( condition == 0 ) giet_exit( string ); 768 } 769 770 //////////////////////////////////////////////////// 771 void giet_vobj_get_vbase( char* vspace_name, 772 char* vobj_name, 773 unsigned int* vobj_vaddr ) 774 { 775 if ( sys_call( SYSCALL_VOBJ_GET_VBASE, 776 (unsigned int) vspace_name, 777 (unsigned int) vobj_name, 778 (unsigned int) vobj_vaddr, 779 0 ) ) giet_exit("in giet_vobj_get_vbase()"); 780 } 781 782 /////////////////////////////////////////////// 783 void giet_proc_number( unsigned int cluster_id, 784 unsigned int* buffer ) 785 { 786 if ( sys_call( SYSCALL_PROC_NUMBER, 787 cluster_id, 788 (unsigned int) buffer, 789 0, 0) ) giet_exit("in giet_proc_number()"); 790 } 791 792 ////////////////////////// 793 void giet_context_switch() 794 { 795 sys_call( SYSCALL_CTX_SWITCH, 796 0, 0, 0, 0 ); 797 } 798 799 ///////////////////////////////////////// 800 void giet_heap_info( unsigned int* vaddr, 801 unsigned int* length ) 802 { 803 if ( sys_call( SYSCALL_HEAP_INFO, 804 (unsigned int)vaddr, 805 (unsigned int)length, 806 0, 0 ) ) giet_exit("in giet_heap_info()"); 807 } 808 824 809 825 810 // Local Variables: -
soft/giet_vm/giet_libs/stdio.h
r267 r295 18 18 #define SYSCALL_TIMER_START 0x04 19 19 #define SYSCALL_TIMER_STOP 0x05 20 #define SYSCALL_ FREE_060x0621 #define SYSCALL_ FREE_070x0720 #define SYSCALL_TTY_GET_LOCK 0x06 21 #define SYSCALL_TTY_RELEASE_LOCK 0x07 22 22 #define SYSCALL_HEAP_INFO 0x08 23 23 #define SYSCALL_LOCAL_TASK_ID 0x09 … … 32 32 #define SYSCALL_FB_SYNC_READ 0x11 33 33 #define SYSCALL_THREAD_ID 0x12 34 #define SYSCALL_ TTY_LOCK0x1334 #define SYSCALL_FREE_13 0x13 35 35 #define SYSCALL_FREE_14 0x14 36 36 #define SYSCALL_FREE_15 0x15 … … 99 99 100 100 ////////////////////////////////////////////////////////////////////////// 101 // MIPS32 related system calls 102 ////////////////////////////////////////////////////////////////////////// 103 104 extern int giet_procid(); 105 106 extern int giet_proctime(); 107 108 ////////////////////////////////////////////////////////////////////////// 109 // TTY device related system calls 110 ////////////////////////////////////////////////////////////////////////// 111 112 extern int giet_tty_putc(char byte); 113 114 extern int giet_tty_puts(char* buf); 115 116 extern int giet_tty_putw(unsigned int val); 117 118 extern int giet_tty_getc_no_irq(char* byte); 119 120 extern int giet_tty_getc(char* byte); 121 122 extern int giet_tty_gets(char* buf, unsigned int bufsize); 123 124 extern int giet_tty_getw(unsigned int* val); 125 126 extern int giet_tty_printf(char* format,...); 127 128 ////////////////////////////////////////////////////////////////////////// 129 // TIMER device related system calls 130 ////////////////////////////////////////////////////////////////////////// 131 132 extern int giet_timer_start(); 133 134 extern int giet_timer_stop(); 101 ////////////////////////////////////////////////////////////////////////// 102 // MIPS32 related system calls 103 ////////////////////////////////////////////////////////////////////////// 104 ////////////////////////////////////////////////////////////////////////// 105 106 ////////////////////////////////////////////////////////////////////////// 107 ////////////////////////////////////////////////////////////////////////// 108 // TTY device related system calls 109 ////////////////////////////////////////////////////////////////////////// 110 ////////////////////////////////////////////////////////////////////////// 111 112 ////////////////////////////////////////////////////////////////////////// 113 // This function is a modified version of the mutek_printf(). 114 // It uses a private terminal allocated to the calling task in the boot. 115 // ("use_tty" argument in xml mapping), and does not take the TTY lock. 116 // It calls several times the _tty_write system function. 117 // Only a limited number of formats are supported: 118 // - %d : signed decimal 119 // - %u : unsigned decimal 120 // - %x : 32 bits hexadecimal 121 // - %l : 64 bits hexadecimal 122 // - %c : char 123 // - %s : string 124 // In case or error returned by syscall, it makes a giet_exit(). 125 ////////////////////////////////////////////////////////////////////////// 126 extern void giet_tty_printf( char* format, ... ); 127 128 ////////////////////////////////////////////////////////////////////////// 129 // This function is a modified version of the mutek_printf(). 130 // It uses the kernel TTY0 as a shared terminal, and it takes the 131 // TTY lock to get exclusive access during the format display. 132 // It calls several times the _tty_write system function. 133 // Only a limited number of formats are supported: 134 // - %d : signed decimal 135 // - %u : unsigned decimal 136 // - %x : 32 bits hexadecimal 137 // - %l : 64 bits hexadecimal 138 // - %c : char 139 // - %s : string 140 // In case or error returned by syscall, it makes a giet_exit(). 141 ////////////////////////////////////////////////////////////////////////// 142 extern void giet_shr_printf( char* format, ... ); 143 144 ////////////////////////////////////////////////////////////////////////// 145 // This blocking function fetches a single character from the private 146 // terminal allocated to the calling task in the boot. 147 // It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer. 148 // In case or error returned by syscall, it makes a giet_exit(). 149 ////////////////////////////////////////////////////////////////////////// 150 extern void giet_tty_getc( char* byte ); 151 152 ////////////////////////////////////////////////////////////////////////// 153 // This blocking function fetches a string from the private terminal 154 // allocated to the calling task to a fixed length buffer. 155 // The terminal index must be defined in the task context in the boot. 156 // It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer. 157 // - Up to (bufsize - 1) characters (including the non printable characters) 158 // are copied into buffer, and the string is completed by a NUL character. 159 // - The <LF> character is interpreted, and the function close the string 160 // with a NUL character if <LF> is read. 161 // - The <DEL> character is interpreted, and the corresponding character(s) 162 // are removed from the target buffer. 163 // - It does not provide an echo. 164 // In case or error returned by syscall, it makes a giet_exit(). 165 ///////////////////////////////////////////////////////////////////////// 166 extern void giet_tty_gets( char* buf, unsigned int bufsize ); 167 168 ///////////////////////////////////////////////////////////////////////// 169 // This blocking function fetches a string of decimal characters (most 170 // significant digit first) to build a 32-bit unsigned integer from 171 // the private TTY terminal allocated to the calling task. 172 // The terminal index must be defined in the task context in the boot. 173 // It uses the TTY_RX_IRQ interrupt, and the associated kernel buffer. 174 // - The non-blocking system function _tty_read is called several times, 175 // and the decimal characters are written in a 32 characters buffer 176 // until a <LF> character is read. 177 // - It ignores non-decimal characters, and displays an echo 178 // system function) for each decimal character. 179 // - The <DEL> character is interpreted, and previous characters can be cancelled. 180 // - When the <LF> character is received, the string is converted to an 181 // unsigned int value. If the number of decimal digit is too large for the 32 182 // bits range, the zero value is returned. 183 // In case or error returned by syscall, it makes a giet_exit(). 184 ////////////////////////////////////////////////////////////////////////// 185 extern void giet_tty_getw( unsigned int* val ); 186 187 ////////////////////////////////////////////////////////////////////////// 188 ////////////////////////////////////////////////////////////////////////// 189 // TIMER device related system calls 190 ////////////////////////////////////////////////////////////////////////// 191 ////////////////////////////////////////////////////////////////////////// 192 193 ////////////////////////////////////////////////////////////////////////// 194 // This function activates the private user timer allocated 195 // to the calling task in the boot phase. 196 // In case or error returned by syscall, it makes a giet_exit(). 197 ////////////////////////////////////////////////////////////////////////// 198 extern void giet_timer_start(); 199 200 ////////////////////////////////////////////////////////////////////////// 201 // This function stops the private user timer allocated 202 // to the calling task. 203 // In case or error returned by syscall, it makes a giet_exit(). 204 ////////////////////////////////////////////////////////////////////////// 205 extern void giet_timer_stop(); 135 206 136 207 ////////////////////////////////////////////////////////////////////////// 137 // Frame buffer device related system calls 138 ////////////////////////////////////////////////////////////////////////// 139 140 extern int giet_fb_sync_read( unsigned int offset, 141 void* buffer, 208 ////////////////////////////////////////////////////////////////////////// 209 // Frame buffer device related system calls 210 ////////////////////////////////////////////////////////////////////////// 211 ////////////////////////////////////////////////////////////////////////// 212 213 ////////////////////////////////////////////////////////////////////////// 214 // This blocking function use a memory copy strategy to transfer data 215 // from the frame buffer device in kernel space to an user buffer. 216 // offset : offset (in bytes) in the frame buffer 217 // buffer : base address of the user buffer 218 // length : number of bytes to be transfered 219 // In case or error returned by syscall, it makes a giet_exit(). 220 ////////////////////////////////////////////////////////////////////////// 221 extern void giet_fb_sync_read( unsigned int offset, 222 void* buffer, 223 unsigned int length ); 224 225 ////////////////////////////////////////////////////////////////////////// 226 // This blocking function use a memory copy strategy to transfer data 227 // from a user buffer to the frame buffer device in kernel space. 228 // offset : offset (in bytes) in the frame buffer 229 // buffer : base address of the memory buffer 230 // length : number of bytes to be transfered 231 // In case or error returned by syscall, it makes a giet_exit(). 232 ////////////////////////////////////////////////////////////////////////// 233 extern void giet_fb_sync_write( unsigned int offset, 234 void* buffer, 235 unsigned int length ); 236 237 ////////////////////////////////////////////////////////////////////////// 238 // This function initializes the two chbuf SRC an DST used by the CMA 239 // controller and activates the CMA channel allocated to the calling task. 240 // - buf0 : first user buffer virtual address 241 // - buf1 : second user buffer virtual address 242 // - length : buffer size (bytes) 243 // In case or error returned by syscall, it makes a giet_exit(). 244 ////////////////////////////////////////////////////////////////////////// 245 extern void giet_fb_cma_init( void* buf0, 246 void* buf1, 142 247 unsigned int length ); 143 248 144 extern int giet_fb_sync_write(unsigned int offset, 145 void* buffer, 146 unsigned int length); 147 148 extern int giet_fb_cma_init( void* buf0, 149 void* buf1, 150 unsigned int length); 151 152 extern int giet_fb_cma_write(unsigned int buf_id); 153 154 extern int giet_fb_cma_stop(); 155 156 ////////////////////////////////////////////////////////////////////////// 157 // Network controller related system calls 158 ////////////////////////////////////////////////////////////////////////// 159 160 extern int giet_nic_cma_start(); 161 162 extern int giet_nic_cma_stop(); 163 164 ////////////////////////////////////////////////////////////////////////// 165 // FAT related system calls 166 ////////////////////////////////////////////////////////////////////////// 167 249 ////////////////////////////////////////////////////////////////////////// 250 // This function initializes the two chbuf SRC an DST used by the CMA 251 // controller and activates the CMA channel allocated to the calling task. 252 // - buf0 : first user buffer virtual address 253 // - buf0 : second user buffer virtual address 254 // - length : buffer size (bytes) 255 // In case or error returned by syscall, it makes a giet_exit(). 256 ////////////////////////////////////////////////////////////////////////// 257 extern void giet_fb_cma_write( unsigned int buf_id ); 258 259 ////////////////////////////////////////////////////////////////////////// 260 // This function desactivates the CMA channel allocated to the task. 261 // In case or error returned by syscall, it makes a giet_exit(). 262 ////////////////////////////////////////////////////////////////////////// 263 extern void giet_fb_cma_stop(); 264 265 ////////////////////////////////////////////////////////////////////////// 266 ////////////////////////////////////////////////////////////////////////// 267 // NIC related system calls 268 ////////////////////////////////////////////////////////////////////////// 269 ////////////////////////////////////////////////////////////////////////// 270 271 ////////////////////////////////////////////////////////////////////////// 272 // This function initializes the memory chbuf used by the CMA controller, 273 // activates the NIC channel allocated to the calling task, 274 // and activates the two CMA channels. 275 // - tx : RX channel if 0 / TX channel if non 0 276 // - buf0 : first user buffer virtual address 277 // - buf1 : second user buffer virtual address 278 // - length : buffer size (bytes) 279 // In case or error returned by syscall, it makes a giet_exit(). 280 ////////////////////////////////////////////////////////////////////////// 281 extern void giet_nic_cma_start(); 282 283 ////////////////////////////////////////////////////////////////////////// 284 // This function desactivates the NIC channel and the two CMA channels 285 // allocated to the calling task. 286 // In case or error returned by syscall, it makes a giet_exit(). 287 ////////////////////////////////////////////////////////////////////////// 288 extern void giet_nic_cma_stop(); 289 290 ////////////////////////////////////////////////////////////////////////// 291 ////////////////////////////////////////////////////////////////////////// 292 // FAT related system calls 293 ////////////////////////////////////////////////////////////////////////// 294 ////////////////////////////////////////////////////////////////////////// 295 296 ////////////////////////////////////////////////////////////////////////// 297 // Open a file identified by a pathname, and contained in the system FAT. 298 // The read/write flags are not supported yet: no effect. 299 // Return -1 in case or error. 300 ////////////////////////////////////////////////////////////////////////// 168 301 extern int giet_fat_open( const char* pathname, 169 302 unsigned int flags ); 170 303 171 extern int giet_fat_read( unsigned int fd, 172 void* buffer, 173 unsigned int count, 174 unsigned int offset ); 175 176 extern int giet_fat_write( unsigned int fd, 177 void* buffer, 178 unsigned int count, 179 unsigned int offset ); 180 181 extern int giet_fat_lseek( unsigned int fd, 182 unsigned int offset, 183 unsigned int whence ); 184 185 extern int giet_fat_fstat( unsigned int fd ); 186 187 extern int giet_fat_close( unsigned int fd ); 188 189 ////////////////////////////////////////////////////////////////////////// 190 // Miscelaneous system calls 191 ////////////////////////////////////////////////////////////////////////// 192 193 extern int giet_vobj_get_vbase( char* vspace_name, 194 char* vobj_name, 195 unsigned int vobj_type, 196 unsigned int* vobj_vaddr); 197 198 extern int giet_procnumber(); 199 304 /////////////////////////////////////////////////////////////////////////////////// 305 // Read "count" sectors from a file identified by "fd", skipping "offset" 306 // sectors in file, and writing into the user "buffer". 307 // The user buffer base address shoulb be 64 bytes aligned. 308 // In case or error returned by syscall, it makes a giet_exit(). 309 /////////////////////////////////////////////////////////////////////////////////// 310 extern void giet_fat_read( unsigned int fd, 311 void* buffer, 312 unsigned int count, 313 unsigned int offset ); 314 315 /////////////////////////////////////////////////////////////////////////////////// 316 // Write "count" sectors from a file identified by "fd", skipping "offset" 317 // sectors in file, and reading from the user "buffer". 318 // The user buffer base address shoulb be 64 bytes aligned. 319 // In case or error returned by syscall, it makes a giet_exit(). 320 /////////////////////////////////////////////////////////////////////////////////// 321 extern void giet_fat_write( unsigned int fd, 322 void* buffer, 323 unsigned int count, 324 unsigned int offset ); 325 326 /////////////////////////////////////////////////////////////////////////////////// 327 // Change the lseek file pointer value for a file identified by "fd". 328 // In case or error returned by syscall, it makes a giet_exit(). 329 /////////////////////////////////////////////////////////////////////////////////// 330 extern void giet_fat_lseek( unsigned int fd, 331 unsigned int offset, 332 unsigned int whence ); 333 334 /////////////////////////////////////////////////////////////////////////////////// 335 // Returns general informations of a file identified by "fd". 336 // (Only the file_size in sectors for this moment) 337 /////////////////////////////////////////////////////////////////////////////////// 338 extern void giet_fat_fstat( unsigned int fd ); 339 340 ////////////////////////////////////////////////////////////////////////// 341 // Close a file identified by "fd". 342 ////////////////////////////////////////////////////////////////////////// 343 extern void giet_fat_close( unsigned int fd ); 344 345 ////////////////////////////////////////////////////////////////////////// 346 ////////////////////////////////////////////////////////////////////////// 347 // Miscelaneous system calls 348 ////////////////////////////////////////////////////////////////////////// 349 ////////////////////////////////////////////////////////////////////////// 350 351 ////////////////////////////////////////////////////////////////////////// 352 // This function returns the processor identifier. 353 ////////////////////////////////////////////////////////////////////////// 354 extern int giet_procid(); 355 356 ////////////////////////////////////////////////////////////////////////// 357 // This function returns the local processor time. 358 ////////////////////////////////////////////////////////////////////////// 359 extern int giet_proctime(); 360 361 ////////////////////////////////////////////////////////////////////////// 362 // This functions returns the local task id. 363 // If processor has n tasks the local task index is ranging from 0 to n-1 364 ////////////////////////////////////////////////////////////////////////// 365 extern int giet_proc_task_id(); 366 367 ////////////////////////////////////////////////////////////////////////// 368 // This functions returns the global task id, (unique in the system). 369 ////////////////////////////////////////////////////////////////////////// 370 extern int giet_global_task_id(); 371 372 ////////////////////////////////////////////////////////////////////////// 373 // This functions returns the thread index of the task in its vspace. 374 ////////////////////////////////////////////////////////////////////////// 375 extern int giet_thread_id(); 376 377 ////////////////////////////////////////////////////////////////////////// 378 // This function returns a pseudo-random value derived from the processor 379 // cycle count. This value is comprised between 0 & 65535. 380 ///////////////////////////////////////////////////////////////////////// 381 extern int giet_rand(); 382 383 ////////////////////////////////////////////////////////////////////////// 384 // This function stops execution of the calling task with a TTY message, 385 // the user task is descheduled and becomes not runable. 386 // It does not consume processor cycles anymore. 387 ////////////////////////////////////////////////////////////////////////// 200 388 extern void giet_exit(); 201 389 202 extern int giet_context_switch(); 203 204 extern int giet_proc_task_id(); 205 206 extern int giet_heap_info( unsigned int* vaddr, 207 unsigned int* size ); 208 209 extern int giet_global_task_id(); 210 211 extern int giet_thread_id(); 212 390 ////////////////////////////////////////////////////////////////////////// 391 // This function uses the giet_exit() system call 392 // and kill the calling task if the condition is false. 393 ////////////////////////////////////////////////////////////////////////// 213 394 extern void giet_assert( unsigned int, 214 395 char* string ); 215 396 216 extern int giet_rand(); 397 ////////////////////////////////////////////////////////////////////////// 398 // This function writes in argument "vobj_vaddr" the virtual base address 399 // of a vobj (defined in the mapping_info data structure), identified by 400 // the two arguments "vspace_name" and "vobj_name". 401 // In case or error returned by syscall, it makes a giet_exit(). 402 // ( vobj not defined or wrong vspace ) 403 ////////////////////////////////////////////////////////////////////////// 404 extern void giet_vobj_get_vbase( char* vspace_name, 405 char* vobj_name, 406 unsigned int* vobj_vaddr); 407 408 ////////////////////////////////////////////////////////////////////////// 409 // This function returns in the "buffer" argument the number of processors 410 // in the cluster specified by the "cluster_xy" argument. 411 // In case or error returned by syscall, it makes a giet_exit(). 412 ////////////////////////////////////////////////////////////////////////// 413 extern void giet_procnumber( unsigned int cluster_xy, 414 unsigned int buffer ); 415 416 ////////////////////////////////////////////////////////////////////////// 417 // The user task calling this function is descheduled and 418 // the processor is allocated to another task. 419 ////////////////////////////////////////////////////////////////////////// 420 extern void giet_context_switch(); 421 422 ////////////////////////////////////////////////////////////////////////// 423 // This function returns the base address and size of the task's heap 424 ////////////////////////////////////////////////////////////////////////// 425 extern void giet_heap_info( unsigned int* vaddr, 426 unsigned int* size ); 427 217 428 218 429 #endif -
soft/giet_vm/giet_xml/mapping_info.h
r289 r295 30 30 // - mapping_vspace_t vspace[] 31 31 // - mapping_vseg_t vseg[] 32 // - mapping_v seg_t vobj[]32 // - mapping_vobj_t vobj[] 33 33 // - mapping_task_t task[] 34 34 // - mapping_proc_t proc[] … … 61 61 #define U_MODE_MASK 0b0001 // user access 62 62 63 #define IN_MAPPING_SIGNATURE 0xD EADBEEF63 #define IN_MAPPING_SIGNATURE 0xDACE2014 64 64 #define OUT_MAPPING_SIGNATURE 0xBABEF00D 65 65 … … 85 85 { 86 86 IRQ_TYPE_HWI = 0, // HARD in map.xml file 87 IRQ_TYPE_ SWI = 1, // SOFT in map.xml file,87 IRQ_TYPE_WTI = 1, // SOFT in map.xml file, 88 88 IRQ_TYPE_PTI = 2, // TIME in map.xml file, 89 89 }; … … 115 115 PERIPH_TYPE_TTY = 12, 116 116 PERIPH_TYPE_XCU = 13, 117 118 PERIPH_TYPE_MAX_VALUE = 14, 117 PERIPH_TYPE_PIC = 14, 118 119 PERIPH_TYPE_MAX_VALUE = 15, 119 120 }; 120 121 … … 145 146 unsigned int globals; // number of vsegs mapped in all vspaces 146 147 unsigned int vspaces; // number of virtual spaces 147 unsigned int increment; // vseg cluster increment for replicated periphs 148 unsigned int x_io; // x coordinate for cluster_io_ext 149 unsigned int y_io; // y coordinate for cluster_io_ext 148 150 unsigned int irq_per_proc; // number of IRQ per processor 149 150 unsigned int cma_cluster; // index of cluster containing CMA controler 151 unsigned int cma_cluster_bis; // index of cluster containing second CMA controler 152 153 unsigned int fbf_cluster; // index of cluster containing FBF controler 154 unsigned int fbf_cluster_bis; // index of cluster containing second FBF controler 155 156 unsigned int iob_cluster; // index of cluster containing IOB controler 157 unsigned int iob_cluster_bis; // index of cluster containing second IOB controler 158 159 unsigned int ioc_cluster; // index of cluster containing IOC controler 160 unsigned int ioc_cluster_bis; // index of cluster containing second IOC controler 161 162 unsigned int nic_cluster; // index of cluster containing NIC controler 163 unsigned int nic_cluster_bis; // index of cluster containing second NIC controler 164 165 unsigned int rom_cluster; // index of cluster containing ROM controler 166 unsigned int rom_cluster_bis; // index of cluster containing second ROM controler 167 168 unsigned int sim_cluster; // index of cluster containing SIM controler 169 unsigned int sim_cluster_bis; // index of cluster containing second SIM controler 170 171 unsigned int tty_cluster; // index of cluster containing TTY controler 172 unsigned int tty_cluster_bis; // index of cluster containing second TTY controler 151 unsigned int use_ramdisk; // does not use IOC peripheral if non zero 152 unsigned int increment; // vbase address increment (replicated peripherals) 173 153 174 154 unsigned int psegs; // total number of physical segments (for all clusters) … … 286 266 typedef struct __attribute__((packed)) mapping_proc_s 287 267 { 288 unsigned int irqs; // number of IRQs allocated to processor 289 unsigned int irq_offset; // index of first IRQ allocated to processor 268 unsigned int index; // processor local index (in cluster) 290 269 } mapping_proc_t; 291 292 293 /////////////////////////////////////////////////////294 typedef struct __attribute__((packed)) mapping_irq_s295 {296 unsigned int type; // HWI / SWI / PTI297 unsigned int icuid; // IRQ Index for the ICU component298 unsigned int isr; // ISR Index (defined in irq_handler.h)299 unsigned int channel; // Channel Index (for multi-channels peripherals)300 } mapping_irq_t;301 270 302 271 … … 323 292 typedef struct __attribute__((packed)) mapping_periph_s 324 293 { 325 unsigned int type; 294 unsigned int type; // legal values defined above 326 295 unsigned int subtype; // periph specialization 327 296 unsigned int psegid; // pseg index in cluster 328 297 unsigned int channels; // number of channels 298 unsigned int irqs; // number of input IRQs (for ICU, XCU or PIC) 299 unsigned int irq_offset; // index of first IRQ (can be HWI/PTI/WTI) 329 300 } mapping_periph_t; 301 302 303 ///////////////////////////////////////////////////// 304 typedef struct __attribute__((packed)) mapping_irq_s 305 { 306 unsigned int srctype; // source IRQ type (HWI / WTI / PTI) 307 unsigned int srcid; // source IRQ index (for ICU/PIC component) 308 unsigned int isr; // ISR type (defined in irq_handler.h) 309 unsigned int channel; // channel index (for multi-channels peripherals) 310 unsigned int dstx; // x coordinate of destination cluster 311 unsigned int dsty; // y coordinate of destination cluster 312 unsigned int dstid; // destination IRQ index (can be PROC or ICU) 313 } mapping_irq_t; 330 314 331 315 -
soft/giet_vm/giet_xml/xml_driver.c
r289 r295 18 18 19 19 ////////////////////////////////////////////////////// 20 void buildXml(mapping_header_t * header, FILE * fpout) { 20 void buildXml(mapping_header_t * header, FILE * fpout) 21 { 22 // mnemonics defined in mapping_info.h 21 23 const char * vobj_type[] = 22 24 { … … 27 29 "MWMR", // MWMR channel 28 30 "LOCK", // Spin-Lock 29 "BUFFER", // Any "no intialiasation needed" object s(stacks...)31 "BUFFER", // Any "no intialiasation needed" object (stacks...) 30 32 "BARRIER", // Barrier 31 33 "CONST", // Constant … … 34 36 }; 35 37 38 // mnemonics defined in mapping_info.h 36 39 const char * pseg_type[] = 37 40 { 38 41 "RAM", 39 "ROM", 42 "ROM", // deprecated => use PERI 40 43 "PERI", 41 44 }; 42 45 46 // mnemonics defined in mapping_info.h 43 47 const char * irq_type[] = 44 48 { 45 "HARD", 46 "SOFT", 47 "TIME", 48 }; 49 49 "HWI", 50 "WTI", 51 "PTI", 52 }; 53 54 // mnemonics defined in irq_handler.h 50 55 const char * isr_type[] = 51 56 { 52 "ISR_DEFAULT", 53 "ISR_ SWITCH",54 "ISR_TTY ",55 "ISR_ DMA",56 "ISR_ IOC",57 "ISR_DEFAULT", 58 "ISR_TICK", 59 "ISR_TTY_RX", 60 "ISR_TTY_TX", 61 "ISR_BDV", 57 62 "ISR_TIMER", 58 }; 59 63 "ISR_WAKUP", 64 "ISR_NIC_RX", 65 "ISR_NIC_TX", 66 "ISR_CMA", 67 }; 68 69 // mnemonics defined in mapping_info.h 60 70 const char * periph_type[] = 61 71 { … … 74 84 "TTY", 75 85 "XCU", 76 }; 77 78 const char * periph_subtype[] = 86 "PIC", 87 }; 88 89 const char * ioc_subtype[] = 79 90 { 80 91 "BDV", … … 242 253 fprintf(fpout, " x_width = \"%d\" \n" , header->x_width); 243 254 fprintf(fpout, " y_width = \"%d\" \n" , header->y_width); 244 fprintf(fpout, " vspaces = \"%d\" \n" , header->vspaces); 245 fprintf(fpout, " increment = \"%d\" \n" , header->vspaces); 246 fprintf(fpout, " irq_per_proc = \"%d\" >\n\n", header->irq_per_proc); 255 fprintf(fpout, " irq_per_proc = \"%d\" \n" , header->irq_per_proc); 256 fprintf(fpout, " use_ramdisk = \"%d\" \n" , header->use_ramdisk); 257 fprintf(fpout, " x_io = \"%d\" \n" , header->x_io); 258 fprintf(fpout, " y_io = \"%d\" >\n\n", header->y_io); 247 259 248 260 ///////////////////// clusters /////////////////////////////////////////////// … … 271 283 for (proc_id = cluster[cluster_id].proc_offset; 272 284 proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs; 273 proc_id++) 274 { 275 fprintf(fpout, " <proc index = \"%d\" >\n", proc_index); 276 for (irq_id = proc[proc_id].irq_offset; 277 irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs; 278 irq_id++) 279 { 280 fprintf(fpout, " <irq type = \"%s\" ", irq_type[irq[irq_id].type]); 281 fprintf(fpout, " icuid = \"0x%x\" ", irq[irq_id].icuid); 282 fprintf(fpout, " isr = \"%s\" ", isr_type[irq[irq_id].isr]); 283 fprintf(fpout, " channel = \"0x%x\" />\n", irq[irq_id].channel); 284 } 285 fprintf(fpout, " </proc>\n" ); 286 } 287 285 proc_id++, proc_index++) 286 { 287 fprintf(fpout, " <proc index = \"%d\" />\n", proc_index); 288 } 288 289 289 290 ///////////////////// coprocessors /////////////////////////////////////////// … … 316 317 317 318 if (periph[periph_id].subtype < PERIPH_SUBTYPE_MAX_VALUE) 318 fprintf(fpout, " subtype = \"%s\" ", periph_subtype[periph[periph_id].subtype]);319 fprintf(fpout, " subtype = \"%s\" ", ioc_subtype[periph[periph_id].subtype]); 319 320 320 321 fprintf(fpout, " psegname = \"%s\" ", pseg[periph[periph_id].psegid].name); 321 fprintf(fpout, " channels = \"%d\" />\n", periph[periph_id].channels); 322 fprintf(fpout, " channels = \"%d\" >\n", periph[periph_id].channels); 323 for (irq_id = periph[periph_id].irq_offset; 324 irq_id < periph[periph_id].irq_offset + periph[periph_id].irqs; 325 irq_id++) 326 { 327 fprintf(fpout, " <irq srctype = \"%s\" ", irq_type[irq[irq_id].srctype]); 328 fprintf(fpout, " srcid = \"%d\" ", irq[irq_id].srcid); 329 fprintf(fpout, " isr = \"%s\" ", isr_type[irq[irq_id].isr]); 330 fprintf(fpout, " channel = \"%d\" ", irq[irq_id].channel); 331 fprintf(fpout, " dstx = \"%d\" ", irq[irq_id].dstx); 332 fprintf(fpout, " dsty = \"%d\" ", irq[irq_id].dsty); 333 fprintf(fpout, " dstid = \"%d\" />\n", irq[irq_id].dstid); 334 } 335 fprintf(fpout, " </periph>\n"); 322 336 } 323 337 fprintf(fpout, " </cluster>\n" ); -
soft/giet_vm/giet_xml/xml_parser.c
r289 r295 104 104 char found_mmc = 0; 105 105 106 107 //////////////////////////////////////////////////////////////////// 108 // These variables are used to generate the hard_config.h file 109 //////////////////////////////////////////////////////////////////// 110 111 unsigned int nb_proc_max = 0; // max number of processors per cluster 106 //////////////////////////////////////////////////////////////////////// 107 // These variables are used to generate the hard_config.h file. 108 //////////////////////////////////////////////////////////////////////// 109 110 unsigned int nb_procs_max = 0; // max number of processors per cluster 112 111 unsigned int nb_tasks_max = 0; // max number of tasks (in all vspaces) 113 112 114 unsigned int tim_channels = 0; // max number of user timers(per cluster)115 unsigned int dma_channels = 0; // maxnumber of DMA channels (per cluster)116 117 unsigned int icu_channels = 0; // total number of channels in ICU/XICU118 unsigned int tty_channels = 0; // total number of terminals in TTY119 unsigned int hba_channels = 0; // total number of channels in HBA120 unsigned int nic_channels = 0; // total number of channels in NIC121 unsigned int cma_channels = 0; // total number of channels in CMA113 unsigned int tim_channels = 0; // number of user timers (per cluster) 114 unsigned int dma_channels = 0; // number of DMA channels (per cluster) 115 116 unsigned int tty_channels = 0; // number of TTY channels 117 unsigned int ioc_channels = 0; // number of HBA channels 118 unsigned int nic_channels = 0; // number of NIC channels 119 unsigned int cma_channels = 0; // number of CMA channels 120 unsigned int pic_channels = 0; // number of PIC channels 122 121 123 122 unsigned int use_iob = 0; // using IOB component 123 unsigned int use_pic = 0; // using PIC component 124 124 unsigned int use_xcu = 0; // using XCU (not ICU) 125 125 126 126 // These variables define the IOC peripheral subtype 127 unsigned int use_hba = 0; // using HBA 128 unsigned int use_bdv = 0; // using SoCLIB block device 129 unsigned int use_spi = 0; // using SD Card-SPI 127 128 unsigned int use_hba = 0; // using SoClib AHCI controller 129 unsigned int use_bdv = 0; // using SoCLIB block device controller 130 unsigned int use_spi = 0; // using SDCard-SPI 130 131 131 132 //////////////////////////////////////////////////////////////// … … 283 284 284 285 /////////////////////////////////////////////////////////////////////////////////// 285 // This function set the vbase address for all peripheral types. 286 // For replicated peripherals with the same type the virtual base address must be: 287 // vbase = seg_type_base & 0XFF000000 + 288 // (cluster_id * vbase_cluster_increment) & 0x00FF0000 286 // This function set the vbase addresses for all peripheral types, in order 287 // to generate the ldscript file, that contains one single virtual address 288 // for peripherals replicated in all clusters, and one virtual addresses for 289 // each non replicated peripheral type. 290 // 291 // It makes the following checks on the virtual addresses: 292 // 293 // - For replicated peripherals the virtual base address must be: 294 // vbase = seg_type_base & 0XFF000000 + (cluster_xy * increment) & 0x00FF0000 295 // 296 // - For non-replicated peripherals, the cluster index must be cluster_io. 289 297 /////////////////////////////////////////////////////////////////////////////////// 290 298 void set_periph_vbase_array() … … 300 308 unsigned int cluster_mask = 0x00FF0000; 301 309 302 // We are analysing all vsegs corresponding to a peripheral 310 #if XML_PARSER_DEBUG 311 printf("\n set peripherals vbase array\n"); 312 #endif 303 313 304 314 // scan all vsegs … … 308 318 if ( vobj[vseg[vseg_id]->vobj_offset]->type == VOBJ_TYPE_PERI ) 309 319 { 310 pseg_id = vseg[vseg_id]->psegid; 320 pseg_id = vseg[vseg_id]->psegid; 321 322 #if XML_PARSER_DEBUG 323 printf(" - found vseg %s with psegid = %d", vseg[vseg_id]->name, pseg_id ); 324 #endif 311 325 312 326 // scan all periphs to retrieve peripheral type (same psegid) … … 315 329 if( periph[periph_id]->psegid == pseg_id ) // matching !!! 316 330 { 317 type = periph[periph_id]->type; 318 if ( periph_vbase_array[type] == 0xFFFFFFFF ) // vbase not set 331 cluster_id = pseg[pseg_id]->clusterid; 332 type = periph[periph_id]->type; 333 334 #if XML_PARSER_DEBUG 335 printf(" / matching periph type %d\n", type ); 336 #endif 337 338 if ( (type == PERIPH_TYPE_DMA) || 339 (type == PERIPH_TYPE_MMC) || 340 (type == PERIPH_TYPE_ICU) || 341 (type == PERIPH_TYPE_XCU) || 342 (type == PERIPH_TYPE_TIM) ) // replicated peripheral 319 343 { 320 periph_vbase_array[type] = vseg[vseg_id]->vbase & type_mask; 321 } 322 else // vbase already set 323 { 324 // checking mask bits 325 if( (vseg[vseg_id]->vbase & type_mask) != 326 (periph_vbase_array[type]) ) 344 cluster_xy = (cluster[cluster_id]->x << header->y_width) + 345 cluster[cluster_id]->y; 346 347 if( (vseg[vseg_id]->vbase & cluster_mask) != 348 (header->increment * cluster_xy) ) 327 349 { 328 printf("[XML ERROR] All peripherals with same type "); 329 printf(" should share the same 8 MSB bits in base address\n"); 350 printf("[XML ERROR] All replicated peripherals " 351 "must have cluster bits = cluster_xy * increment\n"); 352 printf("periph index = %d / periph type = %d / vbase = %x\n", 353 periph_id, type, vseg[vseg_id]->vbase); 354 exit(1); 355 } 356 else if ( periph_vbase_array[type] == 0xFFFFFFFF ) // vbase not set 357 { 358 periph_vbase_array[type] = vseg[vseg_id]->vbase & type_mask; 359 } 360 else if ((vseg[vseg_id]->vbase & type_mask) != (periph_vbase_array[type])) 361 { 362 printf("[XML ERROR] All peripherals with same type" 363 " should share the same 8 MSB bits in vbase address\n"); 330 364 printf("periph index = %d / periph type = %d / vbase = %x\n", 331 365 periph_id, type, vseg[vseg_id]->vbase); … … 333 367 } 334 368 } 335 336 // checking cluster bits for all replicated peripherals 337 if ( (type == PERIPH_TYPE_DMA) || 338 (type == PERIPH_TYPE_MMC) || 339 (type == PERIPH_TYPE_ICU) || 340 (type == PERIPH_TYPE_XCU) || 341 (type == PERIPH_TYPE_TIM) ) 369 else // non replicated peripheral 342 370 { 343 cluster_id = pseg[pseg_id]->clusterid; 344 cluster_xy = (cluster[cluster_id]->x << header->y_width) + 345 cluster[cluster_id]->y; 346 347 if( (vseg[vseg_id]->vbase & cluster_mask) != 348 (header->increment * cluster_xy) ) 371 if ( (cluster[cluster_id]->x == header->x_io) && 372 (cluster[cluster_id]->y == header->y_io) ) 349 373 { 350 printf("[XML ERROR] All replicated peripherals "); 351 printf("must have cluster bits = cluster_id * increment"); 352 printf("periph index = %d / periph type = %d / vbase = %x\n", 353 periph_id, type, vseg[vseg_id]->vbase); 374 periph_vbase_array[type] = vseg[vseg_id]->vbase; 375 } 376 else 377 { 378 printf("[XML ERROR] Non replicated peripherals must be in cluster_io\n"); 379 printf(" periph index = %d / periph type = %d / vbase = %x" 380 " / pseg index = %d / cluster index = %d\n", 381 periph_id, type, vseg[vseg_id]->vbase, pseg_id, cluster_id); 354 382 exit(1); 355 383 } 356 } 384 } 357 385 } 358 386 } … … 428 456 } 429 457 458 /////////////////////////////////////////////////////////// 459 unsigned int alignTo( unsigned int value, unsigned int pow2 ) 460 { 461 unsigned int mask = (1 << pow2) - 1; 462 return ( (value + mask) & ~mask); 463 } 464 465 //////////////////// 466 void setVsegLength() 467 { 468 // for a given vseg identified vseg_index 469 // scan all contained vobjs to compute the vseg lenth 470 471 unsigned int vobj_id; 472 unsigned int cur_length = 0; 473 474 unsigned int first = vseg[vseg_index]->vobj_offset; 475 unsigned int last = first + vseg[vseg_index]->vobjs; 476 477 for ( vobj_id = first ; vobj_id < last ; vobj_id++ ) 478 { 479 if (vobj[vobj_id]->align) 480 { 481 cur_length = alignTo( cur_length, vobj[vobj_id]->align ); 482 } 483 cur_length += vobj[vobj_id]->length; 484 } 485 vseg[vseg_index]->length = alignTo( cur_length, 12 ); 486 } 487 488 /////////////////////// 489 void checkVsegOverlap() 490 { 491 // for a given vseg identified by vseg_index, 492 // check overlap with all vsegs in same vspace, 493 // and check overlap with all global vsegs. 494 495 unsigned int vseg_id; 496 unsigned int prev_vbase; // previous vseg vbase 497 unsigned int prev_length; // previous vseg length 498 499 unsigned int vbase = vseg[vseg_index]->vbase; // new vseg vbase 500 unsigned int length = vseg[vseg_index]->length; // new vseg length 501 502 // checking overlap with other vsegs in same vspace 503 if ( header->vspaces > 0 ) 504 { 505 unsigned int first = vspace[vspace_index]->vseg_offset; 506 unsigned int last = vseg_index; 507 508 for( vseg_id = first ; vseg_id < last ; vseg_id++ ) 509 { 510 prev_vbase = vseg[vseg_id]->vbase; 511 prev_length = vseg[vseg_id]->length; 512 if ( ((vbase + length) > prev_vbase) && ((prev_vbase + prev_length) > vbase) ) 513 { 514 printf("[XML ERROR] vseg %s in vspace %s overlaps other vseg %s\n", 515 vseg[vseg_index]->name, vspace[vspace_index]->name, vseg[vseg_id]->name ); 516 exit(1); 517 } 518 } 519 } 520 521 // checking overlap with existing global vsegs 522 for ( vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ ) 523 { 524 prev_vbase = vseg[vseg_id]->vbase; 525 prev_length = vseg[vseg_id]->length; 526 if ( ((vbase + length) > prev_vbase) && ((prev_vbase + prev_length) > vbase) ) 527 { 528 printf("[XML ERROR] vseg %s in vspace %s overlaps global vseg %s\n", 529 vseg[vseg_index]->name, vspace[vspace_index]->name, vseg[vseg_id]->name ); 530 exit(1); 531 } 532 } 533 } 534 430 535 ////////////////////////////////////// 431 536 void taskNode(xmlTextReaderPtr reader) … … 466 571 } 467 572 468 ///////// get x coordinate573 ///////// get trdid attribute (optional) 469 574 task[task_index]->trdid = getIntValue(reader, "trdid", &ok); 470 575 #if XML_PARSER_DEBUG 471 printf(" x= %d\n", x);576 printf(" trdid = %d\n", x); 472 577 #endif 473 578 if ( !ok ) 474 579 { 475 580 task[task_index]->trdid = task_loc_index; 476 printf("[XML WARNING] missing trdid (thread index) attribute "477 "for task in vspace %d. Using value %d\n"478 , vspace_index, task_loc_index);479 581 } 480 582 … … 720 822 ////////// get length attribute 721 823 value = getIntValue(reader, "length", &ok); 722 if (ok) { 723 #if XML_PARSER_DEBUG 724 printf(" length = %d\n", value); 824 if (ok) 825 { 826 #if XML_PARSER_DEBUG 827 printf(" length = %x\n", value); 725 828 #endif 726 829 vobj[vobj_index]->length = value; … … 734 837 ////////// get align attribute (optional : 0 if missing) 735 838 value = getIntValue(reader, "align", &ok); 736 if (ok) { 839 if (ok) 840 { 737 841 #if XML_PARSER_DEBUG 738 842 printf(" align = %d\n", value); … … 740 844 vobj[vobj_index]->align = value; 741 845 } 742 else { 846 else 847 { 743 848 vobj[vobj_index]->align = 0; 744 849 } … … 746 851 ////////// get binpath attribute (optional : '\0' if missing) 747 852 str = getStringValue(reader, "binpath", &ok); 748 if (ok) { 853 if (ok) 854 { 749 855 #if XML_PARSER_DEBUG 750 856 printf(" binpath = %s\n", str); … … 958 1064 { 959 1065 vseg[vseg_index]->vobjs = vobj_count; 1066 setVsegLength(); 1067 checkVsegOverlap(); 960 1068 vseg_index++; 961 1069 vseg_loc_index++; … … 984 1092 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return; 985 1093 986 // checking source file consistency987 if (vspace_index >= header->vspaces) {988 printf("[XML ERROR] The vspace index is too large : %d\n",989 vspace_index);990 exit(1);991 }992 993 1094 #if XML_PARSER_DEBUG 994 1095 printf("\n vspace %d\n", vspace_index); … … 996 1097 997 1098 vspace[vspace_index] = (mapping_vspace_t *) malloc(sizeof(mapping_vspace_t)); 1099 header->vspaces = header->vspaces + 1; 998 1100 999 1101 ////////// get name attribute … … 1036 1138 1037 1139 int status = xmlTextReaderRead(reader); 1038 while (status == 1) { 1140 while (status == 1) 1141 { 1039 1142 const char * tag = (const char *) xmlTextReaderConstName(reader); 1040 1143 … … 1050 1153 else if (strcmp(tag, "#text") == 0) { } 1051 1154 else if (strcmp(tag, "#comment") == 0) { } 1052 else if (strcmp(tag, "vspace") == 0) { 1155 else if (strcmp(tag, "vspace") == 0) 1156 { 1053 1157 vspace[vspace_index]->vobjs = vobj_loc_index; 1054 1158 vspace[vspace_index]->tasks = task_loc_index ; … … 1099 1203 } // end vspaceNode() 1100 1204 1205 ///////////////////////////////////// 1206 void irqNode(xmlTextReaderPtr reader) 1207 { 1208 unsigned int ok; 1209 unsigned int value; 1210 char * str; 1211 1212 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return; 1213 1214 if (irq_index >= MAX_IRQS) 1215 { 1216 printf("[XML ERROR] The number of irqs is larger than %d\n", MAX_IRQS); 1217 } 1218 1219 #if XML_PARSER_DEBUG 1220 printf(" irq %d\n", irq_loc_index); 1221 #endif 1222 1223 irq[irq_index] = (mapping_irq_t *) malloc(sizeof(mapping_irq_t)); 1224 1225 ///////// get srctype attribute 1226 str = getStringValue(reader, "srctype", &ok); 1227 if (ok) 1228 { 1229 #if XML_PARSER_DEBUG 1230 printf(" srctype = %s\n", str); 1231 #endif 1232 if ( strcmp(str, "HWI") == 0 ) irq[irq_index]->srctype = IRQ_TYPE_HWI; 1233 else if ( strcmp(str, "WTI") == 0 ) irq[irq_index]->srctype = IRQ_TYPE_WTI; 1234 else if ( strcmp(str, "PTI") == 0 ) irq[irq_index]->srctype = IRQ_TYPE_PTI; 1235 else 1236 { 1237 printf("[XML ERROR] illegal IRQ <srctype> for periph %d in cluster %d\n", 1238 cluster_index, periph_loc_index); 1239 exit(1); 1240 } 1241 } 1242 else 1243 { 1244 printf("[XML ERROR] missing IRQ <srctype> for periph %d in cluster %d\n", 1245 cluster_index, periph_loc_index); 1246 exit(1); 1247 } 1248 1249 ///////// get srcid attribute 1250 value = getIntValue(reader, "srcid", &ok); 1251 if (ok) 1252 { 1253 #if XML_PARSER_DEBUG 1254 printf(" srcid = %d\n", value); 1255 #endif 1256 irq[irq_index]->srcid = value; 1257 if (value >= 32) 1258 { 1259 printf("[XML ERROR] IRQ <srcid> too large for periph %d in cluster %d\n", 1260 cluster_index, periph_loc_index); 1261 exit(1); 1262 } 1263 } 1264 else 1265 { 1266 printf("[XML ERROR] missing IRQ <icuid> for periph %d in cluster %d\n", 1267 cluster_index, periph_loc_index); 1268 exit(1); 1269 } 1270 1271 ///////// get isr attribute 1272 str = getStringValue(reader, "isr", &ok); 1273 if (ok) 1274 { 1275 #if XML_PARSER_DEBUG 1276 printf(" isr = %s\n", str); 1277 #endif 1278 if (strcmp(str, "ISR_TICK" ) == 0) irq[irq_index]->isr = ISR_TICK; 1279 else if (strcmp(str, "ISR_BDV" ) == 0) irq[irq_index]->isr = ISR_BDV; 1280 else if (strcmp(str, "ISR_CMA" ) == 0) irq[irq_index]->isr = ISR_CMA; 1281 else if (strcmp(str, "ISR_TTY_RX" ) == 0) irq[irq_index]->isr = ISR_TTY_RX; 1282 else if (strcmp(str, "ISR_TTY_TX" ) == 0) irq[irq_index]->isr = ISR_TTY_TX; 1283 else if (strcmp(str, "ISR_TIMER" ) == 0) irq[irq_index]->isr = ISR_TIMER; 1284 else if (strcmp(str, "ISR_WAKUP" ) == 0) irq[irq_index]->isr = ISR_WAKUP; 1285 else if (strcmp(str, "ISR_NIC_RX" ) == 0) irq[irq_index]->isr = ISR_NIC_RX; 1286 else if (strcmp(str, "ISR_NIC_TX" ) == 0) irq[irq_index]->isr = ISR_NIC_TX; 1287 else if (strcmp(str, "ISR_DEFAULT") == 0) irq[irq_index]->isr = ISR_DEFAULT; 1288 else 1289 { 1290 printf("[XML ERROR] illegal IRQ <isr> for periph %d in cluster %d\n", 1291 cluster_index, periph_loc_index); 1292 exit(1); 1293 } 1294 } 1295 else 1296 { 1297 printf("[XML ERROR] missing IRQ <isr> for periph %d in cluster %d\n", 1298 cluster_index, periph_loc_index); 1299 exit(1); 1300 } 1301 1302 ///////// get channel attribute (optionnal : 0 if missing) 1303 value = getIntValue(reader, "channel", &ok); 1304 if (ok) 1305 { 1306 #if XML_PARSER_DEBUG 1307 printf(" channel = %d\n", value); 1308 #endif 1309 irq[irq_index]->channel = value; 1310 } 1311 else 1312 { 1313 irq[irq_index]->channel = 0; 1314 } 1315 1316 ///////// get dstx attribute 1317 value = getIntValue(reader, "dstx", &ok); 1318 if (ok) 1319 { 1320 #if XML_PARSER_DEBUG 1321 printf(" dstx = %d\n", value); 1322 #endif 1323 1324 if ( value < header->x_size ) 1325 { 1326 irq[irq_index]->dstx = value; 1327 } 1328 else 1329 { 1330 printf("[XML ERROR] IRQ <dstx> too large for periph %d in cluster %d\n", 1331 cluster_index, periph_loc_index); 1332 exit(1); 1333 } 1334 } 1335 else 1336 { 1337 printf("[XML ERROR] missing IRQ <dstx> for periph %d in cluster %d\n", 1338 cluster_index, periph_loc_index); 1339 exit(1); 1340 } 1341 1342 ///////// get dsty attribute 1343 value = getIntValue(reader, "dsty", &ok); 1344 if (ok) 1345 { 1346 #if XML_PARSER_DEBUG 1347 printf(" dsty = %d\n", value); 1348 #endif 1349 1350 if ( value < header->y_size ) 1351 { 1352 irq[irq_index]->dsty = value; 1353 } 1354 else 1355 { 1356 printf("[XML ERROR] IRQ <dsty> too large for periph %d in cluster %d\n", 1357 cluster_index, periph_loc_index); 1358 exit(1); 1359 } 1360 } 1361 else 1362 { 1363 printf("[XML ERROR] missing IRQ <dsty> for periph %d in cluster %d\n", 1364 cluster_index, periph_loc_index); 1365 exit(1); 1366 } 1367 1368 ///////// get dstid attribute 1369 value = getIntValue(reader, "dstid", &ok); 1370 if (ok) 1371 { 1372 #if XML_PARSER_DEBUG 1373 printf(" dstid = %d\n", value); 1374 #endif 1375 irq[irq_index]->dstid = value; 1376 if (value >= 32) 1377 { 1378 printf("[XML ERROR] IRQ <dstid> too large for periph %d in cluster %d\n", 1379 cluster_index, periph_loc_index); 1380 exit(1); 1381 } 1382 } 1383 else 1384 { 1385 printf("[XML ERROR] missing IRQ <dstid> for periph %d in cluster %d\n", 1386 cluster_index, periph_loc_index); 1387 exit(1); 1388 } 1389 1390 irq_index++; 1391 irq_loc_index++; 1392 1393 } // end irqNode 1394 1395 1396 1101 1397 //////////////////////////////////////// 1102 1398 void cpPortNode(xmlTextReaderPtr reader) … … 1115 1411 1116 1412 #if XML_PARSER_DEBUG 1117 1413 printf("\n port %d\n", cp_port_index); 1118 1414 #endif 1119 1415 … … 1126 1422 { 1127 1423 #if XML_PARSER_DEBUG 1128 1424 printf(" direction = %s\n", str); 1129 1425 #endif 1130 1426 if (strcmp(str, "TO_COPROC") == 0) … … 1153 1449 str = getStringValue(reader, "vspacename", &ok); 1154 1450 #if XML_PARSER_DEBUG 1155 1451 printf(" vspacename = %s\n", str); 1156 1452 #endif 1157 1453 if (ok) … … 1169 1465 str = getStringValue(reader, "vobjname", &ok); 1170 1466 #if XML_PARSER_DEBUG 1171 1467 printf(" vobjname = %s\n", str); 1172 1468 #endif 1173 1469 if (ok) … … 1192 1488 unsigned int ok; 1193 1489 1490 irq_loc_index = 0; 1491 1194 1492 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return; 1195 1493 … … 1201 1499 1202 1500 #if XML_PARSER_DEBUG 1203 printf("\nperiph %d\n", periph_index);1501 printf("\n periph %d\n", periph_index); 1204 1502 #endif 1205 1503 … … 1211 1509 { 1212 1510 #if XML_PARSER_DEBUG 1213 printf(" channels= %d\n", value);1511 printf(" channels = %d\n", value); 1214 1512 #endif 1215 1513 periph[periph_index]->channels = value; … … 1234 1532 { 1235 1533 #if XML_PARSER_DEBUG 1236 printf(" clusterid= %d\n", cluster_index);1237 printf(" psegname= %s\n", str);1238 printf(" psegid= %d\n", index);1534 printf(" clusterid = %d\n", cluster_index); 1535 printf(" psegname = %s\n", str); 1536 printf(" psegid = %d\n", index); 1239 1537 #endif 1240 1538 periph[periph_index]->psegid = index; … … 1252 1550 { 1253 1551 #if XML_PARSER_DEBUG 1254 printf(" type= %s\n", str);1552 printf(" type = %s\n", str); 1255 1553 #endif 1256 1554 unsigned int error = 0; … … 1260 1558 1261 1559 // The CMA, FBF, HBA, IOB, IOC, NIC, ROM, SIM, TTY, peripherals are not 1262 // replicated in all clusters but can be replicated in two clusters (fault tolerance) 1263 // In case of replication, the two copies must have same number of channels. 1560 // replicated in all clusters but can be instanciated twice. 1264 1561 1265 1562 //////////////////////////// … … 1267 1564 { 1268 1565 periph[periph_index]->type = PERIPH_TYPE_CMA; 1269 if ( header->cma_cluster == 0xFFFFFFFF)1566 if ( cma_channels < periph[periph_index]->channels ) 1270 1567 { 1271 header->cma_cluster = cluster_index;1272 1568 cma_channels = periph[periph_index]->channels; 1273 1569 } 1274 else if (header->cma_cluster_bis == 0xFFFFFFFF)1275 {1276 header->cma_cluster_bis = cluster_index;1277 assert( (cma_channels == periph[periph_index]->channels) &&1278 "[XML ERROR] unconsistent non replicated peripheral");1279 }1280 else1281 {1282 error = 1;1283 }1284 1570 } 1285 1571 ///////////////////////////////// … … 1287 1573 { 1288 1574 periph[periph_index]->type = PERIPH_TYPE_FBF; 1289 if (header->fbf_cluster == 0xFFFFFFFF)1290 {1291 header->fbf_cluster = cluster_index;1292 }1293 else if (header->fbf_cluster_bis == 0xFFFFFFFF)1294 {1295 header->fbf_cluster_bis = cluster_index;1296 }1297 else1298 {1299 error = 1;1300 }1301 1575 } 1302 1576 ///////////////////////////////// … … 1305 1579 periph[periph_index]->type = PERIPH_TYPE_IOB; 1306 1580 use_iob = 1; 1307 if (header->iob_cluster == 0xFFFFFFFF)1308 {1309 header->iob_cluster = cluster_index;1310 }1311 else if (header->iob_cluster_bis == 0xFFFFFFFF)1312 {1313 header->iob_cluster_bis = cluster_index;1314 }1315 else1316 {1317 error = 1;1318 }1319 1581 } 1320 1582 ///////////////////////////////// 1321 1583 else if (strcmp(str, "IOC") == 0) 1322 1584 { 1323 periph[periph_index]->type = PERIPH_TYPE_IOC; 1324 if (header->ioc_cluster == 0xFFFFFFFF) 1325 { 1326 header->ioc_cluster = cluster_index; 1327 } 1328 else if (header->ioc_cluster_bis == 0xFFFFFFFF) 1329 { 1330 header->ioc_cluster_bis = cluster_index; 1331 } 1332 else 1333 { 1334 printf("[XML ERROR] At most two copies for non replicated " 1335 "peripheral\n"); 1336 exit(1); 1337 } 1338 1339 str = getStringValue(reader, "subtype", &ok); 1340 1585 char* subtype = getStringValue(reader, "subtype", &ok); 1341 1586 if (!ok) 1342 1587 { 1343 printf("[XML ERROR] IOC peripheral needs a subtype parameter: " 1344 "BDV, HBA or SPI\n"); 1588 printf("[XML ERROR] IOC peripheral needs a subtype: BDV, HBA or SPI\n"); 1345 1589 exit(1); 1346 1590 } 1347 1591 1348 if (strcmp(str, "BDV") == 0) 1349 { 1592 if ( strcmp(subtype, "BDV") == 0 ) 1593 { 1594 periph[periph_index]->type = PERIPH_TYPE_IOC; 1350 1595 periph[periph_index]->subtype = PERIPH_SUBTYPE_BDV; 1351 use_bdv = 1; 1596 ioc_channels = 1; 1597 if ( header->use_ramdisk == 0 ) use_bdv = 1; 1352 1598 } 1353 else if ( strcmp(str, "HBA") == 0)1599 else if ( strcmp(subtype, "HBA") == 0 ) 1354 1600 { 1601 periph[periph_index]->type = PERIPH_TYPE_IOC; 1355 1602 periph[periph_index]->subtype = PERIPH_SUBTYPE_HBA; 1356 1357 if (use_hba == 0) 1358 { 1359 use_hba = 1; 1360 hba_channels = periph[periph_index]->channels; 1361 } 1362 else 1363 { 1364 assert( (hba_channels == periph[periph_index]->channels) && 1365 "[XML ERROR] unconsistent non replicated peripheral"); 1366 } 1603 ioc_channels = periph[periph_index]->channels; 1604 if ( header->use_ramdisk == 0 ) use_hba = 1; 1367 1605 } 1368 else if ( strcmp(str, "SPI") == 0)1606 else if ( strcmp(subtype, "SPI") == 0 ) 1369 1607 { 1608 periph[periph_index]->type = PERIPH_TYPE_IOC; 1370 1609 periph[periph_index]->subtype = PERIPH_SUBTYPE_SPI; 1371 use_spi = 1; 1610 ioc_channels = periph[periph_index]->channels; 1611 if ( header->use_ramdisk == 0 ) use_spi = 1; 1372 1612 } 1373 1613 else … … 1381 1621 { 1382 1622 periph[periph_index]->type = PERIPH_TYPE_NIC; 1383 if ( header->nic_cluster == 0xFFFFFFFF)1623 if ( nic_channels < periph[periph_index]->channels ) 1384 1624 { 1385 header->nic_cluster = cluster_index;1386 1625 nic_channels = periph[periph_index]->channels; 1387 1626 } 1388 else if (header->nic_cluster_bis == 0xFFFFFFFF)1389 {1390 header->nic_cluster_bis = cluster_index;1391 assert( (nic_channels == periph[periph_index]->channels) &&1392 "[XML ERROR] unconsistent non replicated peripheral");1393 }1394 else1395 {1396 error = 1;1397 }1398 1627 } 1399 1628 ///////////////////////////////// … … 1401 1630 { 1402 1631 periph[periph_index]->type = PERIPH_TYPE_ROM; 1403 if (header->rom_cluster == 0xFFFFFFFF)1404 {1405 header->rom_cluster = cluster_index;1406 }1407 else if (header->rom_cluster_bis == 0xFFFFFFFF)1408 {1409 header->rom_cluster_bis = cluster_index;1410 }1411 else1412 {1413 error = 1;1414 }1415 1632 } 1416 1633 ///////////////////////////////// … … 1418 1635 { 1419 1636 periph[periph_index]->type = PERIPH_TYPE_SIM; 1420 if (header->sim_cluster == 0xFFFFFFFF)1421 {1422 header->sim_cluster = cluster_index;1423 }1424 else if (header->sim_cluster_bis == 0xFFFFFFFF)1425 {1426 header->sim_cluster_bis = cluster_index;1427 }1428 else1429 {1430 error = 1;1431 }1432 1637 } 1433 1638 ///////////////////////////////// … … 1435 1640 { 1436 1641 periph[periph_index]->type = PERIPH_TYPE_TTY; 1437 if ( header->tty_cluster == 0xFFFFFFFF)1642 if ( tty_channels < periph[periph_index]->channels ) 1438 1643 { 1439 header->tty_cluster = cluster_index;1440 1644 tty_channels = periph[periph_index]->channels; 1441 1645 } 1442 else if (header->tty_cluster_bis == 0xFFFFFFFF) 1646 } 1647 ///////////////////////////////// 1648 else if (strcmp(str, "PIC") == 0) 1649 { 1650 periph[periph_index]->type = PERIPH_TYPE_PIC; 1651 if ( pic_channels < periph[periph_index]->channels ) 1443 1652 { 1444 header->tty_cluster_bis = cluster_index; 1445 assert( (tty_channels == periph[periph_index]->channels) && 1446 "[XML ERROR] unconsistent non replicated peripheral"); 1653 pic_channels = periph[periph_index]->channels; 1447 1654 } 1448 else 1449 { 1450 error = 1; 1451 } 1452 } 1655 use_pic = 1; 1656 } 1657 1453 1658 1454 1659 // The DMA, ICU, MMC, TIM, XCU peripherals can be replicated in all clusters 1455 // but it must exist onlyone component of each type per cluster1660 // but no more than one component of each type per cluster 1456 1661 1457 1662 ///////////////////////////////// … … 1471 1676 found_icu = 1; 1472 1677 1473 if (icu_channels > 0) 1678 if ( periph[periph_index]->channels < 1679 (header->irq_per_proc * cluster[cluster_index]->procs) ) 1474 1680 { 1475 assert( (periph[periph_index]->channels == icu_channels) && 1476 "[XML ERROR] the number of interruptions per processor " 1477 "from the ICU (icu channels) must be the same on all " 1478 "clusters"); 1479 } 1480 else 1481 { 1482 icu_channels = periph[periph_index]->channels; 1681 printf("[XML ERROR] ICU channels smaller than PROCS * IRQ_PER_PROC\n"); 1682 printf(" - icu channels = %d\n - nprocs = %d\n - irq_per_proc = %d\n", 1683 periph[periph_index]->channels, 1684 cluster[cluster_index]->procs, 1685 header->irq_per_proc ); 1686 exit(1); 1483 1687 } 1484 1688 } … … 1498 1702 found_timer = 1; 1499 1703 if (tim_channels < periph[periph_index]->channels) 1500 {1501 1704 tim_channels = periph[periph_index]->channels; 1502 }1503 1705 } 1504 1706 ////////////////////////////////// … … 1512 1714 use_xcu = 1; 1513 1715 1514 if (icu_channels > 0) 1716 if ( periph[periph_index]->channels < 1717 (header->irq_per_proc * cluster[cluster_index]->procs) ) 1515 1718 { 1516 assert( (periph[periph_index]->channels == icu_channels) && 1517 "[XML ERROR] the number of interruptions per processor " 1518 "from the ICU (icu channels) must be the same on all " 1519 "clusters"); 1719 printf("[XML ERROR] XCU channels smaller than PROCS * IRQ_PER_PROC\n"); 1720 printf(" - xcu channels = %d\n - nprocs = %d\n - irq_per_proc = %d\n", 1721 periph[periph_index]->channels, 1722 cluster[cluster_index]->procs, 1723 header->irq_per_proc ); 1724 exit(1); 1725 } 1726 } 1727 else 1728 { 1729 printf("[XML ERROR] illegal peripheral type: %s in cluster %d\n", 1730 str, cluster_index); 1731 exit(1); 1732 } 1733 1734 if (error) 1735 { 1736 printf("[XML ERROR] illegal peripheral %s in cluster %d\n", 1737 str, cluster_index); 1738 exit(1); 1739 } 1740 } 1741 else 1742 { 1743 printf("[XML ERROR] illegal or missing <type> for peripheral %d in cluster %d\n", 1744 periph_loc_index, cluster_index); 1745 exit(1); 1746 } 1747 1748 ////////////// set irq_offset attribute 1749 periph[periph_index]->irq_offset = irq_index; 1750 1751 #if XML_PARSER_DEBUG 1752 printf(" irq_offset = %d\n", irq_index ); 1753 #endif 1754 1755 ///////////// get IRQs 1756 int status = xmlTextReaderRead(reader); 1757 while (status == 1) 1758 { 1759 const char * tag = (const char *) xmlTextReaderConstName(reader); 1760 1761 if (strcmp(tag, "irq") == 0) 1762 { 1763 if ( (periph[periph_index]->type != PERIPH_TYPE_ICU) && 1764 (periph[periph_index]->type != PERIPH_TYPE_XCU) && 1765 (periph[periph_index]->type != PERIPH_TYPE_PIC) ) 1766 { 1767 printf("[XML ERROR] periph %d in cluster(%d,%d) " 1768 " only ICU, XCU and PIC can contain IRQs", 1769 periph_loc_index, cluster[cluster_index]->x, cluster[cluster_index]->y); 1770 exit(1); 1520 1771 } 1521 1772 else 1522 1773 { 1523 icu_channels = periph[periph_index]->channels;1774 irqNode(reader); 1524 1775 } 1525 1776 } 1777 else if (strcmp(tag, "#text") == 0) { } 1778 else if (strcmp(tag, "#comment") == 0) { } 1779 else if (strcmp(tag, "periph") == 0) 1780 { 1781 periph[periph_index]->irqs = irq_loc_index; 1782 cluster[cluster_index]->periphs++; 1783 periph_loc_index++; 1784 periph_index++; 1785 1786 #if XML_PARSER_DEBUG 1787 printf(" irqs = %d\n", irq_loc_index); 1788 printf(" irq_offset = %d\n", irq_index); 1789 #endif 1790 return; 1791 } 1526 1792 else 1527 1793 { 1528 printf("[XML ERROR] illegal <type>: %s for peripheral %d in cluster %d\n", 1529 str, periph_loc_index, cluster_index); 1794 printf("[XML ERROR] Unknown tag %s", tag); 1530 1795 exit(1); 1531 1796 } 1532 1533 if (error) 1534 { 1535 printf("[XML ERROR] illegal <type>: %s for peripheral %d in cluster %d\n", 1536 str, periph_loc_index, cluster_index); 1537 exit(1); 1538 } 1539 } 1540 else 1541 { 1542 printf("[XML ERROR] missing <type> for peripheral %d in cluster %d\n", 1543 periph_loc_index, cluster_index); 1544 exit(1); 1545 } 1546 1547 periph_index++; 1548 periph_loc_index++; 1549 cluster[cluster_index]->periphs++; 1550 1797 status = xmlTextReaderRead(reader); 1798 } 1551 1799 } // end periphNode 1552 1800 … … 1568 1816 1569 1817 #if XML_PARSER_DEBUG 1570 1818 printf("\n coproc %d\n", coproc_index); 1571 1819 #endif 1572 1820 … … 1578 1826 { 1579 1827 #if XML_PARSER_DEBUG 1580 1828 printf(" name = %s\n", str); 1581 1829 #endif 1582 1830 strncpy(coproc[coproc_index]->name, str, 31); … … 1603 1851 { 1604 1852 #if XML_PARSER_DEBUG 1605 1606 1607 1853 printf(" clusterid = %d\n", cluster_index); 1854 printf(" psegname = %s\n", str); 1855 printf(" psegid = %d\n", index); 1608 1856 #endif 1609 1857 coproc[coproc_index]->psegid = index; 1610 assert(pseg[index]->type == PSEG_TYPE_PERI && "coproc psegname attribute must refer to a pseg of type PERI" ); 1858 assert(pseg[index]->type == PSEG_TYPE_PERI && 1859 "coproc psegname attribute must refer to a pseg of type PERI" ); 1611 1860 } 1612 1861 else … … 1621 1870 1622 1871 #if XML_PARSER_DEBUG 1623 1872 printf(" port_offset = %d\n", cp_port_index); 1624 1873 #endif 1625 1874 … … 1653 1902 1654 1903 1655 ///////////////////////////////////// 1656 void irqNode(xmlTextReaderPtr reader)1904 ////////////////////////////////////// 1905 void procNode(xmlTextReaderPtr reader) 1657 1906 { 1658 1907 unsigned int ok; 1659 1908 unsigned int value; 1660 char * str;1661 1909 1662 1910 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return; 1663 1911 1664 if (irq_index >= MAX_IRQS) {1665 printf("[XML ERROR] The number of irqs is larger than %d\n", MAX_IRQS);1666 }1667 1668 #if XML_PARSER_DEBUG1669 printf(" irq %d\n", irq_loc_index);1670 #endif1671 1672 irq[irq_index] = (mapping_irq_t *) malloc(sizeof(mapping_irq_t));1673 1674 ///////// get type attribute1675 str = getStringValue(reader, "type", &ok);1676 if (ok)1677 {1678 #if XML_PARSER_DEBUG1679 printf(" type = %s\n", str);1680 #endif1681 if ( strcmp(str, "HARD") == 0 ) irq[irq_index]->type = IRQ_TYPE_HWI;1682 else if ( strcmp(str, "SOFT") == 0 ) irq[irq_index]->type = IRQ_TYPE_SWI;1683 else if ( strcmp(str, "TIME") == 0 ) irq[irq_index]->type = IRQ_TYPE_PTI;1684 else1685 {1686 printf("[XML ERROR] illegal IRQ <type> for processor %d in cluster %d\n",1687 cluster_index, proc_loc_index);1688 exit(1);1689 }1690 }1691 else1692 {1693 printf("[XML ERROR] missing IRQ <type> for processor %d in cluster %d\n",1694 cluster_index, proc_loc_index);1695 exit(1);1696 }1697 1698 ///////// get icuid attribute1699 value = getIntValue(reader, "icuid", &ok);1700 if (ok)1701 {1702 #if XML_PARSER_DEBUG1703 printf(" icuid = %d\n", value);1704 #endif1705 irq[irq_index]->icuid = value;1706 if (value >= 32)1707 {1708 printf("[XML ERROR] IRQ <icuid> too large for processor %d in cluster %d\n",1709 cluster_index, proc_loc_index);1710 exit(1);1711 }1712 }1713 else1714 {1715 printf("[XML ERROR] missing IRQ <icuid> for processor %d in cluster %d\n",1716 cluster_index, proc_loc_index);1717 exit(1);1718 }1719 1720 ///////// get isr attribute1721 str = getStringValue(reader, "isr", &ok);1722 if (ok)1723 {1724 #if XML_PARSER_DEBUG1725 printf(" isr = %s\n", str);1726 #endif1727 if (strcmp(str, "ISR_SWITCH" ) == 0) irq[irq_index]->isr = ISR_SWITCH;1728 else if (strcmp(str, "ISR_IOC" ) == 0) irq[irq_index]->isr = ISR_IOC;1729 else if (strcmp(str, "ISR_DMA" ) == 0) irq[irq_index]->isr = ISR_DMA;1730 else if (strcmp(str, "ISR_TTY" ) == 0) irq[irq_index]->isr = ISR_TTY;1731 else if (strcmp(str, "ISR_TIMER" ) == 0) irq[irq_index]->isr = ISR_TIMER;1732 else if (strcmp(str, "ISR_WAKUP" ) == 0) irq[irq_index]->isr = ISR_WAKUP;1733 else if (strcmp(str, "ISR_DEFAULT") == 0) irq[irq_index]->isr = ISR_DEFAULT;1734 else1735 {1736 printf("[XML ERROR] illegal IRQ <isr> for processor %d in cluster %d\n",1737 cluster_index, proc_loc_index);1738 exit(1);1739 }1740 #if XML_PARSER_DEBUG1741 printf(" isrnum = %d\n", irq[irq_index]->isr);1742 #endif1743 }1744 else1745 {1746 printf("[XML ERROR] missing IRQ <isr> for processor %d in cluster %d\n",1747 cluster_index, proc_loc_index);1748 exit(1);1749 }1750 1751 ///////// get channel attribute (optionnal : 0 if missing)1752 value = getIntValue(reader, "channel", &ok);1753 if (ok)1754 {1755 #if XML_PARSER_DEBUG1756 printf(" channel = %d\n", value);1757 #endif1758 irq[irq_index]->channel = value;1759 }1760 else1761 {1762 irq[irq_index]->channel = 0;1763 }1764 1765 irq_index++;1766 irq_loc_index++;1767 1768 } // end irqNode1769 1770 1771 //////////////////////////////////////1772 void procNode(xmlTextReaderPtr reader)1773 {1774 unsigned int ok;1775 unsigned int value;1776 1777 irq_loc_index = 0;1778 1779 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;1780 1781 1912 if (proc_index >= MAX_PROCS) 1782 1913 { … … 1786 1917 1787 1918 #if XML_PARSER_DEBUG 1788 printf("\nproc %d\n", proc_index);1919 printf("\n proc %d\n", proc_index); 1789 1920 #endif 1790 1921 … … 1799 1930 exit(1); 1800 1931 } 1801 1802 ////////// set irq_offset attribute 1803 proc[proc_index]->irq_offset = irq_index; 1804 1805 #if XML_PARSER_DEBUG 1806 printf(" irq_offset = %d\n", irq_index); 1807 #endif 1808 1809 int status = xmlTextReaderRead(reader); 1810 while (status == 1) 1811 { 1812 const char * tag = (const char *) xmlTextReaderConstName(reader); 1813 1814 if (strcmp(tag, "irq") == 0) 1815 { 1816 irqNode(reader); 1817 } 1818 else if (strcmp(tag, "#text") == 0) { } 1819 else if (strcmp(tag, "#comment") == 0) { } 1820 else if (strcmp(tag, "proc") == 0) 1821 { 1822 proc[proc_index]->irqs = irq_loc_index; 1823 cluster[cluster_index]->procs++; 1824 proc_loc_index++; 1825 proc_index++; 1826 return; 1827 } 1828 else 1829 { 1830 printf("[XML ERROR] Unknown tag %s", tag); 1831 exit(1); 1832 } 1833 status = xmlTextReaderRead(reader); 1834 } 1932 proc[proc_index]->index = proc_loc_index; 1933 1934 cluster[cluster_index]->procs++; 1935 proc_loc_index++; 1936 proc_index++; 1835 1937 } // end procNode() 1836 1938 … … 1852 1954 1853 1955 #if XML_PARSER_DEBUG 1854 1956 printf(" pseg %d\n", pseg_index); 1855 1957 #endif 1856 1958 … … 1860 1962 str = getStringValue(reader, "name", &ok); 1861 1963 #if XML_PARSER_DEBUG 1862 1964 printf(" name = %s\n", str); 1863 1965 #endif 1864 1966 if (ok) … … 1876 1978 str = getStringValue(reader, "type", &ok); 1877 1979 #if XML_PARSER_DEBUG 1878 1980 printf(" type = %s\n", str); 1879 1981 #endif 1880 1982 if (ok && (strcmp(str, "RAM" ) == 0)) { pseg[pseg_index]->type = PSEG_TYPE_RAM; } … … 1891 1993 ll_value = getPaddrValue(reader, "base", &ok); 1892 1994 #if XML_PARSER_DEBUG 1893 1995 printf(" base = 0x%llx\n", ll_value); 1894 1996 #endif 1895 1997 if (ok) … … 1906 2008 ll_value = getPaddrValue(reader, "length", &ok); 1907 2009 #if XML_PARSER_DEBUG 1908 2010 printf(" length = 0x%llx\n", ll_value); 1909 2011 #endif 1910 2012 if (ok) … … 1956 2058 found_mmc = 0; 1957 2059 1958 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { 1959 return; 1960 } 2060 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return; 1961 2061 1962 2062 #if XML_PARSER_DEBUG … … 2024 2124 else if (strcmp(tag, "cluster") == 0) 2025 2125 { 2026 2027 ///////// TIMER and ICU peripheral are mandatory //////////////2028 if ( !found_timer && !found_xcu)2126 ///////// TIMER and ICU peripheral are mandatory when nprocs != 0 2127 unsigned int procs = cluster[cluster_index]->procs; 2128 if ( procs && !found_timer && !found_xcu) 2029 2129 { 2030 2130 printf("[XML ERROR] missing timer peripheral in cluster %d\n", cluster_index); … … 2032 2132 } 2033 2133 2034 if ( !found_icu && !found_xcu)2134 if ( procs && !found_icu && !found_xcu) 2035 2135 { 2036 2136 printf("[XML ERROR] missing icu peripheral in cluster %d\n", cluster_index); … … 2038 2138 } 2039 2139 2040 if (nb_proc_max < cluster[cluster_index]->procs) 2041 { 2042 nb_proc_max = cluster[cluster_index]->procs; 2043 } 2140 if (nb_procs_max < procs) nb_procs_max = procs; 2044 2141 2045 2142 #if XML_PARSER_DEBUG … … 2077 2174 else if (strcmp(tag, "clusterset") == 0) 2078 2175 { 2079 // checking source file consistency2176 // checking number of clusters 2080 2177 if ( cluster_index != (header->x_size * header->y_size) ) 2081 2178 { … … 2084 2181 } 2085 2182 2086 // At least oneTTY terminal for system boot2087 if ( header->tty_cluster == 0xFFFFFFFF)2183 // checking TTY terminal for system boot 2184 if ( tty_channels == 0 ) 2088 2185 { 2089 printf("[XML ERROR] illegal or missing tty peripheral");2186 printf("[XML ERROR] missing TTY peripheral\n"); 2090 2187 exit(1); 2091 2188 } 2092 2189 2093 // the number of ICU channels must be NB_PROCS * irq_per_proc2094 if ( icu_channels != (header->irq_per_proc * proc_loc_index))2190 // checking IOC sub-types 2191 if ( (use_bdv + use_hba + use_spi) > 1 ) 2095 2192 { 2096 printf("[XML ERROR] illegal ICU number of channels. " 2097 "It must be equal to NB_PROCS * IRQ_PER_PROC\n"); 2193 printf("[XML ERROR] all IOC peripherals must have the same type\n"); 2098 2194 exit(1); 2099 2195 } … … 2134 2230 const char * tag = (const char *) xmlTextReaderConstName(reader); 2135 2231 2136 if (strcmp(tag, "vseg") == 0) { vsegNode(reader); } 2232 if (strcmp(tag, "vseg") == 0) 2233 { 2234 vsegNode( reader ); 2235 header->globals = header->globals + 1; 2236 } 2137 2237 else if (strcmp(tag, "#text") == 0) { } 2138 2238 else if (strcmp(tag, "#comment") == 0) { } … … 2142 2242 printf(" end global set\n\n"); 2143 2243 #endif 2144 header->globals = vseg_index;2145 2244 vseg_loc_index = 0; 2146 2245 return; … … 2178 2277 else if (strcmp(tag, "vspaceset") == 0 ) 2179 2278 { 2180 // checking source file consistency 2181 if (vspace_index != header->vspaces) 2182 { 2183 printf("[XML ERROR] Wrong number of vspaces\n"); 2184 exit(1); 2185 } 2186 else 2187 { 2188 header->vsegs = vseg_index; 2189 header->vobjs = vobj_index; 2190 header->tasks = task_index; 2191 return; 2192 } 2279 header->vsegs = vseg_index; 2280 header->vobjs = vobj_index; 2281 header->tasks = task_index; 2282 return; 2193 2283 } 2194 2284 else … … 2282 2372 } 2283 2373 2284 //check the number of cluster 2374 /////////// get x_io attribute 2375 unsigned int x_io = getIntValue(reader, "x_io", &ok); 2376 #if XML_PARSER_DEBUG 2377 printf(" x_io = %d\n", x_io); 2378 #endif 2379 if ( ok && (x_io < x_size) ) 2380 { 2381 header->x_io = x_io; 2382 } 2383 else 2384 { 2385 printf("[XML ERROR] illegal or missing <x_io> attribute in header\n"); 2386 exit(1); 2387 } 2388 2389 /////////// get y_io attribute 2390 unsigned int y_io = getIntValue(reader, "y_io", &ok); 2391 #if XML_PARSER_DEBUG 2392 printf(" y_io = %d\n", y_size); 2393 #endif 2394 if ( ok &&(y_io < y_size) ) 2395 { 2396 header->y_io = y_io; 2397 } 2398 else 2399 { 2400 printf("[XML ERROR] illegal or missing <y_io> attribute in header\n"); 2401 exit(1); 2402 } 2403 2404 // check the number of cluster 2285 2405 if ( (x_size * y_size) >= MAX_CLUSTERS ) 2286 2406 { … … 2289 2409 } 2290 2410 2291 ///////// get vspaces attribute 2292 value = getIntValue(reader, "vspaces", &ok); 2293 if (ok) 2294 { 2295 if (value >= MAX_VSPACES) 2296 { 2297 printf("[XML ERROR] The number of vspaces is larger than %d\n", MAX_VSPACES); 2298 exit(1); 2299 } 2300 #if XML_PARSER_DEBUG 2301 printf(" vspaces = %d\n", value); 2302 #endif 2303 header->vspaces = value; 2304 } 2305 else 2306 { 2307 printf("[XML ERROR] illegal or missing <vspaces> attribute in mapping\n"); 2308 exit(1); 2309 } 2310 2311 ///////// get increment attribute 2312 value = getIntValue(reader, "increment", &ok); 2313 if (ok) 2314 { 2315 if ( (value != 0x10000) && (value != 0x8000) && 2316 (value != 0x4000) && (value != 0x2000) ) 2317 2318 { 2319 printf("[XML ERROR] The vseg increment must be one of the following: "); 2320 printf(" 0x00010000 / 0x00008000 / 0x00004000 / 0x00002000"); 2321 exit(1); 2322 } 2323 #if XML_PARSER_DEBUG 2324 printf(" increment = %d\n", value); 2325 #endif 2326 header->increment = value; 2327 } 2328 else 2329 { 2330 printf("[XML ERROR] illegal or missing <increment> attribute in mapping\n"); 2331 exit(1); 2332 } 2333 2334 ///////// get increment attribute 2411 ///////// get irq_per_proc attribute 2335 2412 value = getIntValue(reader, "irq_per_proc", &ok); 2336 2413 if (ok) … … 2347 2424 } 2348 2425 2349 //////// initialise non replicated peripherals cluster index 2350 header->cma_cluster = 0xFFFFFFFF; 2351 header->cma_cluster_bis = 0xFFFFFFFF; 2352 2353 header->fbf_cluster = 0xFFFFFFFF; 2354 header->fbf_cluster_bis = 0xFFFFFFFF; 2355 2356 header->iob_cluster = 0xFFFFFFFF; 2357 header->iob_cluster_bis = 0xFFFFFFFF; 2358 2359 header->ioc_cluster = 0xFFFFFFFF; 2360 header->ioc_cluster_bis = 0xFFFFFFFF; 2361 2362 header->nic_cluster = 0xFFFFFFFF; 2363 header->nic_cluster_bis = 0xFFFFFFFF; 2364 2365 header->rom_cluster = 0xFFFFFFFF; 2366 header->rom_cluster_bis = 0xFFFFFFFF; 2367 2368 header->sim_cluster = 0xFFFFFFFF; 2369 header->sim_cluster_bis = 0xFFFFFFFF; 2370 2371 header->tty_cluster = 0xFFFFFFFF; 2372 header->tty_cluster_bis = 0xFFFFFFFF; 2373 2374 ///////// set signature 2426 ///////// get use_ramdisk attribute (default = 0) 2427 value = getIntValue(reader, "use_ramdisk", &ok); 2428 if (ok) 2429 { 2430 #if XML_PARSER_DEBUG 2431 printf(" use_ramdisk = %d\n", value); 2432 #endif 2433 header->use_ramdisk = value; 2434 } 2435 else 2436 { 2437 header->use_ramdisk = 0; 2438 } 2439 2440 ///////// set other header fields 2441 header->increment = 0x10000; 2375 2442 header->signature = IN_MAPPING_SIGNATURE; 2443 header->globals = 0; 2444 header->vspaces = 0; 2445 header->psegs = 0; 2446 header->vsegs = 0; 2447 header->vobjs = 0; 2448 header->tasks = 0; 2449 header->procs = 0; 2450 header->irqs = 0; 2451 header->coprocs = 0; 2452 header->cp_ports = 0; 2453 header->periphs = 0; 2454 2376 2455 2377 2456 int status = xmlTextReaderRead(reader); … … 2380 2459 const char * tag = (const char *) xmlTextReaderConstName(reader); 2381 2460 2382 if (strcmp(tag, "clusterset") == 0) 2383 { 2384 clusterSetNode(reader); 2385 } 2461 if (strcmp(tag, "clusterset") == 0) { clusterSetNode(reader); } 2386 2462 else if (strcmp(tag, "globalset") == 0) { globalSetNode(reader); } 2387 2463 else if (strcmp(tag, "vspaceset") == 0) { vspaceSetNode(reader); } … … 2591 2667 def_int_write(fdout, "X_WIDTH ", header->x_width); 2592 2668 def_int_write(fdout, "Y_WIDTH ", header->y_width); 2669 def_int_write(fdout, "X_IO ", header->x_io); 2670 def_int_write(fdout, "Y_IO ", header->y_io); 2593 2671 2594 2672 file_write(fdout, "\n"); 2595 2673 2596 def_int_write(fdout, "NB_PROCS_MAX ", nb_proc _max);2674 def_int_write(fdout, "NB_PROCS_MAX ", nb_procs_max); 2597 2675 def_int_write(fdout, "NB_TASKS_MAX ", nb_tasks_max); 2598 2676 … … 2605 2683 2606 2684 def_int_write(fdout, "NB_TTY_CHANNELS ", tty_channels); 2607 def_int_write(fdout, "NB_ HBA_CHANNELS ", hba_channels);2685 def_int_write(fdout, "NB_IOC_CHANNELS ", ioc_channels); 2608 2686 def_int_write(fdout, "NB_NIC_CHANNELS ", nic_channels); 2609 2687 def_int_write(fdout, "NB_CMA_CHANNELS ", cma_channels); … … 2613 2691 def_int_write(fdout, "USE_XICU ", use_xcu); 2614 2692 def_int_write(fdout, "USE_IOB ", use_iob); 2615 def_int_write(fdout, "USE_HBA ", use_hba); 2616 def_int_write(fdout, "USE_BDV ", use_bdv); 2617 def_int_write(fdout, "USE_SPI ", use_spi); 2693 def_int_write(fdout, "USE_PIC ", use_pic); 2694 2695 file_write(fdout, "\n"); 2696 2697 def_int_write(fdout, "USE_IOC_RDK ", header->use_ramdisk); 2698 def_int_write(fdout, "USE_IOC_HBA ", use_hba); 2699 def_int_write(fdout, "USE_IOC_BDV ", use_bdv); 2700 def_int_write(fdout, "USE_IOC_SPI ", use_spi); 2618 2701 2619 2702 file_write(fdout, "\n"); … … 2638 2721 { 2639 2722 int fdout = open_file(file_path); 2640 unsigned int count = 0;2723 unsigned int count; 2641 2724 unsigned int vseg_id; 2642 2725 unsigned int base; // vseg base … … 2648 2731 file_write(fdout, prol); 2649 2732 2650 // boot and kernel segments2651 for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++)2733 // boot mandatory global vsegs 2734 for (vseg_id = 0 , count = 0 ; vseg_id < header->vsegs ; vseg_id++) 2652 2735 { 2653 2736 if ( strcmp(vseg[vseg_id]->name, "seg_boot_code") == 0 ) … … 2691 2774 count++; 2692 2775 } 2693 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_code") == 0 ) 2694 { 2695 base = vseg[vseg_id]->vbase; 2696 size = vobj[vseg[vseg_id]->vobj_offset]->length; 2697 ld_write(fdout, "seg_kernel_code_base ", base); 2698 ld_write(fdout, "seg_kernel_code_size ", size); 2699 count++; 2700 } 2701 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_data") == 0 ) 2702 { 2703 base = vseg[vseg_id]->vbase; 2704 size = vobj[vseg[vseg_id]->vobj_offset]->length; 2705 ld_write(fdout, "seg_kernel_data_base ", base); 2706 ld_write(fdout, "seg_kernel_data_size ", size); 2707 count++; 2708 } 2709 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_uncdata") == 0 ) 2710 { 2711 base = vseg[vseg_id]->vbase; 2712 size = vobj[vseg[vseg_id]->vobj_offset]->length; 2713 ld_write(fdout, "seg_kernel_uncdata_base ", base); 2714 ld_write(fdout, "seg_kernel_uncdata_size ", size); 2715 count++; 2716 } 2717 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_init") == 0 ) 2718 { 2719 base = vseg[vseg_id]->vbase; 2720 size = vobj[vseg[vseg_id]->vobj_offset]->length; 2721 ld_write(fdout, "seg_kernel_init_base ", base); 2722 ld_write(fdout, "seg_kernel_init_size ", size); 2723 count++; 2724 } 2725 } 2726 if ( count != 9 ) 2776 } 2777 2778 if ( count != 5 ) 2727 2779 { 2728 printf ("[XML ERROR] Missing Boot or Kernel vseg : only %d\n", count);2780 printf ("[XML ERROR] Missing mandatory Boot global vseg : only %d\n", count); 2729 2781 printf ("Mandatory segments are :\n"); 2730 2782 printf (" - seg_boot_code\n"); … … 2733 2785 printf (" - seg_boot_mapping\n"); 2734 2786 printf (" - seg_boot_buffer\n"); 2787 exit(0); 2788 } 2789 2790 file_write(fdout, "\n"); 2791 2792 // kernel mandatory global vsegs 2793 for (vseg_id = 0, count = 0 ; vseg_id < header->vsegs ; vseg_id++) 2794 { 2795 if ( strcmp(vseg[vseg_id]->name, "seg_kernel_code") == 0 ) 2796 { 2797 base = vseg[vseg_id]->vbase; 2798 size = vobj[vseg[vseg_id]->vobj_offset]->length; 2799 ld_write(fdout, "seg_kernel_code_base ", base); 2800 ld_write(fdout, "seg_kernel_code_size ", size); 2801 count++; 2802 } 2803 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_data") == 0 ) 2804 { 2805 base = vseg[vseg_id]->vbase; 2806 size = vobj[vseg[vseg_id]->vobj_offset]->length; 2807 ld_write(fdout, "seg_kernel_data_base ", base); 2808 ld_write(fdout, "seg_kernel_data_size ", size); 2809 count++; 2810 } 2811 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_uncdata") == 0 ) 2812 { 2813 base = vseg[vseg_id]->vbase; 2814 size = vobj[vseg[vseg_id]->vobj_offset]->length; 2815 ld_write(fdout, "seg_kernel_uncdata_base ", base); 2816 ld_write(fdout, "seg_kernel_uncdata_size ", size); 2817 count++; 2818 } 2819 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_init") == 0 ) 2820 { 2821 base = vseg[vseg_id]->vbase; 2822 size = vobj[vseg[vseg_id]->vobj_offset]->length; 2823 ld_write(fdout, "seg_kernel_init_base ", base); 2824 ld_write(fdout, "seg_kernel_init_size ", size); 2825 count++; 2826 } 2827 } 2828 if ( count != 4 ) 2829 { 2830 printf ("[XML ERROR] Missing mandatory Kernel global vseg : only %d\n", count); 2831 printf ("Mandatory segments are :\n"); 2735 2832 printf (" - seg_kernel_code\n"); 2736 2833 printf (" - seg_kernel_data\n"); 2737 2834 printf (" - seg_kernel_uncdata\n"); 2738 2835 printf (" - seg_kernel_init\n"); 2739 } 2740 2836 exit(0); 2837 } 2838 2839 file_write(fdout, "\n"); 2840 2841 // boot and kernel optionnal global vsegs (pseudo ROMs) 2842 unsigned int seg_ram_disk_base = 0xFFFFFFFF; 2843 unsigned int seg_ram_disk_size = 0; 2844 unsigned int seg_reset_code_base = 0xFFFFFFFF; 2845 unsigned int seg_reset_code_size = 0; 2846 for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++) 2847 { 2848 if ( strcmp(vseg[vseg_id]->name, "seg_reset_code") == 0 ) 2849 { 2850 seg_reset_code_base = vseg[vseg_id]->vbase; 2851 seg_reset_code_size = vobj[vseg[vseg_id]->vobj_offset]->length; 2852 } 2853 if ( strcmp(vseg[vseg_id]->name, "seg_ram_disk") == 0 ) 2854 { 2855 seg_ram_disk_base = vseg[vseg_id]->vbase; 2856 seg_ram_disk_size = vobj[vseg[vseg_id]->vobj_offset]->length; 2857 } 2858 } 2859 2860 ld_write(fdout, "seg_reset_code_base ", seg_reset_code_base); 2861 ld_write(fdout, "seg_reset_code_size ", seg_reset_code_size); 2862 ld_write(fdout, "seg_ram_disk_base ", seg_ram_disk_base); 2863 ld_write(fdout, "seg_ram_disk_size ", seg_ram_disk_size); 2864 2741 2865 file_write(fdout, "\n"); 2742 2866 … … 2744 2868 set_periph_vbase_array(); 2745 2869 2746 // non replicated peripherals2870 // non replicated peripherals 2747 2871 ld_write(fdout, "seg_cma_base ", periph_vbase_array[PERIPH_TYPE_CMA]); 2748 2872 ld_write(fdout, "seg_fbf_base ", periph_vbase_array[PERIPH_TYPE_FBF]); … … 2753 2877 ld_write(fdout, "seg_sim_base ", periph_vbase_array[PERIPH_TYPE_SIM]); 2754 2878 ld_write(fdout, "seg_tty_base ", periph_vbase_array[PERIPH_TYPE_TTY]); 2879 ld_write(fdout, "seg_pic_base ", periph_vbase_array[PERIPH_TYPE_PIC]); 2755 2880 2756 2881 file_write(fdout, "\n"); -
soft/giet_vm/hello/main.c
r254 r295 1 1 #include "stdio.h" 2 #include "hard_config.h" 2 3 3 4 __attribute__((constructor)) void main() … … 6 7 unsigned int proc = giet_procid(); 7 8 8 giet_tty_printf("Starting task HELLO on processor %d at cycle %d\n", 9 giet_procid(), giet_proctime() ); 10 9 unsigned int procid = giet_procid(); 10 unsigned int cluster_xy = procid/NB_PROCS_MAX; 11 unsigned int lpid = procid%NB_PROCS_MAX; 12 unsigned int x = cluster_xy >> Y_WIDTH; 13 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 14 15 giet_tty_printf( "*** Starting task hello on processor[%d,%d,%d] at cycle %d\n\n", 16 x, y, lpid, giet_proctime() ); 17 11 18 while (1) 12 19 { 13 giet_tty_printf(" hello from processor %d\n", proc);20 giet_tty_printf(" hello world\n"); 14 21 giet_tty_getc((void*)&byte); 15 22 if ( byte == 'q' ) giet_exit(); -
soft/giet_vm/mappings/4c_4p_sort_leti.xml
r292 r295 1 1 <?xml version="1.0"?> 2 2 3 <mapping_info signature = "0xd eadbeef"4 name = "4c_4p_sort_ intact"3 <mapping_info signature = "0xdace2014" 4 name = "4c_4p_sort_leti" 5 5 x_size = "2" 6 y_size = " 2"6 y_size = "3" 7 7 x_width = "4" 8 8 y_width = "4" 9 vspaces = "1" 10 increment = "0x10000" 11 irq_per_proc = "4" > 12 13 *** The "increment" parameter is the virtual address cluster increment 14 *** The physical address cluster increment is 0x10000000000 / NB_CLUSTERS 15 16 *** This first section describes an instance of the "tsar_generic_iob" architecture 17 *** with 4 clusters, 1 processor per cluster and 40 bits physical address. 9 irq_per_proc = "4" 10 use_ramdisk = "1" 11 x_io = "0" 12 y_io = "0" > 13 14 *** This mapping is for the "tsar_generic_leti" hardware architecture 15 *** with 4 clusters containing processors and 4 processors per cluster 16 *** 40 bits physical address, and 64 Mbytes per cluster. 17 *** There is 4 IRQ inputs per processor 18 *** It does not use the external peripherals. 19 *** It uses the RAMDISK in cluster(0,0) 20 *** It uses the mono-channel TTY implemented in cluster(0,0). 18 21 19 22 <clusterset> 20 21 23 <cluster x = "0" y = "0" > 22 <pseg name = "PSEG_RAM" type = "RAM" base = "0x0000000000" length = "0x0 000800000" />24 <pseg name = "PSEG_RAM" type = "RAM" base = "0x0000000000" length = "0x0400000000" /> 23 25 <pseg name = "PSEG_XCU" type = "PERI" base = "0x00F0000000" length = "0x0000002000" /> 24 26 <pseg name = "PSEG_MMC" type = "PERI" base = "0x00E0000000" length = "0x0000001000" /> 25 26 *** Non replicated peripherals (including the ROM containing the preloader code)27 28 27 <pseg name = "PSEG_IOC" type = "PERI" base = "0x00F2000000" length = "0x0000001000" /> 29 28 <pseg name = "PSEG_TTY" type = "PERI" base = "0x00F4000000" length = "0x0000001000" /> 30 29 31 <proc index = "0" > 32 <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" /> 33 <irq type = "TIME" icuid = "4" isr = "ISR_SWITCH" /> 34 <irq type = "HARD" icuid = "8" isr = "ISR_DEFAULT" /> 35 <irq type = "HARD" icuid = "9" isr = "ISR_IOC" /> 36 <irq type = "HARD" icuid = "10" isr = "ISR_TTY" /> 37 </proc> 38 <proc index = "1" > 39 <irq type = "SOFT" icuid = "1" isr = "ISR_WAKUP" /> 40 <irq type = "TIME" icuid = "5" isr = "ISR_SWITCH" /> 41 </proc> 42 <proc index = "2" > 43 <irq type = "SOFT" icuid = "2" isr = "ISR_WAKUP" /> 44 <irq type = "TIME" icuid = "6" isr = "ISR_SWITCH" /> 45 </proc> 46 <proc index = "3" > 47 <irq type = "SOFT" icuid = "3" isr = "ISR_WAKUP" /> 48 <irq type = "TIME" icuid = "7" isr = "ISR_SWITCH" /> 49 </proc> 50 51 <periph type = "XCU" psegname = "PSEG_XCU" channels = "16" /> 52 <periph type = "MMC" psegname = "PSEG_MMC" channels = "1" /> 53 <periph type = "IOC" psegname = "PSEG_IOC" channels = "1" subtype = "BDV" /> 54 <periph type = "TTY" psegname = "PSEG_TTY" channels = "1" /> 55 30 <proc index = "0" /> 31 <proc index = "1" /> 32 <proc index = "2" /> 33 <proc index = "3" /> 34 35 <periph type = "MMC" psegname = "PSEG_MMC" > 36 </periph> 37 <periph type = "IOC" psegname = "PSEG_IOC" subtype = "BDV" > 38 </periph> 39 <periph type = "TTY" psegname = "PSEG_TTY" channels = "1" > 40 </periph> 41 <periph type = "XCU" psegname = "PSEG_XCU" channels = "16" > 42 <irq srcid = "0" srctype = "WTI" isr = "ISR_WAKUP" dstx = "0" dsty = "0" dstid = "0" /> 43 <irq srcid = "1" srctype = "WTI" isr = "ISR_WAKUP" dstx = "0" dsty = "0" dstid = "1" /> 44 <irq srcid = "2" srctype = "WTI" isr = "ISR_WAKUP" dstx = "0" dsty = "0" dstid = "2" /> 45 <irq srcid = "3" srctype = "WTI" isr = "ISR_WAKUP" dstx = "0" dsty = "0" dstid = "3" /> 46 <irq srcid = "4" srctype = "WTI" isr = "ISR_NIC_RX" channel = "0" dstx = "0" dsty = "0" dstid = "0" /> 47 <irq srcid = "5" srctype = "WTI" isr = "ISR_NIC_RX" channel = "1" dstx = "0" dsty = "0" dstid = "0" /> 48 <irq srcid = "6" srctype = "WTI" isr = "ISR_NIC_TX" channel = "0" dstx = "0" dsty = "0" dstid = "0" /> 49 <irq srcid = "7" srctype = "WTI" isr = "ISR_NIC_TX" channel = "1" dstx = "0" dsty = "0" dstid = "0" /> 50 <irq srcid = "8" srctype = "WTI" isr = "ISR_CMA" channel = "0" dstx = "0" dsty = "0" dstid = "0" /> 51 <irq srcid = "9" srctype = "WTI" isr = "ISR_CMA" channel = "1" dstx = "0" dsty = "0" dstid = "0" /> 52 <irq srcid = "10" srctype = "WTI" isr = "ISR_CMA" channel = "2" dstx = "0" dsty = "0" dstid = "0" /> 53 <irq srcid = "11" srctype = "WTI" isr = "ISR_CMA" channel = "3" dstx = "0" dsty = "0" dstid = "0" /> 54 <irq srcid = "12" srctype = "WTI" isr = "ISR_BDV" channel = "0" dstx = "0" dsty = "0" dstid = "0" /> 55 <irq srcid = "13" srctype = "WTI" isr = "ISR_TTY_RX" channel = "0" dstx = "0" dsty = "0" dstid = "0" /> 56 57 <irq srcid = "0" srctype = "PTI" isr = "ISR_TICK" dstx = "0" dsty = "0" dstid = "0" /> 58 <irq srcid = "1" srctype = "PTI" isr = "ISR_TICK" dstx = "0" dsty = "0" dstid = "1" /> 59 <irq srcid = "2" srctype = "PTI" isr = "ISR_TICK" dstx = "0" dsty = "0" dstid = "2" /> 60 <irq srcid = "3" srctype = "PTI" isr = "ISR_TICK" dstx = "0" dsty = "0" dstid = "3" /> 61 62 <irq srcid = "8" srctype = "HWI" isr = "ISR_DEFAULT" dstx = "0" dsty = "0" dstid = "0" /> 63 <irq srcid = "9" srctype = "HWI" isr = "ISR_BDV" channel = "0" dstx = "0" dsty = "0" dstid = "0" /> 64 <irq srcid = "10" srctype = "HWI" isr = "ISR_TTY_RX" channel = "0" dstx = "0" dsty = "0" dstid = "0" /> 65 </periph> 56 66 </cluster> 57 67 58 68 <cluster x = "0" y = "1" > 59 <pseg name = "PSEG_RAM" type = "RAM" base = "0x0100000000" length = "0x0 000800000" />69 <pseg name = "PSEG_RAM" type = "RAM" base = "0x0100000000" length = "0x0400000000" /> 60 70 <pseg name = "PSEG_XCU" type = "PERI" base = "0x01F0000000" length = "0x0000002000" /> 61 71 <pseg name = "PSEG_MMC" type = "PERI" base = "0x01E0000000" length = "0x0000001000" /> 62 72 63 <proc index = "0" >64 <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />65 <irq type = "TIME" icuid = "4" isr = "ISR_SWITCH" />66 <irq type = "HARD" icuid = "8" isr = "ISR_DEFAULT" />67 </proc> 68 <p roc index = "1" >69 <irq type = "SOFT" icuid = "1" isr = "ISR_WAKUP" />70 <irq type = "TIME" icuid = "5" isr = "ISR_SWITCH" />71 </proc>72 <proc index = "2">73 <irq type = "SOFT" icuid = "2" isr = "ISR_WAKUP" />74 <irq type = "TIME" icuid = "6" isr = "ISR_SWITCH" />75 </proc> 76 <proc index = "3">77 <irq type = "SOFT" icuid = "3" isr = "ISR_WAKUP" />78 <irq type = "TIME" icuid = "7" isr = "ISR_SWITCH" />79 </proc>80 81 <periph type = "XCU" psegname = "PSEG_XCU" channels = "16" />82 < periph type = "MMC" psegname = "PSEG_MMC" channels = "1" />73 <proc index = "0" /> 74 <proc index = "1" /> 75 <proc index = "2" /> 76 <proc index = "3" /> 77 78 <periph type = "MMC" psegname = "PSEG_MMC" > 79 </periph> 80 <periph type = "XCU" psegname = "PSEG_XCU" channels = "16" > 81 <irq srcid = "0" srctype = "WTI" isr = "ISR_WAKUP" dstx = "0" dsty = "1" dstid = "0" /> 82 <irq srcid = "1" srctype = "WTI" isr = "ISR_WAKUP" dstx = "0" dsty = "1" dstid = "1" /> 83 <irq srcid = "2" srctype = "WTI" isr = "ISR_WAKUP" dstx = "0" dsty = "1" dstid = "2" /> 84 <irq srcid = "3" srctype = "WTI" isr = "ISR_WAKUP" dstx = "0" dsty = "1" dstid = "3" /> 85 86 <irq srcid = "0" srctype = "PTI" isr = "ISR_TICK" dstx = "0" dsty = "1" dstid = "0" /> 87 <irq srcid = "1" srctype = "PTI" isr = "ISR_TICK" dstx = "0" dsty = "1" dstid = "1" /> 88 <irq srcid = "2" srctype = "PTI" isr = "ISR_TICK" dstx = "0" dsty = "1" dstid = "2" /> 89 <irq srcid = "3" srctype = "PTI" isr = "ISR_TICK" dstx = "0" dsty = "1" dstid = "3" /> 90 91 <irq srcid = "8" srctype = "HWI" isr = "ISR_DEFAULT" dstx = "0" dsty = "1" dstid = "0" /> 92 </periph> 83 93 </cluster> 84 94 85 95 <cluster x = "1" y = "0" > 86 <pseg name = "PSEG_RAM" type = "RAM" base = "0x1000000000" length = "0x0 000800000" />96 <pseg name = "PSEG_RAM" type = "RAM" base = "0x1000000000" length = "0x0400000000" /> 87 97 <pseg name = "PSEG_XCU" type = "PERI" base = "0x10F0000000" length = "0x0000002000" /> 88 98 <pseg name = "PSEG_MMC" type = "PERI" base = "0x10E0000000" length = "0x0000001000" /> 89 99 90 <proc index = "0" >91 <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />92 <irq type = "TIME" icuid = "4" isr = "ISR_SWITCH" />93 <irq type = "HARD" icuid = "8" isr = "ISR_DEFAULT" />94 </proc> 95 <p roc index = "1" >96 <irq type = "SOFT" icuid = "1" isr = "ISR_WAKUP" />97 <irq type = "TIME" icuid = "5" isr = "ISR_SWITCH" />98 </proc>99 <proc index = "2">100 <irq type = "SOFT" icuid = "2" isr = "ISR_WAKUP" />101 <irq type = "TIME" icuid = "6" isr = "ISR_SWITCH" />102 </proc> 103 <proc index = "3">104 <irq type = "SOFT" icuid = "3" isr = "ISR_WAKUP" />105 <irq type = "TIME" icuid = "7" isr = "ISR_SWITCH" />106 </proc>107 108 <periph type = "XCU" psegname = "PSEG_XCU" channels = "16" />109 < periph type = "MMC" psegname = "PSEG_MMC" channels = "1" />100 <proc index = "0" /> 101 <proc index = "1" /> 102 <proc index = "2" /> 103 <proc index = "3" /> 104 105 <periph type = "MMC" psegname = "PSEG_MMC" > 106 </periph> 107 <periph type = "XCU" psegname = "PSEG_XCU" channels = "16" > 108 <irq srcid = "0" srctype = "WTI" isr = "ISR_WAKUP" dstx = "1" dsty = "0" dstid = "0" /> 109 <irq srcid = "1" srctype = "WTI" isr = "ISR_WAKUP" dstx = "1" dsty = "0" dstid = "1" /> 110 <irq srcid = "2" srctype = "WTI" isr = "ISR_WAKUP" dstx = "1" dsty = "0" dstid = "2" /> 111 <irq srcid = "3" srctype = "WTI" isr = "ISR_WAKUP" dstx = "1" dsty = "0" dstid = "3" /> 112 113 <irq srcid = "0" srctype = "PTI" isr = "ISR_TICK" dstx = "1" dsty = "0" dstid = "0" /> 114 <irq srcid = "1" srctype = "PTI" isr = "ISR_TICK" dstx = "1" dsty = "0" dstid = "1" /> 115 <irq srcid = "2" srctype = "PTI" isr = "ISR_TICK" dstx = "1" dsty = "0" dstid = "2" /> 116 <irq srcid = "3" srctype = "PTI" isr = "ISR_TICK" dstx = "1" dsty = "0" dstid = "3" /> 117 118 <irq srcid = "8" srctype = "HWI" isr = "ISR_DEFAULT" dstx = "1" dsty = "0" dstid = "0" /> 119 </periph> 110 120 </cluster> 111 121 112 122 <cluster x = "1" y = "1" > 113 <pseg name = "PSEG_RAM" type = "RAM" base = "0x1100000000" length = "0x0 000800000" />123 <pseg name = "PSEG_RAM" type = "RAM" base = "0x1100000000" length = "0x0400000000" /> 114 124 <pseg name = "PSEG_XCU" type = "PERI" base = "0x11F0000000" length = "0x0000002000" /> 115 125 <pseg name = "PSEG_MMC" type = "PERI" base = "0x11E0000000" length = "0x0000001000" /> 116 126 117 <proc index = "0" > 118 <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" /> 119 <irq type = "TIME" icuid = "4" isr = "ISR_SWITCH" /> 120 <irq type = "HARD" icuid = "8" isr = "ISR_DEFAULT" /> 121 </proc> 122 <proc index = "1" > 123 <irq type = "SOFT" icuid = "1" isr = "ISR_WAKUP" /> 124 <irq type = "TIME" icuid = "5" isr = "ISR_SWITCH" /> 125 </proc> 126 <proc index = "2" > 127 <irq type = "SOFT" icuid = "2" isr = "ISR_WAKUP" /> 128 <irq type = "TIME" icuid = "6" isr = "ISR_SWITCH" /> 129 </proc> 130 <proc index = "3" > 131 <irq type = "SOFT" icuid = "3" isr = "ISR_WAKUP" /> 132 <irq type = "TIME" icuid = "7" isr = "ISR_SWITCH" /> 133 </proc> 134 135 <periph type = "XCU" psegname = "PSEG_XCU" channels = "16" /> 136 <periph type = "MMC" psegname = "PSEG_MMC" channels = "1" /> 137 </cluster> 127 <proc index = "0" /> 128 <proc index = "1" /> 129 <proc index = "2" /> 130 <proc index = "3" /> 131 132 <periph type = "MMC" psegname = "PSEG_MMC" > 133 </periph> 134 <periph type = "XCU" psegname = "PSEG_XCU" channels = "16" > 135 <irq srcid = "0" srctype = "WTI" isr = "ISR_WAKUP" dstx = "1" dsty = "1" dstid = "0" /> 136 <irq srcid = "1" srctype = "WTI" isr = "ISR_WAKUP" dstx = "1" dsty = "1" dstid = "1" /> 137 <irq srcid = "2" srctype = "WTI" isr = "ISR_WAKUP" dstx = "1" dsty = "1" dstid = "2" /> 138 <irq srcid = "3" srctype = "WTI" isr = "ISR_WAKUP" dstx = "1" dsty = "1" dstid = "3" /> 139 140 <irq srcid = "0" srctype = "PTI" isr = "ISR_TICK" dstx = "1" dsty = "1" dstid = "0" /> 141 <irq srcid = "1" srctype = "PTI" isr = "ISR_TICK" dstx = "1" dsty = "1" dstid = "1" /> 142 <irq srcid = "2" srctype = "PTI" isr = "ISR_TICK" dstx = "1" dsty = "1" dstid = "2" /> 143 <irq srcid = "3" srctype = "PTI" isr = "ISR_TICK" dstx = "1" dsty = "1" dstid = "3" /> 144 145 <irq srcid = "8" srctype = "HWI" isr = "ISR_DEFAULT" dstx = "1" dsty = "1" dstid = "0" /> 146 </periph> 147 </cluster> 148 149 *** empty clusters 150 151 <cluster x = "0" y = "2" > 152 </cluster> 153 <cluster x = "1" y = "2" > 154 </cluster> 155 138 156 </clusterset> 139 157 140 158 <globalset> 141 159 142 *** Segments used by the boot code / A[31:28] = 0x0 / Identity mapping 143 - seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. The content is reused by the kernel. 144 - seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader The content is not reused by the kernel. 145 - seg_boot_stack is contains the stacks used by all processors during reset and boot. The content is not reused by the Kernel. 146 - seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel. 160 *** Global vsegs associated to peripherals replicated in all clusters (XCU, MMC, SCHED) 161 *** must respect the following policy (checked by the XML parser) : 162 *** vbase[x,y] = vbase[0,0] + 64K * cluster_xy 163 *** pbase[x,y] = pbase[0,0] + 4G * cluster_xy 164 *** ( with cluster_xy = x*16 + y ) 165 *** the vseg type is entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000) 166 *** The cluster index must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000) 167 168 *** 5 global vsegs used by the boot code / A[31:28] = 0x0 / Identity mapping 169 *** seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. Reused by the kernel. 170 *** seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader. Not reused by the kernel. 171 *** seg_boot_stack contains the stacks used by all processors during reset and boot. Not reused by the Kernel. 172 *** seg_boot_buffer is used by the boot-loader. It contains a complete .elf file. Not reused by the kernel. 147 173 148 174 <vseg name = "seg_boot_code" vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" > … … 153 179 </vseg> 154 180 <vseg name = "seg_boot_buffer" vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" > 155 <vobj name = "boot_buffer" type = "BUFFER" length = "0x000 20000" />156 </vseg> 157 <vseg name = "seg_boot_stack" vbase = "0x000 60000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >158 <vobj name = "boot_stack" type = "BUFFER" length = "0x000 90000" />181 <vobj name = "boot_buffer" type = "BUFFER" length = "0x00060000" /> 182 </vseg> 183 <vseg name = "seg_boot_stack" vbase = "0x000A0000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" > 184 <vobj name = "boot_stack" type = "BUFFER" length = "0x00050000" /> 159 185 </vseg> 160 186 <vseg name = "seg_boot_mapping" vbase = "0x000F0000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" > 161 187 <vobj name = "boot_mapping" type = "BLOB" length = "0x00010000" binpath = "map.bin" /> 162 188 </vseg> 163 164 *** Segments used by the kernel / A[31:28] = 0x8189 190 *** 4 global vsegs used by the kernel / A[31:28] = 0x8 / No identity mapping constraint 165 191 166 192 <vseg name = "seg_kernel_code" vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > … … 177 203 </vseg> 178 204 179 *** Segments for non replicated peripherals / A[31:28] = 0xF / Identity mapping180 181 <vseg name = "seg_ioc" vbase = "0xF2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1">205 *** 2 global vsegs for non replicated peripherals in cluster(0,0) / A[31:28] = 0xF / 206 207 <vseg name = "seg_ioc" vbase = "0xF2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" > 182 208 <vobj name = "ioc" type = "PERI" length = "0x00001000" /> 183 209 </vseg> 184 <vseg name = "seg_tty" vbase = "0xF4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" > 210 211 <vseg name = "seg_tty" vbase = "0xF4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" > 185 212 <vobj name = "tty" type = "PERI" length = "0x00001000" /> 186 213 </vseg> 187 <vseg name = "seg_preloader" vbase = "0x00000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" > 214 215 *** 2 global vsegs for pseudo-peripherals (PRELOADER and RAMDISK) / A[31:28] = 0x0 216 217 <vseg name = "seg_reset_code" vbase = "0x00000000" mode = "CX__" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" > 188 218 <vobj name = "preloader" type = "BUFFER" length = "0x00010000" /> 189 219 </vseg> 190 220 191 *** Segments for replicated ICUS / A[31:24] = 0xF0 / Increment = 0x10000 / Identity mapping in cluster 0 221 <vseg name = "seg_ram_disk" vbase = "0x02000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" > 222 <vobj name = "ramdisk" type = "BUFFER" length = "0x02000000" /> 223 </vseg> 224 225 *** 4 global vsegs for replicated ICUS / A[31:24] = 0xF0 / Increment = 0x10000 / Identity mapping in cluster (0,0) 192 226 193 227 <vseg name = "seg_icu_0" vbase = "0xF0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" > … … 204 238 </vseg> 205 239 206 *** segments for replicated MMC / A[31:24] = 0xE0 / Increment = 0x10000 / Identity mapping in cluster 0 207 *** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000) 208 *** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000) 240 *** 4 global vsegs for replicated MMC / A[31:24] = 0xE0 / Increment = 0x10000 / Identity mapping in cluster 0 209 241 210 242 <vseg name = "seg_memc_0" vbase = "0xE0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" > … … 221 253 </vseg> 222 254 223 *** segments for replicated schedulers / A[31:28] = 0xC / Increment = 0x10000 224 *** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000) 225 *** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000) 255 *** 4 global vsegs for replicated schedulers / A[31:28] = 0xC / Increment = 0x10000 226 256 227 257 <vseg name = "seg_sched_0" vbase = "0xC0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > … … 237 267 <vobj name = "sched_3" type = "SCHED" length = "0x00008000" /> 238 268 </vseg> 239 *** 269 240 270 </globalset> 241 271 … … 249 279 250 280 <vspace name = "sort" startname = "sort_data" > 251 <vseg name = "seg_sort_code" vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" > 252 <vobj name = "sort_code" type = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" /> 253 </vseg> 254 <vseg name = "seg_sort_data" vbase = "0x00500000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" > 255 <vobj name = "sort_data" type = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" /> 256 </vseg> 257 <vseg name = "seg_sort_ptab" vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" > 258 <vobj name = "sort_ptab" type = "PTAB" length = "0x00020000" align = "13" /> 259 </vseg> 260 <vseg name = "seg_sort_stack00" vbase = "0x00800000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" > 261 <vobj name = "sort_stack0" type = "BUFFER" length = "0x00010000" /> 262 <vobj name = "sort_stack1" type = "BUFFER" length = "0x00010000" /> 263 <vobj name = "sort_stack2" type = "BUFFER" length = "0x00010000" /> 264 <vobj name = "sort_stack3" type = "BUFFER" length = "0x00010000" /> 265 <vobj name = "sort_heap0" type = "BUFFER" length = "0x00010000" /> 266 </vseg> 267 <vseg name = "seg_sort_stack01" vbase = "0x00A00000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" > 268 <vobj name = "sort_stack4" type = "BUFFER" length = "0x00010000" /> 269 <vobj name = "sort_stack5" type = "BUFFER" length = "0x00010000" /> 270 <vobj name = "sort_stack6" type = "BUFFER" length = "0x00010000" /> 271 <vobj name = "sort_stack7" type = "BUFFER" length = "0x00010000" /> 272 <vobj name = "sort_heap1" type = "BUFFER" length = "0x00010000" /> 273 </vseg> 274 <vseg name = "seg_sort_stack10" vbase = "0x00C00000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" > 275 <vobj name = "sort_stack8" type = "BUFFER" length = "0x00010000" /> 276 <vobj name = "sort_stack9" type = "BUFFER" length = "0x00010000" /> 277 <vobj name = "sort_stack10" type = "BUFFER" length = "0x00010000" /> 278 <vobj name = "sort_stack11" type = "BUFFER" length = "0x00010000" /> 279 <vobj name = "sort_heap2" type = "BUFFER" length = "0x00010000" /> 280 </vseg> 281 <vseg name = "seg_sort_stack11" vbase = "0x00E00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" > 282 <vobj name = "sort_stack12" type = "BUFFER" length = "0x00010000" /> 283 <vobj name = "sort_stack13" type = "BUFFER" length = "0x00010000" /> 284 <vobj name = "sort_stack14" type = "BUFFER" length = "0x00010000" /> 285 <vobj name = "sort_stack15" type = "BUFFER" length = "0x00010000" /> 286 <vobj name = "sort_heap3" type = "BUFFER" length = "0x00010000" /> 287 </vseg> 288 <vseg name = "seg_params" vbase = "0x00F00000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" > 289 <vobj name = "nb_thread" type = "CONST" length = "0x4" init = "16" /> 281 <vseg name = "seg_sort_code" vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" > 282 <vobj name = "sort_code" type = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" /> 283 </vseg> 284 <vseg name = "seg_sort_data" vbase = "0x00500000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" > 285 <vobj name = "sort_data" type = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" /> 286 </vseg> 287 <vseg name = "seg_sort_ptab" vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" > 288 <vobj name = "sort_ptab" type = "PTAB" length = "0x00020000" align = "13" /> 289 </vseg> 290 <vseg name = "seg_sort_stack_0" vbase = "0x00200000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" > 291 <vobj name = "sort_stack_00" type = "BUFFER" length = "0x00010000" /> 292 <vobj name = "sort_stack_01" type = "BUFFER" length = "0x00010000" /> 293 <vobj name = "sort_stack_02" type = "BUFFER" length = "0x00010000" /> 294 <vobj name = "sort_stack_03" type = "BUFFER" length = "0x00010000" /> 295 <vobj name = "sort_heap_0" type = "BUFFER" length = "0x00040000" /> 296 </vseg> 297 <vseg name = "seg_sort_stack_1" vbase = "0x00280000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" > 298 <vobj name = "sort_stack_10" type = "BUFFER" length = "0x00010000" /> 299 <vobj name = "sort_stack_11" type = "BUFFER" length = "0x00010000" /> 300 <vobj name = "sort_stack_12" type = "BUFFER" length = "0x00010000" /> 301 <vobj name = "sort_stack_13" type = "BUFFER" length = "0x00010000" /> 302 <vobj name = "sort_heap_1" type = "BUFFER" length = "0x00040000" /> 303 </vseg> 304 <vseg name = "seg_sort_stack_2" vbase = "0x00300000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" > 305 <vobj name = "sort_stack_20" type = "BUFFER" length = "0x00010000" /> 306 <vobj name = "sort_stack_21" type = "BUFFER" length = "0x00010000" /> 307 <vobj name = "sort_stack_22" type = "BUFFER" length = "0x00010000" /> 308 <vobj name = "sort_stack_23" type = "BUFFER" length = "0x00010000" /> 309 <vobj name = "sort_heap_2" type = "BUFFER" length = "0x00040000" /> 310 </vseg> 311 <vseg name = "seg_sort_stack_3" vbase = "0x00380000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" > 312 <vobj name = "sort_stack_30" type = "BUFFER" length = "0x00010000" /> 313 <vobj name = "sort_stack_31" type = "BUFFER" length = "0x00010000" /> 314 <vobj name = "sort_stack_32" type = "BUFFER" length = "0x00010000" /> 315 <vobj name = "sort_stack_33" type = "BUFFER" length = "0x00010000" /> 316 <vobj name = "sort_heap_3" type = "BUFFER" length = "0x00040000" /> 317 </vseg> 318 319 *** This vobj emulates a command line argument for the sort application 320 321 <vseg name = "seg_params" vbase = "0x00100000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" > 322 <vobj name = "nb_thread" type = "CONST" length = "0x4" init = "16" /> 290 323 </vseg> 291 <task name = "sort_0" x = "0" y = "0" proclocid = "0" stackname = "sort_stack0" heapname = "sort_heap0" startid = "0" usetty = "1" /> 292 <task name = "sort_1" x = "0" y = "0" proclocid = "1" stackname = "sort_stack1" heapname = "sort_heap0" startid = "0" usetty = "1" /> 293 <task name = "sort_2" x = "0" y = "0" proclocid = "2" stackname = "sort_stack2" heapname = "sort_heap0" startid = "0" usetty = "1" /> 294 <task name = "sort_3" x = "0" y = "0" proclocid = "3" stackname = "sort_stack3" heapname = "sort_heap0" startid = "0" usetty = "1" /> 295 <task name = "sort_4" x = "0" y = "1" proclocid = "0" stackname = "sort_stack4" heapname = "sort_heap1" startid = "0" usetty = "1" /> 296 <task name = "sort_5" x = "0" y = "1" proclocid = "1" stackname = "sort_stack5" heapname = "sort_heap1" startid = "0" usetty = "1" /> 297 <task name = "sort_6" x = "0" y = "1" proclocid = "2" stackname = "sort_stack6" heapname = "sort_heap1" startid = "0" usetty = "1" /> 298 <task name = "sort_7" x = "0" y = "1" proclocid = "3" stackname = "sort_stack7" heapname = "sort_heap1" startid = "0" usetty = "1" /> 299 <task name = "sort_8" x = "1" y = "0" proclocid = "0" stackname = "sort_stack8" heapname = "sort_heap2" startid = "0" usetty = "1" /> 300 <task name = "sort_9" x = "1" y = "0" proclocid = "1" stackname = "sort_stack9" heapname = "sort_heap2" startid = "0" usetty = "1" /> 301 <task name = "sort_10" x = "1" y = "0" proclocid = "2" stackname = "sort_stack10" heapname = "sort_heap2" startid = "0" usetty = "1" /> 302 <task name = "sort_11" x = "1" y = "0" proclocid = "3" stackname = "sort_stack11" heapname = "sort_heap2" startid = "0" usetty = "1" /> 303 <task name = "sort_12" x = "1" y = "1" proclocid = "0" stackname = "sort_stack12" heapname = "sort_heap3" startid = "0" usetty = "1" /> 304 <task name = "sort_13" x = "1" y = "1" proclocid = "1" stackname = "sort_stack13" heapname = "sort_heap3" startid = "0" usetty = "1" /> 305 <task name = "sort_14" x = "1" y = "1" proclocid = "2" stackname = "sort_stack14" heapname = "sort_heap3" startid = "0" usetty = "1" /> 306 <task name = "sort_15" x = "1" y = "1" proclocid = "3" stackname = "sort_stack15" heapname = "sort_heap3" startid = "0" usetty = "1" /> 307 324 325 <task name = "sort_00" x = "0" y = "0" proclocid = "0" stackname = "sort_stack_00" heapname = "sort_heap_0" startid = "0" /> 326 <task name = "sort_01" x = "0" y = "0" proclocid = "1" stackname = "sort_stack_01" heapname = "sort_heap_0" startid = "0" /> 327 <task name = "sort_02" x = "0" y = "0" proclocid = "2" stackname = "sort_stack_02" heapname = "sort_heap_0" startid = "0" /> 328 <task name = "sort_03" x = "0" y = "0" proclocid = "3" stackname = "sort_stack_03" heapname = "sort_heap_0" startid = "0" /> 329 330 <task name = "sort_10" x = "0" y = "1" proclocid = "0" stackname = "sort_stack_10" heapname = "sort_heap_1" startid = "0" /> 331 <task name = "sort_11" x = "0" y = "1" proclocid = "1" stackname = "sort_stack_11" heapname = "sort_heap_1" startid = "0" /> 332 <task name = "sort_12" x = "0" y = "1" proclocid = "2" stackname = "sort_stack_12" heapname = "sort_heap_1" startid = "0" /> 333 <task name = "sort_13" x = "0" y = "1" proclocid = "3" stackname = "sort_stack_13" heapname = "sort_heap_1" startid = "0" /> 334 335 <task name = "sort_20" x = "1" y = "0" proclocid = "0" stackname = "sort_stack_20" heapname = "sort_heap_2" startid = "0" /> 336 <task name = "sort_21" x = "1" y = "0" proclocid = "1" stackname = "sort_stack_21" heapname = "sort_heap_2" startid = "0" /> 337 <task name = "sort_22" x = "1" y = "0" proclocid = "2" stackname = "sort_stack_22" heapname = "sort_heap_2" startid = "0" /> 338 <task name = "sort_23" x = "1" y = "0" proclocid = "3" stackname = "sort_stack_23" heapname = "sort_heap_2" startid = "0" /> 339 340 <task name = "sort_30" x = "1" y = "1" proclocid = "0" stackname = "sort_stack_30" heapname = "sort_heap_3" startid = "0" /> 341 <task name = "sort_31" x = "1" y = "1" proclocid = "1" stackname = "sort_stack_31" heapname = "sort_heap_3" startid = "0" /> 342 <task name = "sort_32" x = "1" y = "1" proclocid = "2" stackname = "sort_stack_32" heapname = "sort_heap_3" startid = "0" /> 343 <task name = "sort_33" x = "1" y = "1" proclocid = "3" stackname = "sort_stack_33" heapname = "sort_heap_3" startid = "0" /> 308 344 </vspace> 309 345 </vspaceset> -
soft/giet_vm/pgcd/main.c
r254 r295 1 1 #include "stdio.h" 2 #include "hard_config.h" 2 3 3 4 ///////////////////////////////////////// … … 7 8 unsigned int opy; 8 9 9 giet_tty_printf("Starting task PGCD on processor %d at cycle %d\n", 10 giet_procid(), giet_proctime()); 10 unsigned int procid = giet_procid(); 11 unsigned int cluster_xy = procid/NB_PROCS_MAX; 12 unsigned int lpid = procid%NB_PROCS_MAX; 13 unsigned int x = cluster_xy >> Y_WIDTH; 14 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 15 16 giet_tty_printf( "*** Starting task pgcd on processor[%d,%d,%d] at cycle %d\n\n", 17 x, y, lpid, giet_proctime() ); 11 18 12 19 while (1) -
soft/giet_vm/router/main.c
r264 r295 2 2 #include "mwmr_channel.h" 3 3 #include "mapping_info.h" 4 #include "hard_config.h" 4 5 5 #define NMAX 2006 #define NMAX 50 6 7 7 8 ///////////////////////////////////////////// … … 13 14 mwmr_channel_t* mwmr; 14 15 15 giet_tty_printf( "*** Starting task producer on processor %d", giet_procid() ); 16 giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() ); 16 unsigned int procid = giet_procid(); 17 unsigned int cluster_xy = procid/NB_PROCS_MAX; 18 unsigned int lpid = procid%NB_PROCS_MAX; 19 unsigned int x = cluster_xy >> Y_WIDTH; 20 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 17 21 18 if( giet_vobj_get_vbase( "router" , 19 "mwmr_in", 20 VOBJ_TYPE_MWMR, 21 (void*)&mwmr ) ) 22 { 23 giet_tty_printf( "\n[ERROR] in producer task :\n"); 24 giet_tty_printf( " undefined <mwmr_in> channel: %d\n", mwmr); 25 giet_tty_printf( "*** &mwmr_in = %x\n\n", (unsigned int)mwmr ); 26 giet_exit(); 27 } 22 giet_tty_printf( "*** Starting task producer on processor[%d,%d,%d] at cycle %d\n\n", 23 x, y, lpid, giet_proctime() ); 24 25 giet_vobj_get_vbase( "router" , 26 "mwmr_in", 27 (void*)&mwmr ); 28 28 29 29 // main loop : display token value = source index … … 35 35 } 36 36 37 giet_tty_printf( "\n*** Completing producer task at cycle %d ***\n", giet_proctime()); 38 giet_exit(); 37 giet_exit( "Producer task completed"); 39 38 40 39 } // end producer() … … 47 46 mwmr_channel_t* mwmr; 48 47 49 giet_tty_printf( "*** Starting task consumer on processor %d", giet_procid() ); 50 giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() ); 48 unsigned int procid = giet_procid(); 49 unsigned int cluster_xy = procid/NB_PROCS_MAX; 50 unsigned int lpid = procid%NB_PROCS_MAX; 51 unsigned int x = cluster_xy >> Y_WIDTH; 52 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 51 53 52 if ( giet_vobj_get_vbase( "router" , 53 "mwmr_out", 54 VOBJ_TYPE_MWMR, 55 (void*)&mwmr ) ) 56 { 57 giet_tty_printf( "\n[ERROR] in consumer task :\n"); 58 giet_tty_printf( " undefined <mwmr_out> channel\n"); 59 giet_exit(); 60 } 54 giet_tty_printf( "*** Starting task consumer on processor[%d,%d,%d] at cycle %d\n\n", 55 x, y, lpid, giet_proctime() ); 56 57 giet_vobj_get_vbase( "router" , 58 "mwmr_out", 59 (void*)&mwmr ); 61 60 62 61 // main loop : display token arrival index and value … … 67 66 } 68 67 69 giet_tty_printf( "\n*** Completing consumer task at cycle %d ***\n", giet_proctime()); 70 giet_exit(); 68 giet_exit( "Consumer task completed"); 71 69 72 70 } // end consumer() … … 76 74 { 77 75 unsigned int buf; 78 unsigned int x;76 unsigned int n; 79 77 unsigned int tempo; 80 78 mwmr_channel_t* mwmr_in ; 81 79 mwmr_channel_t* mwmr_out ; 82 80 83 84 giet_tty_printf( "*** Starting task router on processor %d", giet_procid() ); 85 giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() ); 81 unsigned int procid = giet_procid(); 82 unsigned int cluster_xy = procid/NB_PROCS_MAX; 83 unsigned int lpid = procid%NB_PROCS_MAX; 84 unsigned int x = cluster_xy >> Y_WIDTH; 85 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 86 86 87 if ( giet_vobj_get_vbase( "router" , 88 "mwmr_out", 89 VOBJ_TYPE_MWMR, 90 (void*)&mwmr_out ) ) 91 { 92 giet_tty_printf( "\n[ERROR] in router task :\n"); 93 giet_tty_printf( " undefined <mwmr_in> channel\n"); 94 giet_exit(); 95 } 87 giet_tty_printf( "*** Starting task router on processor[%d,%d,%d] at cycle %d\n\n", 88 x, y, lpid, giet_proctime() ); 96 89 97 if ( giet_vobj_get_vbase( "router" , 98 "mwmr_in", 99 VOBJ_TYPE_MWMR, 100 (void*)&mwmr_in ) ) 101 { 102 giet_tty_printf( "\n[ERROR] in router task :\n"); 103 giet_tty_printf( " undefined <mwmr_out> channel\n"); 104 giet_exit(); 105 } 90 giet_vobj_get_vbase( "router" , 91 "mwmr_out", 92 (void*)&mwmr_out ); 106 93 94 giet_vobj_get_vbase( "router" , 95 "mwmr_in", 96 (void*)&mwmr_in ); 107 97 // main loop 108 98 while(1) … … 110 100 mwmr_read( mwmr_in , &buf , 1 ); 111 101 tempo = giet_rand() >> 6; 112 for ( x = 0 ; x < tempo ; x++ ) asm volatile ("");102 for ( n = 0 ; n < tempo ; n++ ) asm volatile (""); 113 103 giet_tty_printf( "token value : %d / temporisation = %d\n", buf, tempo); 114 104 mwmr_write( mwmr_out, &buf , 1 ); -
soft/giet_vm/sort/main.c
r292 r295 1 1 /////////////////////////////////////////////////////////////////////////////// 2 // File : 3 // 4 // main.c 5 // 6 // Date : 7 // 8 // November 2013 9 // 10 // Author : 11 // 12 // Cesar Fuguet Tortolero <cesar.fuguet-tortolero@lip6.fr> 2 // File : main.c 3 // Date : November 2013 4 // Author : Cesar Fuguet Tortolero <cesar.fuguet-tortolero@lip6.fr> 13 5 // 14 6 // Description : … … 38 30 #include "barrier.h" 39 31 40 #define ARRAY_LENGTH 204832 #define ARRAY_LENGTH 512 41 33 #define IPT (ARRAY_LENGTH / *nb_thread) // ITEMS PER THREAD 42 34 … … 47 39 #define VERBOSE 1 48 40 49 /////////////////////////////////////////////////////////////////////// 41 //////////////////////////////////////////////////////////////////////////////// 50 42 // Define printf according to verbosity option and number of available 51 43 // TTY 52 44 53 45 #if (VERBOSE == 1) 54 # define printf(...) giet_tty_printf(__VA_ARGS__) 55 # define puts(...) giet_tty_puts(__VA_ARGS__) 46 # define printf(...) giet_shr_printf(__VA_ARGS__) 56 47 #else // VERBOSE == 0 57 48 # define printf(...) 58 # define puts(...)59 49 #endif 60 50 61 #define task0_printf(...) if(thread_id == 0) giet_ tty_printf(__VA_ARGS__)51 #define task0_printf(...) if(thread_id == 0) giet_shr_printf(__VA_ARGS__) 62 52 63 53 #define exit giet_exit … … 89 79 giet_barrier_t barrier[8]; 90 80 81 ////////////////////////////////////////// 91 82 __attribute__ ((constructor)) void sort() 92 83 { … … 100 91 unsigned int time_end; 101 92 102 if( giet_vobj_get_vbase( "sort" , 103 "nb_thread", 104 VOBJ_TYPE_CONST, 105 (unsigned int*)&nb_thread ) ) 106 { 107 printf( "\n[ERROR] in sort task :\n"); 108 printf( " undefined <nb_thread> constant: %d\n", nb_thread); 109 exit(); 110 } 93 giet_vobj_get_vbase( "sort" , 94 "nb_thread", 95 (unsigned int*)&nb_thread ); 111 96 112 task0_printf(" [Thread 0 ] Starting sort application with %d threads "97 task0_printf("\n[ Thread 0 ] Starting sort application with %d threads " 113 98 "at cycle %d\n", *nb_thread, time_start); 114 99 … … 141 126 // Parallel sort of array elements 142 127 143 printf("[ Thread %d ] Stage 0: ProcessorSorting...\n\r", thread_id);128 printf("[ Thread %d ] Stage 0: Sorting...\n\r", thread_id); 144 129 145 130 bubbleSort(array0, IPT, IPT * thread_id); … … 154 139 if((thread_id % (2 << i)) != 0) 155 140 { 156 printf("[ Thread %d ] Quit s\n\r", thread_id);157 exit( );158 } 159 160 printf("[ Thread %d ] Stage %d: S tarting...\n\r", thread_id, i+1);141 printf("[ Thread %d ] Quit\n\r", thread_id ); 142 exit("Completed"); 143 } 144 145 printf("[ Thread %d ] Stage %d: Sorting...\n\r", thread_id, i+1); 161 146 162 147 if((i % 2) == 0) … … 203 188 204 189 time_end = giet_proctime(); 190 205 191 printf("[ Thread 0 ] Finishing sort application at cycle %d\n" 206 192 "[ Thread 0 ] Time elapsed = %d\n", … … 209 195 if (success) 210 196 { 211 212 printf("[ Thread 0 ] Success!!\n\r"); 197 exit("!!! Success !!!"); 213 198 } 214 199 else 215 200 { 216 printf("[ Thread 0 ] Failure!! Incorrect element: %d\n\r", failure_index); 217 218 201 printf("[ Thread 0 ] Failure!! Incorrect element: %d\n\r", 202 failure_index); 219 203 for(i=0; i<ARRAY_LENGTH; i++) 220 204 { 221 205 printf("array[%d] = %d\n", i, dst_array[i]); 222 206 } 223 }224 }225 226 exit( );207 exit("!!! Failure !!!"); 208 } 209 } 210 exit("Completed"); 227 211 } 228 212 229 void bubbleSort( 230 int *array,231 unsigned int length,232 unsigned int init_pos)213 //////////////////////////////////// 214 void bubbleSort( int * array, 215 unsigned int length, 216 unsigned int init_pos ) 233 217 { 234 218 int i; … … 250 234 } 251 235 236 ///////////// 252 237 void merge( 253 238 int * array,
Note: See TracChangeset
for help on using the changeset viewer.