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

Subversion Repositories or1k

[/] [or1k/] [branches/] [newlib/] [newlib/] [libgloss/] [sparc/] [salib.c] - Blame information for rev 39

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

Line No. Rev Author Line
1 39 lampret
/* 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
#ifdef SL931
20
#define SDTR_BASE 0x200
21
#define SDTR_ASI 1
22
#define SDTR_SHIFT 0
23
#else
24
#define SDTR_BASE 0x10000000
25
#define SDTR_ASI 4
26
#define SDTR_SHIFT 16
27
#endif
28
 
29
#define get_uart_status(PORT) \
30
  (read_asi (SDTR_ASI, SDTR_BASE + 0x24 + (PORT) * 0x10) >> SDTR_SHIFT)
31
 
32
#define xmt_char(PORT, C) \
33
  write_asi (SDTR_ASI, SDTR_BASE + 0x20 + (PORT) * 0x10, (C) << SDTR_SHIFT)
34
 
35
#define rcv_char(PORT) \
36
  (read_asi (SDTR_ASI, SDTR_BASE + 0x20 + (PORT) * 0x10) >> SDTR_SHIFT)
37
 
38
void putDebugChar();
39
 
40
#if 0
41
void
42
set_uart (cmd)
43
     int cmd;
44
{
45
  write_asi (SDTR_ASI, SDTR_BASE + 0x24, cmd << SDTR_SHIFT);
46
}
47
 
48
void
49
set_timer_3 (val)
50
     int val;
51
{
52
  write_asi (SDTR_ASI, SDTR_BASE + 0x78, val << SDTR_SHIFT);
53
}
54
#endif
55
 
56
/* This cache code is known to work on both the 930 & 932 processors.  It just
57
   cheats and clears the all of the address space that could contain tags, as
58
   opposed to striding the tags at 8 or 16 word intervals, or using the cache
59
   flush registers, which don't exist on all processors.  */
60
 
61
void
62
cache_off ()
63
{
64
  write_asi (1, 0, 0);
65
}
66
 
67
void
68
cache_on ()
69
{
70
  unsigned long addr;
71
 
72
  cache_off ();                 /* Make sure the cache is off */
73
 
74
  /* Reset all of the cache line valid bits */
75
 
76
  for (addr = 0; addr < 0x1000; addr += 8)
77
    {
78
      write_asi (0xc, addr, 0);  /* Clear bank 1, icache */
79
      write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
80
 
81
      write_asi (0xe, addr, 0);  /* Clear bank 1, dcache */
82
      write_asi (0xe, addr + 0x80000000, 0); /* Clear bank 2, dcache */
83
    }
84
 
85
  /* turn on the cache */
86
 
87
  write_asi (1, 0, 0x35);        /* Write buf ena, prefetch buf ena, data
88
                                   & inst caches enab */
89
}
90
 
91
/* Flush the instruction cache.  We need to do this for the debugger stub so
92
   that breakpoints, et. al. become visible to the instruction stream after
93
   storing them in memory.
94
 */
95
 
96
void
97
flush_i_cache ()
98
{
99
  int cache_reg;
100
  unsigned long addr;
101
 
102
  cache_reg = read_asi (1, 0);   /* Read cache/bus interface reg */
103
 
104
  if (!(cache_reg & 1))
105
    return;                     /* Just return if cache is already off */
106
 
107
  for (addr = 0; addr < 0x1000; addr += 8)
108
    {
109
      write_asi (0xc, addr, 0);  /* Clear bank 1, icache */
110
      write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
111
    }
112
}
113
 
