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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-newlib/] [newlib-1.17.0/] [libgloss/] [sparc/] [salib.c] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 jlechner
/* Stand-alone library for SPARClite
2
 *
3
 * Copyright (c) 1995 Cygnus Support
4
 *
5
 * The authors hereby grant permission to use, copy, modify, distribute,
6
 * and license this software and its documentation for any purpose, provided
7
 * that existing copyright notices are retained in all copies and that this
8
 * notice is included verbatim in any distributions. No written agreement,
9
 * license, or royalty fee is required for any of the authorized uses.
10
 * Modifications to this software may be copyrighted by their authors
11
 * and need not follow the licensing terms described here, provided that
12
 * the new terms are clearly indicated on the first page of each file where
13
 * they apply.
14
 */
15
 
16
#include "sparclite.h"
17
#include "asm.h"
18
 
19
/* LED blinking pattern can be changed by modifying __led_algorithm. */
20
 
21
enum ledtype
22
{
23
  led_marching,         /* marching pattern, only one led on at a time */
24
  led_random,           /* pseudo-random pattern */
25
  led_blinking,         /* all leds blink on and off */
26
  led_none              /* leds off all the time */
27
};
28
 
29
enum ledtype __led_algorithm = led_marching;
30
 
31
 
32
/* Pointer to hook for outbyte, set by stub's exception handler.  */
33
void (*__outbyte_hook) (int c);
34
 
35
#ifdef SL931
36
#define SDTR_BASE 0x200
37
#define SDTR_ASI 1
38
#define SDTR_SHIFT 0
39
#else
40
#define SDTR_BASE 0x10000000
41
#define SDTR_ASI 4
42
#define SDTR_SHIFT 16
43
#endif
44
 
45
#define get_uart_status(PORT) \
46
  (read_asi (SDTR_ASI, SDTR_BASE + 0x24 + (PORT) * 0x10) >> SDTR_SHIFT)
47
 
48
#define xmt_char(PORT, C) \
49
  write_asi (SDTR_ASI, SDTR_BASE + 0x20 + (PORT) * 0x10, (C) << SDTR_SHIFT)
50
 
51
#define rcv_char(PORT) \
52
  (read_asi (SDTR_ASI, SDTR_BASE + 0x20 + (PORT) * 0x10) >> SDTR_SHIFT)
53
 
54
void putDebugChar();
55
 
56
#if 0
57
void
58
set_uart (cmd)
59
     int cmd;
60
{
61
  write_asi (SDTR_ASI, SDTR_BASE + 0x24, cmd << SDTR_SHIFT);
62
}
63
 
64
void
65
set_timer_3 (val)
66
     int val;
67
{
68
  write_asi (SDTR_ASI, SDTR_BASE + 0x78, val << SDTR_SHIFT);
69
}
70
#endif
71
 
72
 
