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

Subversion Repositories eco32

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

powered by: WebSVN 2.1.0

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