OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [stdalone/] [twotasks-2/] [os/] [main.c] - Blame information for rev 18

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 hellwig
/*
2
 * main.c -- start the ball rolling
3
 */
4
 
5
 
6
#include "stdarg.h"
7
#include "start.h"
8
 
9
 
10
/**************************************************************/
11
 
12
 
13
int currentTask;
14
unsigned int **currentPageDir;
15
unsigned int *currentStkTop;
16
 
17
 
18
/**************************************************************/
19
 
20
 
21
unsigned int task0Stack[256];
22
unsigned int *task0StkTop = task0Stack + 256;
23
 
24
 
25
unsigned char task1Code[] = {
26
  #include "task1.dump"
27
};
28
 
29
unsigned int task1Stack[256];
30
unsigned int *task1StkTop = task1Stack + 256;
31
 
32
unsigned int **task1PageDir;
33
 
34
 
35
unsigned char task2Code[] = {
36
  #include "task2.dump"
37
};
38
 
39
unsigned int task2Stack[256];
40
unsigned int *task2StkTop = task2Stack + 256;
41
 
42
unsigned int **task2PageDir;
43
 
44
 
45
/**************************************************************/
46
 
47
 
48
unsigned int pageTablePool[10][1024];
49
int nextPageTable = 0;
50
 
51
 
52
unsigned int *allocPageTable(void) {
53
  unsigned int *pageTable;
54
  int i;
55
 
56
  pageTable = pageTablePool[nextPageTable++];
57
  for (i = 0; i < 1024; i++) {
58
    pageTable[i] = 0;
59
  }
60
  return pageTable;
61
}
62
 
63
 
64
/**************************************************************/
65
 
66
 
67
void putchar(char c) {
68
  unsigned int *base;
69
 
70
  if (c == '\n') {
71
    putchar('\r');
72
  }
73
  base = (unsigned int *) 0xF0300000;
74
  while ((*(base + 2) & 1) == 0) ;
75
  *(base + 3) = c;
76
}
77
 
78
 
79
void puts(char *s) {
80
  char c;
81
 
82
  while ((c = *s++) != '\0') {
83
    putchar(c);
84
  }
85
}
86
 
87
 
88
void printn(int n) {
89
  int a;
90
 
91
  if (n < 0) {
92
    putchar('-');
93
    n = -n;
94
  }
95
  a = n / 10;
96
  if (a != 0) {
97
    printn(a);
98
  }
99
  putchar(n % 10 + '0');
100
}
101
 
102
 
103
void printu(unsigned int n, unsigned int b) {
104
  unsigned int a;
105
 
106
  a = n / b;
107
  if (a != 0) {
108
    printu(a, b);
109
  }
110
  putchar("0123456789ABCDEF"[n % b]);
111
}
112
 
113
 
114
void printf(char *fmt, ...) {
115
  va_list ap;
116
  char c;
117
  int n;
118
  unsigned int u;
119
  char *s;
120
 
121
  va_start(ap, fmt);
122
  while (1) {
123
    while ((c = *fmt++) != '%') {
124
      if (c == '\0') {
125
        va_end(ap);
126
        return;
127
      }
128
      putchar(c);
129
    }
130
    c = *fmt++;
131
    if (c == 'd') {
132
      n = va_arg(ap, int);
133
      printn(n);
134
    } else
135
    if (c == 'u' || c == 'o' || c == 'x') {
136
      u = va_arg(ap, int);
137
      printu(u, c == 'o' ? 8 : (c == 'x' ? 16 : 10));
138
    } else
139
    if (c == 's') {
140
      s = va_arg(ap, char *);
141
      puts(s);
142
    } else {
143
      putchar(c);
144
    }
145
  }
146
}
147
 
148
 
149
/**************************************************************/
150
 
151
 
152
static char *exceptionCause[32] = {
153
  /* 00 */  "terminal 0 transmitter interrupt",
154
  /* 01 */  "terminal 0 receiver interrupt",
155
  /* 02 */  "terminal 1 transmitter interrupt",
156
  /* 03 */  "terminal 1 receiver interrupt",
157
  /* 04 */  "keyboard interrupt",
158
  /* 05 */  "unknown interrupt",
159
  /* 06 */  "unknown interrupt",
160
  /* 07 */  "unknown interrupt",
161
  /* 08 */  "disk interrupt",
162
  /* 09 */  "unknown interrupt",
163
  /* 10 */  "unknown interrupt",
164
  /* 11 */  "unknown interrupt",
165
  /* 12 */  "unknown interrupt",
166
  /* 13 */  "unknown interrupt",
167
  /* 14 */  "timer interrupt",
168
  /* 15 */  "unknown interrupt",
169
  /* 16 */  "bus timeout exception",
170
  /* 17 */  "illegal instruction exception",
171
  /* 18 */  "privileged instruction exception",
172
  /* 19 */  "divide instruction exception",
173
  /* 20 */  "trap instruction exception",
174
  /* 21 */  "TLB miss exception",
175
  /* 22 */  "TLB write exception",
176
  /* 23 */  "TLB invalid exception",
177
  /* 24 */  "illegal address exception",
178
  /* 25 */  "privileged address exception",
179
  /* 26 */  "unknown exception",
180
  /* 27 */  "unknown exception",
181
  /* 28 */  "unknown exception",
182
  /* 29 */  "unknown exception",
183
  /* 30 */  "unknown exception",
184
  /* 31 */  "unknown exception"
185
};
186
 
187
 
188
void defaultISR(int irq, unsigned int *registers) {
189
  printf("\n%s\n", exceptionCause[irq]);
190
}
191
 
192
 
193
void initInterrupts(void) {
194
  int i;
195
 
196
  for (i = 0; i < 32; i++) {
197
    setISR(i, defaultISR);
198
  }
199
}
200
 
