Changeset 440


Ignore:
Timestamp:
Nov 3, 2014, 11:03:55 AM (10 years ago)
Author:
alain
Message:

Introducing dynamic allocation of peripheral channels (NIC, TTY, CMA, TIM)
Intoducing a kernel function for all system calls: No more direct call
to the peripheral drivers.

Location:
soft/giet_vm/giet_kernel
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_kernel/ctx_handler.c

    r428 r440  
    66//////////////////////////////////////////////////////////////////////////////////
    77
     8#include <ctx_handler.h>
    89#include <giet_config.h>
    9 #include <tim_driver.h>
     10#include <utils.h>
     11#include <kernel_utils.h>
    1012#include <xcu_driver.h>
    11 #include <tty_driver.h>
    12 #include <utils.h>
    13 #include <ctx_handler.h>
    14 #include <mapping_info.h>
    15 #include <sys_handler.h>
    1613
     14////////// defined in giet_kernel/switch.s file /////////
    1715extern void _task_switch(unsigned int *, unsigned int *);
    1816
    19 /////////////////////////////////////////////////////////////////////////////////
    20 // This function performs a context switch between the running task
    21 // and  another task, using a round-robin sheduling policy between all
    22 // tasks allocated to a given processor (static allocation).
    23 // It selects the next runable task to resume execution.
    24 // If the only runable task is the current task, return without context switch.
    25 // If there is no runable task, the scheduler switch to the default "idle" task.
    26 /////////////////////////////////////////////////////////////////////////////////
    27 // Implementation note
    28 // The return address contained in $31 is saved in the current task context
    29 // (in the ctx[31] slot), and the function actually returns to the address
    30 // contained in the ctx[31] slot of the next task context.
    31 /////////////////////////////////////////////////////////////////////////////////
     17//////////////////
    3218void _ctx_switch()
    3319{
     
    9884} //end _ctx_switch()
    9985
    100 /////////////////////////////////////////////////////////////////////////////////////
    101 // This function is executed as the"idle" task when no other task can be executed
    102 /////////////////////////////////////////////////////////////////////////////////////
     86/////////////////
    10387void _idle_task()
    10488{
     
    10791    unsigned int x          = cluster_xy >> Y_WIDTH;
    10892    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    109     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
     93    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    11094
    11195    while(1)
     
    126110
    127111        // warning message
    128         _printf("\n[GIET WARNING] Processor[%d,%d,%d] still idle at cycle %d\n",
    129                 x, y, lpid, _get_proctime() );
     112        _puts("\n[GIET WARNING] Processor[");
     113        _putd( x );
     114        _puts(",");
     115        _putd( y );
     116        _puts(",");
     117        _putd( p );
     118        _puts("] still idle at cycle ");
     119        _putd( _get_proctime() );
     120        _puts("\n");
    130121    }
    131122} // end ctx_idle()
    132123
    133124
    134 /////////////////////////////////////////////////////////////////////////////////
    135 // The address of this function is used to initialise the return address
    136 // in the "idle" task context.
    137 /////////////////////////////////////////////////////////////////////////////////
     125////////////////
    138126void _ctx_eret()
    139127{
  • soft/giet_vm/giet_kernel/ctx_handler.h

    r396 r440  
    99// in time multiplexing on a single processor.
    1010// 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,
     11// there is one private scheduler per processor. Each sheduler occupies 8K bytes,
    1212// and contains up to 14 task contexts (task_id is from 0 to 13).
    1313// The task context [13] is reserved for the "idle" task that does nothing, and
     
    1515/////////////////////////////////////////////////////////////////////////////////////////
    1616// A task context is an array of 64 words = 256 bytes.
    17 // It contains copies of processor registers (when the task is preempted):
    18 // - GPR[i], generally stored in slot (i). $0, $26 & $27 are not saved.
    19 // - HI & LO registers
    20 // - CP0 registers: EPC, SR, CR, BVAR
    21 // - CP2 registers : PTPR
    22 // It contains some general informations associated to the task:
    23 // - TTY    : TTY channel global index
    24 // - NIC    : NIC channel global index
    25 // - CMA    : CMA channel global index
    26 // - HBA    : HBA channel global index
    27 // - DMA    : DMA channel local index
    28 // - TIM    : TIM channel local index
    29 // - PTAB   : page table virtual base address
    30 // - LTID   : Task local index (in scheduler)
    31 // - VSID   : Virtual space index
    32 // - RUN    : Task state (0 => sleeping / 1 => runnable )
    33 // - TRDID  : Thread ID index (in vspace)
    34 //
     17// It contains copies of processor registers (when the task is preempted)
     18// and some general informations associated to a task, such as the peripherals
     19// allocated to the task (private peripheral channel for multi-channels peripherals).
     20/////////////////////////////////////////////////////////////////////////////////////////
    3521// ctx[0] <- ***   |ctx[8] <- $8    |ctx[16]<- $16   |ctx[24]<- $24
    3622// ctx[1] <- $1    |ctx[9] <- $9    |ctx[17]<- $17   |ctx[25]<- $25
     
    4228// ctx[7] <- $7    |ctx[15]<- $15   |ctx[23]<- $23   |ctx[31]<- RA
    4329//
    44 // ctx[32]<- EPC   |ctx[40]<- TTY   |ctx[48]<- TRDID |
    45 // ctx[33]<- CR    |ctx[41]<- DMA
    46 // ctx[34]<- SR    |ctx[42]<- NIC
    47 // ctx[35]<- BVAR  |ctx[43]<- TIM
    48 // ctx[36]<- PTAB  |ctx[44]<- HBA
    49 // ctx[37]<- LTID  |ctx[45]<- CMA
    50 // ctx[38]<- VSID  |ctx[46]<- GTID
    51 // ctx[39]<- PTPR  |ctx[47]<- RUN
     30// ctx[32]<- EPC   |ctx[40]<- TTY   |ctx[48]<- TRDID |ctx[56]<- ***
     31// ctx[33]<- CR    |ctx[41]<- FBCMA |ctx[49]<- GTID  |ctx[57]<- ***
     32// ctx[34]<- SR    |ctx[42]<- TXCMA |ctx[50]<- ***   |ctx[58]<- ***
     33// ctx[35]<- BVAR  |ctx[43]<- RXCMA |ctx[51]<- ***   |ctx[59]<- ***
     34// ctx[36]<- PTAB  |ctx[44]<- NIC   |ctx[52]<- ***   |ctx[60]<- ***
     35// ctx[37]<- LTID  |ctx[45]<- HBA   |ctx[53]<- ***   |ctx[61]<- ***
     36// ctx[38]<- VSID  |ctx[46]<- TIM   |ctx[54]<- ***   |ctx[62]<- ***
     37// ctx[39]<- PTPR  |ctx[47]<- RUN   |ctx[55]<- ***   |ctx[63]<- ***
    5238/////////////////////////////////////////////////////////////////////////////////////////
    5339
     
    5642
    5743#include <giet_config.h>
     44
     45/////////////////////////////////////////////////////////////////////////////////
     46//    Definition of the task context slots indexes
     47/////////////////////////////////////////////////////////////////////////////////
     48
     49#define CTX_SP_ID        29  // Stack Pointer
     50#define CTX_RA_ID        31  // Return Address
     51
     52#define CTX_EPC_ID       32  // Exception Program Counter (CP0)
     53#define CTX_CR_ID        33  // Cause Register (CP0)
     54#define CTX_SR_ID        34  // Status Register (CP0)
     55#define CTX_BVAR_ID      35      // Bad Virtual Address Register (CP0)
     56#define CTX_PTAB_ID      36  // Page Table Virtual address
     57#define CTX_LTID_ID      37  // Local  Task Index (in scheduler)
     58#define CTX_VSID_ID      38  // Vspace Index     
     59#define CTX_PTPR_ID      39  // Page Table Pointer Register (PADDR>>13)
     60
     61#define CTX_TTY_ID       40  // private TTY channel index 
     62#define CTX_FBCMA_ID     41  // private CMA channel index for FBF write
     63#define CTX_TXCMA_ID     42  // private CMA channel index for NIC TX
     64#define CTX_RXCMA_ID     43  // private CMA channel index for NIC RX
     65#define CTX_NIC_ID       44  // private NIC channel index
     66#define CTX_HBA_ID       45  // private HBA channel index
     67#define CTX_TIM_ID       46  // ptivate TIM channel index
     68#define CTX_RUN_ID       47  // Boolean: task runable
     69
     70#define CTX_TRDID_ID     48  // Thread Task Index in vspace
     71#define CTX_GTID_ID      49  // Global Task Index in all system
     72
     73/////////////////////////////////////////////////////////////////////////////////
    5874
    5975/////////////////////////////////////////////////////////////////////////////////
     
    7389} static_scheduler_t;
    7490
     91#define IDLE_TASK_INDEX        13
     92
    7593
    7694/////////////////////////////////////////////////////////////////////////////////
    77 //  "idle" task index and stack size definition
     95//                 Schedulers array
     96/////////////////////////////////////////////////////////////////////////////////
     97extern static_scheduler_t _scheduler[];
     98
     99/////////////////////////////////////////////////////////////////////////////////
     100//               External Functions
    78101/////////////////////////////////////////////////////////////////////////////////
    79102
    80 #define IDLE_TASK_INDEX        13
     103/////////////////////////////////////////////////////////////////////////////////
     104// This function performs a context switch between the running task
     105// and  another task, using a round-robin sheduling policy between all
     106// tasks allocated to a given processor (static allocation).
     107// It selects the next runable task to resume execution.
     108// If the only runable task is the current task, return without context switch.
     109// If there is no runable task, the scheduler switch to the default "idle" task.
     110// The return address contained in $31 is saved in the current task context
     111// (in the ctx[31] slot), and the function actually returns to the address
     112// contained in the ctx[31] slot of the next task context.
     113/////////////////////////////////////////////////////////////////////////////////
     114extern void _ctx_switch();
    81115
    82116/////////////////////////////////////////////////////////////////////////////////
    83 //    Definition of the task context slots indexes
     117// The address of this function is used to initialise the return address
     118// in the "idle" task context.
    84119/////////////////////////////////////////////////////////////////////////////////
     120extern void _ctx_eret();
    85121
    86 #define CTX_SP_ID        29  // Stack Pointer
    87 #define CTX_RA_ID        31  // Return Address
    88 
    89 #define CTX_EPC_ID       32  // Exception Program Counter (CP0)
    90 #define CTX_CR_ID        33  // Cause Register (CP0)
    91 #define CTX_SR_ID        34  // Status Register (CP0)
    92 #define CTX_BVAR_ID      35      // Bad Virtual Address Register (CP0)
    93 #define CTX_PTAB_ID      36  // Page Table Virtual address
    94 #define CTX_LTID_ID      37  // Local  Task Index (in scheduler)
    95 #define CTX_VSID_ID      38  // Vspace Index     
    96 #define CTX_PTPR_ID      39  // Page Table Pointer Register (PADDR>>13)
    97 
    98 #define CTX_TTY_ID       40  // global TTY channel   
    99 #define CTX_DMA_ID       41  // local DMA channel
    100 #define CTX_NIC_ID       42  // global NIC channel
    101 #define CTX_TIM_ID       43  // local TIMER channel
    102 #define CTX_HBA_ID       44  // global HBA channel
    103 #define CTX_CMA_ID       45  // global CMA channel
    104 #define CTX_GTID_ID      46  // Global Task Index
    105 #define CTX_RUN_ID       47  // Boolean: task runable
    106 
    107 #define CTX_TRDID_ID     48  // Thread Index in vspace
    108 
    109 //////////////////////////////////////////////////////////////////////////////////
    110 //    context switch functions
    111 //////////////////////////////////////////////////////////////////////////////////
    112 
    113 extern void _ctx_switch();
    114 extern void _ctx_eret();
     122/////////////////////////////////////////////////////////////////////////////////
     123// This function is executed task when no other task can be executed.
     124/////////////////////////////////////////////////////////////////////////////////
    115125extern void _idle_task();
    116126
    117 extern static_scheduler_t _scheduler[];
    118127
    119128#endif
  • soft/giet_vm/giet_kernel/exc_handler.c

    r428 r440  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The exc_handler.c and exc_handler.h files are part of the GIET nano-kernel.
    8 // They contains the exception handler code.
    9 ///////////////////////////////////////////////////////////////////////////////////
    107
    118#include <exc_handler.h>
    129#include <ctx_handler.h>
    1310#include <sys_handler.h>
    14 #include <tty_driver.h>
    1511#include <utils.h>
     12#include <kernel_utils.h>
    1613
    1714///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_kernel/exc_handler.h

    r258 r440  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The exc_handler.c and exc_handler.h files are part of the GIET nano-kernel.
     8// They define the exception handler code.
     9///////////////////////////////////////////////////////////////////////////////////
     10
    711
    812#ifndef _EXCP_HANDLER_H
     
    1014
    1115///////////////////////////////////////////////////////////////////////////////////
    12 // Exception Vector Table (indexed by cause register)
     16// Exception Vector Table (indexed by cause register XCODE field)
    1317///////////////////////////////////////////////////////////////////////////////////
    1418
    1519typedef void (*_exc_func_t)(void);
     20
    1621extern const _exc_func_t _cause_vector[16];
    1722
  • soft/giet_vm/giet_kernel/irq_handler.c

    r428 r440  
    1111#include <ctx_handler.h>
    1212#include <tim_driver.h>
    13 #include <icu_driver.h>
    1413#include <xcu_driver.h>
    1514#include <tty_driver.h>
     
    2221#include <mapping_info.h>
    2322#include <utils.h>
    24 
    25 #if !defined( USE_XCU )
    26 # error: You must define USE_XCU in the hard_config.h file
    27 #endif
     23#include <kernel_utils.h>
    2824
    2925#if NB_TIM_CHANNELS
    30 extern volatile unsigned char _user_timer_event[X_SIZE*Y_SIZE*NB_TIM_CHANNELS] ;
    31 #endif
    32 
    33 ///////////////////////////////////////////////////////////////////////////////////
    34 // This function uses the ICU or XICU component (Interrupt Controler Unit)
    35 // to get the interrupt vector entry. There is one ICU or XICU component per
    36 // cluster, and this component can support up to NB_PROCS_MAX output IRQs.
    37 // It returns the highest priority active interrupt index (smaller
    38 // indexes have the highest priority).
    39 // Any value larger than 31 means "no active interrupt", and no ISR is executed.
    40 //
    41 // There is three interrupt vectors per processor (stored in the processor's
    42 // scheduler) for the three HWI, PTI, and WTI interrupts types.
    43 // Each interrupt vector entry contains three bits fields:
    44 // - isr_id     bits[15:0]  : defines the type of ISR to be executed.
    45 // - channel_id bits[30:16] : defines the channel for multi-channels peripherals.
    46 // - valid      bit 31      : valid interrupt vector entry
    47 // If the peripheral is replicated in clusters, the channel_id is
    48 // a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id   
    49 ///////////////////////////////////////////////////////////////////////////////////
     26extern volatile unsigned char _user_timer_event[NB_TIM_CHANNELS] ;
     27#endif
     28
     29// ISR_TYPE names for display
     30char* _isr_type_name[] = { "DEFAULT",
     31                           "TICK"   ,
     32                           "TTY_RX" ,
     33                           "TTY_TX" ,
     34                           "BDV"    ,
     35                           "TIMER"  ,
     36                           "WAKUP"  ,
     37                           "NIC_RX" ,
     38                           "NIC_TX" ,
     39                           "CMA"    ,
     40                           "MMC"    ,
     41                           "DMA"    ,
     42                           "SPI"    };
     43/////////////////
    5044void _irq_demux()
    5145{
     
    6155    unsigned int icu_out_index = lpid * IRQ_PER_PROCESSOR;
    6256
    63 #if USE_XCU
    6457    _xcu_get_index( cluster_xy, icu_out_index, &irq_id, &irq_type );
    65 #else
    66     irq_type = IRQ_TYPE_HWI;
    67     _icu_get_index( cluster_xy, icu_out_index, &irq_id );
    68 #endif
    6958
    7059    if (irq_id < 32)
     
    137126}
    138127
    139 ///////////////////////////////////////////////////////////////////////////////////
    140 // The default ISR is called when there is no active IRQ when the interrupt
    141 // handler is called. It simply displays a warning message on TTY[0].
    142 ///////////////////////////////////////////////////////////////////////////////////
     128///////////////////
    143129void _isr_default()
    144130{
     
    155141
    156142
    157 ///////////////////////////////////////////////////////////////////////////////////
    158 // This ISR can only be executed after a WTI (IPI) to force a context switch
    159 // on a remote processor. The context switch is only executed if the current task
    160 // is the IDLE_TASK, or if the value written in the mailbox is non zero.
    161 ///////////////////////////////////////////////////////////////////////////////////
     143////////////////////////////////////////////////////////////
    162144void _isr_wakup( unsigned int irq_type,   // HWI / WTI / PTI
    163145                 unsigned int irq_id,     // index returned by ICU
     
    175157    if ( irq_type != IRQ_TYPE_WTI )
    176158    {
    177         // we don't take the TTY lock to avoid deadlocks
    178159        _puts("[GIET ERROR] _isr_wakup() not called by a WTI on processor[");
    179160        _putd( x );
     
    209190    // context swich if required
    210191    if ( (task == IDLE_TASK_INDEX) || (value != 0) ) _ctx_switch();
    211 }
    212 
    213 /////////////////////////////////////////////////////////////////////////////////////
    214 // This ISR is in charge of context switch, and handles the IRQs generated by
    215 // the "system" timers contained in the MULTI_TIMER or in the XICU component.
    216 // The ISR acknowledges the IRQ, and calls the _ctx_switch() function.
    217 /////////////////////////////////////////////////////////////////////////////////////
     192} // end _isr_wakup
     193
     194///////////////////////////////////////////////////////////
    218195void _isr_tick( unsigned int irq_type,   // HWI / WTI / PTI
    219196                unsigned int irq_id,     // index returned by ICU
     
    222199    unsigned int gpid       = _get_procid();
    223200    unsigned int cluster_xy = gpid >> P_WIDTH;
    224 
    225     // acknowledge HWI or PTI
    226     if ( irq_type == IRQ_TYPE_HWI ) _timer_reset_irq( cluster_xy, channel );
    227     else                            _xcu_timer_reset_irq( cluster_xy, irq_id );
    228 
    229 #if GIET_DEBUG_IRQS  // we don't take the lock to avoid deadlock
    230 unsigned int x          = cluster_xy >> Y_WIDTH;
    231 unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    232 unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
     201    unsigned int x          = cluster_xy >> Y_WIDTH;
     202    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     203    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
     204
     205    if ( irq_type != IRQ_TYPE_PTI )
     206    {
     207        _puts("[GIET ERROR] _isr_tick() not called by a PTI on processor[");
     208        _putd( x );
     209        _puts(",");
     210        _putd( y );
     211        _puts(",");
     212        _putd( lpid );
     213        _puts("] at cycle ");
     214        _putd( _get_proctime() );
     215        _puts("\n");
     216        _exit();
     217    }
     218
     219    // acknowledge PTI
     220    _xcu_timer_reset_irq( cluster_xy, irq_id );
     221
     222#if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
    233223_puts("\n[IRQS DEBUG] Processor[");
    234224_putd( x );
     
    244234    // context switch
    245235    _ctx_switch();
    246 }
     236}  // end _isr_tick
    247237
    248238
  • soft/giet_vm/giet_kernel/irq_handler.h

    r322 r440  
    3636};
    3737
    38 ///////////////////////////////////////////////////////////////////////////////
    39 // Prototypes of the Interrupt Service Routines (ISRs) supported by the GIET.
    40 ///////////////////////////////////////////////////////////////////////////////
     38///////////////////////////////////////////////////////////////////////////////////
     39//    irq_handler functions
     40///////////////////////////////////////////////////////////////////////////////////
    4141
     42///////////////////////////////////////////////////////////////////////////////////
     43// This function access the ICU or XICU component (Interrupt Controler Unit)
     44// to get the interrupt vector entry. There is one ICU or XICU component per
     45// cluster, and this component can support up to NB_PROCS_MAX output IRQs.
     46// It returns the highest priority active interrupt index (smaller
     47// indexes have the highest priority).
     48// Any value larger than 31 means "no active interrupt", and no ISR is executed.
     49//
     50// There is three interrupt vectors per processor (stored in the processor's
     51// scheduler) for the three HWI, PTI, and WTI interrupts types.
     52// Each interrupt vector entry contains three bits fields:
     53// - isr_id     bits[15:0]  : defines the type of ISR to be executed.
     54// - channel_id bits[30:16] : defines the channel for multi-channels peripherals.
     55// - valid      bit 31      : valid interrupt vector entry
     56// If the peripheral is replicated in clusters, the channel_id is
     57// a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id   
     58///////////////////////////////////////////////////////////////////////////////////
    4259extern void _irq_demux();
    4360
     61///////////////////////////////////////////////////////////////////////////////////
     62// This default ISR is called  when the interrupt handler is called,
     63// and there is no active IRQ. It simply displays a warning message on TTY[0].
     64///////////////////////////////////////////////////////////////////////////////////
    4465extern void _isr_default();
    4566
     67///////////////////////////////////////////////////////////////////////////////////
     68// This ISR can only be executed after a WTI (IPI) to force a context switch
     69// on a remote processor. The context switch is only executed if the current task
     70// is the IDLE_TASK, or if the value written in the mailbox is non zero.
     71///////////////////////////////////////////////////////////////////////////////////
     72extern void _isr_wakup( unsigned int irq_type,
     73                        unsigned int irq_id,
     74                        unsigned int channel );
     75
     76/////////////////////////////////////////////////////////////////////////////////////
     77// This ISR is in charge of context switch, and handles the IRQs generated by
     78// the "system" timers. It can be PTI in case of XCU, or it can be HWI generated
     79// by an external timer in case of ICU.
     80// The ISR acknowledges the IRQ, and calls the _ctx_switch() function.
     81/////////////////////////////////////////////////////////////////////////////////////
    4682extern void _isr_tick( unsigned int irq_type,
    4783                       unsigned int irq_id,
    4884                       unsigned int channel );
    49 
    50 extern void _isr_wakup( unsigned int irq_type,
    51                         unsigned int irq_id,
    52                         unsigned int channel );
    5385
    5486#endif
  • soft/giet_vm/giet_kernel/kernel_init.c

    r428 r440  
    55// Copyright (c) UPMC-LIP6
    66////////////////////////////////////////////////////////////////////////////////////
    7 // The kernel_init.c file is part of the GIET-VM nano-kernel.
    8 //
    9 // This nano-kernel has been written for the MIPS32 processor.
    10 // The virtual adresses are on 32 bits and use the (unsigned int) type, but the
    11 // physicals addresses can have up to 40 bits, and use the (unsigned long long) type.
    12 // It natively supports clusterised shared mmemory multi-processors architectures,
    13 // where each processor is identified by a composite index [x,y,lpid],
    14 // and where there is one physical memory bank per cluster.
    15 //
    16 // The kernel_init() function is executed sequencially by all procesors.
    17 // It completes the system initialisation that has been started by processor[0,0,0]
    18 // in the boot_init() function. It makes the following assuptions, regarding the work
    19 // bone by the boot code:
    20 //
    21 // 1) The page tables associated to the various vspaces have been build
    22 //    in physical memory, and can be used by the kernel code.
    23 //
    24 // 2) All schedulers (this include all task contexts) have been initialised,
    25 //    Both the virtual and the physical base addresses of the page tables
    26 //    are available in the CTX_PTAB and CTX_PTPR slots.
    27 //
    28 // 3) The CP0_SCHED register of each processor contains a pointer on its
    29 //    private scheduler (virtual address).
    30 //
    31 // 4) The CP2_PTPR register of each processor contains a pointer on
    32 //    the vspace_0 page table (physical address>>13).
    33 //
    34 // 5) For all processors, the MMU is activated (CP2_MODE contains 0xF).
    35 //
    36 // This code must be loaded in .kinit section, in order to control seg_kinit_base,
    37 // as this address is used by the boot code to jump into kernel code.
    38 //
    39 // Each processor performs the following actions:
    40 // 1/ contribute to _schedulers_paddr[] array initialisation.
    41 // 2/ contribute to _ptabs_paddr[] and _ptabs_vaddr arrays initialisation
    42 // 3/ completes task context initialisation for ech allocated task
    43 // 4/ compute and set the ICU mask for its private ICU channel
    44 // 5/ initialise its private TICK timer (if tasks > 0)
    45 // 6/ initialise the "idle" task context in its private scheduler
    46 // 7/ initialise SP, SR, PTPR, EPC registers and jump to user code with an eret.
     7// This kernel_init.c file is part of the GIET-VM nano-kernel.
    478////////////////////////////////////////////////////////////////////////////////////
    489
    4910#include <giet_config.h>
    50 
    51 // kernel libraries
     11#include <hard_config.h>
    5212#include <utils.h>
     13#include <kernel_utils.h>
    5314#include <fat32.h>
    54 
    55 //for peripheral initialisation
    56 #include <dma_driver.h>
    57 #include <fbf_driver.h>
    58 #include <tty_driver.h>
    59 #include <icu_driver.h>
    6015#include <xcu_driver.h>
    61 #include <ioc_driver.h>
    62 #include <mmc_driver.h>
    63 #include <mwr_driver.h>
    64 #include <nic_driver.h>
    65 #include <tim_driver.h>
    66 
    6716#include <ctx_handler.h>
    6817#include <irq_handler.h>
    69 
    7018#include <mapping_info.h>
    7119#include <mips32_registers.h>
     
    14694{
    14795    // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH)
    148     // lpid : local processor id in a cluster ( lpid < NB_PROCS_MAX)
     96    // p : local processor id in a cluster ( p < NB_PROCS_MAX)
    14997    // cpid : "continuous" processor index = (((x * Y_SIZE + y) * NB_PROCS_MAX) + p
    15098
     
    153101    unsigned int x          = cluster_xy >> Y_WIDTH & ((1<<X_WIDTH)-1);
    154102    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    155     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
    156     unsigned int cpid       = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + lpid;
     103    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     104    unsigned int cpid       = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + p;
    157105
    158106
     
    160108    while( cpid != kernel_init_barrier ) asm volatile ( "nop" );
    161109
    162     // Step 1 : each processor get its scheduler virtual address from CP0 register
    163     //          and contribute to initialise the _schedulers[] array
     110    // Step 1 : each processor get its scheduler virtual address from CP0_SCHED register
     111    //          and contributes to _schedulers[] array initialisation
    164112
    165113    static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
    166114    unsigned int        tasks      = psched->tasks;
    167115
    168     _schedulers[x][y][lpid] = psched;
     116    _schedulers[x][y][p] = psched;
    169117
    170118#if GIET_DEBUG_INIT
     
    172120        " - scheduler vbase = %x\n"
    173121        " - tasks           = %d\n",
    174         x, y, lpid, (unsigned int)psched, tasks );
     122        x, y, p, (unsigned int)psched, tasks );
    175123#endif
    176124
     
    181129    //          - set CTX_EPC slot that must contain the task entry point,
    182130    //            and contain only at this point the virtual address of the memory
    183     //            location containing this entry point. We must switch the PTPR
    184     //            to use the page table corresponding to the task.
     131    //            location containing this entry point.
    185132
    186133    unsigned int ltid;
     
    188135    for (ltid = 0; ltid < tasks; ltid++)
    189136    {
    190         unsigned int vsid = _get_task_slot( x, y, lpid, ltid , CTX_VSID_ID );
    191         unsigned int ptab = _get_task_slot( x, y, lpid, ltid , CTX_PTAB_ID );
    192         unsigned int ptpr = _get_task_slot( x, y, lpid, ltid , CTX_PTPR_ID );
     137        unsigned int vsid = _get_task_slot( x, y, p, ltid , CTX_VSID_ID );
     138        unsigned int ptab = _get_task_slot( x, y, p, ltid , CTX_PTAB_ID );
     139        unsigned int ptpr = _get_task_slot( x, y, p, ltid , CTX_PTPR_ID );
    193140
    194141        // initialize PTABS arrays
     
    199146_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] contributes to PTABS arrays\n"
    200147        " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n",
    201         x, y, lpid
     148        x, y, p
    202149        vsid, ptab, vsid, ((unsigned long long)ptpr)<<13 );
    203150#endif
     
    209156        // compute ctx_ra
    210157        unsigned int ctx_ra = (unsigned int)(&_ctx_eret);
    211         _set_task_slot( x, y, lpid, ltid, CTX_RA_ID, ctx_ra );
     158        _set_task_slot( x, y, p, ltid, CTX_RA_ID, ctx_ra );
    212159
    213160        // compute ctx_epc
    214         unsigned int* ptr = (unsigned int*)_get_task_slot( x, y, lpid, ltid, CTX_EPC_ID );
    215         _set_task_slot( x, y, lpid, ltid, CTX_EPC_ID, *ptr );
     161        unsigned int* ptr = (unsigned int*)_get_task_slot( x, y, p, ltid, CTX_EPC_ID );
     162        _set_task_slot( x, y, p, ltid, CTX_EPC_ID, *ptr );
    216163
    217164#if GIET_DEBUG_INIT
     
    219166        " - ctx_epc   = %x\n"
    220167        " - ctx_ra    = %x\n",
    221         x, y, lpid, ltid,
    222         _get_task_slot( x, y, lpid, ltid, CTX_EPC_ID ),
    223         _get_task_slot( x, y, lpid, ltid, CTX_RA_ID ) );
     168        x, y, p, ltid,
     169        _get_task_slot( x, y, p, ltid, CTX_EPC_ID ),
     170        _get_task_slot( x, y, p, ltid, CTX_RA_ID ) );
    224171#endif
    225172
    226173    }  // end for tasks
    227174
    228     // step 4 : compute and set ICU or XCU masks
     175    // step 4 : compute and set XCU masks
    229176
    230177    unsigned int isr_switch_index = 0xFFFFFFFF;
     
    252199#if GIET_DEBUG_INIT
    253200_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] sets XCU masks\n"
    254         " - ICU HWI_MASK = %x\n"
    255         " - ICU WTI_MASK = %x\n"
    256         " - ICU PTI_MASK = %x\n",
    257         x, y, lpid, hwi_mask, wti_mask, pti_mask );
    258 #endif
    259 
    260     unsigned int channel = lpid * IRQ_PER_PROCESSOR;
    261 
    262 #if USE_XCU
     201        " - XCU HWI_MASK = %x\n"
     202        " - XCU WTI_MASK = %x\n"
     203        " - XCU PTI_MASK = %x\n",
     204        x, y, p, hwi_mask, wti_mask, pti_mask );
     205#endif
     206
     207    unsigned int channel = p * IRQ_PER_PROCESSOR;
     208
    263209    _xcu_set_mask( cluster_xy, channel, hwi_mask, IRQ_TYPE_HWI );
    264210    _xcu_set_mask( cluster_xy, channel, wti_mask, IRQ_TYPE_WTI );
    265211    _xcu_set_mask( cluster_xy, channel, pti_mask, IRQ_TYPE_PTI );
    266 #else
    267     _icu_set_mask( cluster_xy, channel, hwi_mask );   
    268 #endif
    269212
    270213    // step 5 : start TICK timer if at least one task
     
    275218        {
    276219            _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",
    277                     x, y, lpid );
     220                    x, y, p );
    278221            _exit();
    279222        }
    280223
    281224        // start system timer
    282 
    283 #if USE_XCU
    284225        _xcu_timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE );
    285 #else
    286         _timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE );
    287 #endif
    288226
    289227    }
     
    291229#if GIET_DEBUG_INIT
    292230_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] starts TICK timer\n",
    293         x, y, lpid );
     231        x, y, p );
    294232#endif
    295233
     
    302240    unsigned int pstack = ((unsigned int)psched) + 0x2000;
    303241
    304     _set_task_slot( x, y, lpid, IDLE_TASK_INDEX, CTX_SP_ID,  pstack);
    305     _set_task_slot( x, y, lpid, IDLE_TASK_INDEX, CTX_RA_ID,  (unsigned int) &_ctx_eret);
    306     _set_task_slot( x, y, lpid, IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_idle_task);
     242    _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_SP_ID,  pstack);
     243    _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_RA_ID,  (unsigned int) &_ctx_eret);
     244    _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_idle_task);
    307245
    308246#if GIET_DEBUG_INIT
     
    310248        " - stack_base = %x\n"
    311249        " - stack_size = 0x1000\n",
    312         x, y, lpid, pstack - 0x1000 );
     250        x, y, p, pstack - 0x1000 );
    313251#endif
    314252
     
    324262
    325263        _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n",
    326                 x, y, lpid );
     264                x, y, p );
    327265    }
    328266    else
     
    331269    }
    332270
    333     unsigned int sp_value   = _get_task_slot( x, y, lpid, ltid, CTX_SP_ID);
    334     unsigned int sr_value   = _get_task_slot( x, y, lpid, ltid, CTX_SR_ID);
    335     unsigned int ptpr_value = _get_task_slot( x, y, lpid, ltid, CTX_PTPR_ID);
    336     unsigned int epc_value  = _get_task_slot( x, y, lpid, ltid, CTX_EPC_ID);
     271    unsigned int sp_value   = _get_task_slot( x, y, p, ltid, CTX_SP_ID);
     272    unsigned int sr_value   = _get_task_slot( x, y, p, ltid, CTX_SR_ID);
     273    unsigned int ptpr_value = _get_task_slot( x, y, p, ltid, CTX_PTPR_ID);
     274    unsigned int epc_value  = _get_task_slot( x, y, p, ltid, CTX_EPC_ID);
    337275
    338276#if GIET_DEBUG_INIT
    339277_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] reach barrier at cycle %d\n",
    340         x, y, lpid, _get_proctime() );
     278        x, y, p, _get_proctime() );
    341279#endif
    342280
     
    353291        " - ptpr = %x\n"
    354292        " - epc  = %x\n",
    355         x, y, lpid, _get_proctime(),
     293        x, y, p, _get_proctime(),
    356294        sp_value, sr_value, ptpr_value, epc_value );
    357295#endif
  • soft/giet_vm/giet_kernel/sys_handler.c

    r428 r440  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
    8 // It define the syscall_vector[] (at the end of this file), as well as the
    9 // associated syscall handlers that are not related to peripherals.
    10 // The syscall handlers for peripherals are defined in the drivers.c file.
    11 ///////////////////////////////////////////////////////////////////////////////////
    127
    138#include <sys_handler.h>
     
    1611#include <ioc_driver.h>
    1712#include <nic_driver.h>
    18 #include <fbf_driver.h>
     13#include <mmc_driver.h>
     14#include <cma_driver.h>
    1915#include <ctx_handler.h>
    2016#include <fat32.h>
    2117#include <utils.h>
     18#include <kernel_utils.h>
    2219#include <vmem.h>
    2320#include <hard_config.h>
     
    2825# error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file
    2926#endif
     27
     28////////////////////////////////////////////////////////////////////////////
     29//     Channel allocators for peripherals
     30//     (TTY[0] is reserved for kernel)
     31////////////////////////////////////////////////////////////////////////////
     32
     33unsigned int _tty_channel_allocator = 1;
     34unsigned int _tim_channel_allocator = 0;
     35unsigned int _cma_channel_allocator = 0;
     36unsigned int _nic_channel_allocator = 0;
    3037
    3138////////////////////////////////////////////////////////////////////////////
     
    3542const void * _syscall_vector[64] =
    3643{
    37     &_proc_xyp,            /* 0x00 */
    38     &_get_proctime,        /* 0x01 */
    39     &_tty_write,           /* 0x02 */
    40     &_tty_read,            /* 0x03 */
    41     &_timer_start,         /* 0x04 */
    42     &_timer_stop,          /* 0x05 */
    43     &_tty_get_lock,        /* 0x06 */
    44     &_tty_release_lock,    /* 0x07 */
    45     &_heap_info,           /* 0x08 */
    46     &_local_task_id,       /* 0x09 */
    47     &_global_task_id,      /* 0x0A */
    48     &_fb_cma_init,         /* 0x0B */
    49     &_fb_cma_write,        /* 0x0C */
    50     &_fb_cma_stop,         /* 0x0D */
    51     &_task_exit,           /* 0x0E */
    52     &_procs_number,        /* 0x0F */
    53 
    54     &_fb_sync_write,       /* 0x10 */
    55     &_fb_sync_read,        /* 0x11 */
    56     &_thread_id,           /* 0x12 */
    57     &_sys_ukn,             /* 0x13 */
    58     &_sys_ukn,             /* 0x14 */
    59     &_sys_ukn,             /* 0x15 */
    60     &_sys_ukn,             /* 0x16 */
    61     &_sys_ukn,             /* 0x17 */
    62     &_sys_ukn,             /* 0x18 */   
    63     &_context_switch,      /* 0x19 */
    64     &_vobj_get_vbase,      /* 0x1A */
    65     &_get_xy_from_ptr,     /* 0x1B */
    66     &_nic_cma_start,       /* 0x1C */
    67     &_nic_cma_stop,        /* 0x1D */
    68     &_nic_sync_read,       /* 0x1E */
    69     &_nic_sync_write,      /* 0x1F */
    70 
    71     &_fat_user_open,       /* 0x20 */
    72     &_fat_user_read,       /* 0x21 */
    73     &_fat_user_write,      /* 0x22 */
    74     &_fat_user_lseek,      /* 0x23 */
    75     &_fat_fstat,           /* 0x24 */
    76     &_fat_close,           /* 0x25 */
    77     &_sys_ukn,             /* 0x26 */
    78     &_sys_ukn,             /* 0x27 */
    79     &_sys_ukn,             /* 0x28 */
    80     &_sys_ukn,             /* 0x29 */
    81     &_sys_ukn,             /* 0x2A */
    82     &_sys_ukn,             /* 0x2B */
    83     &_sys_ukn,             /* 0x2C */
    84     &_sys_ukn,             /* 0x2D */
    85     &_sys_ukn,             /* 0x2E */
    86     &_sys_ukn,             /* 0x2F */
    87 
    88     &_sys_ukn,             /* 0x30 */
    89     &_sys_ukn,             /* 0x31 */
    90     &_sys_ukn,             /* 0x32 */
    91     &_sys_ukn,             /* 0x33 */
    92     &_sys_ukn,             /* 0x34 */
    93     &_sys_ukn,             /* 0x35 */
    94     &_sys_ukn,             /* 0x36 */
    95     &_sys_ukn,             /* 0x37 */
    96     &_sys_ukn,             /* 0x38 */   
    97     &_sys_ukn,             /* 0x39 */
    98     &_sys_ukn,             /* 0x3A */
    99     &_sys_ukn,             /* 0x3B */
    100     &_sys_ukn,             /* 0x3C */
    101     &_sys_ukn,             /* 0x3D */
    102     &_sys_ukn,             /* 0x3E */
    103     &_sys_ukn,             /* 0x3F */
     44    &_sys_proc_xyp,         /* 0x00 */
     45    &_get_proctime,         /* 0x01 */
     46    &_sys_tty_write,        /* 0x02 */
     47    &_sys_tty_read,         /* 0x03 */
     48    &_sys_tty_alloc,        /* 0x04 */
     49    &_sys_tty_get_lock,     /* 0x05 */
     50    &_sys_tty_release_lock, /* 0x06 */
     51    &_sys_heap_info,        /* 0x07 */
     52    &_sys_local_task_id,    /* 0x08 */
     53    &_sys_global_task_id,   /* 0x09 */
     54    &_sys_fbf_cma_alloc,    /* 0x0A */
     55    &_sys_fbf_cma_start,    /* 0x0B */
     56    &_sys_fbf_cma_display,  /* 0x0C */
     57    &_sys_fbf_cma_stop,     /* 0x0D */
     58    &_sys_task_exit,        /* 0x0E */
     59    &_sys_procs_number,     /* 0x0F */
     60
     61    &_sys_fbf_sync_write,   /* 0x10 */
     62    &_sys_fbf_sync_read,    /* 0x11 */
     63    &_sys_thread_id,        /* 0x12 */
     64    &_sys_ukn,              /* 0x13 */
     65    &_sys_tim_alloc,        /* 0x14 */
     66    &_sys_tim_start,        /* 0x15 */
     67    &_sys_tim_stop,         /* 0x16 */
     68    &_sys_ukn,              /* 0x17 */
     69    &_sys_ukn,              /* 0x18 */   
     70    &_context_switch,       /* 0x19 */
     71    &_sys_vobj_get_vbase,   /* 0x1A */
     72    &_sys_vobj_get_length,  /* 0x1B */
     73    &_sys_xy_from_ptr,      /* 0x1C */
     74    &_sys_nic_alloc,        /* 0x1D */
     75    &_sys_nic_sync_send,    /* 0x1E */
     76    &_sys_nic_sync_receive, /* 0x1F */
     77
     78    &_fat_user_open,        /* 0x20 */
     79    &_fat_user_read,        /* 0x21 */
     80    &_fat_user_write,       /* 0x22 */
     81    &_fat_user_lseek,       /* 0x23 */
     82    &_fat_fstat,            /* 0x24 */
     83    &_fat_close,            /* 0x25 */
     84    &_sys_ukn,              /* 0x26 */
     85    &_sys_ukn,              /* 0x27 */
     86    &_sys_ukn,              /* 0x28 */
     87    &_sys_ukn,              /* 0x29 */
     88    &_sys_ukn,              /* 0x2A */
     89    &_sys_ukn,              /* 0x2B */
     90    &_sys_ukn,              /* 0x2C */
     91    &_sys_ukn,              /* 0x2D */
     92    &_sys_ukn,              /* 0x2E */
     93    &_sys_ukn,              /* 0x2F */
     94
     95    &_sys_ukn,              /* 0x30 */
     96    &_sys_ukn,              /* 0x31 */
     97    &_sys_ukn,              /* 0x32 */
     98    &_sys_ukn,              /* 0x33 */
     99    &_sys_ukn,              /* 0x34 */
     100    &_sys_ukn,              /* 0x35 */
     101    &_sys_ukn,              /* 0x36 */
     102    &_sys_ukn,              /* 0x37 */
     103    &_sys_ukn,              /* 0x38 */   
     104    &_sys_ukn,              /* 0x39 */
     105    &_sys_ukn,              /* 0x3A */
     106    &_sys_ukn,              /* 0x3B */
     107    &_sys_ukn,              /* 0x3C */
     108    &_sys_ukn,              /* 0x3D */
     109    &_sys_ukn,              /* 0x3E */
     110    &_sys_ukn,              /* 0x3F */
    104111};
    105112
    106113//////////////////////////////////////////////////////////////////////////////
    107 // function executed in case of undefined syscall
     114//             TTY related syscall handlers
    108115//////////////////////////////////////////////////////////////////////////////
    109 void _sys_ukn()
    110 {
    111     _printf("\n\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
    112     _exit();
     116
     117////////////////////
     118int _sys_tty_alloc()
     119{
     120    // get a new TTY terminal index
     121    unsigned int channel = _tty_channel_allocator;
     122    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
     123    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     124
     125    if ( channel >= NB_TTY_CHANNELS )
     126    {
     127        _printf("\n[GIET_ERROR] in _sys_tty_alloc() : not enough TTY channels\n");
     128        return -1;
     129    }
     130    else
     131    {
     132        _printf("\n[GIET WARNING] TTY channel %d allocated "
     133                " to thread %d in vspace %d\n", channel, thread, vspace );
     134    }
     135
     136    // register timer index in task context
     137    _set_context_slot( CTX_TTY_ID, _tty_channel_allocator );
     138
     139    // update timer allocator
     140    _tty_channel_allocator++;
     141
     142    return 0;
     143}
     144
     145/////////////////////////////////////////////////
     146int _sys_tty_write( const char*  buffer,   
     147                    unsigned int length,    // number of characters
     148                    unsigned int channel)   // channel index
     149{
     150    unsigned int  nwritten;
     151
     152    // compute and check tty channel
     153    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
     154    if( channel >= NB_TTY_CHANNELS ) return -1;
     155
     156    // write string to TTY channel
     157    for (nwritten = 0; nwritten < length; nwritten++)
     158    {
     159        // check tty's status
     160        if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 )  break;
     161
     162        // write one byte
     163        if (buffer[nwritten] == '\n')
     164        {
     165            _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' );
     166        }
     167        _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] );
     168    }
     169   
     170    return nwritten;
     171}
     172
     173////////////////////////////////////////////////
     174int _sys_tty_read( char*        buffer,
     175                   unsigned int length,    // unused
     176                   unsigned int channel)   // channel index
     177{
     178    // compute and check tty channel
     179    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
     180    if( channel >= NB_TTY_CHANNELS ) return -1;
     181
     182    // read one character from TTY channel
     183    if (_tty_rx_full[channel] == 0)
     184    {
     185        return 0;
     186    }
     187    else
     188    {
     189        *buffer = _tty_rx_buf[channel];
     190        _tty_rx_full[channel] = 0;
     191        return 1;
     192    }
     193}
     194
     195///////////////////////////////////////////
     196int _sys_tty_get_lock( unsigned int   channel,
     197                       unsigned int * save_sr_ptr )
     198{
     199    // compute and check tty channel
     200    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
     201    if( channel >= NB_TTY_CHANNELS ) return -1;
     202
     203    _it_disable( save_sr_ptr );
     204    _get_lock( &_tty_lock[channel] );
     205    return 0;
     206}
     207
     208///////////////////////////////////////////////
     209int _sys_tty_release_lock( unsigned int   channel,
     210                           unsigned int * save_sr_ptr )
     211{
     212    // compute and check tty channel
     213    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
     214    if( channel >= NB_TTY_CHANNELS ) return -1;
     215
     216    _release_lock( &_tty_lock[channel] );
     217    _it_restore( save_sr_ptr );
     218    return 0;
    113219}
    114220
    115221//////////////////////////////////////////////////////////////////////////////
    116 // This function returns the processor (x,y,p) identifiers.
     222//             TIM related syscall handlers
    117223//////////////////////////////////////////////////////////////////////////////
    118 void _proc_xyp( unsigned int* x,
    119                 unsigned int* y,
    120                 unsigned int* p )
     224
     225////////////////////
     226int _sys_tim_alloc()
     227{
     228    // get a new timer index
     229    unsigned int channel = _tim_channel_allocator;
     230    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
     231    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     232
     233    if ( channel >= NB_TIM_CHANNELS )
     234    {
     235        _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n");
     236        return -1;
     237    }
     238    else
     239    {
     240        _printf("\n[GIET WARNING] TIM channel %d allocated "
     241                " to thread %d in vspace %d\n", channel, thread, vspace );
     242    }
     243
     244    // register timer index in task context
     245    _set_context_slot( CTX_TIM_ID, channel );
     246
     247    // update timer allocator
     248    _tim_channel_allocator++;
     249
     250    return 0;
     251}
     252
     253/////////////////////////////////////////
     254int _sys_tim_start( unsigned int period )
     255{
     256    // get timer index
     257    unsigned int channel = _get_context_slot( CTX_TIM_ID );
     258    if ( channel >= NB_TIM_CHANNELS )
     259    {
     260        _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n");
     261        return -1;
     262    }
     263
     264    // start timer
     265    _timer_start( channel, period );
     266
     267    return 0;
     268}
     269
     270///////////////////
     271int _sys_tim_stop()
     272{
     273    // get timer index
     274    unsigned int channel = _get_context_slot( CTX_TIM_ID );
     275    if ( channel >= NB_TIM_CHANNELS )
     276    {
     277        _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n");
     278        return -1;
     279    }
     280
     281    // stop timer
     282    _timer_stop( channel );
     283
     284    return 0;
     285}
     286
     287//////////////////////////////////////////////////////////////////////////////
     288//             NIC related syscall handlers
     289//////////////////////////////////////////////////////////////////////////////
     290
     291////////////////////
     292int _sys_nic_alloc()
     293{
     294    // get a new NIC channel index
     295    unsigned int channel = _nic_channel_allocator;
     296    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
     297    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     298
     299    if ( channel >= NB_NIC_CHANNELS )
     300    {
     301        _printf("\n[GIET_ERROR] in _sys_nic_alloc() : not enough NIC channels\n");
     302        return -1;
     303    }
     304    else
     305    {
     306        _printf("\n[GIET WARNING] NIC channel %d allocated "
     307                " to thread %d in vspace %d\n", channel, thread, vspace );
     308    }
     309
     310    // register channel index in task context
     311    _set_context_slot( CTX_NIC_ID, channel );
     312
     313    // update NIC channel allocator
     314    _nic_channel_allocator++;
     315
     316    return 0;
     317}
     318
     319////////////////////////////////////
     320int _sys_nic_sync_send( void* vbuf )
     321{
     322    unsigned int ppn;
     323    unsigned int flags;
     324    unsigned int vaddr = (unsigned int)vbuf;
     325
     326    // get NIC channel index
     327    unsigned int channel = _get_context_slot( CTX_NIC_ID );
     328    if ( channel >= NB_NIC_CHANNELS )
     329    {
     330        _printf("\n[GIET_ERROR] in _sys_nic_sync_send() : illegal NIC channel index\n");
     331        return -1;
     332    }
     333
     334    // get page table pointer
     335    unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID );
     336
     337    // Compute user buffer physical address and check access rights
     338    unsigned int ko = _v2p_translate( (page_table_t*)user_ptab,
     339                                      vaddr,
     340                                      &ppn,
     341                                      &flags );
     342    if ( ko )
     343    {
     344        _printf("\n[GIET ERROR] in _sys_nic_sync_send() : user buffer unmapped\n");
     345        return -1;
     346    }
     347    if ( (flags & PTE_U) == 0 )
     348    {
     349        _printf("\n[GIET ERROR] in _sys_nic_sync_send() : illegal buffer address\n");
     350        return -1;
     351    }
     352    unsigned long long pbuf = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
     353
     354    _nic_sync_send( channel, pbuf );
     355
     356    return 0;
     357}
     358
     359///////////////////////////////////////
     360int _sys_nic_sync_receive( void* vbuf )
     361{
     362    unsigned int ppn;
     363    unsigned int flags;
     364    unsigned int vaddr = (unsigned int)vbuf;
     365
     366    // get NIC channel index
     367    unsigned int channel = _get_context_slot( CTX_NIC_ID );
     368    if ( channel >= NB_NIC_CHANNELS )
     369    {
     370        _printf("\n[GIET_ERROR] in _sys_nic_sync_send() : illegal NIC channel index\n");
     371        return -1;
     372    }
     373
     374    // get page table pointer
     375    unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID );
     376
     377    // Compute user buffer physical address and check access rights
     378    unsigned int ko = _v2p_translate( (page_table_t*)user_ptab,
     379                                      vaddr,
     380                                      &ppn,
     381                                      &flags );
     382    if ( ko )
     383    {
     384        _printf("\n[GIET ERROR] in _sys_nic_sync_send() : user buffer unmapped\n");
     385        return -1;
     386    }
     387    if ( (flags & PTE_U) == 0 )
     388    {
     389        _printf("\n[GIET ERROR] in _sys_nic_sync_send() : illegal buffer address\n");
     390        return -1;
     391    }
     392    unsigned long long pbuf = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF);
     393
     394    _nic_sync_receive( channel, pbuf );
     395
     396    return 0;
     397}
     398
     399/////////////////////////////////////////////////////////////////////////////////////////
     400//    FBF related syscall handlers
     401/////////////////////////////////////////////////////////////////////////////////////////
     402
     403// Array of fbf_chbuf descriptors, indexed by the CMA channel index.
     404__attribute__((section (".unckdata")))
     405volatile fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(32)));
     406
     407// Physical addresses of these fbf_chbuf descriptors (required for L2 cache sync)
     408__attribute__((section (".unckdata")))
     409unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS];
     410
     411/////////////////////////////////////////////
     412int _sys_fbf_sync_write( unsigned int offset,
     413                         void*        buffer,
     414                         unsigned int length )
     415{
     416    char* fbf_address = (char *)SEG_FBF_BASE + offset;
     417    memcpy( fbf_address, buffer, length);
     418
     419    return 0;
     420}
     421
     422/////////////////////////////////////////////
     423int _sys_fbf_sync_read(  unsigned int offset,
     424                         void*        buffer,
     425                         unsigned int length )
     426{
     427    char* fbf_address = (char *)SEG_FBF_BASE + offset;
     428    memcpy( buffer, fbf_address, length);
     429
     430    return 0;
     431}
     432
     433////////////////////////
     434int _sys_fbf_cma_alloc()
     435{
     436#if NB_CMA_CHANNELS > 0
     437
     438   // get a new CMA channel index
     439    unsigned int channel = _cma_channel_allocator;
     440    unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
     441    unsigned int vspace  = _get_context_slot( CTX_VSID_ID );
     442
     443    if ( channel >= NB_CMA_CHANNELS )
     444    {
     445        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : not enough CMA channels\n");
     446        return -1;
     447    }
     448    else
     449    {
     450        _printf("\n[GIET WARNING] FBF_CMA channel %d allocated "
     451                " to thread %d in vspace %d\n", channel, thread, vspace );
     452    }
     453
     454    // register channel index in task context
     455    _set_context_slot( CTX_FBCMA_ID, channel );
     456
     457    // update CMA channel allocator
     458    _cma_channel_allocator++;
     459
     460    return 0;
     461
     462#else
     463
     464    _printf("\n[GIET ERROR] in _fb_cma_start() : NB_CMA_CHANNELS = 0\n");
     465    return -1;
     466
     467#endif
     468} // end sys_fbf_cma_alloc()
     469
     470////////////////////////////////////////////
     471int _sys_fbf_cma_start( void*        vbase0,
     472                        void*        vbase1, 
     473                        unsigned int length )
     474{
     475#if NB_CMA_CHANNELS > 0
     476
     477    unsigned int       ptab;            // page table virtual address
     478    unsigned int       ko;              // unsuccessfull V2P translation
     479    unsigned int       vaddr;           // virtual address
     480    unsigned int       flags;           // protection flags
     481    unsigned int       ppn;             // physical page number
     482    unsigned long long chbuf_paddr;     // physical address of source chbuf descriptor
     483
     484    // get channel index
     485    unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
     486
     487    if ( channel >= NB_CMA_CHANNELS )
     488    {
     489        _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n");
     490        return -1;
     491    }
     492
     493#if GIET_DEBUG_FBF_CMA
     494_printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_start()\n"
     495        " - channel      = %d\n"
     496        " - buf0   vbase = %x\n"
     497        " - buf1   vbase = %x\n"
     498        " - buffer size  = %x\n",
     499        channel,
     500        (unsigned int)vbase0,
     501        (unsigned int)vbase1,
     502        length );
     503#endif
     504
     505    // checking user buffers virtual addresses and length alignment
     506    if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) )
     507    {
     508        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not word aligned\n");
     509        return -1;
     510    }
     511
     512    // get page table virtual address
     513    ptab = _get_context_slot(CTX_PTAB_ID);
     514
     515    // compute frame buffer physical address and initialize _fbf_chbuf[channel]
     516    vaddr = ((unsigned int)SEG_FBF_BASE);
     517    ko    = _v2p_translate( (page_table_t*) ptab,
     518                            (vaddr >> 12),
     519                            &ppn,
     520                            &flags );
     521    if (ko)
     522    {
     523        _printf("\n[GIET ERROR] in _fb_cma_start() : frame buffer unmapped\n");
     524        return -1;
     525    }
     526
     527    _fbf_chbuf[channel].fbf    = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
     528
     529    // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel]
     530    vaddr = (unsigned int)vbase0;
     531    ko = _v2p_translate( (page_table_t*) ptab,
     532                         (vaddr >> 12),
     533                         &ppn,
     534                         &flags );
     535    if (ko)
     536    {
     537        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 unmapped\n");
     538        return -1;
     539    }
     540    if ((flags & PTE_U) == 0)
     541    {
     542        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 not in user space\n");
     543        return -1;
     544    }
     545
     546    _fbf_chbuf[channel].buf0 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
     547
     548    // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel]
     549    vaddr = (unsigned int)vbase1;
     550    ko = _v2p_translate( (page_table_t*) ptab,
     551                         (vaddr >> 12),
     552                         &ppn,
     553                         &flags );
     554    if (ko)
     555    {
     556        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 unmapped\n");
     557        return -1;
     558    }
     559    if ((flags & PTE_U) == 0)
     560    {
     561        _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 not in user space\n");
     562        return -1;
     563    }
     564
     565    _fbf_chbuf[channel].buf1 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
     566
     567    // initializes buffer length
     568    _fbf_chbuf[channel].length = length;
     569
     570    // Compute and register physical adress of the chbuf descriptor
     571    vaddr = (unsigned int)(&_fbf_chbuf[channel]);
     572    ko = _v2p_translate( (page_table_t*) ptab,
     573                         (vaddr >> 12),
     574                         &ppn,
     575                         &flags );
     576    if (ko)
     577    {
     578        _printf("\n[GIET ERROR] in _fbf_cma_start() : chbuf descriptor unmapped\n");
     579        return -1;
     580    }
     581 
     582    chbuf_paddr = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
     583
     584    _fbf_chbuf_paddr[channel] = chbuf_paddr;
     585
     586
     587    if ( USE_IOB )
     588    {
     589        // SYNC request for channel descriptor
     590        _mmc_sync( chbuf_paddr, 32 );
     591    }
     592
     593#if GIET_DEBUG_FBF_CMA
     594_printf(" - fbf    pbase = %l\n"
     595        " - buf0   pbase = %l\n"
     596        " - buf1   pbase = %l\n"
     597        " - chbuf  pbase = %l\n",
     598        _fbf_chbuf[channel].fbf,
     599        _fbf_chbuf[channel].buf0,
     600        _fbf_chbuf[channel].buf1,
     601        chbuf_paddr );
     602#endif
     603
     604    // call CMA driver to start transfer
     605    _cma_start_channel( channel,
     606                        chbuf_paddr,
     607                        2,
     608                        chbuf_paddr + 16,
     609                        1,
     610                        length );
     611    return 0;
     612
     613#else
     614
     615    _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n");
     616    return -1;
     617
     618#endif
     619} // end _sys_fbf_cma_start()
     620
     621/////////////////////////////////////////////////////
     622int _sys_fbf_cma_display( unsigned int buffer_index )
     623{
     624#if NB_CMA_CHANNELS > 0
     625
     626    volatile paddr_t buf_paddr;
     627    unsigned int     full = 1;
     628
     629    // get channel index
     630    unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
     631
     632    if ( channel >= NB_CMA_CHANNELS )
     633    {
     634        _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : CMA channel index too large\n");
     635        return -1;
     636    }
     637
     638#if GIET_DEBUG_FBF_CMA
     639_printf("\n[FBF_CMA DEBUG] enters _sys_fb_cma_display()\n"
     640        " - channel      = %d\n"
     641        " - buffer       = %d\n",
     642        channel, buffer_index );
     643#endif
     644
     645    // waiting user buffer empty
     646    while ( full )
     647    { 
     648        if ( USE_IOB )
     649        {
     650            // INVAL L1 cache for the chbuf descriptor,
     651            _dcache_buf_invalidate( (unsigned int)&_fbf_chbuf[channel], 32 );
     652
     653            // INVAL L2 cache for the chbuf descriptor,
     654            _mmc_inval( _fbf_chbuf_paddr[channel], 32 );
     655        }
     656
     657        // read user buffer descriptor
     658        if ( buffer_index == 0 ) buf_paddr = _fbf_chbuf[channel].buf0;
     659        else                     buf_paddr = _fbf_chbuf[channel].buf1;
     660
     661        full = ( (unsigned int)(buf_paddr>>63) );
     662    }
     663
     664    if ( USE_IOB )
     665    {
     666        // SYNC request for the user buffer, because
     667        // it will be read from XRAM by the CMA component
     668        _mmc_sync( buf_paddr, _fbf_chbuf[channel].length );
     669    }
     670
     671    // set user buffer status
     672    if ( buffer_index == 0 ) _fbf_chbuf[channel].buf0 = buf_paddr | 0x8000000000000000ULL;
     673    else                     _fbf_chbuf[channel].buf1 = buf_paddr | 0x8000000000000000ULL;
     674
     675    // reset fbf buffer status
     676    _fbf_chbuf[channel].fbf  = _fbf_chbuf[channel].fbf & 0x7FFFFFFFFFFFFFFFULL;
     677
     678    if ( USE_IOB )
     679    {
     680        // SYNC request for the channel descriptor, because
     681        // it will be read from XRAM by the CMA component
     682        _mmc_sync( _fbf_chbuf_paddr[channel], 32 );
     683    }
     684
     685#if GIET_DEBUG_FBF_CMA
     686_printf(" - fbf    pbase = %l\n"
     687        " - buf0   pbase = %l\n"
     688        " - buf1   pbase = %l\n",
     689        _fbf_chbuf[channel].fbf,
     690        _fbf_chbuf[channel].buf0,
     691        _fbf_chbuf[channel].buf1 );
     692#endif
     693
     694
     695    return 0;
     696
     697#else
     698
     699    _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n");
     700    return -1;
     701
     702#endif
     703} // end _sys_fbf_cma_display()
     704
     705///////////////////////
     706int _sys_fbf_cma_stop()
     707{
     708#if NB_CMA_CHANNELS > 0
     709
     710    // get channel index
     711    unsigned int channel = _get_context_slot( CTX_FBCMA_ID );
     712
     713    if ( channel >= NB_CMA_CHANNELS )
     714    {
     715        _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n");
     716        return -1;
     717    }
     718
     719    // Desactivate CMA channel
     720    _cma_stop_channel( channel );
     721
     722    return 0;
     723
     724#else
     725
     726    _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n");
     727    return -1;
     728
     729#endif
     730} // end _sys_fbf_cma_stop()
     731
     732
     733//////////////////////////////////////////////////////////////////////////////
     734//           Miscelaneous syscall handlers
     735//////////////////////////////////////////////////////////////////////////////
     736
     737///////////////
     738int _sys_ukn()
     739{
     740    _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
     741    return -1;
     742}
     743
     744////////////////////////////////////
     745int _sys_proc_xyp( unsigned int* x,
     746                   unsigned int* y,
     747                   unsigned int* p )
    121748{
    122749    unsigned int gpid = _get_procid();  // global processor index from CPO register
     
    125752    *y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
    126753    *p = gpid & ((1<<P_WIDTH)-1);
    127 }
    128 ////////////////////////////////////////////////////////////////////////////
    129 // Task suicide... after printing a death message.
    130 ////////////////////////////////////////////////////////////////////////////
    131 void _task_exit( char* string )
     754
     755    return 0;
     756}
     757
     758//////////////////////////////////
     759int _sys_task_exit( char* string )
    132760{
    133761    unsigned int date       = _get_proctime();
     
    141769    unsigned int task_id    = _get_context_slot(CTX_LTID_ID);
    142770
    143     // print death message
     771    // print exit message
    144772    _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
    145773            "\n       Cause : %s\n\n",
     
    151779    // deschedule
    152780    _context_switch();
     781
     782    return 0;
    153783}
    154784
    155 //////////////////////////////////////////////////////////////////////////////
    156 // returns in buffer argument the number of processors in the cluster
    157 // specified by the cluster_id argument.
    158 //////////////////////////////////////////////////////////////////////////////
    159 unsigned int _procs_number(unsigned int  cluster_id,
    160                            unsigned int* buffer)
     785//////////////////////
     786int _context_switch()
     787{
     788    unsigned int save_sr;
     789
     790    _it_disable( &save_sr );
     791    _ctx_switch();
     792    _it_restore( &save_sr );
     793
     794    return 0;
     795}
     796
     797////////////////////////
     798int _sys_local_task_id()
     799{
     800    return _get_context_slot(CTX_LTID_ID);
     801}
     802
     803/////////////////////////
     804int _sys_global_task_id()
     805{
     806    return _get_context_slot(CTX_GTID_ID);
     807}
     808
     809////////////////////
     810int _sys_thread_id()
     811{
     812    return _get_context_slot(CTX_TRDID_ID);
     813}
     814
     815//////////////////////////////////////
     816int _sys_procs_number( unsigned int  x,
     817                       unsigned int  y,
     818                       unsigned int* number )
    161819{
    162820    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    163821    mapping_cluster_t * cluster = _get_cluster_base(header);
    164822
    165     if ( cluster_id < X_SIZE * Y_SIZE )
    166     {
    167         *buffer = cluster[cluster_id].procs;
     823    if ( (x < X_SIZE) && (y < Y_SIZE) )
     824    {
     825        *number = cluster[(x*Y_SIZE)+y].procs;
    168826        return 0;
    169827    }
    170828    else
    171829    {
    172         return 1;
    173     }
    174 }
    175 
    176 /////////////////////////////////////////////////////////////////////////////
    177 // Returns current task local index.
    178 /////////////////////////////////////////////////////////////////////////////
    179 unsigned int _local_task_id()
    180 {
    181     return _get_context_slot(CTX_LTID_ID);
    182 }
    183 
    184 /////////////////////////////////////////////////////////////////////////////
    185 // Returns current task global index.
    186 /////////////////////////////////////////////////////////////////////////////
    187 unsigned int _global_task_id()
    188 {
    189     return _get_context_slot(CTX_GTID_ID);
    190 }
    191 
    192 /////////////////////////////////////////////////////////////////////////////
    193 // Returns current thread index.
    194 /////////////////////////////////////////////////////////////////////////////
    195 unsigned int _thread_id()
    196 {
    197     return _get_context_slot(CTX_TRDID_ID);
    198 }
    199 
    200 /////////////////////////////////////////////////////////////////////////////
    201 // This function writes in res_vobj a pointer on a vobj
    202 // identified by the (vspace_name / vobj_name ) couple.
    203 // returns 0 if success, >0 if not found
    204 /////////////////////////////////////////////////////////////////////////////
    205 int _get_vobj( char*             vspace_name,
    206                char*             vobj_name,
    207                mapping_vobj_t**  res_vobj )
     830        _printf("\n[GIET ERROR] in _sys_procs_number() : illegal (x,y) coordinates\n" );
     831        return -1;
     832    }
     833}
     834
     835///////////////////////////////////////////////////////
     836int _sys_vobj_get_vbase( char*             vspace_name,
     837                         char*             vobj_name,
     838                         unsigned int*     vbase )
    208839{
    209840    mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     
    226857                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0)
    227858                {
    228                     *res_vobj = &vobj[vobj_id];
     859                    *vbase = vobj[vobj_id].vbase;
    229860                    return 0;
    230861                }
     
    232863        }
    233864    }
    234     return 1;    //not found
    235 }
    236 
    237 /////////////////////////////////////////////////////////////////////////////
    238 // This function writes in vobj_vbase the virtual base address of a vobj
    239 // identified by the (vspace_name / vobj_name ) couple.
    240 // returns 0 if success, >0 if not found
    241 /////////////////////////////////////////////////////////////////////////////
    242 unsigned int _vobj_get_vbase( char*         vspace_name,
    243                               char*         vobj_name,
    244                               unsigned int* vobj_vbase )
    245 {
    246     mapping_vobj_t* res_vobj;
    247     unsigned int    ret;
    248     if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj)))
    249     {
    250         return ret;
    251     }
    252     *vobj_vbase = res_vobj->vbase;
    253     return 0;
    254 }
    255 
    256 /////////////////////////////////////////////////////////////////////////////
    257 // This function writes in vobj_length the length of a vobj
    258 // identified by the (vspace_name / vobj_name ) couple.
    259 // returns 0 if success, >0 if not found
    260 /////////////////////////////////////////////////////////////////////////////
    261 unsigned int _vobj_get_length( char*         vspace_name,
    262                                char*         vobj_name,
    263                                unsigned int* vobj_length )
    264 {
    265     mapping_vobj_t * res_vobj;
    266     unsigned int ret;
    267     if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj)))
    268     {
    269         return ret;
    270     }
    271     *vobj_length = res_vobj->length;
    272     return 0;
    273 }
    274 
    275 /////////////////////////////////////////////////////////////////////////////
    276 // This function returns in the (x,y) arguments the coordinates of the
    277 // where is mapped the ptr virtual address. It use the _get_context_slot()
    278 // function to get the calling task page table, and uses the _v2p_translate()
    279 // function to obtain the physical address.
    280 // returns 0 if success, > 0 if ptr not mapped in the calling task vspace.
    281 /////////////////////////////////////////////////////////////////////////////
    282 
    283 unsigned int _get_xy_from_ptr( void*         ptr,
    284                                unsigned int* px,
    285                                unsigned int* py )
     865    return -1;    // not found
     866}
     867
     868/////////////////////////////////////////////////////////
     869int _sys_vobj_get_length( char*         vspace_name,
     870                          char*         vobj_name,
     871                          unsigned int* length )
     872{
     873    mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     874    mapping_vspace_t * vspace = _get_vspace_base(header);
     875    mapping_vobj_t * vobj     = _get_vobj_base(header);
     876
     877    unsigned int vspace_id;
     878    unsigned int vobj_id;
     879
     880    // scan vspaces
     881    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
     882    {
     883        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0)
     884        {
     885            // scan vobjs
     886            for (vobj_id = vspace[vspace_id].vobj_offset;
     887                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs);
     888                 vobj_id++)
     889            {
     890                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0)
     891                {
     892                    *length = vobj[vobj_id].length;
     893                    return 0;
     894                }
     895            }
     896        }
     897    }
     898    return -1;    // not found
     899}
     900
     901////////////////////////////////////////
     902int _sys_xy_from_ptr( void*         ptr,
     903                      unsigned int* x,
     904                      unsigned int* y )
    286905{
    287906    unsigned int ret;
     
    294913
    295914    // compute the physical address
    296     if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) )
    297     {
    298         return ret;
    299     }
    300 
    301     *px = (ppn>>24) & 0xF;
    302     *py = (ppn>>20) & 0xF;
    303     return 0;
    304 }
    305 
    306 ////////////////////////////////////////////////////////////////////////////
    307 // This sysrem function deschedule the requestint task.
    308 // It mask interrupts before calling the _ctx_switch, and restore it
    309 // when the task is rescheduled.
    310 ////////////////////////////////////////////////////////////////////////////
    311 void _context_switch()
    312 {
    313     unsigned int save_sr;
    314 
    315     _it_disable( &save_sr );
    316     _ctx_switch();
    317     _it_restore( &save_sr );
    318 }
     915    if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) ) return -1;
     916
     917    *x = (ppn>>24) & 0xF;
     918    *y = (ppn>>20) & 0xF;
     919    return 0;
     920}
     921
     922/////////////////////////////////////////
     923int _sys_heap_info( unsigned int* vaddr,
     924                    unsigned int* length,
     925                    unsigned int  x,
     926                    unsigned int  y )
     927{
     928    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     929    mapping_task_t *   tasks   = _get_task_base(header);
     930    mapping_vobj_t *   vobjs   = _get_vobj_base(header);
     931    mapping_vspace_t * vspaces = _get_vspace_base(header);
     932
     933    unsigned int task_id;
     934    unsigned int vspace_id;
     935    unsigned int vobj_id = 0xFFFFFFFF;
     936
     937    // searching the heap vobj_id
     938    if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
     939    {
     940        // get vspace global index
     941        vspace_id = _get_context_slot(CTX_VSID_ID);
     942
     943        // scan all tasks in vspace
     944        unsigned int min = vspaces[vspace_id].task_offset ;
     945        unsigned int max = min + vspaces[vspace_id].tasks ;
     946        for ( task_id = min ; task_id < max ; task_id++ )
     947        {
     948            if ( tasks[task_id].clusterid == (x * Y_SIZE + y) )
     949            {
     950                vobj_id = tasks[task_id].heap_vobj_id;
     951                if ( vobj_id != 0xFFFFFFFF ) break;
     952            }
     953        }
     954    }
     955    else                                // searching in the calling task
     956    {
     957        task_id = _get_context_slot(CTX_GTID_ID);
     958        vobj_id = tasks[task_id].heap_vobj_id;
     959    }
     960
     961    // analysing the vobj_id
     962    if ( vobj_id != 0xFFFFFFFF )
     963    {
     964        *vaddr  = vobjs[vobj_id].vbase;
     965        *length = vobjs[vobj_id].length;
     966        return 0;
     967    }
     968    else
     969    {
     970        *vaddr  = 0;
     971        *length = 0;
     972        return -1;
     973    }
     974}  // end _sys_heap_info()
     975
    319976
    320977// Local Variables:
  • soft/giet_vm/giet_kernel/sys_handler.h

    r428 r440  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
     8// It define the syscall_vector[] (at the end of this file), as well as the
     9// associated syscall handlers.
     10///////////////////////////////////////////////////////////////////////////////////
    711
    812#ifndef _SYS_HANDLER_H
    913#define _SYS_HANDLER_H
    1014
    11 //////////////////////////////////////////////////////////////////////////////////
     15#include <mapping_info.h>
     16
     17///////////////////////////////////////////////////////////////////////////////////
    1218//     Syscall Vector Table (indexed by syscall index)
    13 //////////////////////////////////////////////////////////////////////////////////
     19///////////////////////////////////////////////////////////////////////////////////
    1420
    1521extern const void * _syscall_vector[64];
    1622
     23///////////////////////////////////////////////////////////////////////////////////
     24// This structure can be used by the vci_chbuf_dma component to transfer a stream
     25// of images from two buffers in user space to the frame buffer in kernel space.
     26// It contains two chbuf descriptors
     27// - The SRC chbuf contains two buffers (buf0 & buf1), that can be in user space.
     28// - The DST cbuf contains one single buffer (fbf), that is the frame buffer.
     29///////////////////////////////////////////////////////////////////////////////////
     30
     31typedef struct fbf_chbuf_s
     32{
     33    unsigned long long  buf0;     // physical address + status for user buffer 0
     34    unsigned long long  buf1;     // physical address + status for user buffer 1
     35    unsigned long long  fbf;      // physical address + status for user buffer 0
     36    unsigned int        length;   // buffer length (bytes)
     37    unsigned int        padding;  // for 32 bytes alignment
     38} fbf_chbuf_t;   
     39
    1740//////////////////////////////////////////////////////////////////////////////////
    18 // Prototypes os the syscall handlers (other than peripheral drivers)
     41//    TTY related syscall handlers
    1942//////////////////////////////////////////////////////////////////////////////////
    2043
    21 void         _sys_ukn();
     44int _sys_tty_alloc();
    2245
    23 void         _proc_xyp( unsigned int* x,
    24                         unsigned int* y,
    25                         unsigned int* p );
     46int _sys_tty_write( const char*  buffer,
     47                    unsigned int length,
     48                    unsigned int channel );
    2649
    27 void         _task_exit();
     50int _sys_tty_read(  char*        buffer,
     51                    unsigned int length,
     52                    unsigned int channel );
    2853
    29 void         _context_switch();
     54int _sys_tty_get_lock( unsigned int   channel,
     55                       unsigned int * save_sr_ptr );
    3056
    31 unsigned int _local_task_id();
     57int _sys_tty_release_lock( unsigned int   channel,
     58                           unsigned int * save_sr_ptr );
    3259
    33 unsigned int _global_task_id();
     60//////////////////////////////////////////////////////////////////////////////
     61//    TIM related syscall handlers
     62//////////////////////////////////////////////////////////////////////////////
    3463
    35 unsigned int _thread_id();
     64int _sys_tim_alloc();
    3665
    37 unsigned int _procs_number( unsigned int  cluster_id,
    38                             unsigned int* number );
     66int _sys_tim_start( unsigned int period );
    3967
    40 unsigned int _vobj_get_vbase( char*         vspace_name,
    41                               char*         vobj_name,
    42                               unsigned int* vobj_vbase );
     68int _sys_tim_stop();
    4369
    44 unsigned int _vobj_get_length( char*         vspace_name,
    45                                char*         vobj_name,
    46                                unsigned int* vobj_length );
     70//////////////////////////////////////////////////////////////////////////////
     71//    NIC related syscall handlers
     72//////////////////////////////////////////////////////////////////////////////
    4773
    48 unsigned int _get_xy_from_ptr( void*          ptr,
    49                                unsigned int*  x,
    50                                unsigned int*  y );
     74int _sys_nic_alloc();
    5175
     76int _sys_nic_sync_send( void* vbuf );
     77
     78int _sys_nic_sync_receive( void* vbuf );
     79
     80//////////////////////////////////////////////////////////////////////////////
     81//    FBF related syscall handlers
     82//////////////////////////////////////////////////////////////////////////////
     83
     84int _sys_fbf_sync_write( unsigned int offset,
     85                         void*        buffer,
     86                         unsigned int length );
     87
     88int _sys_fbf_sync_read(  unsigned int offset,
     89                         void*        buffer,
     90                         unsigned int length );
     91
     92int _sys_fbf_cma_alloc();
     93
     94int _sys_fbf_cma_start( void*        vbase0,
     95                        void*        vbase1, 
     96                        unsigned int length );
     97
     98int _sys_fbf_cma_display( unsigned int buffer_index );
     99
     100int _sys_fbf_cma_stop();
     101
     102//////////////////////////////////////////////////////////////////////////////
     103//    Miscelaneous syscall handlers
     104//////////////////////////////////////////////////////////////////////////////
     105
     106int _sys_ukn();
     107
     108int _sys_proc_xyp( unsigned int* x,
     109                   unsigned int* y,
     110                   unsigned int* p );
     111
     112int _sys_task_exit( char* string );
     113
     114int _context_switch();
     115
     116int _sys_local_task_id();
     117
     118int _sys_global_task_id();
     119
     120int _sys_thread_id();
     121
     122int _sys_procs_number( unsigned int  x,
     123                       unsigned int  y,
     124                       unsigned int* number );
     125
     126int _sys_vobj_get_vbase( char*         vspace_name,
     127                         char*         vobj_name,
     128                         unsigned int* vbase );
     129
     130int _sys_vobj_get_length( char*         vspace_name,
     131                          char*         vobj_name,
     132                          unsigned int* length );
     133
     134int _sys_xy_from_ptr( void*          ptr,
     135                      unsigned int*  x,
     136                      unsigned int*  y );
     137
     138int _sys_heap_info( unsigned int* vaddr,
     139                    unsigned int* length,
     140                    unsigned int  x,
     141                    unsigned int  y );
    52142
    53143#endif
Note: See TracChangeset for help on using the changeset viewer.