diff options
author | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
---|---|---|
committer | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
commit | 03261851a10dd2d6900a0a00a7515a0a46fb5d76 (patch) | |
tree | 7c22ac6cbbc99fd5cd1b5426853be8d4fd7bfcf1 /libgloss/sparc/salib.c | |
parent | fae4c299f14fc23e2829c8656992eba21f79242a (diff) | |
download | cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.gz cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.bz2 cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.zip |
20000317 sourceware import
Diffstat (limited to 'libgloss/sparc/salib.c')
-rw-r--r-- | libgloss/sparc/salib.c | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/libgloss/sparc/salib.c b/libgloss/sparc/salib.c new file mode 100644 index 000000000..8076a6b31 --- /dev/null +++ b/libgloss/sparc/salib.c @@ -0,0 +1,388 @@ +/* Stand-alone library for SPARClite + * + * Copyright (c) 1995 Cygnus Support + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "sparclite.h" +#include "asm.h" + +/* LED blinking pattern can be changed by modifying __led_algorithm. */ + +enum ledtype +{ + led_marching, /* marching pattern, only one led on at a time */ + led_random, /* pseudo-random pattern */ + led_blinking, /* all leds blink on and off */ + led_none /* leds off all the time */ +}; + +enum ledtype __led_algorithm = led_marching; + + +/* Pointer to hook for outbyte, set by stub's exception handler. */ +void (*__outbyte_hook) (int c); + +#ifdef SL931 +#define SDTR_BASE 0x200 +#define SDTR_ASI 1 +#define SDTR_SHIFT 0 +#else +#define SDTR_BASE 0x10000000 +#define SDTR_ASI 4 +#define SDTR_SHIFT 16 +#endif + +#define get_uart_status(PORT) \ + (read_asi (SDTR_ASI, SDTR_BASE + 0x24 + (PORT) * 0x10) >> SDTR_SHIFT) + +#define xmt_char(PORT, C) \ + write_asi (SDTR_ASI, SDTR_BASE + 0x20 + (PORT) * 0x10, (C) << SDTR_SHIFT) + +#define rcv_char(PORT) \ + (read_asi (SDTR_ASI, SDTR_BASE + 0x20 + (PORT) * 0x10) >> SDTR_SHIFT) + +void putDebugChar(); + +#if 0 +void +set_uart (cmd) + int cmd; +{ + write_asi (SDTR_ASI, SDTR_BASE + 0x24, cmd << SDTR_SHIFT); +} + +void +set_timer_3 (val) + int val; +{ + write_asi (SDTR_ASI, SDTR_BASE + 0x78, val << SDTR_SHIFT); +} +#endif + + +asm(" + .text + .align 4 + +! Register window overflow handler. Come here when save would move us +! into the invalid window. This routine runs with traps disabled, and +! must be careful not to touch the condition codes, as PSR is never +! restored. +! +! We are called with %l0 = wim, %l1 = pc, %l2 = npc + + .globl " STRINGSYM(win_ovf) " +" STRINGSYM(win_ovf) ": + mov %g1, %l3 ! Save g1, we use it to hold the wim + srl %l0, 1, %g1 ! Rotate wim right + sll %l0, __WINSIZE-1, %l0 + or %l0, %g1, %g1 + + save %g0, %g0, %g0 ! Slip into next window + mov %g1, %wim ! Install the new wim + + std %l0, [%sp + 0 * 4] ! save L & I registers + std %l2, [%sp + 2 * 4] + std %l4, [%sp + 4 * 4] + std %l6, [%sp + 6 * 4] + + std %i0, [%sp + 8 * 4] + std %i2, [%sp + 10 * 4] + std %i4, [%sp + 12 * 4] + std %i6, [%sp + 14 * 4] + + restore ! Go back to trap window. + mov %l3, %g1 ! Restore %g1 + + jmpl %l1, %g0 + rett %l2 + +! Register window underflow handler. Come here when restore would move us +! into the invalid window. This routine runs with traps disabled, and +! must be careful not to touch the condition codes, as PSR is never +! restored. +! +! We are called with %l0 = wim, %l1 = pc, %l2 = npc + + .globl " STRINGSYM(win_unf) " +" STRINGSYM(win_unf) ": + sll %l0, 1, %l3 ! Rotate wim left + srl %l0, __WINSIZE-1, %l0 + or %l0, %l3, %l0 + + mov %l0, %wim ! Install the new wim + + restore ! User's window + restore ! His caller's window + + ldd [%sp + 0 * 4], %l0 ! restore L & I registers + ldd [%sp + 2 * 4], %l2 + ldd [%sp + 4 * 4], %l4 + ldd [%sp + 6 * 4], %l6 + + ldd [%sp + 8 * 4], %i0 + ldd [%sp + 10 * 4], %i2 + ldd [%sp + 12 * 4], %i4 + ldd [%sp + 14 * 4], %i6 + + save %g0, %g0, %g0 ! Back to trap window + save %g0, %g0, %g0 + + jmpl %l1, %g0 + rett %l2 + +! Read the TBR. + + .globl " STRINGSYM(rdtbr) " +" STRINGSYM(rdtbr) ": + retl + mov %tbr, %o0 + +"); + +extern unsigned long rdtbr(); + +void +die(val) + int val; +{ + static unsigned char *leds = (unsigned char *)0x02000003; + + *leds = val; + + while (1) ; +} + +/* Each entry in the trap vector occupies four words. */ + +struct trap_entry +{ + unsigned sethi_filler:10; + unsigned sethi_imm22:22; + unsigned jmpl_filler:19; + unsigned jmpl_simm13:13; + unsigned long filler[2]; +}; + +extern struct trap_entry fltr_proto; +asm (" + .data + .globl " STRINGSYM(fltr_proto) " + .align 4 +" STRINGSYM(fltr_proto) ": ! First level trap routine prototype + sethi 0, %l0 + jmpl 0+%l0, %g0 + nop + nop + + .text + .align 4 +"); + +/* Setup trap TT to go to ROUTINE. If TT is between 0 and 255 inclusive, the + normal trap vector will be used. If TT is 256, then it's for the SPARClite + DSU, and that always vectors off to 255 unrelocated. +*/ + +void +exceptionHandler (tt, routine) + int tt; + unsigned long routine; +{ + struct trap_entry *tb; /* Trap vector base address */ + + if (tt != 256) + tb = (struct trap_entry *) (rdtbr() & ~0xfff); + else + { + tt = 255; + tb = (struct trap_entry *) 0; + } + + tb[tt] = fltr_proto; + + tb[tt].sethi_imm22 = routine >> 10; + tb[tt].jmpl_simm13 = routine & 0x3ff; +} + +void +update_leds() +{ + static unsigned char *leds = (unsigned char *)0x02000003; + static enum ledtype prev_algorithm = led_none; + + if (prev_algorithm != __led_algorithm) + { + *leds = 0xff; /* turn the LEDs off */ + prev_algorithm = __led_algorithm; + } + + switch (__led_algorithm) + { + case led_marching: + { + static unsigned char curled = 1; + static unsigned char dir = 0; + + *leds = ~curled; + + if (dir) + curled <<= 1; + else + curled >>= 1; + + if (curled == 0) + { + if (dir) + curled = 0x80; + else + curled = 1; + dir = ~dir; + } + break; + } + + case led_random: + { + static unsigned int next = 0; + *leds = next & 0xff; + next = (next * 1103515245 + 12345) & 0x7fff; + break; + } + + case led_blinking: + { + static unsigned char next = 0; + *leds = next; + next = ~next; + break; + } + + default: + break; + } +} + + /* 1/5th of a second? */ + +#define LEDTIME (20000000 / 500) + +unsigned long ledtime = LEDTIME; + +int +inbyte() +{ + return (getDebugChar()); +} + +int +getDebugChar() +{ + unsigned long countdown = ledtime; + + update_leds(); + + while (1) + { + if ((get_uart_status(0) & 2) != 0) break; + + if (countdown-- == 0) + { + countdown = ledtime; + update_leds(); + } + } + + return rcv_char(0); +} + +/* Output one character to the serial port */ +void +outbyte(c) + int c; +{ + if (__outbyte_hook) + __outbyte_hook (c); + else + putDebugChar(c); +} + +void +putDebugChar(c) + int c; +{ + update_leds(); + + while ((get_uart_status(0) & 1) == 0) ; + + xmt_char(0, c); +} + +#if 0 +int +write(fd, data, length) + int fd; + unsigned char *data; + int length; +{ + int olength = length; + + while (length--) + putDebugChar(*data++); + + return olength; +} + +int +read(fd, data, length) + int fd; + unsigned char *data; + int length; +{ + int olength = length; + int c; + + while (length--) + *data++ = getDebugChar(); + + return olength; +} +#endif + +/* Set the baud rate for the serial port, returns 0 for success, + -1 otherwise */ + +#if 0 +int +set_baud_rate(baudrate) + int baudrate; +{ + /* Convert baud rate to uart clock divider */ + switch (baudrate) + { + case 38400: + baudrate = 16; + break; + case 19200: + baudrate = 33; + break; + case 9600: + baudrate = 65; + break; + default: + return -1; + } + + set_timer_3(baudrate); /* Set it */ +} +#endif |