source: soft/giet_vm/sys/kernel_init.c @ 193

Last change on this file since 193 was 189, checked in by alain, 12 years ago

Introducing a new release where all initialisation
is done in the boot code.

File size: 6.0 KB
RevLine 
[165]1///////////////////////////////////////////////////////////////////////////////////
2// File     : kernel_init.c
3// Date     : 26/05/2012
4// Authors  : alain greiner & mohamed karaoui
5// Copyright (c) UPMC-LIP6
6////////////////////////////////////////////////////////////////////////////////////
7// The kernel_init.c files is part of the GIET-VM nano-kernel.
[189]8// It contains the kernel entry point for the last step of system initialisation.
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.
[165]15////////////////////////////////////////////////////////////////////////////////////
16
17#include <common.h>
[189]18#include <irq_handler.h>
[165]19#include <ctx_handler.h>
20#include <sys_handler.h>
21#include <mapping_info.h>
22#include <giet_config.h>
23#include <mips32_registers.h>
24#include <irq_handler.h>
[166]25#include <vm_handler.h>
[165]26#include <hwr_mapping.h>
27#include <mwmr_channel.h>
28#include <barrier.h>
29#include <drivers.h>
30
31///////////////////////////////////////////////////////////////////////////////////
[189]32// Kernel Global variables
[167]33///////////////////////////////////////////////////////////////////////////////////
34
[189]35__attribute__((section (".kdata"))) 
36page_table_t* _ptabs_paddr[GIET_NB_VSPACE_MAX]; 
[167]37
[189]38__attribute__((section (".kdata"))) 
39page_table_t* _ptabs_vaddr[GIET_NB_VSPACE_MAX]; 
[165]40
[189]41__attribute__((section (".kdata"))) 
42static_scheduler_t*     _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX]; 
[165]43
44//////////////////////////////////////////////////////////////////////////////////
[189]45// This function is the entry point for the last step of the boot sequence.
[165]46//////////////////////////////////////////////////////////////////////////////////
[189]47__attribute__((section (".kinit"))) void _kernel_init()
[165]48{
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
[189]55    unsigned int        proc_id    = _procid();
56    unsigned int    cluster_id = proc_id / NB_PROCS_MAX;
57    unsigned int    lpid       = proc_id % NB_PROCS_MAX;
[165]58
[189]59    // step 1 : Initialise scheduler physical addresses array
60
61    // get scheduler physical address from register
62    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
63    _schedulers_paddr[proc_id]     = psched;
64
65#if GIET_DEBUG_INIT
66_get_lock(&_tty_put_lock);
67_puts("\n[GIET DEBUG] step 1 for processor ");
68_putw( proc_id );
69_puts("\n");
70_puts("- scheduler pbase = ");
71_putw( (unsigned int)psched );
72_puts("\n");
73_release_lock(&_tty_put_lock);
74#endif
75
76    // step 2 : compute and set ICU mask
77    unsigned int irq_id;
78    unsigned int mask = 0;
79    for ( irq_id = 0 ; irq_id < 32 ; irq_id++ )
[165]80    {
[189]81        unsigned int entry   = _get_interrupt_vector_entry(irq_id);
82        if ( entry ) mask = mask | 0x1<< irq_id;
[165]83    }
[189]84    _icu_write( cluster_id,
85                lpid,
86                ICU_MASK_SET,
87                mask );
88   
89#if GIET_DEBUG_INIT
90_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 = ");
95_putw( mask );
96_puts("\n");
97_release_lock(&_tty_put_lock);
98#endif
[165]99
100
[189]101    // step 3 : TODO initialise page table addresse arrays
[165]102
[189]103
104    // step 4 : start TICK timer if more than one task
105    unsigned int tasks = _get_tasks_number();
106    if ( tasks > 1 )
[165]107    {
[189]108        unsigned int period     = GIET_TICK_VALUE;
109        unsigned int mode       = 0x3;
110        _timer_access( 0,                       // write access
111                       cluster_id, 
112                       proc_id, 
113                       TIMER_PERIOD, 
114                       &period );
115        _timer_access( 0,                       // write access
116                       cluster_id, 
117                       proc_id, 
118                       TIMER_MODE, 
119                       &mode );
120       
121#if GIET_DEBUG_INIT
122_get_lock(&_tty_put_lock);
123_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");
129_release_lock(&_tty_put_lock);
130#endif
131   
132    } 
133
134    // step 5 : each processor initialises SP, SR, PTPR, EPC, registers
135    //          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    {
[165]140        // initialise registers
[189]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);
[165]145
[189]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");
151_puts("- sp   = ");
152_putw( sp_value );
153_puts("\n");
154_puts("- sr   = ");
155_putw( sr_value );
156_puts("\n");
157_puts("- ptpr = ");
158_putw( ptpr_value<<13 );
159_puts("\n");
160_puts("- epc  = ");
161_putw( epc_value );
162_puts("\n");
163_release_lock(&_tty_put_lock);
164#endif
[165]165    }
166    else                                        // no task allocated
167    {
168        _get_lock( &_tty_put_lock );
169        _puts("\n No task allocated to processor ");
[189]170        _putw( proc_id );
[165]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
[189]183    // set critical registers and jump to user code
[165]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) );
193
194} // end _kernel_init()
Note: See TracBrowser for help on using the repository browser.