114
asm("
115
        .text
116
        .align 4
117
 
118
! Register window overflow handler.  Come here when save would move us
119
! into the invalid window.  This routine runs with traps disabled, and
120
! must be careful not to touch the condition codes, as PSR is never
121
! restored.
122
!
123
! We are called with %l0 = wim, %l1 = pc, %l2 = npc
124
 
125
        .globl " STRINGSYM(win_ovf) "
126
" STRINGSYM(win_ovf) ":
127
        mov     %g1, %l3                ! Save g1, we use it to hold the wim
128
        srl     %l0, 1, %g1             ! Rotate wim right
129
        sll     %l0, __WINSIZE-1, %l0
130
        or      %l0, %g1, %g1
131
 
132
        save    %g0, %g0, %g0           ! Slip into next window
133
        mov     %g1, %wim               ! Install the new wim
134
 
135
        std     %l0, [%sp + 0 * 4]      ! save L & I registers
136
        std     %l2, [%sp + 2 * 4]
137
        std     %l4, [%sp + 4 * 4]
138
        std     %l6, [%sp + 6 * 4]
139
 
140
        std     %i0, [%sp + 8 * 4]
141
        std     %i2, [%sp + 10 * 4]
142
        std     %i4, [%sp + 12 * 4]
143
        std     %i6, [%sp + 14 * 4]
144
 
145
        restore                         ! Go back to trap window.
146
        mov     %l3, %g1                ! Restore %g1
147
 
148
        jmpl    %l1,  %g0
149
        rett    %l2
150
 
151
! Register window underflow handler.  Come here when restore would move us
152
! into the invalid window.  This routine runs with traps disabled, and
153
! must be careful not to touch the condition codes, as PSR is never
154
! restored.
155
!
156
! We are called with %l0 = wim, %l1 = pc, %l2 = npc
157
 
158
        .globl " STRINGSYM(win_unf) "
159
" STRINGSYM(win_unf) ":
160
        sll     %l0, 1, %l3             ! Rotate wim left
161
        srl     %l0, __WINSIZE-1, %l0
162
        or      %l0, %l3, %l0
163
 
164
        mov     %l0, %wim               ! Install the new wim
165
 
166
        restore                         ! User's window
167
        restore                         ! His caller's window
168
 
169
        ldd     [%sp + 0 * 4], %l0      ! restore L & I registers
170
        ldd     [%sp + 2 * 4], %l2
171
        ldd     [%sp + 4 * 4], %l4
172
        ldd     [%sp + 6 * 4], %l6
173
 
174
        ldd     [%sp + 8 * 4], %i0
175
        ldd     [%sp + 10 * 4], %i2
176
        ldd     [%sp + 12 * 4], %i4
177
        ldd     [%sp + 14 * 4], %i6
178
 
179
        save    %g0, %g0, %g0           ! Back to trap window
180
        save    %g0, %g0, %g0
181
 
182
        jmpl    %l1,  %g0
183
        rett    %l2
184
 
185
! Read the TBR.
186
 
187
        .globl " STRINGSYM(rdtbr) "
188
" STRINGSYM(rdtbr) ":
189
        retl
190
        mov     %tbr, %o0
191
 
192
");
193
 
194
extern unsigned long rdtbr();
195
 
196
void
197
die(val)
198
     int val;
199
{
200
  static unsigned char *leds = (unsigned char *)0x02000003;
201
 
202
  *leds = val;
203
 
204
  while (1) ;
205
}
206
 
207
/* Each entry in the trap vector occupies four words. */
208
 
209
struct trap_entry
210
{
211
  unsigned sethi_filler:10;
212
  unsigned sethi_imm22:22;
213
  unsigned jmpl_filler:19;
214
  unsigned jmpl_simm13:13;
215
  unsigned long filler[2];
216
};
217
 
218
extern struct trap_entry fltr_proto;
219
asm ("
220
        .data
221
        .globl " STRINGSYM(fltr_proto) "
222
        .align 4
223
" STRINGSYM(fltr_proto) ":                      ! First level trap routine prototype
224
        sethi 0, %l0
225
        jmpl 0+%l0, %g0
226
        nop
227
        nop
228
 
229
        .text
230
        .align 4
231
");
232
 
233
/* Setup trap TT to go to ROUTINE.  If TT is between 0 and 255 inclusive, the
234
   normal trap vector will be used.  If TT is 256, then it's for the SPARClite
235
   DSU, and that always vectors off to 255 unrelocated.
236
*/
237
 
238
void
239
exceptionHandler (tt, routine)
240
     int tt;
241
     unsigned long routine;
242
{
243
  struct trap_entry *tb;        /* Trap vector base address */
244
 
245
  if (tt != 256)
246
    tb = (struct trap_entry *) (rdtbr() & ~0xfff);
247
  else
248
    {
249
      tt = 255;
250
      tb = (struct trap_entry *) 0;
251
    }
252
 
253
  tb[tt] = fltr_proto;
254
 
255
  tb[tt].sethi_imm22 = routine >> 10;
256
  tb[tt].jmpl_simm13 = routine & 0x3ff;
257
}
258
 
259
void
260
update_leds()
261
{
262
  static unsigned char *leds = (unsigned char *)0x02000003;
263
  static unsigned char curled = 1;
264
  static unsigned char dir = 0;
265
 
266
  *leds = ~curled;
267
 
268
  if (dir)
269
    curled <<= 1;
270
  else
271
    curled >>= 1;
272
 
273
  if (curled == 0)
274
    {
275
      if (dir)
276
        curled = 0x80;
277
      else
278
        curled = 1;
279
      dir = ~dir;
280
    }
281
}
282
 
283
 /* 1/5th of a second? */
284
 
285
#define LEDTIME (20000000 / 500)
286
 
287
unsigned long ledtime = LEDTIME;
288
 
289
int
290
inbyte()
291
{
292
        return (getDebugChar());
293
}
294
 
295
int
296
getDebugChar()
297
{
298
  unsigned long countdown = ledtime;
299
 
300
  update_leds();
301
 
302
  while (1)
303
    {
304
      if ((get_uart_status(0) & 2) != 0) break;
305
 
306
      if (countdown-- == 0)
307
        {
308
          countdown = ledtime;
309
          update_leds();
310
        }
311
    }
312
 
313
  return rcv_char(0);
314
}
315
 
316
/* Output one character to the serial port */
317
void
318
outbyte(c)
319
    int c;
320
{
321
        putDebugChar(c);
322
}
323
void
324
putDebugChar(c)
325
     int c;
326
{
327
  update_leds();
328
 
329
  while ((get_uart_status(0) & 1) == 0) ;
330
 
331
  xmt_char(0, c);
332
}
333
 
334
#if 0
335
int
336
write(fd, data, length)
337
     int fd;
338
     unsigned char *data;
339
     int length;
340
{
341
  int olength = length;
342
 
343
  while (length--)
344
    putDebugChar(*data++);
345
 
346
  return olength;
347
}
348
 
349
int
350
read(fd, data, length)
351
     int fd;
352
     unsigned char *data;
353
     int length;
354
{
355
  int olength = length;
356
  int c;
357
 
358
  while (length--)
359
    *data++ = getDebugChar();
360
 
361
  return olength;
362
}
363
#endif
364
 
365
/* Set the baud rate for the serial port, returns 0 for success,
366
   -1 otherwise */
367
 
368
#if 0
369
int
370
set_baud_rate(baudrate)
371
     int baudrate;
372
{
373
  /* Convert baud rate to uart clock divider */
374
  switch (baudrate)
375
    {
376
    case 38400:
377
      baudrate = 16;
378
      break;
379
    case 19200:
380
      baudrate = 33;
381
      break;
382
    case 9600:
383
      baudrate = 65;
384
      break;
385
    default:
386
      return -1;
387
    }
388
 
389
  set_timer_3(baudrate);        /* Set it */
390
}
391
#endif

powered by: WebSVN 2.1.0

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