- Timestamp:
- Aug 9, 2012, 2:38:06 PM (12 years ago)
- Location:
- soft/giet_vm
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/boot/boot_init.c
r198 r199 23 23 // and the mapping: 24 24 // - physical segmentation of the physical address space, 25 // - number of virtual spaces(one multi-task application per vspace),26 // - static placement of tasks on the processors,27 // - staticplacement of virtual segments (vseg) in the physical segments (pseg).28 // - static placement of virtual objects (vobj) on virtual segments (vseg).25 // - virtual spaces definition (one multi-task application per vspace), 26 // - placement of virtual objects (vobj) in the virtual segments (vseg). 27 // - placement of virtual segments (vseg) in the physical segments (pseg). 28 // - placement of tasks on the processors, 29 29 // 30 // The page table are statically constructed in the boot phase, and they do not30 // The page table are statically build in the boot phase, and they do not 31 31 // change during execution. The GIET uses only 4 Kbytes pages. 32 32 // As most applications use only a limited number of segments, the number of PT2s 33 33 // actually used by a given virtual space is generally smaller than 2048, and is 34 // computed using the length of the vobj and stored in the boot_max_pt2 global variable, 35 // which is a table indexed by the vspace_id. 36 37 // defined by the (GIET_NB_PT2_MAX) configuration parameter. 34 // computed during the boot phase. 38 35 // The max number of virtual spaces (GIET_NB_VSPACE_MAX) is a configuration parameter. 39 36 // … … 794 791 mapping_periph_t* periph = boot_get_periph_base( header ); 795 792 796 unsigned int periph_id;797 unsigned int cluster_id;798 unsigned int channels;799 800 793 // checking mapping availability 801 794 if ( header->signature != IN_MAPPING_SIGNATURE ) … … 807 800 } 808 801 809 // checking NB_CLUSTERS802 // checking Rnumber of clusters 810 803 if ( header->clusters != NB_CLUSTERS ) 811 804 { … … 819 812 } 820 813 821 // checking NB_PROC_MAX 814 // checking number of virtual spaces 815 if ( header->vspaces > GIET_NB_VSPACE_MAX ) 816 { 817 boot_puts("\n[BOOT ERROR] : number of vspaces > GIET_NB_VSPACE_MAX\n"); 818 boot_puts("\n"); 819 boot_exit(); 820 } 821 822 // checking harware 823 unsigned int periph_id; 824 unsigned int cluster_id; 825 unsigned int channels; 826 unsigned int tty_found = 0; 827 unsigned int nic_found = 0; 822 828 for ( cluster_id = 0 ; cluster_id < NB_CLUSTERS ; cluster_id++ ) 823 829 { 830 // NB_PROCS_MAX 824 831 if ( cluster[cluster_id].procs > NB_PROCS_MAX ) 825 832 { 826 833 boot_puts("\n[BOOT ERROR] too much processors in cluster "); 827 834 boot_putw( cluster_id ); 828 boot_puts("\n - In giet_config, NB_PROCS_MAX = "); 829 boot_putw ( NB_PROCS_MAX ); 830 boot_puts("\n - In mapping_info, nprocs = "); 835 boot_puts(" : procs = "); 831 836 boot_putw ( cluster[cluster_id].procs ); 832 837 boot_puts("\n"); 833 838 boot_exit(); 834 839 } 835 } 836 837 // checking number of virtual spaces 838 if ( header->vspaces > GIET_NB_VSPACE_MAX ) 839 { 840 boot_puts("\n[BOOT ERROR] : number of vspaces > GIET_NB_VSPACE_MAX\n"); 841 boot_puts("\n"); 842 boot_exit(); 843 } 844 845 // checking TTY number 846 cluster_id = header->tty_clusterid; 847 for ( periph_id = cluster[cluster_id].periph_offset ; 848 periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs ; 849 periph_id++ ) 850 { 851 if ( periph[periph_id].type == PERIPH_TYPE_TTY ) 852 { 853 channels = periph[periph_id].channels; 854 break; 855 } 856 857 } 858 if ( channels > NB_TTYS ) 859 { 860 boot_puts("\n[BOOT ERROR] Incoherent NB_TTYS"); 861 boot_puts("\n - In giet_config, value = "); 862 boot_putw ( NB_TTYS ); 863 boot_puts("\n - In mapping_info, value = "); 864 boot_putw ( channels ); 865 boot_puts("\n"); 866 boot_exit(); 867 } 868 869 // TODO same type of checking for TIMERS, DMAS, NIC channels 870 840 841 for ( periph_id = cluster[cluster_id].periph_offset ; 842 periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs ; 843 periph_id++ ) 844 { 845 // NB_TTYS 846 if ( periph[periph_id].type == PERIPH_TYPE_TTY ) 847 { 848 if ( tty_found ) 849 { 850 boot_puts("\n[BOOT ERROR] TTY component should not be replicated\n"); 851 boot_exit(); 852 } 853 if ( periph[periph_id].channels > NB_TTYS ) 854 { 855 boot_puts("\n[BOOT ERROR] Too much TTY terminals in cluster "); 856 boot_putw( cluster_id ); 857 boot_puts(" : ttys = "); 858 boot_putw ( periph[periph_id].channels ); 859 boot_puts("\n"); 860 boot_exit(); 861 } 862 tty_found = 1; 863 } 864 // NB_NICS 865 if ( periph[periph_id].type == PERIPH_TYPE_NIC ) 866 { 867 if ( nic_found ) 868 { 869 boot_puts("\n[BOOT ERROR] NIC component should not be replicated\n"); 870 boot_exit(); 871 } 872 if ( periph[periph_id].channels > NB_NICS ) 873 { 874 boot_puts("\n[BOOT ERROR] Too much NIC channels in cluster "); 875 boot_putw( cluster_id ); 876 boot_puts(" : nics = "); 877 boot_putw ( periph[periph_id].channels ); 878 boot_puts("\n"); 879 boot_exit(); 880 } 881 nic_found = 1; 882 } 883 // NB_TIMERS 884 if ( periph[periph_id].type == PERIPH_TYPE_TIM ) 885 { 886 if ( periph[periph_id].channels > NB_TIMERS_MAX ) 887 { 888 boot_puts("\n[BOOT ERROR] Too much user timers in cluster "); 889 boot_putw( cluster_id ); 890 boot_puts(" : timers = "); 891 boot_putw ( periph[periph_id].channels ); 892 boot_puts("\n"); 893 boot_exit(); 894 } 895 } 896 // NB_DMAS 897 if ( periph[periph_id].type == PERIPH_TYPE_DMA ) 898 { 899 if ( periph[periph_id].channels > NB_DMAS_MAX ) 900 { 901 boot_puts("\n[BOOT ERROR] Too much DMA channels in cluster "); 902 boot_putw( cluster_id ); 903 boot_puts(" : channels = "); 904 boot_putw ( periph[periph_id].channels ); 905 boot_puts("\n"); 906 boot_exit(); 907 } 908 } 909 } // end for periphs 910 } // end for clusters 871 911 } // end boot_check_mapping() 872 912 … … 1419 1459 task_id++ ) 1420 1460 { 1421 // ra : the return address is &boot_eret()1422 unsigned int ra = (unsigned int)&boot_eret;1423 1424 // sr : value required before an eret instruction1425 unsigned int sr = 0x0000FF13;1426 1427 // ptpr : page table physical base address (shifted by 13 bit)1428 unsigned int ptpr = (unsigned int)boot_ptabs_paddr[vspace_id] >> 13;1429 1430 // ptab : page_table virtual base address (not a register)1431 unsigned int ptab = (unsigned int)boot_ptabs_vaddr[vspace_id];1432 1433 // tty : terminal global index provided by a global allocator1434 unsigned int tty = 0xFFFFFFFF;1461 // ctx_ra : the return address is &boot_eret() 1462 unsigned int ctx_ra = (unsigned int)&boot_eret; 1463 1464 // ctx_sr : value required before an eret instruction 1465 unsigned int ctx_sr = 0x0000FF13; 1466 1467 // ctx_ptpr : page table physical base address (shifted by 13 bit) 1468 unsigned int ctx_ptpr = (unsigned int)boot_ptabs_paddr[vspace_id] >> 13; 1469 1470 // ctx_ptab : page_table virtual base address 1471 unsigned int ctx_ptab = (unsigned int)boot_ptabs_vaddr[vspace_id]; 1472 1473 // ctx_tty : terminal global index provided by a global allocator 1474 unsigned int ctx_tty = 0xFFFFFFFF; 1435 1475 if ( task[task_id].use_tty ) 1436 1476 { … … 1444 1484 boot_exit(); 1445 1485 } 1446 tty = alloc_tty_channel;1486 ctx_tty = alloc_tty_channel; 1447 1487 alloc_tty_channel++; 1448 1488 } 1449 1489 1450 // nic : NIC channel global index provided by a global allocator1451 unsigned int nic = 0xFFFFFFFF;1490 // ctx_nic : NIC channel global index provided by a global allocator 1491 unsigned int ctx_nic = 0xFFFFFFFF; 1452 1492 if ( task[task_id].use_nic ) 1453 1493 { … … 1461 1501 boot_exit(); 1462 1502 } 1463 nic = alloc_nic_channel;1503 ctx_nic = alloc_nic_channel; 1464 1504 alloc_nic_channel++; 1465 1505 } 1466 1506 1467 // timer : user TIMER global index provided by a cluster allocator1468 unsigned int timer = 0xFFFFFFFF;1507 // ctx_timer : user TIMER global index provided by a cluster allocator 1508 unsigned int ctx_timer = 0xFFFFFFFF; 1469 1509 if ( task[task_id].use_timer ) 1470 1510 { … … 1479 1519 boot_exit(); 1480 1520 } 1481 timer = cluster_id*NB_TIMERS_MAX + alloc_timer_channel[cluster_id];1521 ctx_timer = cluster_id*NB_TIMERS_MAX + alloc_timer_channel[cluster_id]; 1482 1522 alloc_timer_channel[cluster_id]++; 1483 1523 } 1484 1524 1485 // fbdma : DMA global index provided by a cluster allocator1486 unsigned int fbdma = 0xFFFFFFFF;1525 // ctx_fbdma : DMA global index provided by a cluster allocator 1526 unsigned int ctx_fbdma = 0xFFFFFFFF; 1487 1527 if ( task[task_id].use_fbdma ) 1488 1528 { … … 1497 1537 boot_exit(); 1498 1538 } 1499 fbdma = cluster_id*NB_DMAS_MAX + alloc_fbdma_channel[cluster_id];1539 ctx_fbdma = cluster_id*NB_DMAS_MAX + alloc_fbdma_channel[cluster_id]; 1500 1540 alloc_fbdma_channel[cluster_id]++; 1501 1541 } 1502 1542 1503 // epc : Get the (virtual) base address of the start_vector containing 1504 // the start addresses for all tasks defined in the vspace. 1543 // ctx_epc : Get the virtual address of the start function 1505 1544 mapping_vobj_t* pvobj = &vobj[vspace[vspace_id].vobj_offset + 1506 1545 vspace[vspace_id].start_offset]; 1507 1546 unsigned int* start_vector_vbase = (unsigned int*)pvobj->vaddr; 1508 unsigned int epc = start_vector_vbase[task[task_id].startid];1509 1510 // sp : Get the vobj containing the stack1547 unsigned int ctx_epc = start_vector_vbase[task[task_id].startid]; 1548 1549 // ctx_sp : Get the vobj containing the stack 1511 1550 unsigned int vobj_id = task[task_id].vobjlocid + vspace[vspace_id].vobj_offset; 1512 unsigned int sp = vobj[vobj_id].vaddr + vobj[vobj_id].length;1551 unsigned int ctx_sp = vobj[vobj_id].vaddr + vobj[vobj_id].length; 1513 1552 1514 1553 // compute gpid = global processor index … … 1516 1555 task[task_id].proclocid; 1517 1556 1518 // sched : scheduler physical address1519 unsigned int sched = (unsigned int)boot_schedulers_paddr[gpid];1520 1521 1557 // In the code below, we access the scheduler with specific access 1522 1558 // functions, because we only have the physical address of the scheduler, … … 1526 1562 unsigned int ltid = boot_scheduler_get_tasks( gpid ); 1527 1563 1528 if ( ltid >= 15)1564 if ( ltid >= IDLE_TASK_INDEX ) 1529 1565 { 1530 1566 boot_puts("\n[BOOT ERROR] : "); … … 1543 1579 1544 1580 // initializes the task context in scheduler[gpid] 1545 boot_scheduler_set_context( gpid, ltid, CTX_SR_ID , sr ); 1546 boot_scheduler_set_context( gpid, ltid, CTX_SP_ID , sp ); 1547 boot_scheduler_set_context( gpid, ltid, CTX_RA_ID , ra ); 1548 boot_scheduler_set_context( gpid, ltid, CTX_EPC_ID , epc ); 1549 boot_scheduler_set_context( gpid, ltid, CTX_PTPR_ID , ptpr ); 1550 boot_scheduler_set_context( gpid, ltid, CTX_TTY_ID , tty ); 1551 boot_scheduler_set_context( gpid, ltid, CTX_TIMER_ID , timer ); 1552 boot_scheduler_set_context( gpid, ltid, CTX_FBDMA_ID , fbdma ); 1553 boot_scheduler_set_context( gpid, ltid, CTX_PTAB_ID , ptab ); 1554 boot_scheduler_set_context( gpid, ltid, CTX_SCHED_ID , sched ); 1581 boot_scheduler_set_context( gpid, ltid, CTX_SR_ID , ctx_sr ); 1582 boot_scheduler_set_context( gpid, ltid, CTX_SP_ID , ctx_sp ); 1583 boot_scheduler_set_context( gpid, ltid, CTX_RA_ID , ctx_ra ); 1584 boot_scheduler_set_context( gpid, ltid, CTX_EPC_ID , ctx_epc ); 1585 boot_scheduler_set_context( gpid, ltid, CTX_PTPR_ID , ctx_ptpr ); 1586 boot_scheduler_set_context( gpid, ltid, CTX_TTY_ID , ctx_tty ); 1587 boot_scheduler_set_context( gpid, ltid, CTX_FBDMA_ID , ctx_fbdma ); 1588 boot_scheduler_set_context( gpid, ltid, CTX_NIC_ID , ctx_nic ); 1589 boot_scheduler_set_context( gpid, ltid, CTX_TIMER_ID , ctx_timer ); 1590 boot_scheduler_set_context( gpid, ltid, CTX_PTAB_ID , ctx_ptab ); 1591 boot_scheduler_set_context( gpid, ltid, CTX_LTID_ID , ltid ); 1592 boot_scheduler_set_context( gpid, ltid, CTX_VSID_ID , vspace_id ); 1593 boot_scheduler_set_context( gpid, ltid, CTX_RUN_ID , 1 ); 1555 1594 1556 1595 #if BOOT_DEBUG_SCHED … … 1559 1598 boot_puts(" allocated to processor "); 1560 1599 boot_putw( gpid ); 1561 boot_puts(" / ltid= ");1600 boot_puts(" - ctx[LTID] = "); 1562 1601 boot_putw( ltid ); 1563 1602 boot_puts("\n"); 1564 1603 1565 boot_puts(" - SR = "); 1566 boot_putw( sr ); 1567 boot_puts("\n"); 1568 1569 boot_puts(" - SP = "); 1570 boot_putw( sp ); 1571 boot_puts("\n"); 1572 1573 boot_puts(" - RA = "); 1574 boot_putw( ra ); 1575 boot_puts("\n"); 1576 1577 boot_puts(" - EPC = "); 1578 boot_putw( epc ); 1579 boot_puts("\n"); 1580 1581 boot_puts(" - PTPR = "); 1582 boot_putw( ptpr<<13 ); 1583 boot_puts("\n"); 1584 1585 boot_puts(" - TTY = "); 1586 boot_putw( tty ); 1587 boot_puts("\n"); 1588 1589 boot_puts(" - TIMER = "); 1590 boot_putw( timer ); 1591 boot_puts("\n"); 1592 1593 boot_puts(" - FBDMA = "); 1594 boot_putw( fbdma ); 1595 boot_puts("\n"); 1596 1597 boot_puts(" - PTAB = "); 1598 boot_putw( ptab ); 1599 boot_puts("\n"); 1600 1601 boot_puts(" - SCHED = "); 1602 boot_putw( sched ); 1603 boot_puts("\n"); 1604 boot_puts(" - ctx[SR] = "); 1605 boot_putw( ctx_sr ); 1606 boot_puts("\n"); 1607 1608 boot_puts(" - ctx[SR] = "); 1609 boot_putw( ctx_sp ); 1610 boot_puts("\n"); 1611 1612 boot_puts(" - ctx[RA] = "); 1613 boot_putw( ctx_ra ); 1614 boot_puts("\n"); 1615 1616 boot_puts(" - ctx[EPC] = "); 1617 boot_putw( ctx_epc ); 1618 boot_puts("\n"); 1619 1620 boot_puts(" - ctx[PTPR] = "); 1621 boot_putw( ctx_ptpr ); 1622 boot_puts("\n"); 1623 1624 boot_puts(" - ctx[TTY] = "); 1625 boot_putw( ctx_tty ); 1626 boot_puts("\n"); 1627 1628 boot_puts(" - ctx[NIC] = "); 1629 boot_putw( ctx_nic ); 1630 boot_puts("\n"); 1631 1632 boot_puts(" - ctx[TIMER] = "); 1633 boot_putw( ctx_timer ); 1634 boot_puts("\n"); 1635 1636 boot_puts(" - ctx[FBDMA] = "); 1637 boot_putw( ctx_fbdma ); 1638 boot_puts("\n"); 1639 1640 boot_puts(" - ctx[PTAB] = "); 1641 boot_putw( ctx_ptab ); 1642 boot_puts("\n"); 1643 1644 boot_puts(" - ctx[VSID] = "); 1645 boot_putw( vspace_id ); 1646 boot_puts("\n"); 1647 1604 1648 #endif 1605 1649 -
soft/giet_vm/boot/reset.S
r189 r199 115 115 jal boot_puts 116 116 nop 117 mfc0 a0, CP0_B AR117 mfc0 a0, CP0_BVAR 118 118 jal boot_putw 119 119 nop -
soft/giet_vm/giet_config.h
r197 r199 13 13 14 14 #define BOOT_DEBUG_PERI 0 /* display peripherals initialisation on TTY0 */ 15 #define BOOT_DEBUG_PT 1/* display page tables initialisation on TTY0 */15 #define BOOT_DEBUG_PT 0 /* display page tables initialisation on TTY0 */ 16 16 #define BOOT_DEBUG_VOBJS 0 /* display vobjs initialisation on TTY0 */ 17 #define BOOT_DEBUG_SCHED 1/* display schedulers initialisation on TTY0 */17 #define BOOT_DEBUG_SCHED 0 /* display schedulers initialisation on TTY0 */ 18 18 19 #define GIET_DEBUG_INIT 0/* display parallel kernel initialisation on TTY0 */19 #define GIET_DEBUG_INIT 1 /* display parallel kernel initialisation on TTY0 */ 20 20 #define GIET_DEBUG_SWITCH 0 /* display context switchs on TTY0 */ 21 21 … … 31 31 #define NB_DMAS_MAX 1 /* max number of DMA channels per cluster*/ 32 32 #define NB_TTYS 8 /* total number of TTY channels */ 33 #define NB_IOCS 1/* total number of IOC channels */34 #define NB_NICS 1/* total number of NIC channels */33 #define NB_IOCS 0 /* total number of IOC channels */ 34 #define NB_NICS 0 /* total number of NIC channels */ 35 35 36 36 /* software parameters */ -
soft/giet_vm/hello/main.c
r191 r199 3 3 __attribute__((constructor)) void main() 4 4 { 5 unsigned int i;6 5 char byte; 7 6 unsigned int proc = giet_procid(); 7 unsigned int* illegal = 0xFFFFFFF0; 8 8 9 for( i=0 ; i<1000 ; i++)9 while (1) 10 10 { 11 if( giet_tty_printf(" hello from processor %d\n", proc) ) 12 { 13 giet_tty_puts("echec tty_printf\n"); 14 giet_exit(); 15 } 16 if( giet_tty_getc((void*)&byte) ) 17 { 18 giet_tty_puts("echec tty_getc_irq\n"); 19 giet_exit(); 20 } 11 giet_tty_printf(" hello from processor %d\n", proc); 12 giet_tty_getc((void*)&byte); 21 13 if ( byte == 'q' ) giet_exit(); 14 if ( byte == 'x' ) *illegal = 1; 22 15 } 23 giet_exit();24 25 16 } // end main 26 17 -
soft/giet_vm/sys/common.c
r189 r199 324 324 return _physical_read_access( &(psched->current) ); 325 325 } 326 //////////////////////////////////////////////////////////////////////////// 327 // _set_current_task_id() 328 // This function returns the index of the currently running task. 329 //////////////////////////////////////////////////////////////////////////// 330 void _set_current_task_id( unsigned int value ) 331 { 332 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 333 _physical_write_access( &(psched->current), value ); 334 } 326 335 /////////////////////////////////////////////////////////////////////////////// 327 // _get_c urrent_context_slot()328 // This function returns the global TTY index for the currently running task.336 // _get_context_slot() 337 // This function returns a slot content for the task defined by task_id. 329 338 /////////////////////////////////////////////////////////////////////////////// 330 unsigned int _get_current_context_slot(unsigned int slot_id) 331 { 332 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 333 unsigned int current = _physical_read_access( &(psched->current) ); 334 return _physical_read_access( &(psched->context[current][slot_id]) ); 335 } 336 /////////////////////////////////////////////i////////////////////////////////// 339 unsigned int _get_context_slot( unsigned int task_id, 340 unsigned int slot_id ) 341 { 342 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 343 return _physical_read_access( &(psched->context[task_id][slot_id]) ); 344 } 345 /////////////////////////////////////////////////////////////////////////////// 346 // _set_context_slot() 347 // This function returns a slot content for the task defined by task_id. 348 /////////////////////////////////////////////////////////////////////////////// 349 void _set_context_slot( unsigned int task_id, 350 unsigned int slot_id, 351 unsigned int value ) 352 { 353 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 354 _physical_write_access( &(psched->context[task_id][slot_id]), value ); 355 } 356 //////////////////////////////////////////////////////////////////////////////// 337 357 // _get_interrupt_vector_entry() 338 358 // This function returns the interrupt_vector entry defined by argument index. … … 342 362 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 343 363 return _physical_read_access( &(psched->interrupt_vector[index]) ); 344 }345 ////////////////////////////////////////////////////////////////////////////346 // _set_current_task_id()347 // This function returns the index of the currently running task.348 ////////////////////////////////////////////////////////////////////////////349 void _set_current_task_id( unsigned int value )350 {351 static_scheduler_t* psched = (static_scheduler_t*)_get_sched();352 _physical_write_access( &(psched->current), value );353 364 } 354 365 -
soft/giet_vm/sys/common.h
r189 r199 36 36 void _putd(unsigned int val); 37 37 38 unsigned int _strncmp(const char* s1, const char* s2, unsigned int n); 38 unsigned int _strncmp( const char* s1, 39 const char* s2, 40 unsigned int n ); 39 41 40 void _dcache_buf_invalidate(const void *buffer, unsigned int size); 41 42 void _itoa_dec(unsigned int val, char* buf); 43 void _itoa_hex(unsigned int val, char* buf); 42 void _dcache_buf_invalidate( const void *buffer, 43 unsigned int size ); 44 44 45 45 void _dtlb_off(void); … … 55 55 unsigned int _get_sched(void); 56 56 57 unsigned int _get_current_context_slot(unsigned int index); 57 unsigned int _get_context_slot( unsigned int task_id, 58 unsigned int slot_id ); 59 60 void _set_context_slot( unsigned int task_id, 61 unsigned int slot_id, 62 unsigned int value ); 63 58 64 unsigned int _get_interrupt_vector_entry(unsigned int index); 59 unsigned int _get_current_task_id(void); 65 66 unsigned int _get_current_task_id( void ); 67 void _set_current_task_id( unsigned int value ); 68 60 69 unsigned int _get_tasks_number(void); 61 70 62 void _set_current_task_id( unsigned int value);63 71 64 72 void _get_lock(unsigned int* lock); -
soft/giet_vm/sys/ctx_handler.c
r189 r199 1 /////////////////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////////////////// 2 2 // File : ctx_handler.c 3 3 // Date : 01/04/2012 4 4 // Authors : alain greiner & joel porquet 5 5 // Copyright (c) UPMC-LIP6 6 /////////////////////////////////////////////////////////////////////////////////////// 6 ///////////////////////////////////////////////////////////////////////////////////////// 7 7 // The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel. 8 8 // This code is used to support context switch when several tasks are executing 9 9 // in time multiplexing on a single processor. 10 // The tasks must be statically allocated to a processor in the boot phase, and 11 // there is one private scheduler per processor. 12 // Each sheduler contains up to 15 task contexts. 13 /////////////////////////////////////////////////////////////////////////////////////// 10 // The tasks are statically allocated to a processor in the boot phase, and 11 // there is one private scheduler per processor. Each sheduler occupies 4K bytes, 12 // and contains up to 14 task contexts (task_id is from 0 to 13). 13 // The task context [14] is reserved for the "idle" task that does nothing, and 14 // is launched by the scheduler when there is no other runable task. 15 ///////////////////////////////////////////////////////////////////////////////////////// 14 16 15 17 #include <giet_config.h> … … 20 22 #include <sys_handler.h> 21 23 22 /////////////////////////////////////////////////////////////////////////////////////// 24 ///////////////////////////////////////////////////////////////////////////////////////// 23 25 // A task context is an array of 64 words = 256 bytes. 24 // It contains copies of processor registers (when the task is preempted), 25 // and some general informations associated to the task. 26 // It contains copies of processor registers (when the task is preempted): 27 // - GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved. 28 // - HI & LO registers 29 // - CP0 registers: EPC, SR, CR, BVAR 30 // - CP2 registers : PTPR 31 // It contains some general informations associated to the task: 32 // - TTY : terminal global index 33 // - FBDMA : DMA channel global index 34 // - NIC : NIC channel global index 35 // - TIMER : Timer global index 36 // - PTAB : page table virtual base address 37 // - LTID : Task local index (in scheduler) 38 // - VSID : Virtual space index 39 // - RUN : Task state (0 => sleeping / 1 => runable ) 26 40 // 27 // - It contains GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved. 28 // - It contains HI & LO registers. 29 // - It contains CP0 registers: EPC, SR, CR, SCHED 30 // - It contains CP2 registers : PTPR and MODE. 31 // - It contains TTY global index, the FBDMA global index, the virtual base 32 // address of the page table (PTAB), and the task global index (TASK). 33 // 34 // ctx[0]<- SR|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY 35 // ctx[1]<- $1|ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR |ctx[41]<- FBDMA 36 // ctx[2]<- $2|ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- *** |ctx[42]<- PTAB 37 // ctx[3]<- $3|ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- PTPR|ctx[43]<- TASK 38 // ctx[4]<- $4|ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- MODE|ctx[44]<- SCHED 39 // ctx[5]<- $5|ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- TIMER 40 // ctx[6]<- $6|ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- *** 41 // ctx[7]<- $7|ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- *** |ctx[47]<- *** 42 //////////////////////////////////////////////////////////////////////////////////////// 41 // ctx[0]<- ***|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY 42 // ctx[1]<- $1 |ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR |ctx[41]<- FBDMA 43 // ctx[2]<- $2 |ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- SR |ctx[42]<- NIC 44 // ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIMER 45 // ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- *** |ctx[44]<- PTAB 46 // ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- LTID 47 // ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- VSID 48 // ctx[7]<- $7 |ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- PTPR |ctx[47]<- RUN 49 ////////////////////////////////////////////////////////////////////////////////////////// 43 50 44 51 extern void _task_switch(unsigned int*, unsigned int*); … … 47 54 // _ctx_switch() 48 55 // This function performs a context switch between the running task 49 // and another task, using a round-robin sheduling policy. 56 // and another task, using a round-robin sheduling policy between all 57 // tasks allocated to a given processor (static allocation). 58 // It selects the next runable task to resume execution. 59 // If the only runable task is the current task, return without context switch. 60 // If there is no runable task, the scheduler switch to the default "idle" task. 50 61 // 51 // I t desactivate the DTLB, to directly access the scheduler using52 // the physical address stored in register CP0_SCHED.53 // All the context switch procedure is executed with interrupts masked.54 // 55 // The return address contained in $31 is saved in the current task context56 // (in the ctx[31] slot), and the function actually returns to the address57 // contained in the ctx[31] slot of the next task context.62 // Implementation notes: 63 // - As we only have the scheduler physical address (in CP0_SCHED register), 64 // this function must use specific assess functions to access the scheduler. 65 // - All the context switch procedure is executed with interrupts masked. 66 // - The return address contained in $31 is saved in the current task context 67 // (in the ctx[31] slot), and the function actually returns to the address 68 // contained in the ctx[31] slot of the next task context. 58 69 ///////////////////////////////////////////////////////////////////////////////// 59 70 void _ctx_switch() 60 71 { 61 unsigned int tasks;62 unsigned int curr_task_id;63 unsigned int next_task_id;64 unsigned int *curr_ctx_paddr;65 unsigned int *next_ctx_paddr;66 67 72 // get scheduler physical address 68 73 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 69 74 70 75 // get number of tasks allocated to scheduler 71 tasks = _get_tasks_number();76 unsigned int tasks = _get_tasks_number(); 72 77 73 // no switch if only one task 74 if ( tasks > 1) 78 // get current task index 79 unsigned int curr_task_id = _get_current_task_id(); 80 81 // select the next task using a round-robin policy 82 unsigned int next_task_id; 83 unsigned int tid; 84 unsigned int found = 0; 85 86 for ( tid = curr_task_id + 1 ; 87 tid < curr_task_id + 1 + tasks ; 88 tid++ ) 75 89 { 76 // compute the context physical address for the current task 77 curr_task_id = _get_current_task_id(); 78 curr_ctx_paddr = &(psched->context[curr_task_id][0]); 79 80 // select the next task using a round-robin policy 81 next_task_id = (curr_task_id + 1) % tasks; 82 83 // compute the context physical address for the next task 84 next_ctx_paddr = &(psched->context[next_task_id][0]); 90 next_task_id = tid % tasks; 85 91 86 // update the scheduler state 92 // test if the task is runable 93 if ( _get_context_slot( next_task_id, CTX_RUN_ID ) ) 94 { 95 found = 1; 96 break; 97 } 98 } 99 100 // launch "idle" task if no runable task 101 if ( found == 0 ) 102 { 103 next_task_id = IDLE_TASK_INDEX; 104 } 105 106 // no switch if no change 107 if ( curr_task_id != next_task_id ) 108 { 109 unsigned int* curr_ctx_paddr = &(psched->context[curr_task_id][0]); 110 unsigned int* next_ctx_paddr = &(psched->context[next_task_id][0]); 111 87 112 _set_current_task_id( next_task_id ); 113 _task_switch( curr_ctx_paddr, next_ctx_paddr ); 88 114 89 115 #if GIET_DEBUG_SWITCH 90 116 _get_lock( &_tty_put_lock ); 91 _puts( "\n[GIET ] Context switch for processor ");92 _put w( _procid() );117 _puts( "\n[GIET DEBUG] Context switch for processor "); 118 _putd( _procid() ); 93 119 _puts( " at cycle "); 94 _put w( _proctime() );120 _putd( _proctime() ); 95 121 _puts("\n"); 96 122 _puts( " - tasks = "); 97 _put w( tasks );123 _putd( tasks ); 98 124 _puts("\n"); 99 125 _puts( " - curr_task_id = "); 100 _put w( curr_task_id );126 _putd( curr_task_id ); 101 127 _puts("\n"); 102 128 _puts( " - next_task_id = "); 103 _put w( next_task_id );129 _putd( next_task_id ); 104 130 _puts("\n"); 105 131 _release_lock( &_tty_put_lock ); 106 132 #endif 107 133 108 // makes the task switch109 _task_switch( curr_ctx_paddr, next_ctx_paddr ); 134 } 135 } //end _ctx_switch() 110 136 111 /* 112 asm volatile( "ori $27, $0, 0xB \n" 113 "mtc2 $27, $1 \n" // desactivate DTLB 137 ///////////////////////////////////////////////////////////////////////////////////// 138 // This function is executed as the"idle" task when no other task can be executed 139 ///////////////////////////////////////////////////////////////////////////////////// 140 void _ctx_idle() 141 { 142 unsigned int delay = 1000000; 114 143 115 "add $27, %0, $0 \n" // $27 <= &curr_ctx 144 while(1) 145 { 146 asm volatile("move $3, %0 \n" 147 "loop: \n" 148 "addi $3, $3, -1 \n" 149 "bnez $3, loop \n" 150 "nop \n" 151 : 152 : "r"(delay) 153 : "$3" ); 116 154 117 "mfc0 $26, $12 \n" // $26 <= SR 118 "sw $26, 0*4($27) \n" // ctx[0] <= SR 119 ".set noat \n" 120 "sw $1, 1*4($27) \n" // ctx[1] <= $1 121 ".set at \n" 122 "sw $2, 2*4($27) \n" // ctx[2] <= $2 123 "sw $3, 3*4($27) \n" // ctx[3] <= $3 124 "sw $4, 4*4($27) \n" // ctx[4] <= $4 125 "sw $5, 5*4($27) \n" // ctx[5] <= $5 126 "sw $6, 6*4($27) \n" // ctx[6] <= $6 127 "sw $7, 7*4($27) \n" // ctx[7] <= $7 128 "sw $8, 8*4($27) \n" // ctx[8] <= $8 129 "sw $9, 9*4($27) \n" // ctx[9] <= $9 130 "sw $10, 10*4($27) \n" // ctx[10] <= $10 131 "sw $11, 11*4($27) \n" // ctx[11] <= $11 132 "sw $12, 12*4($27) \n" // ctx[12] <= $12 133 "sw $13, 13*4($27) \n" // ctx[13] <= $13 134 "sw $14, 14*4($27) \n" // ctx[14] <= $14 135 "sw $15, 15*4($27) \n" // ctx[15] <= $15 136 "sw $16, 16*4($27) \n" // ctx[16] <= $16 137 "sw $17, 17*4($27) \n" // ctx[17] <= $17 138 "sw $18, 18*4($27) \n" // ctx[18] <= $18 139 "sw $19, 19*4($27) \n" // ctx[19] <= $19 140 "sw $20, 20*4($27) \n" // ctx[20] <= $20 141 "sw $21, 21*4($27) \n" // ctx[21] <= $21 142 "sw $22, 22*4($27) \n" // ctx[22] <= $22 143 "sw $23, 23*4($27) \n" // ctx[23] <= $23 144 "sw $24, 24*4($27) \n" // ctx[24] <= $24 145 "sw $25, 25*4($27) \n" // ctx[25] <= $25 146 "mflo $26 \n" 147 "sw $26, 26*4($27) \n" // ctx[26] <= LO 148 "mfhi $26 \n" 149 "sw $26, 27*4($27) \n" // ctx[27] <= H1 150 "sw $28, 28*4($27) \n" // ctx[28] <= $28 151 "sw $29, 29*4($27) \n" // ctx[29] <= $29 152 "sw $30, 30*4($27) \n" // ctx[30] <= $30 153 "sw $31, 31*4($27) \n" // ctx[31] <= $31 154 "mfc0 $26, $14 \n" 155 "sw $26, 32*4($27) \n" // ctx[32] <= EPC 156 "mfc0 $26, $13 \n" 157 "sw $26, 33*4($27) \n" // ctx[33] <= CR 158 "mfc2 $26, $0 \n" 159 "sw $26, 35*4($27) \n" // ctx[35] <= PTPR 155 _get_lock( &_tty_put_lock ); 156 _puts( "\n[GIET WARNING] Processor "); 157 _putd( _procid() ); 158 _puts( " still idle at cycle "); 159 _putd( _proctime() ); 160 _puts("\n"); 161 _release_lock( &_tty_put_lock ); 162 163 } 164 } // end ctx_idle() 160 165 161 "add $27, %1, $0 \n" // $27<= &next_ctx 166 ///////////////////////////////////////////////////////////////////////////////// 167 // The address of this functionis used to initialise the return address 168 // in the "idle" task context. 169 ///////////////////////////////////////////////////////////////////////////////// 170 void _ctx_eret() 171 { 172 asm volatile("eret"); 173 } 162 174 163 "lw $26, 35*4($27) \n"164 "mtc2 $26, $0 \n" // restore PTPR165 "lw $26, 0*4($27) \n"166 "mtc0 $26, $12 \n" // restore SR167 ".set noat \n"168 "lw $1, 1*4($27) \n" // restore $1169 ".set at \n"170 "lw $2, 2*4($27) \n" // restore $2171 "lw $3, 3*4($27) \n" // restore $3172 "lw $4, 4*4($27) \n" // restore $4173 "lw $5, 5*4($27) \n" // restore $5174 "lw $6, 6*4($27) \n" // restore $6175 "lw $7, 7*4($27) \n" // restore $7176 "lw $8, 8*4($27) \n" // restore $8177 "lw $9, 9*4($27) \n" // restore $9178 "lw $10, 10*4($27) \n" // restore $10179 "lw $11, 11*4($27) \n" // restore $11180 "lw $12, 12*4($27) \n" // restore $12181 "lw $13, 13*4($27) \n" // restore $13182 "lw $14, 14*4($27) \n" // restore $14183 "lw $15, 15*4($27) \n" // restore $15184 "lw $16, 16*4($27) \n" // restore $16185 "lw $17, 17*4($27) \n" // restore $17186 "lw $18, 18*4($27) \n" // restore $18187 "lw $19, 19*4($27) \n" // restore $19188 "lw $20, 20*4($27) \n" // restore $20189 "lw $21, 21*4($27) \n" // restore $21190 "lw $22, 22*4($27) \n" // restore $22191 "lw $23, 23*4($27) \n" // restore $23192 "lw $24, 24*4($27) \n" // restore $24193 "lw $25, 25*4($27) \n" // restore $25194 "lw $26, 26*4($27) \n"195 "mtlo $26 \n" // restore LO196 "lw $26, 27*4($27) \n"197 "mthi $26 \n" // restore HI198 "lw $28, 28*4($27) \n" // restore $28199 "lw $29, 29*4($27) \n" // restore $29200 "lw $30, 30*4($27) \n" // restore $30201 "lw $31, 31*4($27) \n" // restore $31202 "lw $26, 32*4($27) \n"203 "mtc0 $26, $14 \n" // restore EPC204 "lw $26, 33*4($27) \n"205 "mtc0 $26, $13 \n" // restore CR206 175 207 "ori $27, $0, 0xF \n"208 "mtc2 $27, $1 \n" // activate DTLB209 :210 : "r"(curr_ctx_paddr), "r"(next_ctx_paddr)211 : "$1" , "$4" ,"$5" ,"$6" ,"$7" ,"$8" ,"$9" ,"$10",212 "$11","$12","$13","$14","$15","$16","$17","$18","$19","$20",213 "$21","$22","$23","$24","$25","$26","$27", "$29",214 "$31" );215 */216 }217 } // end _ctx_switch218 -
soft/giet_vm/sys/ctx_handler.h
r189 r199 16 16 } static_scheduler_t; 17 17 18 19 ///////////////////////////////////////////////////////////////////////////////// 20 // "idle" task index definition 21 ///////////////////////////////////////////////////////////////////////////////// 22 23 #define IDLE_TASK_INDEX 14 24 18 25 ///////////////////////////////////////////////////////////////////////////////// 19 26 // Definition of the task context slots indexes 20 27 ///////////////////////////////////////////////////////////////////////////////// 21 28 22 #define CTX_SR_ID 023 29 #define CTX_SP_ID 29 24 30 #define CTX_RA_ID 31 … … 26 32 #define CTX_EPC_ID 32 27 33 #define CTX_CR_ID 33 28 #define CTX_PTPR_ID 35 29 #define CTX_MODE_ID 36 34 #define CTX_SR_ID 34 35 #define CTX_BVAR_ID 35 36 37 #define CTX_PTPR_ID 39 30 38 31 39 #define CTX_TTY_ID 40 32 40 #define CTX_FBDMA_ID 41 33 #define CTX_PTAB_ID 42 34 #define CTX_TASK_ID 43 35 #define CTX_SCHED_ID 44 36 #define CTX_TIMER_ID 45 41 #define CTX_NIC_ID 42 42 #define CTX_TIMER_ID 43 43 #define CTX_PTAB_ID 44 44 #define CTX_LTID_ID 45 45 #define CTX_VSID_ID 46 46 #define CTX_RUN_ID 47 37 47 38 48 ////////////////////////////////////////////////////////////////////////////////// … … 41 51 42 52 extern void _ctx_switch(); 53 extern void _ctx_eret(); 54 extern void _ctx_idle(); 43 55 44 56 extern static_scheduler_t _scheduler[]; -
soft/giet_vm/sys/drivers.c
r189 r199 162 162 { 163 163 unsigned int buffer = value; 164 unsigned int timer_id = _get_current_context_slot(CTX_TIMER_ID); 164 unsigned int task_id = _get_current_task_id(); 165 unsigned int timer_id = _get_context_slot(task_id, CTX_TIMER_ID); 165 166 unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX); 166 167 unsigned int local_id = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX); … … 190 191 unsigned int* buffer ) 191 192 { 192 unsigned int timer_id = _get_current_context_slot(CTX_TIMER_ID); 193 unsigned int task_id = _get_current_task_id(); 194 unsigned int timer_id = _get_context_slot(task_id, CTX_TIMER_ID); 193 195 unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX); 194 196 unsigned int local_id = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX); … … 232 234 // _tty_error() 233 235 //////////////////////////////////////////////////////////////////////////////// 234 void _tty_error() 235 { 236 unsigned int task_id = _get_current_task_id(); 236 void _tty_error( unsigned int task_id ) 237 { 237 238 unsigned int proc_id = _procid(); 238 239 … … 259 260 unsigned int nwritten; 260 261 261 unsigned int tty_id = _get_current_context_slot(CTX_TTY_ID); 262 unsigned int task_id = _get_current_task_id(); 263 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 264 262 265 if ( tty_id >= NB_TTYS ) 263 266 { 264 _tty_error( );267 _tty_error( task_id ); 265 268 return 0; 266 269 } … … 291 294 unsigned int length) 292 295 { 293 unsigned int tty_id = _get_current_context_slot(CTX_TTY_ID); 296 unsigned int task_id = _get_current_task_id(); 297 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 294 298 295 299 if ( tty_id >= NB_TTYS ) 296 300 { 297 _tty_error( );301 _tty_error( task_id ); 298 302 return 0; 299 303 } … … 320 324 unsigned int length) 321 325 { 322 unsigned int tty_id = _get_current_context_slot(CTX_TTY_ID); 326 unsigned int task_id = _get_current_task_id(); 327 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 328 323 329 if ( tty_id >= NB_TTYS ) 324 330 { 325 _tty_error( );331 _tty_error( task_id ); 326 332 return 0; 327 333 } … … 544 550 545 551 // get user space page table virtual address 546 unsigned int user_pt_vbase = _get_current_context_slot(CTX_PTAB_ID); 552 unsigned int task_id = _get_current_task_id(); 553 unsigned int user_pt_vbase = _get_context_slot( task_id, CTX_PTAB_ID ); 547 554 548 555 user_vpn_min = user_vaddr >> 12; … … 815 822 816 823 // get DMA channel and compute DMA vbase address 817 unsigned int dma_id = _get_current_context_slot(CTX_FBDMA_ID); 824 unsigned int task_id = _get_current_task_id(); 825 unsigned int dma_id = _get_context_slot( task_id, CTX_FBDMA_ID ); 818 826 unsigned int cluster_id = dma_id / NB_DMAS_MAX; 819 827 unsigned int loc_id = dma_id % NB_DMAS_MAX; … … 830 838 831 839 // get user space page table virtual address 832 unsigned int user_ptab = _get_c urrent_context_slot(CTX_PTAB_ID);840 unsigned int user_ptab = _get_context_slot( task_id, CTX_PTAB_ID ); 833 841 834 842 // compute frame buffer pbase address … … 985 993 unsigned int _fb_completed() 986 994 { 987 unsigned int dma_id = _get_current_context_slot(CTX_FBDMA_ID); 995 unsigned int task_id = _get_current_task_id(); 996 unsigned int dma_id = _get_context_slot( task_id, CTX_FBDMA_ID ); 988 997 989 998 // busy waiting with a pseudo random delay between bus access -
soft/giet_vm/sys/exc_handler.c
r189 r199 10 10 11 11 #include <exc_handler.h> 12 #include <ctx_handler.h> 12 13 #include <sys_handler.h> 13 14 #include <drivers.h> … … 53 54 }; 54 55 55 static const char *exc_message_causes[] = {56 " \n\nException : strange unknown cause\n",57 " \n\nException : illegal read address \n",58 " \n\nException : illegal write address\n",59 " \n\nException : inst bus error \n",60 " \n\nException : data bus error \n",61 " \n\nException : breakpoint \n",62 " \n\nException : reserved instruction \n",63 " \n\nException : illegal coproc access\n"64 " \n\nException : arithmetic overflow \n",56 static const char* exc_type[] = { 57 "strange unknown cause", 58 "illegal read address", 59 "illegal write address", 60 "inst bus error", 61 "data bus error", 62 "breakpoint", 63 "reserved instruction", 64 "illegal coproc access" 65 "arithmetic overflow", 65 66 }; 66 67 67 static void _ cause(unsigned int msg_cause)68 static void _display_cause(unsigned int type) 68 69 { 69 _puts( (char*)(exc_message_causes[msg_cause]) ); 70 _puts("\n - Cycle : "); 70 _puts("\n[GIET] Exception for task "); 71 _putd( _get_current_task_id() ); 72 _puts(" on processor "); 73 _putd( _procid() ); 74 _puts(" at cycle "); 71 75 _putd( _proctime() ); 72 _puts("\n - Processor : "); 73 _putd( _procid() ); 74 _puts("\n - Task : "); 75 _putd( _get_current_task_id() ); 76 _puts("\n - type : "); 77 _puts( (char*)exc_type[type] ); 76 78 _puts("\n - EPC : "); 77 79 _putw( _get_epc() ); … … 79 81 _putw( _get_bvar() ); 80 82 _puts("\n"); 81 _exit(); 83 84 // goes to sleeping state 85 unsigned int task_id = _get_current_task_id(); 86 _set_context_slot( task_id, CTX_RUN_ID, 0 ); 87 88 // deschedule 89 _ctx_switch(); 82 90 } 83 91 84 static void _cause_ukn() { _ cause(0); }85 static void _cause_adel() { _ cause(1); }86 static void _cause_ades() { _ cause(2); }87 static void _cause_ibe() { _ cause(3); }88 static void _cause_dbe() { _ cause(4); }89 static void _cause_bp() { _ cause(5); }90 static void _cause_ri() { _ cause(6); }91 static void _cause_cpu() { _ cause(7); }92 static void _cause_ovf() { _ cause(8); }92 static void _cause_ukn() { _display_cause(0); } 93 static void _cause_adel() { _display_cause(1); } 94 static void _cause_ades() { _display_cause(2); } 95 static void _cause_ibe() { _display_cause(3); } 96 static void _cause_dbe() { _display_cause(4); } 97 static void _cause_bp() { _display_cause(5); } 98 static void _cause_ri() { _display_cause(6); } 99 static void _cause_cpu() { _display_cause(7); } 100 static void _cause_ovf() { _display_cause(8); } 93 101 -
soft/giet_vm/sys/kernel_init.c
r189 r199 8 8 // It contains the kernel entry point for the last step of system initialisation. 9 9 // All procs in this phase have their MMU activated, and are running in parallel. 10 // - each processor updates its own scheduler, to replace the ISR index 11 // by the actual ISR virtual address, and set its own entry in the 12 // kernel _schedulers_paddr[] array. 13 // - each processor initialises the SP, SR, PTPR, EPC registers, and starts 14 // its private Timer, before jumping to the user code with an eret. 10 // Each processor perform the following actions: 11 // 1/ contributes to _schedulers_paddr[] initialisation 12 // 2/ contributes to _ptabs_paddr[] and _ptabs_vaddr arrays initialisation 13 // 3/ computes and set the ICU mask for its private ICU channel 14 // 4/ initialises its private TICK timer (if required) 15 // 5/ initialises the "idle" task context in its private scheduler 16 // 6/ initialises the SP, SR, PTPR, EPC registers 17 // 7/ jumps to the user code with an eret. 15 18 //////////////////////////////////////////////////////////////////////////////////// 16 19 … … 34 37 35 38 __attribute__((section (".kdata"))) 36 page_table_t* _ptabs_paddr[GIET_NB_VSPACE_MAX]; 37 38 __attribute__((section (".kdata"))) 39 page_table_t* _ptabs_vaddr[GIET_NB_VSPACE_MAX]; 40 41 __attribute__((section (".kdata"))) 42 static_scheduler_t* _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX]; 39 unsigned int _ptabs_paddr[GIET_NB_VSPACE_MAX]; 40 41 __attribute__((section (".kdata"))) 42 unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX]; 43 44 __attribute__((section (".kdata"))) 45 static_scheduler_t* _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX]; 46 47 __attribute__((section (".kdata"))) 48 unsigned int _idle_stack[NB_CLUSTERS*NB_PROCS_MAX*64]; 43 49 44 50 ////////////////////////////////////////////////////////////////////////////////// … … 47 53 __attribute__((section (".kinit"))) void _kernel_init() 48 54 { 49 // values to be written in registers 50 unsigned int sp_value; 51 unsigned int sr_value; 52 unsigned int ptpr_value; 53 unsigned int epc_value; 54 55 // compute cluster and local processor index 55 56 unsigned int proc_id = _procid(); 56 57 unsigned int cluster_id = proc_id / NB_PROCS_MAX; … … 66 67 _get_lock(&_tty_put_lock); 67 68 _puts("\n[GIET DEBUG] step 1 for processor "); 68 _putw( proc_id ); 69 _puts("\n"); 70 _puts("- scheduler pbase = "); 69 _putd( proc_id ); 70 _puts(" / scheduler pbase = "); 71 71 _putw( (unsigned int)psched ); 72 72 _puts("\n"); … … 74 74 #endif 75 75 76 // step 2 : compute and set ICU mask 76 77 // step 2 : initialise page table addresse arrays 78 // it scans all tasks contexts in the scheduler 79 // and get VSID, PTAB and PTPR values 80 81 unsigned int ltid; 82 unsigned int tasks = _get_tasks_number(); 83 84 for ( ltid = 0 ; ltid < tasks ; ltid++ ) 85 { 86 unsigned int vspace_id = _get_context_slot( ltid , CTX_VSID_ID ); 87 unsigned int ptab_vaddr = _get_context_slot( ltid , CTX_PTAB_ID ); 88 unsigned int ptab_paddr = _get_context_slot( ltid , CTX_PTPR_ID ) << 13; 89 _ptabs_vaddr[vspace_id] = ptab_vaddr; 90 _ptabs_paddr[vspace_id] = ptab_paddr; 91 92 #if GIET_DEBUG_INIT 93 _get_lock(&_tty_put_lock); 94 _puts("\n[GIET DEBUG] step 2 for processor "); 95 _putd( proc_id ); 96 _puts(" / vspace "); 97 _putd( vspace_id ); 98 _puts("\n- ptab vbase = "); 99 _putw( ptab_vaddr ); 100 _puts("\n- ptab pbase = "); 101 _putw( ptab_paddr ); 102 _puts("\n"); 103 _release_lock(&_tty_put_lock); 104 #endif 105 106 } 107 108 // step 3 : compute and set ICU mask 77 109 unsigned int irq_id; 78 110 unsigned int mask = 0; … … 89 121 #if GIET_DEBUG_INIT 90 122 _get_lock(&_tty_put_lock); 91 _puts("\n[GIET DEBUG] step 2 for processor "); 92 _putw( proc_id ); 93 _puts("\n"); 94 _puts("- ICU mask = "); 123 _puts("\n[GIET DEBUG] step 3 for processor "); 124 _putd( proc_id ); 125 _puts(" / ICU mask = "); 95 126 _putw( mask ); 96 127 _puts("\n"); … … 99 130 100 131 101 // step 3 : TODO initialise page table addresse arrays102 103 104 132 // step 4 : start TICK timer if more than one task 105 unsigned int tasks = _get_tasks_number();106 133 if ( tasks > 1 ) 107 134 { … … 122 149 _get_lock(&_tty_put_lock); 123 150 _puts("\n[GIET DEBUG] Step 4 for processor "); 124 _putw( proc_id ); 125 _puts("\n"); 126 _puts("- TICK period = "); 127 _putd( period ); 128 _puts("\n"); 151 _putd( proc_id ); 152 _puts(" / TICK activated\n"); 129 153 _release_lock(&_tty_put_lock); 130 154 #endif … … 132 156 } 133 157 134 // step 5 : each processor initialises SP, SR, PTPR, EPC, registers 158 // step 5 : initialise the "idle" task context 159 // the SR initialisation value is 0xFF03 because 160 // the task _ctx_idle() executes in kernel mode... 161 // it uses the page table of vspace[0] 162 163 _set_context_slot( IDLE_TASK_INDEX, CTX_RUN_ID, 1 ); 164 _set_context_slot( IDLE_TASK_INDEX, CTX_SR_ID, 0xFF03 ); 165 _set_context_slot( IDLE_TASK_INDEX, CTX_SP_ID, (unsigned int)&_idle_stack[proc_id] + 64 ); 166 _set_context_slot( IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int)&_ctx_eret ); 167 _set_context_slot( IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int)&_ctx_idle ); 168 _set_context_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX ); 169 _set_context_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptabs_paddr[0] >> 13 ); 170 171 #if GIET_DEBUG_INIT 172 _get_lock(&_tty_put_lock); 173 _puts("\n[GIET DEBUG] Step 5 for processor "); 174 _putd( proc_id ); 175 _puts(" / idle task context set\n"); 176 _release_lock(&_tty_put_lock); 177 #endif 178 179 // step 6 : each processor initialises SP, SR, PTPR, EPC, registers 135 180 // with the values corresponding to the first allocated task, 136 // It does nothing, and keep idle if no task allocated. 137 138 if ( tasks ) // at leat one task allocated 139 { 140 // initialise registers 141 sp_value = _get_current_context_slot(CTX_SP_ID); 142 sr_value = _get_current_context_slot(CTX_SR_ID); 143 ptpr_value = _get_current_context_slot(CTX_PTPR_ID); 144 epc_value = _get_current_context_slot(CTX_EPC_ID); 145 146 #if GIET_DEBUG_INIT 147 _get_lock(&_tty_put_lock); 148 _puts("\n[GIET DEBUG] step 5 for processor "); 149 _putw( proc_id ); 150 _puts("\n"); 181 // and starts the "idle" task if there is no task allocated. 182 183 unsigned int task_id; 184 185 if ( tasks == 0 ) 186 { 187 task_id = IDLE_TASK_INDEX; 188 189 _get_lock( &_tty_put_lock ); 190 _puts("\n [GIET WARNING] No task allocated to processor "); 191 _putw( proc_id ); 192 _puts(" => idle\n"); 193 _release_lock ( &_tty_put_lock ); 194 } 195 else 196 { 197 task_id = 0; 198 } 199 200 unsigned int sp_value = _get_context_slot( task_id, CTX_SP_ID ); 201 unsigned int sr_value = _get_context_slot( task_id, CTX_SR_ID ); 202 unsigned int ptpr_value = _get_context_slot( task_id, CTX_PTPR_ID ); 203 unsigned int epc_value = _get_context_slot( task_id, CTX_EPC_ID ); 204 205 #if GIET_DEBUG_INIT 206 _get_lock(&_tty_put_lock); 207 _puts("\n[GIET DEBUG] step 6 for processor "); 208 _putd( proc_id ); 209 _puts(" / registers initialised \n"); 151 210 _puts("- sp = "); 152 211 _putw( sp_value ); … … 163 222 _release_lock(&_tty_put_lock); 164 223 #endif 165 } 166 else // no task allocated 167 { 168 _get_lock( &_tty_put_lock ); 169 _puts("\n No task allocated to processor "); 170 _putw( proc_id ); 171 _puts(" => keep idle\n"); 172 _release_lock ( &_tty_put_lock ); 173 174 // enable interrupts in kernel mode 175 asm volatile ( "li $26, 0xFF01 \n" 176 "mtc0 $26, $12 \n" 177 ::: "$26" ); 178 179 // infinite loop in kernel mode 180 while (1) asm volatile("nop"); 181 } 182 183 // set critical registers and jump to user code 184 asm volatile ( 185 "move $29, %0 \n" /* SP <= ctx[CTX_SP_ID] */ 186 "mtc0 %1, $12 \n" /* SR <= ctx[CTX_SR_ID] */ 187 "mtc2 %2, $0 \n" /* PTPR <= ctx[CTX_PTPR_ID] */ 188 "mtc0 %3, $14 \n" /* EPC <= ctx[CTX_EPC_ID] */ 189 "eret \n" /* jump to user code */ 190 "nop \n" 191 : 192 : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) ); 224 225 // set registers and jump to user code 226 asm volatile ( "move $29, %0 \n" /* SP <= ctx[CTX_SP_ID] */ 227 "mtc0 %1, $12 \n" /* SR <= ctx[CTX_SR_ID] */ 228 "mtc2 %2, $0 \n" /* PTPR <= ctx[CTX_PTPR_ID] */ 229 "mtc0 %3, $14 \n" /* EPC <= ctx[CTX_EPC_ID] */ 230 "eret \n" /* jump to user code */ 231 "nop \n" 232 : 233 : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) ); 193 234 194 235 } // end _kernel_init() -
soft/giet_vm/sys/mips32_registers.h
r189 r199 47 47 /* CP0 registers */ 48 48 49 #define CP0_B AR$849 #define CP0_BVAR $8 50 50 #define CP0_TIME $9 51 51 #define CP0_SR $12 -
soft/giet_vm/sys/switch.s
r189 r199 2 2 * This function receives two arguments that are the current task context 3 3 * physical addresses and the next task context physical address. 4 * The DTLB is temporary desactivated... 4 5 ******************************************************************************/ 5 6 … … 17 18 add $27, $4, $0 /* $27 <= &context[curr_task_id] */ 18 19 19 mfc0 $26, $12 /* $26 <= SR */20 sw $26, 0*4($27) /* ctx[0] <= SR */21 20 .set noat 22 21 sw $1, 1*4($27) /* ctx[1] <= $1 */ … … 47 46 sw $25, 25*4($27) /* ctx[25] <= $25 */ 48 47 mflo $26 49 sw $26, 26*4($27) /* ctx[26] <= LO */48 sw $26, 26*4($27) /* ctx[26] <= LO */ 50 49 mfhi $26 51 sw $26, 27*4($27) /* ctx[27] <= H1 */50 sw $26, 27*4($27) /* ctx[27] <= H1 */ 52 51 sw $28, 28*4($27) /* ctx[28] <= $28 */ 53 52 sw $29, 29*4($27) /* ctx[29] <= $29 */ … … 57 56 sw $26, 32*4($27) /* ctx[32] <= EPC */ 58 57 mfc0 $26, $13 59 sw $26, 33*4($27) /* ctx[33] <= CR */ 58 sw $26, 33*4($27) /* ctx[33] <= CR */ 59 mfc0 $26, $12 60 sw $26, 34*4($27) /* ctx[34] <= SR */ 61 mfc0 $26, $8 62 sw $26, 35*4($27) /* ctx[34] <= BVAR */ 60 63 mfc2 $26, $0 61 sw $26, 3 5*4($27) /* ctx[35] <= PTPR */64 sw $26, 39*4($27) /* ctx[35] <= PTPR */ 62 65 63 66 /* restore next task context */ 64 67 add $27, $5, $0 /* $27<= &context[next_task_id] */ 65 68 66 lw $26, 35*4($27)67 mtc2 $26, $0 /* restore PTPR */68 lw $26, 0*4($27)69 mtc0 $26, $12 /* restore SR */70 69 .set noat 71 70 lw $1, 1*4($27) /* restore $1 */ … … 107 106 lw $26, 33*4($27) 108 107 mtc0 $26, $13 /* restore CR */ 108 lw $26, 34*4($27) 109 mtc0 $26, $12 /* restore SR */ 110 lw $26, 35*4($27) 111 mtc0 $26, $8 /* restore BVAR */ 112 lw $26, 39*4($27) 113 mtc2 $26, $0 /* restore PTPR */ 109 114 110 115 /* activate DTLB */ -
soft/giet_vm/sys/sys_handler.c
r189 r199 75 75 void _exit() 76 76 { 77 /*78 77 unsigned int date = _proctime(); 79 80 78 unsigned int proc_id = _procid(); 81 82 79 unsigned int task_id = _get_current_task_id(); 83 80 84 81 // print death message 85 82 _get_lock(&_tty_put_lock); 86 _puts("\n \n!!!Exit task ");87 _put w( task_id );83 _puts("\n[GIET] Exit task "); 84 _putd( task_id ); 88 85 _puts(" on processor "); 89 _put w( proc_id );86 _putd( proc_id ); 90 87 _puts(" at cycle "); 91 _put w( date );88 _putd( date ); 92 89 _puts("\n\n"); 93 90 _release_lock(&_tty_put_lock); 94 */95 91 96 /* infinite loop */ 97 while (1) asm volatile("nop"); 92 // goes to sleeping state 93 _set_context_slot( task_id, CTX_RUN_ID, 0 ); 94 95 // deschedule 96 _ctx_switch(); 98 97 } 99 98 //////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset
for help on using the changeset viewer.