Subversion Repositories shark

Rev

Rev 3 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   (see the web pages for full authors list)
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/**
20
 ------------
21
 CVS :        $Id: init.c,v 1.1.1.1 2002-03-29 14:12:51 pj Exp $
22
 
23
 File:        $File$
24
 Revision:    $Revision: 1.1.1.1 $
25
 Last update: $Date: 2002-03-29 14:12:51 $
26
 ------------
27
 
28
 Kernel module registration and miscellaneous functions
29
 
30
 This file contains:
31
 
32
 level_alloc_descriptor
33
 resource_alloc_descriptor
34
 __compute_args__
35
 __call_main__
36
 sys_atinit
37
 sys_atexit
38
 
39
**/
40
 
41
/*
42
 * Copyright (C) 2000 Paolo Gai
43
 *
44
 * This program is free software; you can redistribute it and/or modify
45
 * it under the terms of the GNU General Public License as published by
46
 * the Free Software Foundation; either version 2 of the License, or
47
 * (at your option) any later version.
48
 *
49
 * This program is distributed in the hope that it will be useful,
50
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
51
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
52
 * GNU General Public License for more details.
53
 *
54
 * You should have received a copy of the GNU General Public License
55
 * along with this program; if not, write to the Free Software
56
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
57
 *
58
 */
59
 
60
#include <stdarg.h>
61
#include <ll/ll.h>
62
#include <ll/stdlib.h>
63
#include <ll/stdio.h>
64
#include <ll/string.h>
65
#include <kernel/config.h>
66
#include <kernel/model.h>
67
#include <kernel/const.h>
68
#include <sys/types.h>
69
#include <kernel/types.h>
70
#include <kernel/descr.h>
71
#include <errno.h>
72
#include <kernel/var.h>
73
#include <kernel/func.h>
74
 
75
/*+ List of function to call at each rnlevel;
76
    they are posted with sys_atrunlevel +*/
77
static struct exit_func {
78
    void (*f)(void *);
79
    void *arg;
80
    int no_at_abort;
81
    int next;
82
} runlevel_list[MAX_RUNLEVEL_FUNC];
83
 
84
static int runlevel_init_list;
85
static int runlevel_init_tail;
86
static int runlevel_shutdown_list;
87
static int runlevel_before_list;
88
static int runlevel_after_list;
89
static int runlevel_free;
90
 
91
 
92
void runlevel_init()
93
{
94
  int i;
95
 
96
  for (i = 0; i < MAX_RUNLEVEL_FUNC-1; i++)
97
    runlevel_list[i].next = i+1;
98
  runlevel_list[MAX_RUNLEVEL_FUNC-1].next = -1;
99
 
100
  runlevel_init_list     = -1;
101
  runlevel_init_tail     = -1;
102
  runlevel_shutdown_list = -1;
103
  runlevel_before_list   = -1;
104
  runlevel_after_list    = -1;
105
  runlevel_free          = 0;
106
}
107
 
108
/*+ flags may be RUNLEVEL_XXX...
109
    aborting may be 0 or NO_AT_ABORT +*/
110
void call_runlevel_func(int runlevel, int aborting)
111
{
112
  int i, j;
113
 
114
  switch (runlevel) {
115
    case RUNLEVEL_INIT:
116
      i = runlevel_init_list;
117
      runlevel_init_list = -1;
118
      break;
119
    case RUNLEVEL_SHUTDOWN:
120
      i = runlevel_shutdown_list;
121
      runlevel_shutdown_list = -1;
122
      break;
123
    case RUNLEVEL_BEFORE_EXIT:
124
      i = runlevel_before_list;
125
      runlevel_before_list = -1;
126
      break;
127
    case RUNLEVEL_AFTER_EXIT:
128
      i = runlevel_after_list;
129
      runlevel_after_list = -1;
130
      break;
131
    default:
132
      return;
133
  }
134
 
135
  // the task_activate must differ!!! look at activate.c
136
  calling_runlevel_func = 1;
137
 
138
  while (i != -1) {
139
    if (!(aborting && runlevel_list[i].no_at_abort))
140
      runlevel_list[i].f(runlevel_list[i].arg);
141
 
142
    j = i;
143
    i = runlevel_list[i].next;
144
 
145
    runlevel_list[j].next = runlevel_free;
146
    runlevel_free = j;
147
  }
148
 
149
  calling_runlevel_func = 0;
150
 
151
}
152
 
