SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /sos/main.c (Article 6) and /sos/main.c (Article 5)


001 /* Copyright (C) 2004  The SOS Team               001 /* Copyright (C) 2004  The SOS Team
002    Copyright (C) 1999  Free Software Foundatio    002    Copyright (C) 1999  Free Software Foundation, Inc.
003                                                   003 
004    This program is free software; you can redi    004    This program is free software; you can redistribute it and/or
005    modify it under the terms of the GNU Genera    005    modify it under the terms of the GNU General Public License
006    as published by the Free Software Foundatio    006    as published by the Free Software Foundation; either version 2
007    of the License, or (at your option) any lat    007    of the License, or (at your option) any later version.
008                                                   008    
009    This program is distributed in the hope tha    009    This program is distributed in the hope that it will be useful,
010    but WITHOUT ANY WARRANTY; without even the     010    but WITHOUT ANY WARRANTY; without even the implied warranty of
011    MERCHANTABILITY or FITNESS FOR A PARTICULAR    011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012    GNU General Public License for more details    012    GNU General Public License for more details.
013                                                   013    
014    You should have received a copy of the GNU     014    You should have received a copy of the GNU General Public License
015    along with this program; if not, write to t    015    along with this program; if not, write to the Free Software
016    Foundation, Inc., 59 Temple Place - Suite 3    016    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
017    USA.                                           017    USA. 
018 */                                                018 */
019                                                   019 
020 /* Include definitions of the multiboot standa    020 /* Include definitions of the multiboot standard */
021 #include <bootstrap/multiboot.h>                  021 #include <bootstrap/multiboot.h>
022 #include <hwcore/idt.h>                           022 #include <hwcore/idt.h>
023 #include <hwcore/gdt.h>                           023 #include <hwcore/gdt.h>
024 #include <hwcore/irq.h>                           024 #include <hwcore/irq.h>
025 #include <hwcore/exception.h>                     025 #include <hwcore/exception.h>
026 #include <hwcore/i8254.h>                         026 #include <hwcore/i8254.h>
027 #include <sos/list.h>                             027 #include <sos/list.h>
028 #include <sos/physmem.h>                          028 #include <sos/physmem.h>
029 #include <hwcore/paging.h>                        029 #include <hwcore/paging.h>
030 #include <sos/kmem_vmm.h>                         030 #include <sos/kmem_vmm.h>
031 #include <sos/kmalloc.h>                          031 #include <sos/kmalloc.h>
032 #include <sos/klibc.h>                            032 #include <sos/klibc.h>
033 #include <sos/assert.h>                           033 #include <sos/assert.h>
034 #include <drivers/x86_videomem.h>                 034 #include <drivers/x86_videomem.h>
035 #include <drivers/bochs.h>                        035 #include <drivers/bochs.h>
036                                                   036 
037                                                   037 
038 /* Helper function to display each bits of a 3    038 /* Helper function to display each bits of a 32bits integer on the
039    screen as dark or light carrets */             039    screen as dark or light carrets */
040 void display_bits(unsigned char row, unsigned  !! 040 static void display_bits(unsigned char row, unsigned char col,
041                   unsigned char attribute,     !! 041                          unsigned char attribute,
042                   sos_ui32_t integer)          !! 042                          sos_ui32_t integer)
043 {                                                 043 {
044   int i;                                          044   int i;
045   /* Scan each bit of the integer, MSb first *    045   /* Scan each bit of the integer, MSb first */
046   for (i = 31 ; i >= 0 ; i--)                     046   for (i = 31 ; i >= 0 ; i--)
047     {                                             047     {
048       /* Test if bit i of 'integer' is set */     048       /* Test if bit i of 'integer' is set */
049       int bit_i = (integer & (1 << i));           049       int bit_i = (integer & (1 << i));
050       /* Ascii 219 => dark carret, Ascii 177 =    050       /* Ascii 219 => dark carret, Ascii 177 => light carret */
051       unsigned char ascii_code = bit_i?219:177    051       unsigned char ascii_code = bit_i?219:177;
052       sos_x86_videomem_putchar(row, col++,        052       sos_x86_videomem_putchar(row, col++,
053                                attribute,         053                                attribute,
054                                ascii_code);       054                                ascii_code);
055     }                                             055     }
056 }                                                 056 }
057                                                   057 
058                                                   058 
059 /* Clock IRQ handler */                           059 /* Clock IRQ handler */
060 static void clk_it(int intid,                  !! 060 static void clk_it(int intid)
061                    const struct sos_cpu_kstate << 
062 {                                                 061 {
063   static sos_ui32_t clock_count = 0;              062   static sos_ui32_t clock_count = 0;
064                                                   063 
065   display_bits(0, 48,                             064   display_bits(0, 48,
066                SOS_X86_VIDEO_FG_LTGREEN | SOS_    065                SOS_X86_VIDEO_FG_LTGREEN | SOS_X86_VIDEO_BG_BLUE,
067                clock_count);                      066                clock_count);
068   clock_count++;                                  067   clock_count++;
069 }                                              << 
070                                                << 
071                                                << 
072 /* =========================================== << 
073  * Page fault exception handling               << 
074  */                                            << 
075                                                << 
076 /* Helper function to dump a backtrace on boch << 
077 static void dump_backtrace(const struct sos_cp << 
078                            sos_vaddr_t stack_b << 
079                            sos_size_t  stack_s << 
080                            sos_bool_t on_conso << 
081                            sos_bool_t on_bochs << 
082 {                                              << 
083   static void backtracer(sos_vaddr_t PC,       << 
084                          sos_vaddr_t params,   << 
085                          sos_ui32_t depth,     << 
086                          void *custom_arg)     << 
087     {                                          << 
088       sos_ui32_t invalid = 0xffffffff, *arg1,  << 
089                                                   068 
090       /* Get the address of the first 3 argume << 
091          frame. Among these arguments, 0, 1, 2 << 
092          meaningful (depending on how many arg << 
093          take). */                             << 
094       arg1 = (sos_ui32_t*)params;              << 
095       arg2 = (sos_ui32_t*)(params+4);          << 
096       arg3 = (sos_ui32_t*)(params+8);          << 
097       arg4 = (sos_ui32_t*)(params+12);         << 
098                                                << 
099       /* Make sure the addresses of these argu << 
100          stack boundaries */                   << 
101 #define INTERVAL_OK(b,v,u) ( ((b) <= (sos_vadd << 
102                              && ((sos_vaddr_t) << 
103       if (!INTERVAL_OK(stack_bottom, arg1, sta << 
104         arg1 = &invalid;                       << 
105       if (!INTERVAL_OK(stack_bottom, arg2, sta << 
106         arg2 = &invalid;                       << 
107       if (!INTERVAL_OK(stack_bottom, arg3, sta << 
108         arg3 = &invalid;                       << 
109       if (!INTERVAL_OK(stack_bottom, arg4, sta << 
110         arg4 = &invalid;                       << 
111                                                << 
112       /* Print the function context for this f << 
113       if (on_bochs)                            << 
114         sos_bochs_printf("[%d] PC=0x%x arg1=0x << 
115                          (unsigned)depth, (uns << 
116                          (unsigned)*arg1, (uns << 
117                          (unsigned)*arg3);     << 
118                                                << 
119       if (on_console)                          << 
120         sos_x86_videomem_printf(23-depth, 3,   << 
121                                 SOS_X86_VIDEO_ << 
122                                   | SOS_X86_VI << 
123                                 "[%d] PC=0x%x  << 
124                                 (unsigned)dept << 
125                                 (unsigned)*arg << 
126                                 (unsigned)*arg << 
127                                                << 
128     }                                          << 
129                                                << 
130   sos_backtrace(cpu_kstate, 15, stack_bottom,  << 
131 }                                                 069 }
132                                                !! 070 struct digit
133                                                << 
134 /* Page fault exception handler with demand pa << 
135 static void pgflt_ex(int intid, const struct s << 
136 {                                                 071 {
137   static sos_ui32_t demand_paging_count = 0;   !! 072   struct digit *prev, *next;
138   sos_vaddr_t faulting_vaddr = sos_cpu_kstate_ !! 073   char value;
139   sos_paddr_t ppage_paddr;                     !! 074 };
140                                                << 
141   /* Check if address is covered by any VMM ra << 
142   if (! sos_kmem_vmm_is_valid_vaddr(faulting_v << 
143     {                                          << 
144       /* No: The page fault is out of any kern << 
145          the moment, we don't handle this. */  << 
146       dump_backtrace(ctxt,                     << 
147                      bootstrap_stack_bottom,   << 
148                      bootstrap_stack_size,     << 
149                      TRUE, TRUE);              << 
150       sos_display_fatal_error("Unresolved page << 
151                               (unsigned)faulti << 
152                               (unsigned)sos_cp << 
153       SOS_ASSERT_FATAL(! "Got page fault (note << 
154     }                                          << 
155                                                << 
156                                                << 
157   /*                                           << 
158    * Demand paging                             << 
159    */                                          << 
160                                                << 
161   /* Update the number of demand paging reques << 
162   demand_paging_count ++;                      << 
163   display_bits(0, 0,                           << 
164                SOS_X86_VIDEO_FG_LTRED | SOS_X8 << 
165                demand_paging_count);           << 
166                                                << 
167   /* Allocate a new page for the virtual addre << 
168   ppage_paddr = sos_physmem_ref_physpage_new(F << 
169   if (! ppage_paddr)                           << 
170     SOS_ASSERT_FATAL(! "TODO: implement swap.  << 
171   SOS_ASSERT_FATAL(SOS_OK == sos_paging_map(pp << 
172                                             SO << 
173                                             FA << 
174                                             SO << 
175                                             |  << 
176                                             |  << 
177   sos_physmem_unref_physpage(ppage_paddr);     << 
178                                                << 
179   /* Ok, we can now return to interrupted cont << 
180 }                                              << 
181                                                << 
182                                                   075 
                                                   >> 076 /* Representation of a big (positive) integer: Most Significant Digit
                                                   >> 077    (MSD) is the HEAD of the list. Least Significant Digit (LSD) is the
                                                   >> 078    TAIL of the list */
                                                   >> 079 typedef struct digit * big_number_t;
183                                                   080 
184 /* =========================================== << 
185  * Demonstrate the use of the CPU kernet conte << 
186  *  - A coroutine prints "Hlowrd" and switches << 
187  *    letter                                   << 
188  *  - A coroutine prints "el ol\n" and switche << 
189  *    each letter.                             << 
190  * The first to reach the '\n' returns back to << 
191  */                                            << 
192 struct sos_cpu_kstate *ctxt_hello1;            << 
193 struct sos_cpu_kstate *ctxt_hello2;            << 
194 struct sos_cpu_kstate *ctxt_main;              << 
195 sos_vaddr_t hello1_stack, hello2_stack;        << 
196                                                   081 
197 static void reclaim_stack(sos_vaddr_t stack_va !! 082 /* Add a new digit after the LSD */
                                                   >> 083 void bn_push_lsd(big_number_t * bn, char value)
198 {                                                 084 {
199   sos_kfree(stack_vaddr);                      !! 085   struct digit *d;
                                                   >> 086   d = (struct digit*) sos_kmalloc(sizeof(struct digit), 0);
                                                   >> 087   SOS_ASSERT_FATAL(d != NULL);
                                                   >> 088   d->value = value;
                                                   >> 089   list_add_tail(*bn, d);
200 }                                                 090 }
201                                                   091 
202                                                   092 
203 static void exit_hello12(sos_vaddr_t stack_vad !! 093 /* Add a new digit before the MSD */
                                                   >> 094 void bn_push_msd(big_number_t * bn, char value)
204 {                                                 095 {
205   sos_cpu_kstate_exit_to(ctxt_main,            !! 096   struct digit *d;
206                          (sos_cpu_kstate_funct !! 097   d = (struct digit*) sos_kmalloc(sizeof(struct digit), 0);
207                          stack_vaddr);         !! 098   SOS_ASSERT_FATAL(d != NULL);
                                                   >> 099   d->value = value;
                                                   >> 100   list_add_head(*bn, d);
208 }                                                 101 }
209                                                   102 
210                                                   103 
211 static void hello1 (char *str)                 !! 104 /* Construct a big integer from a (machine) integer */
                                                   >> 105 big_number_t bn_new(unsigned long int i)
212 {                                                 106 {
213   for ( ; *str != '\n' ; str++)                !! 107   big_number_t retval;
                                                   >> 108 
                                                   >> 109   list_init(retval);
                                                   >> 110   do
214     {                                             111     {
215       sos_bochs_printf("hello1: %c\n", *str);  !! 112       bn_push_msd(&retval, i%10);
216       sos_cpu_kstate_switch(& ctxt_hello1, ctx !! 113       i /= 10;
217     }                                             114     }
                                                   >> 115   while (i != 0);
218                                                   116 
219   /* You can uncomment this in case you explic !! 117   return retval;
220      now. But returning from the function will << 
221   /* sos_cpu_kstate_exit_to(ctxt_main,         << 
222                          (sos_cpu_kstate_funct << 
223                          hello1_stack); */     << 
224 }                                                 118 }
225                                                   119 
226                                                   120 
227 static void hello2 (char *str)                 !! 121 /* Create a new big integer from another big integer */
                                                   >> 122 big_number_t bn_copy(const big_number_t bn)
228 {                                                 123 {
229   for ( ; *str != '\n' ; str++)                !! 124   big_number_t retval;
                                                   >> 125   int nb_elts;
                                                   >> 126   struct digit *d;
                                                   >> 127 
                                                   >> 128   list_init(retval);
                                                   >> 129   list_foreach(bn, d, nb_elts)
230     {                                             130     {
231       sos_bochs_printf("hello2: %c\n", *str);  !! 131       bn_push_lsd(&retval, d->value);
232       sos_cpu_kstate_switch(& ctxt_hello2, ctx << 
233     }                                             132     }
234                                                   133 
235   /* You can uncomment this in case you explic !! 134   return retval;
236      now. But returning from the function will << 
237   /* sos_cpu_kstate_exit_to(ctxt_main,         << 
238                          (sos_cpu_kstate_funct << 
239                          hello2_stack); */     << 
240 }                                              << 
241                                                << 
242                                                << 
243 void print_hello_world ()                      << 
244 {                                              << 
245 #define DEMO_STACK_SIZE 1024                   << 
246   /* Allocate the stacks */                    << 
247   hello1_stack = sos_kmalloc(DEMO_STACK_SIZE,  << 
248   hello2_stack = sos_kmalloc(DEMO_STACK_SIZE,  << 
249                                                << 
250   /* Initialize the coroutines' contexts */    << 
251   sos_cpu_kstate_init(&ctxt_hello1,            << 
252                       (sos_cpu_kstate_function << 
253                       (sos_ui32_t) "Hlowrd",   << 
254                       (sos_vaddr_t) hello1_sta << 
255                       (sos_cpu_kstate_function << 
256                       (sos_ui32_t) hello1_stac << 
257   sos_cpu_kstate_init(&ctxt_hello2,            << 
258                       (sos_cpu_kstate_function << 
259                       (sos_ui32_t) "el ol\n",  << 
260                       (sos_vaddr_t) hello2_sta << 
261                       (sos_cpu_kstate_function << 
262                       (sos_ui32_t) hello2_stac << 
263                                                << 
264   /* Go to first coroutine */                  << 
265   sos_bochs_printf("Printing Hello World\\n... << 
266   sos_cpu_kstate_switch(& ctxt_main, ctxt_hell << 
267                                                << 
268   /* The first coroutine to reach the '\n' swi << 
269   sos_bochs_printf("Back in main !\n");        << 
270 }                                                 135 }
271                                                   136 
272                                                   137 
273 /* =========================================== !! 138 /* Free the memory used by a big integer */
274  * Generate page faults on an unmapped but all !! 139 void bn_del(big_number_t * bn)
275  * region, which results in a series of physic << 
276  * faulted pages.                              << 
277  */                                            << 
278 static void test_demand_paging(int nb_alloc_vp << 
279 {                                                 140 {
280   int i;                                       !! 141   struct digit *d;
281   sos_vaddr_t base_vaddr;                      << 
282                                                << 
283   sos_x86_videomem_printf(10, 0,               << 
284                           SOS_X86_VIDEO_BG_BLU << 
285                           "Demand paging test  << 
286                           nb_alloc_vpages >> 8 << 
287                                                << 
288   /* Allocate virtual memory */                << 
289   base_vaddr = sos_kmem_vmm_alloc(nb_alloc_vpa << 
290                                                   142 
291   SOS_ASSERT_FATAL(base_vaddr != (sos_vaddr_t) !! 143   list_collapse(*bn, d)
292   sos_x86_videomem_printf(11, 0,               << 
293                           SOS_X86_VIDEO_BG_BLU << 
294                           "Allocated virtual r << 
295                           base_vaddr,          << 
296                           base_vaddr + nb_allo << 
297                                                << 
298   /* Now use part of it in physical memory */  << 
299   for (i = 0 ; (i < nb_alloc_ppages) && (i < n << 
300     {                                             144     {
301       /* Compute an address inside the range * !! 145       sos_kfree((sos_vaddr_t)d);
302       sos_ui32_t *value, j;                    << 
303       sos_vaddr_t vaddr = base_vaddr;          << 
304       vaddr += (nb_alloc_vpages - (i + 1))*SOS << 
305       vaddr += 2345;                           << 
306                                                << 
307       sos_x86_videomem_printf(12, 0,           << 
308                               SOS_X86_VIDEO_BG << 
309                               "Writing %d at v << 
310                               i, vaddr);       << 
311                                                << 
312       /* Write at this address */              << 
313       value = (sos_ui32_t*)vaddr;              << 
314       *value = i;                              << 
315                                                << 
316       /* Yep ! A new page should normally have << 
317       sos_x86_videomem_printf(13, 0,           << 
318                               SOS_X86_VIDEO_BG << 
319                               "Value read at a << 
320                               vaddr, (unsigned << 
321     }                                             146     }
322                                                << 
323   SOS_ASSERT_FATAL(SOS_OK == sos_kmem_vmm_free << 
324   /* Yep ! A new page should normally have bee << 
325   sos_x86_videomem_printf(14, 0,               << 
326                           SOS_X86_VIDEO_BG_BLU << 
327                           "Done (area un-alloc << 
328 }                                                 147 }
329                                                   148 
330                                                   149 
331                                                !! 150 /* Shift left a big integer: bn := bn*10^shift */
332 /* =========================================== !! 151 void bn_shift(big_number_t *bn, int shift)
333  * Shows how the backtrace stuff works         << 
334  */                                            << 
335                                                << 
336 /* Recursive function. Print the backtrace fro << 
337 static void test_backtrace(int i, int magic, s << 
338                            sos_size_t  stack_s << 
339 {                                                 152 {
340   if (i <= 0)                                  !! 153   for ( ; shift > 0 ; shift --)
341     {                                             154     {
342       /* The page fault exception handler will !! 155       bn_push_lsd(bn, 0);
343          this function, because address 0x42 i << 
344       *((char*)0x42) = 12;                     << 
345                                                << 
346       /* More direct variant: */               << 
347       /* dump_backtrace(NULL, stack_bottom, st << 
348     }                                             156     }
349   else                                         << 
350     test_backtrace(i-1, magic, stack_bottom, s << 
351 }                                                 157 }
352                                                   158 
353                                                   159 
354 /* =========================================== !! 160 /* Dump the big integer in bochs */
355  * Parsing of Mathematical expressions         !! 161 void bn_print_bochs(const big_number_t bn)
356  *                                             << 
357  * This is a recursive lexer/parser/evaluator  << 
358  * expressions. Supports both binary +/-* and  << 
359  * well as parentheses.                        << 
360  *                                             << 
361  * Terminal tokens (Lexer):                    << 
362  *  - Number: positive integer number          << 
363  *  - Variable: ascii name (regexp: [a-zA-Z]+) << 
364  *  - Operator: +*-/                           << 
365  *  - Opening/closing parentheses              << 
366  *                                             << 
367  * Grammar (Parser):                           << 
368  *  Expression ::= Term E'                     << 
369  *  Expr_lr    ::= + Term Expr_lr | - Term Exp << 
370  *  Term       ::= Factor Term_lr              << 
371  *  Term_lr    ::= * Factor Term_lr | / Factor << 
372  *  Factor     ::= - Factor | + Factor | Scala << 
373  *  Scalar     ::= Number | Variable           << 
374  *                                             << 
375  * Note. This is the left-recursive equivalent << 
376  *  Expression ::= Expression + Term | Express << 
377  *  Term       ::= Term * Factor | Term / Fact << 
378  *  factor     ::= - Factor | + Factor | Scala << 
379  *  Scalar     ::= Number | Variable           << 
380  *                                             << 
381  * The parsing is composed of a 3 stages pipel << 
382  *  - The reader: reads a string 1 character a << 
383  *    the control back to lexer after each cha << 
384  *    interest in using coroutines, because it << 
385  *    implicitely stored in the stack between  << 
386  *  - The lexer: consumes the characters from  << 
387  *    the terminal tokens, 1 token at a time,  << 
388  *    to the parser after each token. This fun << 
389  *    in using coroutines, because its state ( << 
390  *    implicitely stored in the stack between  << 
391  *  - The parser: consumes the tokens from the << 
392  *    syntax tree of the expression. There is  << 
393  *    interest in defining a coroutine devoted << 
394  *    do use one for that because this allows  << 
395  *    deeper stack. Actually, the parser is hi << 
396  *    the default 16kB stack of the sos_main() << 
397  *    enough. Here, we switch to a 64kB stack, << 
398  *    recursive functions. The Parser uses int << 
399  *    are defined and implemented as internal  << 
400  *    just for the sake of clarity, and is abs << 
401  *    the algorithm: one can transfer these fu << 
402  *    function without restriction.            << 
403  *                                             << 
404  * The evaluator is another recursive function << 
405  * parser's stack to evaluate the parsed expre << 
406  * values for the variables present in the exp << 
407  * parser function, this function defines and  << 
408  * which can be extracted from the main evalua << 
409  *                                             << 
410  * All these functions support a kind of "exce << 
411  * something goes wrong, control is transferre << 
412  * sos_main() context, without unrolling the r << 
413  * how exceptions basically work, but one shou << 
414  * a reference exceptions implementation. Real << 
415  * (such as that in the C++ language) call the << 
416  * objects allocated on the stack during the " << 
417  * upon exception handling, which complicates  << 
418  * don't have real Objects here (in the OOP se << 
419  * destructors), so we don't have to complicat << 
420  *                                             << 
421  * After this little coroutine demo, one shoul << 
422  * a low-level manual direct manipulation of s << 
423  * probably mess up the whole kernel to do wha << 
424  * resources such as mutex/semaphore won't be  << 
425  * ...). Higher level "kernel thread" primitiv << 
426  * presented, which provide a higher-level set << 
427  * contexts. You'll have to use EXCLUSIVELY th << 
428  * need a huge stack to do recursion for examp << 
429  * think of changing manually the stack for so << 
430  * rethink your algorithm, making it non-recur << 
431  */                                            << 
432                                                << 
433                                                << 
434 /* The stacks involved */                      << 
435 static char stack_reader[1024];                << 
436 static char stack_lexer[1024];                 << 
437 static char deep_stack[65536]; /* For the pars << 
438                                                << 
439 /* The CPU states for the various coroutines * << 
440 static struct sos_cpu_kstate *st_reader, *st_l << 
441   *st_eval, *st_free, *st_main;                << 
442                                                << 
443                                                << 
444 /*                                             << 
445  * Default exit/reclaim functions: return cont << 
446  * context                                     << 
447  */                                            << 
448 static void reclaim(int unused)                << 
449 {                                                 162 {
450 }                                              !! 163   int nb_elts;
451 static void func_exit(sos_ui32_t unused)       !! 164   const struct digit *d;
452 {                                              << 
453   sos_cpu_kstate_exit_to(st_main, (sos_cpu_kst << 
454 }                                              << 
455                                                << 
456                                                   165 
457 /*                                             !! 166   if (list_is_empty(bn))
458  * The reader coroutine and associated variabl !! 167     sos_bochs_printf("0");
459  * have been a normal function, except that th !! 168   else
460  * character would have to be stored somewhere !! 169     list_foreach(bn, d, nb_elts)
461  */                                            !! 170       sos_bochs_printf("%d", d->value);
462 static char data_reader_to_lexer;              << 
463                                                << 
464 static void func_reader(const char *str)       << 
465 {                                              << 
466   for ( ; str && (*str != '\0') ; str++)       << 
467     {                                          << 
468       data_reader_to_lexer = *str;             << 
469       sos_cpu_kstate_switch(& st_reader, st_le << 
470     }                                          << 
471                                                << 
472   data_reader_to_lexer = '\0';                 << 
473   sos_cpu_kstate_switch(& st_reader, st_lexer) << 
474 }                                                 171 }
475                                                   172 
476                                                !! 173 /* Dump the big integer on the console */
477 /*                                             !! 174 void bn_print_console(unsigned char row, unsigned char col,
478  * The Lexer coroutine and associated types/va !! 175                       unsigned char attribute,
479  * could have been a normal function, except t !! 176                       const big_number_t bn,
480  * character, token and previous token would h !! 177                       int nb_decimals)
481  * somewhere.                                  << 
482  */                                            << 
483 #define STR_VAR_MAXLEN 16                      << 
484 static struct lex_elem                         << 
485 {                                                 178 {
486   enum { LEX_IS_NUMBER, LEX_IS_OPER, LEX_IS_VA !! 179   if (list_is_empty(bn))
487          LEX_IS_OPENPAR, LEX_IS_CLOSEPAR, LEX_ !! 180     sos_x86_videomem_printf(row, col, attribute, "0");
488   union {                                      !! 181   else
489     int  number;                               << 
490     char operator;                             << 
491     char var[STR_VAR_MAXLEN];                  << 
492   };                                           << 
493 } data_lexer_to_parser;                        << 
494                                                << 
495 static void func_lexer(sos_ui32_t unused)      << 
496 {                                              << 
497   char c;                                      << 
498   enum { GOT_SPACE, GOT_NUM, GOT_OP, GOT_STR,  << 
499          GOT_OPENPAR, GOT_CLOSEPAR } got_what, << 
500                                                << 
501   data_lexer_to_parser.number = 0;             << 
502   got_what_before = GOT_SPACE;                 << 
503   do                                           << 
504     {                                             182     {
505       /* Consume one character from the reader !! 183       int nb_elts;
506       sos_cpu_kstate_switch(& st_lexer, st_rea !! 184       const struct digit *d;
507       c = data_reader_to_lexer;                !! 185       unsigned char x = col;
508                                                << 
509       /* Classify the consumed character */    << 
510       if ( (c >= '0') && (c <= '9') )          << 
511         got_what = GOT_NUM;                    << 
512       else if ( (c == '+') || (c == '-') || (c << 
513         got_what = GOT_OP;                     << 
514       else if ( ( (c >= 'a') && (c <= 'z') )   << 
515                 || ( (c >= 'A') && (c <= 'Z')  << 
516         got_what = GOT_STR;                    << 
517       else if (c == '(')                       << 
518         got_what = GOT_OPENPAR;                << 
519       else if (c == ')')                       << 
520         got_what = GOT_CLOSEPAR;               << 
521       else                                     << 
522         got_what = GOT_SPACE;                  << 
523                                                << 
524       /* Determine whether the current token i << 
525       if ( (got_what != got_what_before)       << 
526            || (got_what_before == GOT_OP)      << 
527            || (got_what_before == GOT_OPENPAR) << 
528            || (got_what_before == GOT_CLOSEPAR << 
529         {                                      << 
530           /* return control back to the parser << 
531              has been recognized */            << 
532           if ( (got_what_before != GOT_SPACE)  << 
533             sos_cpu_kstate_switch(& st_lexer,  << 
534                                                   186 
535           data_lexer_to_parser.number = 0;     !! 187       list_foreach(bn, d, nb_elts)
536         }                                      << 
537                                                << 
538       /* Update the token being currently reco << 
539       if (got_what == GOT_OP)                  << 
540         {                                      << 
541           data_lexer_to_parser.type = LEX_IS_O << 
542           data_lexer_to_parser.operator = c;   << 
543         }                                      << 
544       else if (got_what == GOT_NUM)            << 
545         {                                      << 
546           data_lexer_to_parser.type = LEX_IS_N << 
547           data_lexer_to_parser.number *= 10;   << 
548           data_lexer_to_parser.number += (c -  << 
549         }                                      << 
550       else if (got_what == GOT_STR)            << 
551         {                                         188         {
552           char to_cat[] = { c, '\0' };         !! 189           if (nb_elts == 0)
553           data_lexer_to_parser.type = LEX_IS_V !! 190             {
554           strzcat(data_lexer_to_parser.var, to !! 191               sos_x86_videomem_printf(row, x, attribute, "%d.", d->value);
                                                   >> 192               x += 2;
                                                   >> 193             }
                                                   >> 194           else if (nb_elts < nb_decimals)
                                                   >> 195             {
                                                   >> 196               sos_x86_videomem_printf(row, x, attribute, "%d", d->value);
                                                   >> 197               x ++;
                                                   >> 198             }
555         }                                         199         }
556       else if (got_what == GOT_OPENPAR)        << 
557         data_lexer_to_parser.type = LEX_IS_OPE << 
558       else if (got_what == GOT_CLOSEPAR)       << 
559         data_lexer_to_parser.type = LEX_IS_CLO << 
560                                                   200 
561       got_what_before = got_what;              !! 201       sos_x86_videomem_printf(row, x, attribute, " . 10^{%d}  ", nb_elts-1);
562     }                                             202     }
563   while (c != '\0');                           << 
564                                                << 
565   /* Transfer last recognized token to the par << 
566   if ( (got_what_before != GOT_SPACE) )        << 
567     sos_cpu_kstate_switch(& st_lexer, st_parse << 
568                                                << 
569   /* Signal that no more token are available * << 
570   data_lexer_to_parser.type = LEX_END;         << 
571   sos_cpu_kstate_switch(& st_lexer, st_parser) << 
572                                                << 
573   /* Exception: parser asks for a token AFTER  << 
574      one */                                    << 
575   sos_bochs_printf("Error: end of string alrea << 
576   sos_cpu_kstate_switch(& st_lexer, st_main);  << 
577 }                                                 203 }
578                                                   204 
579                                                   205 
580 /*                                             !! 206 /* Result is the addition of 2 big integers */
581  * The Parser coroutine and associated types/v !! 207 big_number_t bn_add (const big_number_t bn1, const big_number_t bn2)
582  */                                            << 
583 struct syntax_node                             << 
584 {                                                 208 {
585   enum { YY_IS_BINOP, YY_IS_UNAROP, YY_IS_NUM, !! 209   big_number_t retval;
586   union                                        !! 210   const struct digit *d1, *d2;
587   {                                            !! 211   sos_bool_t  bn1_end = FALSE, bn2_end = FALSE;
588     int  number;                               !! 212   char carry = 0;
589     char var[STR_VAR_MAXLEN];                  << 
590     struct                                     << 
591     {                                          << 
592       char op;                                 << 
593       struct syntax_node *parm_left, *parm_rig << 
594     } binop;                                   << 
595     struct                                     << 
596     {                                          << 
597       char op;                                 << 
598       struct syntax_node *parm;                << 
599     } unarop;                                  << 
600   };                                           << 
601 };                                             << 
602                                                   213 
603 static void func_parser(struct syntax_node **  !! 214   list_init(retval);
604 {                                              !! 215   d1 = list_get_tail(bn1);
605   static struct syntax_node *alloc_node_num(in !! 216   bn1_end = list_is_empty(bn1);
606   static struct syntax_node *alloc_node_var(co !! 217   d2 = list_get_tail(bn2);
607   static struct syntax_node *alloc_node_binop( !! 218   bn2_end = list_is_empty(bn2);
608                                                !! 219   do
609                                                << 
610   static struct syntax_node *alloc_node_unarop << 
611                                                << 
612   static struct syntax_node * get_expr();      << 
613   static struct syntax_node * get_expr_lr(stru << 
614   static struct syntax_node * get_term();      << 
615   static struct syntax_node * get_term_lr(stru << 
616   static struct syntax_node * get_factor();    << 
617   static struct syntax_node * get_scalar();    << 
618                                                << 
619   /* Create a new node to store a number */    << 
620   static struct syntax_node *alloc_node_num(in << 
621     {                                          << 
622       struct syntax_node *n                    << 
623         = (struct syntax_node*) sos_kmalloc(si << 
624       n->type   = YY_IS_NUM;                   << 
625       n->number = val;                         << 
626       return n;                                << 
627     }                                          << 
628   /* Create a new node to store a variable */  << 
629   static struct syntax_node *alloc_node_var(co << 
630     {                                          << 
631       struct syntax_node *n                    << 
632         = (struct syntax_node*) sos_kmalloc(si << 
633       n->type   = YY_IS_VAR;                   << 
634       strzcpy(n->var, name, STR_VAR_MAXLEN);   << 
635       return n;                                << 
636     }                                          << 
637   /* Create a new node to store a binary opera << 
638   static struct syntax_node *alloc_node_binop( << 
639                                                << 
640                                                << 
641     {                                          << 
642       struct syntax_node *n                    << 
643         = (struct syntax_node*) sos_kmalloc(si << 
644       n->type             = YY_IS_BINOP;       << 
645       n->binop.op         = op;                << 
646       n->binop.parm_left  = parm_left;         << 
647       n->binop.parm_right = parm_right;        << 
648       return n;                                << 
649     }                                          << 
650   /* Create a new node to store a unary operat << 
651   static struct syntax_node *alloc_node_unarop << 
652                                                << 
653     {                                             220     {
654       struct syntax_node *n                    !! 221       if (! bn1_end)
655         = (struct syntax_node*) sos_kmalloc(si !! 222         carry += d1->value;
656       n->type        = YY_IS_UNAROP;           !! 223       if (! bn2_end)
657       n->unarop.op   = op;                     !! 224         carry += d2->value;
658       n->unarop.parm = parm;                   !! 225 
659       return n;                                !! 226       bn_push_msd(&retval, carry % 10);
                                                   >> 227       carry  /= 10;
                                                   >> 228 
                                                   >> 229       if (! bn1_end)
                                                   >> 230         d1 = d1->prev;
                                                   >> 231       if (! bn2_end)
                                                   >> 232         d2 = d2->prev;
                                                   >> 233       if (d1 == list_get_tail(bn1))
                                                   >> 234         bn1_end = TRUE;
                                                   >> 235       if (d2 == list_get_tail(bn2))
                                                   >> 236         bn2_end = TRUE;
660     }                                             237     }
                                                   >> 238   while (!bn1_end || !bn2_end);
661                                                   239 
662   /* Raise an exception: transfer control back !! 240   if (carry > 0)
663      without unrolling the whole recursion */  << 
664   static void parser_exception(const char *str << 
665     {                                             241     {
666       sos_bochs_printf("Parser exception: %s\n !! 242       bn_push_msd(&retval, carry);
667       sos_cpu_kstate_switch(& st_parser, st_ma << 
668     }                                             243     }
669                                                   244 
670   /* Consume the current terminal "number" tok !! 245   return retval;
671      token */                                  !! 246 }
672   static int get_number()                      << 
673     {                                          << 
674       int v;                                   << 
675       if (data_lexer_to_parser.type != LEX_IS_ << 
676         parser_exception("Expected number");   << 
677       v = data_lexer_to_parser.number;         << 
678       sos_cpu_kstate_switch(& st_parser, st_le << 
679       return v;                                << 
680     }                                          << 
681   /* Consume the current terminal "variable" t << 
682      token */                                  << 
683   static void get_str(char name[STR_VAR_MAXLEN << 
684     {                                          << 
685       if (data_lexer_to_parser.type != LEX_IS_ << 
686         parser_exception("Expected variable"); << 
687       strzcpy(name, data_lexer_to_parser.var,  << 
688       sos_cpu_kstate_switch(& st_parser, st_le << 
689     }                                          << 
690   /* Consume the current terminal "operator" t << 
691      token */                                  << 
692   static char get_op()                         << 
693     {                                          << 
694       char op;                                 << 
695       if (data_lexer_to_parser.type != LEX_IS_ << 
696         parser_exception("Expected operator"); << 
697       op = data_lexer_to_parser.operator;      << 
698       sos_cpu_kstate_switch(& st_parser, st_le << 
699       return op;                               << 
700     }                                          << 
701   /* Consume the current terminal "parenthese" << 
702      token */                                  << 
703   static void get_par()                        << 
704     {                                          << 
705       if ( (data_lexer_to_parser.type != LEX_I << 
706            && (data_lexer_to_parser.type != LE << 
707         parser_exception("Expected parenthese" << 
708       sos_cpu_kstate_switch(& st_parser, st_le << 
709     }                                          << 
710                                                   247 
711   /* Parse an Expression */                    !! 248 
712   static struct syntax_node * get_expr()       !! 249 /* Result is the multiplication of a big integer by a single digit */
713     {                                          !! 250 big_number_t bn_muli (const big_number_t bn, char digit)
714       struct syntax_node *t = get_term();      !! 251 {
715       return get_expr_lr(t);                   !! 252   big_number_t retval;
716     }                                          !! 253   int nb_elts;
717   /* Parse an Expr_lr */                       !! 254   char   carry = 0;
718   static struct syntax_node * get_expr_lr(stru !! 255   const struct digit *d;
719     {                                          !! 256 
720       if ( (data_lexer_to_parser.type == LEX_I !! 257   list_init(retval);
721            && ( (data_lexer_to_parser.operator !! 258   list_foreach_backward(bn, d, nb_elts)
722                 || (data_lexer_to_parser.opera << 
723         {                                      << 
724           char op = get_op();                  << 
725           struct syntax_node *term = get_term( << 
726           struct syntax_node *node_op = alloc_ << 
727           return get_expr_lr(node_op);         << 
728         }                                      << 
729       return n;                                << 
730     }                                          << 
731   /* Parse a Term */                           << 
732   static struct syntax_node * get_term()       << 
733     {                                          << 
734       struct syntax_node *f1 = get_factor();   << 
735       return get_term_lr(f1);                  << 
736     }                                          << 
737   /* Parse a Term_lr */                        << 
738   static struct syntax_node * get_term_lr(stru << 
739     {                                          << 
740       if ( (data_lexer_to_parser.type == LEX_I << 
741            && ( (data_lexer_to_parser.operator << 
742                 || (data_lexer_to_parser.opera << 
743         {                                      << 
744           char op = get_op();                  << 
745           struct syntax_node *factor = get_fac << 
746           struct syntax_node *node_op = alloc_ << 
747           return get_term_lr(node_op);         << 
748         }                                      << 
749       return n;                                << 
750     }                                          << 
751   /* Parse a Factor */                         << 
752   static struct syntax_node * get_factor()     << 
753     {                                             259     {
754       if ( (data_lexer_to_parser.type == LEX_I !! 260       carry += d->value * digit;
755            && ( (data_lexer_to_parser.operator !! 261       bn_push_msd(&retval, carry % 10);
756                 || (data_lexer_to_parser.opera !! 262       carry /= 10;
757         { char op = data_lexer_to_parser.opera << 
758         get_op(); return alloc_node_unarop(op, << 
759       else if (data_lexer_to_parser.type == LE << 
760         {                                      << 
761           struct syntax_node *expr;            << 
762           get_par();                           << 
763           expr = get_expr();                   << 
764           if (data_lexer_to_parser.type != LEX << 
765             parser_exception("Mismatched paren << 
766           get_par();                           << 
767           return expr;                         << 
768         }                                      << 
769                                                << 
770       return get_scalar();                     << 
771     }                                             263     }
772   /* Parse a Scalar */                         !! 264 
773   static struct syntax_node * get_scalar()     !! 265   if (carry > 0)
774     {                                             266     {
775       if (data_lexer_to_parser.type != LEX_IS_ !! 267       bn_push_msd(&retval, carry);
776         {                                      << 
777           char var[STR_VAR_MAXLEN];            << 
778           get_str(var);                        << 
779           return alloc_node_var(var);          << 
780         }                                      << 
781       return alloc_node_num(get_number());     << 
782     }                                             268     }
783                                                   269 
784                                                !! 270   return retval;
785   /*                                           << 
786    * Body of the function                      << 
787    */                                          << 
788                                                << 
789   /* Get the first token */                    << 
790   sos_cpu_kstate_switch(& st_parser, st_lexer) << 
791                                                << 
792   /* Begin the parsing ! */                    << 
793   *syntax_tree = get_expr();                   << 
794   /* The result is returned in the syntax_tree << 
795 }                                                 271 }
796                                                   272 
797                                                   273 
798 /*                                             !! 274 /* Result is the multiplication of 2 big integers */
799  * Setup the parser's pipeline                 !! 275 big_number_t bn_mult(const big_number_t bn1, const big_number_t bn2)
800  */                                            << 
801 static struct syntax_node * parse_expression(c << 
802 {                                                 276 {
803   struct syntax_node *retval = NULL;           !! 277   int shift = 0;
804                                                !! 278   big_number_t retval;
805   /* Build the context of the functions in the !! 279   int nb_elts;
806   sos_cpu_kstate_init(& st_reader,             !! 280   struct digit *d;
807                       (sos_cpu_kstate_function !! 281 
808                       (sos_ui32_t)expr,        !! 282   list_init(retval);
809                       (sos_vaddr_t)stack_reade !! 283   list_foreach_backward(bn2, d, nb_elts)
810                       (sos_cpu_kstate_function !! 284     {
811   sos_cpu_kstate_init(& st_lexer,              !! 285       big_number_t retmult = bn_muli(bn1, d->value);
812                       (sos_cpu_kstate_function !! 286       big_number_t old_retval = retval;
813                       0,                       !! 287       bn_shift(& retmult, shift);
814                       (sos_vaddr_t)stack_lexer !! 288       retval = bn_add(old_retval, retmult);
815                       (sos_cpu_kstate_function !! 289       bn_del(& retmult);
816   sos_cpu_kstate_init(& st_parser,             !! 290       bn_del(& old_retval);
817                       (sos_cpu_kstate_function !! 291       shift ++;
818                       (sos_ui32_t) /* syntax t !! 292     }
819                       (sos_vaddr_t)deep_stack, << 
820                       (sos_cpu_kstate_function << 
821                                                   293 
822   /* Parse the expression */                   << 
823   sos_cpu_kstate_switch(& st_main, st_parser); << 
824   return retval;                                  294   return retval;
825 }                                                 295 }
826                                                   296 
827                                                   297 
828 /*                                             !! 298 /* Result is the factorial of an integer */
829  * The Evaluator coroutine and associated type !! 299 big_number_t bn_fact(unsigned long int v)
830  */                                            << 
831 struct func_eval_params                        << 
832 {                                                 300 {
833   const struct syntax_node *e;                 !! 301   unsigned long int i;
834   const char **var_name;                       !! 302   big_number_t retval = bn_new(1);
835   int *var_val;                                !! 303   for (i = 1 ; i <= v ; i++)
836   int nb_vars;                                 !! 304     {
837                                                !! 305       big_number_t I   = bn_new(i);
838   int result;                                  !! 306       big_number_t tmp = bn_mult(retval, I);
839 };                                             !! 307       sos_x86_videomem_printf(4, 0,
840                                                !! 308                               SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_LTGREEN,
841 static void func_eval(struct func_eval_params  !! 309                               "%d! = ", (int)i);
842 {                                              !! 310       bn_print_console(4, 8, SOS_X86_VIDEO_BG_BLUE | SOS_X86_VIDEO_FG_WHITE,
843   /* The internal (recursive) nested function  !! 311                        tmp, 55);
844      the syntax tree */                        !! 312       bn_del(& I);
845   static int rec_eval(const struct syntax_node !! 313       bn_del(& retval);
846                       const char* var_name[],  !! 314       retval = tmp;
847     {                                          << 
848       switch (n->type)                         << 
849         {                                      << 
850         case YY_IS_NUM:                        << 
851           return n->number;                    << 
852                                                << 
853         case YY_IS_VAR:                        << 
854           {                                    << 
855             int i;                             << 
856             for (i = 0 ; i < nb_vars ; i++)    << 
857               if (0 == strcmp(var_name[i], n-> << 
858                 return var_val[i];             << 
859                                                << 
860             /* Exception: no variable with tha << 
861             sos_bochs_printf("ERROR: unknown v << 
862             sos_cpu_kstate_switch(& st_eval, s << 
863           }                                    << 
864                                                << 
865         case YY_IS_BINOP:                      << 
866           {                                    << 
867             int left = rec_eval(n->binop.parm_ << 
868                                 var_name, var_ << 
869             int right = rec_eval(n->binop.parm << 
870                                  var_name, var << 
871             switch (n->binop.op)               << 
872               {                                << 
873               case '+': return left + right;   << 
874               case '-': return left - right;   << 
875               case '*': return left * right;   << 
876               case '/': return left / right;   << 
877               default:                         << 
878                 /* Exception: no such operator << 
879                 sos_bochs_printf("ERROR: unkno << 
880                 sos_cpu_kstate_switch(& st_eva << 
881               }                                << 
882           }                                    << 
883                                                << 
884         case YY_IS_UNAROP:                     << 
885           {                                    << 
886             int arg = rec_eval(n->unarop.parm, << 
887             switch (n->unarop.op)              << 
888               {                                << 
889               case '-': return -arg;           << 
890               case '+': return arg;            << 
891               default:                         << 
892                 /* Exception: no such operator << 
893                 sos_bochs_printf("ERROR: unkno << 
894                 sos_cpu_kstate_switch(& st_eva << 
895               }                                << 
896           }                                    << 
897         }                                      << 
898                                                << 
899       /* Exception: no such syntax node (INTER << 
900       sos_bochs_printf("ERROR: invalid node ty << 
901       sos_cpu_kstate_switch(& st_eval, st_main << 
902       return -1; /* let's make gcc happy */    << 
903     }                                             315     }
904                                                   316 
905                                                !! 317   return retval;
906   /*                                           << 
907    * Function BODY                             << 
908    */                                          << 
909   /* Update p.result returned back to calling  << 
910   parms->result                                << 
911     = rec_eval(parms->e, parms->var_name, parm << 
912 }                                              << 
913                                                << 
914 /*                                             << 
915  * Change the stack for something larger in or << 
916  * recursive function above in a safe way      << 
917  */                                            << 
918 static int eval_expression(const struct syntax << 
919                            const char* var_nam << 
920 {                                              << 
921   struct func_eval_params p                    << 
922     = (struct func_eval_params){ .e=e,         << 
923                                  .var_name=var << 
924                                  .var_val=var_ << 
925                                  .nb_vars=nb_v << 
926                                  .result = 0 } << 
927                                                << 
928   sos_cpu_kstate_init(& st_eval,               << 
929                       (sos_cpu_kstate_function << 
930                       (sos_ui32_t)/* p.result  << 
931                       (sos_vaddr_t)deep_stack, << 
932                       (sos_cpu_kstate_function << 
933                                                << 
934   /* Go ! */                                   << 
935   sos_cpu_kstate_switch(& st_main, st_eval);   << 
936   return p.result;                             << 
937 }                                                 318 }
938                                                   319 
939                                                   320 
940 /*                                             !! 321 void bn_test()
941  * Function to free the syntax tree            << 
942  */                                            << 
943 static void func_free(struct syntax_node *n)   << 
944 {                                                 322 {
945   switch (n->type)                             !! 323   big_number_t bn = bn_fact(1000);
946     {                                          !! 324   sos_bochs_printf("1000! = ");
947     case YY_IS_NUM:                            !! 325   bn_print_bochs(bn);
948     case YY_IS_VAR:                            !! 326   sos_bochs_printf("\n");
949       break;                                   << 
950                                                << 
951     case YY_IS_BINOP:                          << 
952       func_free(n->binop.parm_left);           << 
953       func_free(n->binop.parm_right);          << 
954       break;                                   << 
955                                                << 
956     case YY_IS_UNAROP:                         << 
957       func_free(n->unarop.parm);               << 
958       break;                                   << 
959     }                                          << 
960                                                   327   
961   sos_kfree((sos_vaddr_t)n);                   << 
962 }                                                 328 }
963                                                   329 
964 /*                                             << 
965  * Change the stack for something larger in or << 
966  * recursive function above in a safe way      << 
967  */                                            << 
968 static void free_syntax_tree(struct syntax_nod << 
969 {                                              << 
970   sos_cpu_kstate_init(& st_free,               << 
971                       (sos_cpu_kstate_function << 
972                       (sos_ui32_t)tree,        << 
973                       (sos_vaddr_t)deep_stack, << 
974                       (sos_cpu_kstate_function << 
975                                                   330 
976   /* Go ! */                                   !! 331 /* The C entry point of our operating system */
977   sos_cpu_kstate_switch(& st_main, st_free);   << 
978 }                                              << 
979                                                << 
980                                                << 
981 /* =========================================== << 
982  * The C entry point of our operating system   << 
983  */                                            << 
984 void sos_main(unsigned long magic, unsigned lo    332 void sos_main(unsigned long magic, unsigned long addr)
985 {                                                 333 {
986   unsigned i;                                     334   unsigned i;
987   sos_paddr_t sos_kernel_core_base_paddr, sos_    335   sos_paddr_t sos_kernel_core_base_paddr, sos_kernel_core_top_paddr;
988   struct syntax_node *syntax_tree;             << 
989                                                   336 
990   /* Grub sends us a structure, called multibo    337   /* Grub sends us a structure, called multiboot_info_t with a lot of
991      precious informations about the system, s    338      precious informations about the system, see the multiboot
992      documentation for more information. */       339      documentation for more information. */
993   multiboot_info_t *mbi;                          340   multiboot_info_t *mbi;
994   mbi = (multiboot_info_t *) addr;                341   mbi = (multiboot_info_t *) addr;
995                                                   342 
996   /* Setup bochs and console, and clear the co    343   /* Setup bochs and console, and clear the console */
997   sos_bochs_setup();                              344   sos_bochs_setup();
998                                                   345 
999   sos_x86_videomem_setup();                       346   sos_x86_videomem_setup();
1000   sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE)    347   sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE);
1001                                                  348 
1002   /* Greetings from SOS */                       349   /* Greetings from SOS */
1003   if (magic == MULTIBOOT_BOOTLOADER_MAGIC)       350   if (magic == MULTIBOOT_BOOTLOADER_MAGIC)
1004     /* Loaded with Grub */                       351     /* Loaded with Grub */
1005     sos_x86_videomem_printf(1, 0,                352     sos_x86_videomem_printf(1, 0,
1006                             SOS_X86_VIDEO_FG_    353                             SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
1007                             "Welcome From GRU    354                             "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)",
1008                             "SOS", ',',          355                             "SOS", ',',
1009                             (unsigned)(mbi->m    356                             (unsigned)(mbi->mem_upper >> 10) + 1,
1010                             (unsigned)mbi->me    357                             (unsigned)mbi->mem_upper);
1011   else                                           358   else
1012     /* Not loaded with grub */                   359     /* Not loaded with grub */
1013     sos_x86_videomem_printf(1, 0,                360     sos_x86_videomem_printf(1, 0,
1014                             SOS_X86_VIDEO_FG_    361                             SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
1015                             "Welcome to SOS")    362                             "Welcome to SOS");
1016                                                  363 
1017   sos_bochs_putstring("Message in a bochs\n")    364   sos_bochs_putstring("Message in a bochs\n");
1018                                                  365 
1019   /* Setup CPU segmentation and IRQ subsystem    366   /* Setup CPU segmentation and IRQ subsystem */
1020   sos_gdt_subsystem_setup();                  !! 367   sos_gdt_setup();
1021   sos_idt_subsystem_setup();                  !! 368   sos_idt_setup();
1022                                                  369 
1023   /* Setup SOS IRQs and exceptions subsystem     370   /* Setup SOS IRQs and exceptions subsystem */
1024   sos_exception_subsystem_setup();            !! 371   sos_exceptions_setup();
1025   sos_irq_subsystem_setup();                  !! 372   sos_irq_setup();
1026                                                  373 
1027   /* Configure the timer so as to raise the I    374   /* Configure the timer so as to raise the IRQ0 at a 100Hz rate */
1028   sos_i8254_set_frequency(100);                  375   sos_i8254_set_frequency(100);
1029                                                  376 
                                                   >> 377 
1030   /* We need a multiboot-compliant boot loade    378   /* We need a multiboot-compliant boot loader to get the size of the RAM */
1031   if (magic != MULTIBOOT_BOOTLOADER_MAGIC)       379   if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
1032     {                                            380     {
1033       sos_x86_videomem_putstring(20, 0,          381       sos_x86_videomem_putstring(20, 0,
1034                                  SOS_X86_VIDE    382                                  SOS_X86_VIDEO_FG_LTRED
1035                                    | SOS_X86_    383                                    | SOS_X86_VIDEO_BG_BLUE
1036                                    | SOS_X86_    384                                    | SOS_X86_VIDEO_FG_BLINKING,
1037                                  "I'm not loa    385                                  "I'm not loaded with Grub !");
1038       /* STOP ! */                               386       /* STOP ! */
1039       for (;;)                                   387       for (;;)
1040         continue;                                388         continue;
1041     }                                            389     }
1042                                                  390 
1043   /*                                          << 
1044    * Some interrupt handlers                  << 
1045    */                                         << 
1046                                               << 
1047   /* Binding some HW interrupts and exception    391   /* Binding some HW interrupts and exceptions to software routines */
1048   sos_irq_set_routine(SOS_IRQ_TIMER,             392   sos_irq_set_routine(SOS_IRQ_TIMER,
1049                       clk_it);                !! 393                             clk_it);
1050                                               !! 394   /* Enabling the HW interrupts here, this will make the timer HW
1051   /*                                          !! 395      interrupt call our clk_it handler */
1052    * Setup physical memory management         !! 396   asm volatile ("sti\n");
1053    */                                         << 
1054                                               << 
1055   /* Multiboot says: "The value returned for     397   /* Multiboot says: "The value returned for upper memory is maximally
1056      the address of the first upper memory ho    398      the address of the first upper memory hole minus 1 megabyte.". It
1057      also adds: "It is not guaranteed to be t    399      also adds: "It is not guaranteed to be this value." aka "YMMV" ;) */
1058   sos_physmem_subsystem_setup((mbi->mem_upper !! 400   sos_physmem_setup((mbi->mem_upper<<10) + (1<<20),
1059                               & sos_kernel_co !! 401                     & sos_kernel_core_base_paddr,
1060                               & sos_kernel_co !! 402                     & sos_kernel_core_top_paddr);
1061                                                  403   
1062   /*                                             404   /*
1063    * Switch to paged-memory mode                 405    * Switch to paged-memory mode
1064    */                                            406    */
1065                                                  407 
1066   /* Disabling interrupts should seem more co    408   /* Disabling interrupts should seem more correct, but it's not really
1067      necessary at this stage */                  409      necessary at this stage */
1068   SOS_ASSERT_FATAL(SOS_OK ==                  !! 410   if (sos_paging_setup(sos_kernel_core_base_paddr,
1069                    sos_paging_subsystem_setup !! 411                        sos_kernel_core_top_paddr))
1070                                               !! 412     sos_bochs_printf("Could not setup paged memory mode\n");
1071                                               !! 413   sos_x86_videomem_printf(2, 0,
1072   /* Bind the page fault exception */         !! 414                           SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE,
1073   sos_exception_set_routine(SOS_EXCEPT_PAGE_F !! 415                           "Paged-memory mode is activated");
1074                             pgflt_ex);        << 
1075                                                  416 
1076   /*                                          << 
1077    * Setup kernel virtual memory allocator    << 
1078    */                                         << 
1079                                                  417 
1080   if (sos_kmem_vmm_subsystem_setup(sos_kernel !! 418   if (sos_kmem_vmm_setup(sos_kernel_core_base_paddr,
1081                                    sos_kernel !! 419                          sos_kernel_core_top_paddr))
1082                                    bootstrap_ << 
1083                                    bootstrap_ << 
1084                                    + bootstra << 
1085     sos_bochs_printf("Could not setup the Ker    420     sos_bochs_printf("Could not setup the Kernel virtual space allocator\n");
1086                                                  421 
1087   if (sos_kmalloc_subsystem_setup())          !! 422   if (sos_kmalloc_setup())
1088     sos_bochs_printf("Could not setup the Kma    423     sos_bochs_printf("Could not setup the Kmalloc subsystem\n");
1089                                                  424 
1090   /*                                          !! 425   /* Run some kmalloc tests */
1091    * Enabling the HW interrupts here, this wi !! 426   bn_test();
1092    * interrupt call our clk_it handler        << 
1093    */                                         << 
1094   asm volatile ("sti\n");                     << 
1095                                               << 
1096   /*                                          << 
1097    * Print hello world using coroutines       << 
1098    */                                         << 
1099   print_hello_world();                        << 
1100                                               << 
1101                                               << 
1102   /*                                          << 
1103    * Run coroutine tests                      << 
1104    */                                         << 
1105   sos_x86_videomem_printf(4, 0,               << 
1106                           SOS_X86_VIDEO_BG_BL << 
1107                           "Coroutine test");  << 
1108   sos_x86_videomem_printf(5, 0,               << 
1109                           SOS_X86_VIDEO_BG_BL << 
1110                           "Parsing...");      << 
1111   syntax_tree = parse_expression(" -  ( (69/  << 
1112                                               << 
1113   if (syntax_tree != NULL)                    << 
1114     {                                         << 
1115       sos_x86_videomem_printf(6, 0,           << 
1116                               SOS_X86_VIDEO_B << 
1117                               "Evaluating..." << 
1118       sos_x86_videomem_printf(7, 0,           << 
1119                               SOS_X86_VIDEO_B << 
1120                               "Result=%d (if  << 
1121                               eval_expression << 
1122                                               << 
1123                                               << 
1124                                               << 
1125       free_syntax_tree(syntax_tree);          << 
1126       sos_x86_videomem_printf(8, 0,           << 
1127                               SOS_X86_VIDEO_B << 
1128                               "Done (un-alloc << 
1129     }                                         << 
1130   else                                        << 
1131     {                                         << 
1132       sos_x86_videomem_printf(6, 0,           << 
1133                               SOS_X86_VIDEO_B << 
1134                               "Error in parsi << 
1135     }                                         << 
1136                                               << 
1137   /*                                          << 
1138    * Run some demand-paging tests             << 
1139    */                                         << 
1140   test_demand_paging(234567, 500);            << 
1141                                               << 
1142                                               << 
1143   /*                                          << 
1144    * Create an un-resolved page fault, which  << 
1145    * handler print the backtrace.             << 
1146    */                                         << 
1147   test_backtrace(6, 0xdeadbeef, bootstrap_sta << 
1148                                               << 
1149   /*                                          << 
1150    * System should be halted BEFORE here !    << 
1151    */                                         << 
1152                                               << 
1153                                                  427 
1154   /* An operatig system never ends */            428   /* An operatig system never ends */
1155   for (;;)                                       429   for (;;)
1156     {                                         !! 430     continue;
1157       /* Remove this instruction if you get a << 
1158          exception (old 80386 CPU) */         << 
1159       asm("hlt\n");                           << 
1160                                                  431 
1161       continue;                               !! 432   return;
1162     }                                         << 
1163 }                                                433 }
                                                      

source navigation ] diff markup ] identifier search ] general search ]