73
asm("
74
        .text
75
        .align 4
76
 
77
! Register window overflow handler.  Come here when save would move us
78
! into the invalid window.  This routine runs with traps disabled, and
79
! must be careful not to touch the condition codes, as PSR is never
80
! restored.
81
!
82
! We are called with %l0 = wim, %l1 = pc, %l2 = npc
83
 
84
        .globl " STRINGSYM(win_ovf) "
85
" STRINGSYM(win_ovf) ":
86
        mov     %g1, %l3                ! Save g1, we use it to hold the wim
87
        srl     %l0, 1, %g1             ! Rotate wim right
88
        sll     %l0, __WINSIZE-1, %l0
89
        or      %l0, %g1, %g1
90
 
91
        save    %g0, %g0, %g0           ! Slip into next window
92
        mov     %g1, %wim               ! Install the new wim
93
 
94
        std     %l0, [%sp + 0 * 4]      ! save L & I registers
95
        std     %l2, [%sp + 2 * 4]
96
        std     %l4, [%sp + 4 * 4]
97
        std     %l6, [%sp + 6 * 4]
98
 
99
        std     %i0, [%sp + 8 * 4]
100
        std     %i2, [%sp + 10 * 4]
101
        std     %i4, [%sp + 12 * 4]
102
        std     %i6, [%sp + 14 * 4]
103
 
104
        restore                         ! Go back to trap window.
105
        mov     %l3, %g1                ! Restore %g1
106
 
107
        jmpl    %l1,  %g0
108
        rett    %l2
109
 
110
! Register window underflow handler.  Come here when restore would move us
111
! into the invalid window.  This routine runs with traps disabled, and
112
! must be careful not to touch the condition codes, as PSR is never
113
! restored.
114
!
115
! We are called with %l0 = wim, %l1 = pc, %l2 = npc
116
 
117
        .globl " STRINGSYM(win_unf) "
118
" STRINGSYM(win_unf) ":
119
        sll     %l0, 1, %l3             ! Rotate wim left
120
        srl     %l0, __WINSIZE-1, %l0
121
        or      %l0, %l3, %l0
122
 
123
        mov     %l0, %wim               ! Install the new wim
124
 
125
        restore                         ! User's window
126
        restore                         ! His caller's window
127
 
128
        ldd     [%sp + 0 * 4], %l0      ! restore L & I registers
129
        ldd     [%sp + 2 * 4], %l2
130
        ldd     [%sp + 4 * 4], %l4
131
        ldd     [%sp + 6 * 4], %l6
132
 
133
        ldd     [%sp + 8 * 4], %i0
134
        ldd     [%sp + 10 * 4], %i2
135
        ldd     [%sp + 12 * 4], %i4
136
        ldd     [%sp + 14 * 4], %i6
137
 
138
        save    %g0, %g0, %g0           ! Back to trap window
139
        save    %g0, %g0, %g0
140
 
141
        jmpl    %l1,  %g0
142
        rett    %l2
143
 
144
! Read the TBR.
145
 
146
        .globl " STRINGSYM(rdtbr) "
147
" STRINGSYM(rdtbr) ":
148
        retl
149
        mov     %tbr, %o0
150
 
151
");
152
 
153
extern unsigned long rdtbr();
154
 
155
void
156
die(val)
157
     int val;
158
{
159
  static unsigned char *leds = (unsigned char *)0x02000003;
160
 
161
  *leds = val;
162
 
163
  while (1) ;
164
}
165
 
166
/* Each entry in the trap vector occupies four words. */
167
 
168
struct trap_entry
169
{
170
  unsigned sethi_filler:10;
171
  unsigned sethi_imm22:22;
172
  unsigned jmpl_filler:19;
173
  unsigned jmpl_simm13:13;
174
  unsigned long filler[2];
175
};
176
 
177
extern struct trap_entry fltr_proto;
178
asm ("
179
        .data
180
        .globl " STRINGSYM(fltr_proto) "
181
        .align 4
182
" STRINGSYM(fltr_proto) ":                      ! First level trap routine prototype
183
        sethi 0, %l0
184
        jmpl 0+%l0, %g0
185
        nop
186
        nop
187
 
188
        .text
189
        .align 4
190
");
191
 
192
/* Setup trap TT to go to ROUTINE.  If TT is between 0 and 255 inclusive, the
193
   normal trap vector will be used.  If TT is 256, then it's for the SPARClite
194
   DSU, and that always vectors off to 255 unrelocated.
195
*/
196
 
197
void
198
exceptionHandler (tt, routine)
199
     int tt;
200
     unsigned long routine;
201
{
202
  struct trap_entry *tb;        /* Trap vector base address */
203
 
204
  if (tt != 256)
205
    tb = (struct trap_entry *) (rdtbr() & ~0xfff);
206
  else
207
    {
208
      tt = 255;
209
      tb = (struct trap_entry *) 0;
210
    }
211
 
212
  tb[tt] = fltr_proto;
213
 
214
  tb[tt].sethi_imm22 = routine >> 10;
215
  tb[tt].jmpl_simm13 = routine & 0x3ff;
216
}
217
 
218
void
219
update_leds()
220
{
221
  static unsigned char *leds = (unsigned char *)0x02000003;
222
  static enum ledtype prev_algorithm = led_none;
223
 
224
  if (prev_algorithm != __led_algorithm)
225
    {
226
       *leds = 0xff;    /* turn the LEDs off */
227
       prev_algorithm = __led_algorithm;
228
    }
229
 
230
  switch (__led_algorithm)
231
    {
232
    case led_marching:
233
      {
234
        static unsigned char curled = 1;
235
        static unsigned char dir = 0;
236
 
237
        *leds = ~curled;
238
 
239
        if (dir)
240
          curled <<= 1;
241
        else
242
          curled >>= 1;
243
 
244
        if (curled == 0)
245
          {
246
            if (dir)
247
              curled = 0x80;
248
            else
249
              curled = 1;
250
            dir = ~dir;
251
          }
252
        break;
253
      }
254
 
255
    case led_random:
256
      {
257
        static unsigned int next = 0;
258
        *leds = next & 0xff;
259
        next = (next * 1103515245 + 12345) & 0x7fff;
260
        break;
261
      }
262
 
263
    case led_blinking:
264
      {
265
        static unsigned char next = 0;
266
        *leds = next;
267
        next = ~next;
268
        break;
269
      }
270
 
271
    default:
272
      break;
273
    }
274
}
275
 
276
 /* 1/5th of a second? */
277
 
278
#define LEDTIME (20000000 / 500)
279
 
280
unsigned long ledtime = LEDTIME;
281
 
282
int
283
inbyte()
284
{
285
        return (getDebugChar());
286
}
287
 
288
int
289
getDebugChar()
290
{
291
  unsigned long countdown = ledtime;
292
 
293
  update_leds();
294
 
295
  while (1)
296
    {
297
      if ((get_uart_status(0) & 2) != 0) break;
298
 
299
      if (countdown-- == 0)
300
        {
301
          countdown = ledtime;
302
          update_leds();
303
        }
304
    }
305
 
306
  return rcv_char(0);
307
}
308
 
309
/* Output one character to the serial port */
310
void
311
outbyte(c)
312
    int c;
313
{
314
  if (__outbyte_hook)
315
    __outbyte_hook (c);
316
  else
317
    putDebugChar(c);
318
}
319
 
320
void
321
putDebugChar(c)
322
     int c;
323
{
324
  update_leds();
325
 
326
  while ((get_uart_status(0) & 1) == 0) ;
327
 
328
  xmt_char(0, c);
329
}
330
 
331
#if 0
332
int
333
write(fd, data, length)
334
     int fd;
335
     unsigned char *data;
336
     int length;
337
{
338
  int olength = length;
339
 
340
  while (length--)
341
    putDebugChar(*data++);
342
 
343
  return olength;
344
}
345
 
346
int
347
read(fd, data, length)
348
     int fd;
349
     unsigned char *data;
350
     int length;
351
{
352
  int olength = length;
353
  int c;
354
 
355
  while (length--)
356
    *data++ = getDebugChar();
357
 
358
  return olength;
359
}
360
#endif
361
 
362
/* Set the baud rate for the serial port, returns 0 for success,
363
   -1 otherwise */
364
 
365
#if 0
366
int
367
set_baud_rate(baudrate)
368
     int baudrate;
369
{
370
  /* Convert baud rate to uart clock divider */
371
  switch (baudrate)
372
    {
373
    case 38400:
374
      baudrate = 16;
375
      break;
376
    case 19200:
377
      baudrate = 33;
378
      break;
379
    case 9600:
380
      baudrate = 65;
381
      break;
382
    default:
383
      return -1;
384
    }
385
 
386
  set_timer_3(baudrate);        /* Set it */
387
}
388
#endif

powered by: WebSVN 2.1.0

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