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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [libgloss/] [sparc/] [salib.c] - Diff between revs 158 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

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

powered by: WebSVN 2.1.0

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