201
 
202
/**************************************************************/
203
 
204
 
205
unsigned int getNumber(unsigned char *p) {
206
  return (unsigned int) *(p + 0) << 24 |
207
         (unsigned int) *(p + 1) << 16 |
208
         (unsigned int) *(p + 2) <<  8 |
209
         (unsigned int) *(p + 3) <<  0;
210
}
211
 
212
 
213
unsigned int **loadTask(unsigned char *code,
214
                        unsigned int physCodeAddr,
215
                        unsigned int physDataAddr,
216
                        unsigned int physStackAddr) {
217
  unsigned int magic;
218
  unsigned int csize;
219
  unsigned int dsize;
220
  unsigned int bsize;
221
  unsigned char *virtLoadAddr;
222
  int i;
223
  unsigned int **pageDir;
224
 
225
  magic = getNumber(code);
226
  code += sizeof(unsigned int);
227
  csize = getNumber(code);
228
  code += sizeof(unsigned int);
229
  dsize = getNumber(code);
230
  code += sizeof(unsigned int);
231
  bsize = getNumber(code);
232
  code += sizeof(unsigned int);
233
  if (magic != 0x1AA09232) {
234
    printf("Error: Load module is not executable!\n");
235
    while (1) ;
236
  }
237
  code += 4 * sizeof(unsigned int);
238
  printf("(csize = 0x%x, dsize = 0x%x, bsize = 0x%x)\n",
239
         csize, dsize, bsize);
240
  virtLoadAddr = (unsigned char *) (0xC0000000 | physCodeAddr);
241
  for (i = 0; i < csize; i++) {
242
    *virtLoadAddr++ = *code++;
243
  }
244
  virtLoadAddr = (unsigned char *) (0xC0000000 | physDataAddr);
245
  for (i = 0; i < dsize; i++) {
246
    *virtLoadAddr++ = *code++;
247
  }
248
  for (i = 0; i < bsize; i++) {
249
    *virtLoadAddr++ = '\0';
250
  }
251
  /* allocate a page directory and two page tables */
252
  pageDir = (unsigned int **) allocPageTable();
253
  pageDir[0] = allocPageTable();
254
  pageDir[0][0] = physCodeAddr | 0x01;
255
  pageDir[0][1] = physDataAddr | 0x03;
256
  pageDir[511] = allocPageTable();
257
  pageDir[511][1023] = physStackAddr | 0x03;
258
  return pageDir;
259
}
260
 
261
 
262
/**************************************************************/
263
 
264
 
265
void trapISR(int irq, unsigned int *registers) {
266
  /* 'putchar' is the only system call yet */
267
  putchar(registers[4]);
268
  /* skip the trap instruction */
269
  registers[30] += 4;
270
}
271
 
272
 
273
/**************************************************************/
274
 
275
 
276
void flushTLB(void) {
277
  unsigned int invalPage;
278
  int i;
279
 
280
  invalPage = 0xC0000000;
281
  for (i = 0; i < 32; i++) {
282
    setTLB(i, invalPage, 0);
283
    invalPage += (1 << 12);
284
  }
285
}
286
 
287
 
288
/**************************************************************/
289
 
290
 
291
void initTimer(void) {
292
  unsigned int *timerBase;
293
 
294
  timerBase = (unsigned int *) 0xF0000000;
295
  *(timerBase + 1) = 1000;
296
  *timerBase = 2;
297
  orMask(1 << 14);
298
}
299
 
300
 
301
int task1Started = 0;
302
int task2Started = 0;
303
 
304
 
305
void timerISR(int irq, unsigned int *registers) {
306
  unsigned int *timerBase;
307
 
308
  timerBase = (unsigned int *) 0xF0000000;
309
  *timerBase = 2;
310
  printf(">|<");
311
  if (currentTask == 0) {
312
    if (!task1Started) {
313
      /* load & start task1 */
314
      printf("\nOS: loading task1\n");
315
      task1PageDir = loadTask(task1Code, 64 << 12, 68 << 12, 80 << 12);
316
      printf("OS: starting task1\n");
317
      task1Started = 1;
318
      currentTask = 1;
319
      currentPageDir = task1PageDir;
320
      currentStkTop = task1StkTop;
321
      flushTLB();
322
      startTask();
323
    }
324
  } else if (currentTask == 1) {
325
    if (!task2Started) {
326
      /* load & start task2 */
327
      printf("\nOS: loading task2\n");
328
      task2PageDir = loadTask(task2Code, 96 << 12, 100 << 12, 112 << 12);
329
      printf("OS: starting task2\n");
330
      task2Started = 1;
331
      currentTask = 2;
332
      currentPageDir = task2PageDir;
333
      currentStkTop = task2StkTop;
334
      flushTLB();
335
      startTask();
336
    } else {
337
      /* switch tasks */
338
      currentTask = 2;
339
      currentPageDir = task2PageDir;
340
      currentStkTop = task2StkTop;
341
      flushTLB();
342
    }
343
  } else if (currentTask == 2) {
344
    /* switch tasks */
345
    currentTask = 1;
346
    currentPageDir = task1PageDir;
347
    currentStkTop = task1StkTop;
348
    flushTLB();
349
  }
350
}
351
 
352
 
353
/**************************************************************/
354
 
355
 
356
void main(void) {
357
  currentTask = 0;
358
  currentStkTop = task0StkTop;
359
  printf("\n");
360
  printf("OS: initializing interrupts\n");
361
  initInterrupts();
362
  setISR(20, trapISR);
363
  setISR(14, timerISR);
364
  printf("OS: initializing timer\n");
365
  initTimer();
366
  printf("OS: waiting for interrupt...\n");
367
  enable();
368
  while (1) ;
369
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.