153
/*+ Use this function to post your own runlevel operations
154
    (when uses some defines contained in const.h) +*/
155
int sys_atrunlevel(void (*func_code)(void *),void *parm, BYTE when)
156
{
157
    register int i = 0;
158
    SYS_FLAGS f;
159
 
160
    f = kern_fsave();
161
    if (runlevel_free == -1) {
162
        errno = ETOOMUCH_EXITFUNC;
163
        kern_frestore(f);
164
        return -1;
165
    }
166
 
167
    i = runlevel_free;
168
    runlevel_free = runlevel_list[runlevel_free].next;
169
 
170
    runlevel_list[i].f = func_code;
171
    runlevel_list[i].arg = parm;
172
    runlevel_list[i].no_at_abort = when & NO_AT_ABORT;
173
 
174
    switch (when & 0x03) {
175
      case RUNLEVEL_INIT:
176
        /* the init functions are called in the order they are posted
177
           so, we insert at the queue tail */
178
        runlevel_list[i].next = -1;
179
        if (runlevel_init_list == -1)
180
          runlevel_init_list = i;
181
        else
182
          runlevel_list[runlevel_init_tail].next = i;
183
        runlevel_init_tail = i;
184
        break;
185
      case RUNLEVEL_SHUTDOWN:
186
        runlevel_list[i].next = runlevel_shutdown_list;
187
        runlevel_shutdown_list = i;
188
        break;
189
      case RUNLEVEL_BEFORE_EXIT:
190
        runlevel_list[i].next = runlevel_before_list;
191
        runlevel_before_list = i;
192
        break;
193
      default: // RUNLEVEL_AFTER_EXIT
194
        runlevel_list[i].next = runlevel_after_list;
195
        runlevel_after_list = i;
196
    }
197
 
198
    kern_frestore(f);
199
    return 0;
200
}
201
 
202
 
203
/*+ This function returns a level_des **. the value returned shall be
204
    used to register a level module. The function shall be called only at
205
    module registration time. It assume that the system is not yet
206
    initialized, so we shall not call sys_abort...                     +*/
207
LEVEL level_alloc_descriptor()
208
{
209
  if (sched_levels == MAX_SCHED_LEVEL)
210
  {
211
    printk("Too many scheduling levels!!!\n");
212
    l1_exit(1);
213
  }
214
 
215
  return sched_levels++;
216
}
217
 
218
 
219
/*+ This function returns a resource_des **. the value returned shall be
220
    used to register a resource module. The function shall be called only at
221
    module registration time. It assume that the system is not yet
222
    initialized, so we shall not call sys_abort...                     +*/
223
RLEVEL resource_alloc_descriptor()
224
{
225
  if (res_levels == MAX_RES_LEVEL)
226
  {
227
    printk("Too many resource levels!!!\n");
228
    l1_exit(1);
229
  }
230
 
231
  return res_levels++;
232
}
233
 
234
/*+ This function compute the command line parameters from the multiboot_info
235
    NOTE: this function modify the multiboot struct, so this function and
236
    __call_main__ are mutually exclusives!!! +*/
237
void __compute_args__(struct multiboot_info *mbi, int *_argc, char **_argv)
238
{
239
  register int i = 0;
240
  char *cmdline = (char *)(mbi->cmdline);
241
 
242
  /* creates the command line... */
243
  *_argc = 0;
244
  if (mbi->flags & MB_INFO_CMDLINE) {
245
    while (cmdline[i] != 0) {
246
      _argv[*_argc] = &(cmdline[i]);
247
      while (cmdline[i] != ' ' && cmdline[i] != 0) i++;
248
      if (cmdline[i] == ' ') {
249
        cmdline[i] = 0; i++; (*_argc)++;
250
      }
251
    }
252
    (*_argc)++;
253
  }
254
}
255
 
256
/* note that the prototype is not public... so the user can
257
    also use a int main(void), void main(void)... and so on... */
258
int main(int argc, char **argv);
259
 
260
/*+ This function calls the standard C main() function, with a
261
    parameter list up to 100 parameters                        +*/
262
int __call_main__(struct multiboot_info *mbi)
263
{
264
  int _argc;
265
  char *_argv[100];
266
  __compute_args__(mbi, &_argc, _argv);
267
  return main(_argc,_argv);
268
}
269
 
270
 
271