Subversion Repositories shark

Rev

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

Rev Author Line No. Line
2 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
/*      Address Spaces test file                        */
23
 
24
#include <ll/i386/stdlib.h>
25
#include <ll/i386/error.h>
26
#include <ll/i386/mem.h>
27
#include <ll/i386/hw-arch.h>
28
#include <ll/i386/farptr.h>
29
#include <ll/sys/ll/ll-func.h>
30
#include <ll/sys/ll/aspace.h>
31
#include <ll/sys/ll/event.h>
32
 
33
#define T  1000
34
#define WAIT()  for (w = 0; w < 0x5FFFFF; w++)                                 
35
 
36
extern DWORD GDT_base;
37
 
38
BYTE space[2048];
39
BYTE stack1[1024];
40
WORD th1, th2, thm;
41
 
42
/* For now, this is not called */
43
void killer(void)
44
{
45
  cli();
46
  message("Killer!!!\n");
47
  ll_context_load(thm);
48
}
49
 
50
/* Used to switch back to main thread */
51
void evtHandler(void *v)
52
{
53
  ll_context_load(thm);
54
}
55
 
56
/*
57
   Dummy thread: used only to test a context switch between two threads
58
   in the same AS
59
*/
60
void nullfun1(void *p)
61
{
62
  message("In thread 1\n");
63
  ll_context_load(thm);
64
}
65
 
66
/*
67
  And this is the thread that runs in the new AS... It cannot call
68
  any function (it is alone in its AS), so it simply plots a star
69
  on the screen and loops waiting for an event that switches to the
70
  main thread.
71
*/
72
void nullfun(void *p)
73
{
74
  /* Some asm to write on the screen (we cannot use libc... it is not
75
     linked in this AS */
76
  __asm__ __volatile__ ("movl $0xb8000, %ebp");
77
  __asm__ __volatile__ ("addl $150, %ebp");
78
  __asm__ __volatile__ ("movb $'*', %fs:0(%ebp)");
79
  __asm__ __volatile__ ("incl %ebp");
80
  __asm__ __volatile__ ("movb $6, %fs:0(%ebp)");
81
 
82
  /* And now, WAIT!!! */
83
  for(;;);
84
  halt();
85
}
86
 
87
int main (int argc, char *argv[])
88
{
89
  DWORD sp1, sp2;
90
  void *res;
91
  AS as, ds;
92
  int ok;
93
  char mystring[20];
94
  struct ll_initparms parms;
95
  struct timespec time;
96
 
97
  sp1 = get_SP();
98
  cli();
99
  if ((argc == 2) && (argv[1][0] == 'O')) {
100
    parms.mode = LL_ONESHOT;
101
  } else {
102
    parms.mode = LL_PERIODIC;
103
    parms.tick = 1000;
104
  }
105
  res = ll_init();
106
  event_init(&parms);
107
 
108
  if (res == NULL) {
109
    message("Error in LowLevel initialization code...\n");
110
    sti();
111
    l1_exit(-1);
112
  }
113
  NULL_TIMESPEC(&time);
114
  ADDNANO2TIMESPEC(500000000, &time);
115
  ADDNANO2TIMESPEC(500000000, &time);
116
  ADDNANO2TIMESPEC(500000000, &time);
117
  ADDNANO2TIMESPEC(500000000, &time);
118
  ADDNANO2TIMESPEC(500000000, &time);
119
  ADDNANO2TIMESPEC(500000000, &time);
120
  ADDNANO2TIMESPEC(500000000, &time);
121
  ADDNANO2TIMESPEC(500000000, &time);
122
  ADDNANO2TIMESPEC(500000000, &time);
123
  ADDNANO2TIMESPEC(500000000, &time);        /* Time1: 5 ms */
124
  event_post(time, evtHandler, NULL);
125
  sti();
126
 
127
  message("LowLevel started...\n");
128
 
129
  as_init();
130
 
131
  message("Creating an Address Space\n");
132
  as = as_create();
133
  message("Created: ID = %d %x\n", as, as);
134
  message("Binding array @ 0x%lx\n", (DWORD)space);
135
  ok = as_bind(as, (DWORD)space, 0, sizeof(space));
136
 
137
  if (ok < 0) {
138
    message("Error in as_bind!!!\n");
139
  } else {
140
    message("Bound\n");
141
  }
142
  _farpokeb(as, 0, 'H');
143
  _farpokeb(as, 1, 'e');
144
  _farpokeb(as, 2, 'l');
145
  _farpokeb(as, 3, 'l');
146
  _farpokeb(as, 4, 'o');
147
  _farpokeb(as, 5, 0);
148
 
149
  ds = get_DS();
150
  fmemcpy(ds, (DWORD)mystring, as, 0, 10);
151
  message("Memory space: %s\n", space);
152
  message("My String: %s\n", mystring);
153
 
154
  fmemcpy(as, 0, ds, (DWORD)nullfun, 1000);
155
  /* Create a thread (in our AS) and a task (in a different AS) */
156
  th2 = ll_context_create(nullfun1, &stack1[1024], NULL,killer, 0);
157
  th1 = ll_context_create(0, (void *)2048, NULL,killer, 0);
158
  ll_context_setspace(th1, as);
159
 
160
  /* Save our context, in order to permit to switch back to main */
161
  thm = ll_context_save();
162
  message("I am thread %x\n", thm);
163
  message("Thread 1 created\n");
164
  message("Switching to it...\n");
165
  ll_context_load(th2);
166
  message("Back to Main\n");
167
 
168
  /* Plot something in a stupid way, just to do some work... */
169
  __asm__ __volatile__ ("movl $0x30, %eax");
170
  __asm__ __volatile__ ("movw %ax, %fs");
171
  __asm__ __volatile__ ("movl $0xb8000, %edi");
172
  __asm__ __volatile__ ("addl $152, %edi");
173
  __asm__ __volatile__ ("movb $'+', %ds:0(%edi)");
174
  __asm__ __volatile__ ("incl %edi");
175
  __asm__ __volatile__ ("movb $6, %ds:0(%edi)");
176
 
177
  /* And now, go to the new task!!! */
178
  ll_context_load(th1);
179
 
180
  message("Main task again...\n");
181
 
182
  __asm__ __volatile__ ("movl $0x30, %eax");
183
  __asm__ __volatile__ ("movw %ax, %fs");
184
  __asm__ __volatile__ ("movl $0xb8000, %edi");
185
  __asm__ __volatile__ ("addl $154, %edi");
186
  __asm__ __volatile__ ("movb $'-', %fs:0(%edi)");
187
  __asm__ __volatile__ ("incl %edi");
188
  __asm__ __volatile__ ("movb $6, %fs:0(%edi)");
189
 
190
  message("Current time: %ld (= %ld?)\n", ll_gettime(TIME_NEW, NULL),
191
          ll_gettime(TIME_EXACT, NULL));
192
  cli();
193
  ll_end();
194
  sp2 = get_SP();
195
  message("End reached!\n");
196
  message("Actual stack : %lx - ", sp2);
197
  message("Begin stack : %lx\n", sp1);
198
  message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
199
 
200
  return 1;
201
}