339 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			339 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * io.c -- all the code to make GCC and the libraries run on
 | 
						|
 *         a bare target board.
 | 
						|
 */
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <errno.h>
 | 
						|
 | 
						|
#include "hppa-defs.h"
 | 
						|
 | 
						|
extern char *_end;                /* _end is set in the linker command file */
 | 
						|
 | 
						|
/* just in case, most boards have at least some memory */
 | 
						|
#ifndef RAMSIZE
 | 
						|
#  define RAMSIZE             (char *)0x100000
 | 
						|
#endif
 | 
						|
 | 
						|
int
 | 
						|
print(ptr)
 | 
						|
char *ptr;
 | 
						|
{
 | 
						|
  while (*ptr)
 | 
						|
    outbyte (*ptr++);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
putnum (Num)
 | 
						|
unsigned int Num;
 | 
						|
{
 | 
						|
  char	Buffer[9];
 | 
						|
  int	Count;
 | 
						|
  char	*BufPtr = Buffer;
 | 
						|
  int	Digit;
 | 
						|
  
 | 
						|
  for (Count = 7 ; Count >= 0 ; Count--) {
 | 
						|
    Digit = (Num >> (Count * 4)) & 0xf;
 | 
						|
    
 | 
						|
    if (Digit <= 9)
 | 
						|
      *BufPtr++ = (char) ('0' + Digit);
 | 
						|
    else
 | 
						|
      *BufPtr++ = (char) ('a' - 10 + Digit);
 | 
						|
  }
 | 
						|
 | 
						|
  *BufPtr = (char) 0;
 | 
						|
  print (Buffer);
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
delay (x)
 | 
						|
     int x;
 | 
						|
{
 | 
						|
  int  y = 17;
 | 
						|
  while (x-- !=0)
 | 
						|
    y = y^2;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * strobe -- do a zylons thing, toggling each led in sequence forever...
 | 
						|
 */
 | 
						|
int
 | 
						|
zylons()
 | 
						|
{
 | 
						|
  while (1) {
 | 
						|
    strobe();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * strobe -- toggle each led in sequence up and back once.
 | 
						|
 */
 | 
						|
int
 | 
						|
strobe()
 | 
						|
{
 | 
						|
  static unsigned char curled = 1;
 | 
						|
  static unsigned char dir = 0;
 | 
						|
 | 
						|
  curled = 1;
 | 
						|
  dir = 0;
 | 
						|
  while (curled != 0) {
 | 
						|
    led_putnum (curled);
 | 
						|
    delay (70000);
 | 
						|
    if (dir)
 | 
						|
      curled >>= 1;
 | 
						|
    else
 | 
						|
      curled <<= 1;
 | 
						|
    
 | 
						|
    if (curled == 128) {
 | 
						|
      dir = ~dir;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  curled = 1;
 | 
						|
  dir = 0;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * iodc_io_call -- this makes a call into the IODC routine
 | 
						|
 */
 | 
						|
int
 | 
						|
iodc_io_call(ep_address,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11)
 | 
						|
int ep_address, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11;
 | 
						|
{ 
 | 
						|
  int         (*iodc_entry_point)();
 | 
						|
  
 | 
						|
  iodc_entry_point = (int (*)())ep_address;
 | 
						|
 | 
						|
  return ((*iodc_entry_point)(arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11));
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * pdc_call -- this makes a call into the PDC routine
 | 
						|
 */
 | 
						|
int
 | 
						|
pdc_call(arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11)
 | 
						|
     int arg0, arg1, arg2, arg3,  arg4, arg5;
 | 
						|
     int arg6, arg7, arg9, arg10, arg11;
 | 
						|
{
 | 
						|
   return ( CALL_PDC(arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11));
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * put_led -- put a bit pattern on the LED's. 
 | 
						|
 */
 | 
						|
int
 | 
						|
led_putnum (byte)
 | 
						|
     unsigned short byte;
 | 
						|
{
 | 
						|
  return (pdc_call(OPT_PDC_CHASSIS,0,byte));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * outbyte -- shove a byte out the serial port
 | 
						|
 */
 | 
						|
int
 | 
						|
outbyte(byte)
 | 
						|
     unsigned char byte;
 | 
						|
{
 | 
						|
  int status;
 | 
						|
  int R_addr[32];
 | 
						|
  struct _dev *console = (struct _dev *)PGZ_CONSOLE_STRUCT;
 | 
						|
 | 
						|
  status = iodc_io_call(console->iodc_io, console->hpa, IO_CONSOLE_OUTPUT, console->spa,
 | 
						|
			console->layer[0], R_addr, 0, &byte, 1,	0);
 | 
						|
 | 
						|
  switch(status)
 | 
						|
    {
 | 
						|
    case 0:  return(1);
 | 
						|
    default: return (-1);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * inbyte -- get a byte from the serial port
 | 
						|
 */
 | 
						|
unsigned char
 | 
						|
inbyte()
 | 
						|
{
 | 
						|
  int status;
 | 
						|
  int R_addr[32];
 | 
						|
  char inbuf;
 | 
						|
  struct _dev *console = (struct _dev *)PGZ_CONSOLE_STRUCT;
 | 
						|
 | 
						|
  while (status == 0) {
 | 
						|
    status = iodc_io_call(console->iodc_io, console->hpa, IO_CONSOLE_INPUT, console->spa,
 | 
						|
			  console->layer[0], R_addr, 0, &inbuf, 1, 0);
 | 
						|
    
 | 
						|
    switch (status) {
 | 
						|
    case 0:
 | 
						|
    case 2:  					/* recoverable error */
 | 
						|
      if (R_addr[0] != 0) {			/* found a character */
 | 
						|
	return(inbuf);
 | 
						|
      }
 | 
						|
      else
 | 
						|
	break; 					/* error, no character */
 | 
						|
    default: 					/* error, no character */
 | 
						|
      return(0);	
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * read  -- read bytes from the serial port. Ignore fd, since
 | 
						|
 *          we only have stdin.
 | 
						|
 */
 | 
						|
int
 | 
						|
read(fd, buf, nbytes)
 | 
						|
     int fd;
 | 
						|
     char *buf;
 | 
						|
     int nbytes;
 | 
						|
{
 | 
						|
  int i = 0;
 | 
						|
  
 | 
						|
  for (i = 0; i < nbytes; i++) {
 | 
						|
    *(buf + i) = inbyte();
 | 
						|
    if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
 | 
						|
      (*(buf + i)) = 0;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return (i);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * write -- write bytes to the serial port. Ignore fd, since
 | 
						|
 *          stdout and stderr are the same. Since we have no filesystem,
 | 
						|
 *          open will only return an error.
 | 
						|
 */
 | 
						|
int
 | 
						|
write(fd, buf, nbytes)
 | 
						|
     int fd;
 | 
						|
     char *buf;
 | 
						|
     int nbytes;
 | 
						|
{
 | 
						|
  int i;
 | 
						|
 | 
						|
  for (i = 0; i < nbytes; i++) {
 | 
						|
    if (*(buf + i) == '\n') {
 | 
						|
      outbyte ('\r');
 | 
						|
    }
 | 
						|
    outbyte (*(buf + i));
 | 
						|
  }
 | 
						|
  return (nbytes);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * open -- open a file descriptor. We don't have a filesystem, so
 | 
						|
 *         we return an error.
 | 
						|
 */
 | 
						|
int
 | 
						|
open(buf, flags, mode)
 | 
						|
     char *buf;
 | 
						|
     int flags;
 | 
						|
     int mode;
 | 
						|
{
 | 
						|
  errno = EIO;
 | 
						|
  return (-1);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * close -- close a file descriptor. We don't need
 | 
						|
 *          to do anything, but pretend we did.
 | 
						|
 */
 | 
						|
int
 | 
						|
close(fd)
 | 
						|
     int fd;
 | 
						|
{
 | 
						|
  return (0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * sbrk -- changes heap size size. Get nbytes more
 | 
						|
 *         RAM. We just increment a pointer in what's
 | 
						|
 *         left of memory on the board.
 | 
						|
 */
 | 
						|
char *
 | 
						|
sbrk(nbytes)
 | 
						|
     int nbytes;
 | 
						|
{
 | 
						|
  static char * heap_ptr = NULL;
 | 
						|
  char *        base;
 | 
						|
 | 
						|
  if (heap_ptr == NULL) {
 | 
						|
    heap_ptr = (char *)&_end;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((RAMSIZE - heap_ptr) >= 0) {
 | 
						|
    base = heap_ptr;
 | 
						|
    heap_ptr += nbytes;
 | 
						|
    return (heap_ptr);
 | 
						|
  } else {
 | 
						|
    errno = ENOMEM;
 | 
						|
    return ((char *)-1);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * isatty -- returns 1 if connected to a terminal device,
 | 
						|
 *           returns 0 if not. Since we're hooked up to a
 | 
						|
 *           serial port, we'll say yes return a 1.
 | 
						|
 */
 | 
						|
int
 | 
						|
isatty(fd)
 | 
						|
     int fd;
 | 
						|
{
 | 
						|
  return (1);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * lseek -- move read/write pointer. Since a serial port
 | 
						|
 *          is non-seekable, we return an error.
 | 
						|
 */
 | 
						|
off_t
 | 
						|
lseek(fd,  offset, whence)
 | 
						|
     int fd;
 | 
						|
     off_t offset;
 | 
						|
     int whence;
 | 
						|
{
 | 
						|
  errno = ESPIPE;
 | 
						|
  return ((off_t)-1);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * fstat -- get status of a file. Since we have no file
 | 
						|
 *          system, we just return an error.
 | 
						|
 */
 | 
						|
int
 | 
						|
fstat(fd, buf)
 | 
						|
     int fd;
 | 
						|
     struct stat *buf;
 | 
						|
{
 | 
						|
  errno = EIO;
 | 
						|
  return (-1);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * getpid -- only one process, so just return 1.
 | 
						|
 */
 | 
						|
#define __MYPID 1
 | 
						|
int
 | 
						|
getpid()
 | 
						|
{
 | 
						|
  return __MYPID;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * kill -- assume mvme.S, and go out via exit...
 | 
						|
 */
 | 
						|
int
 | 
						|
kill(pid, sig)
 | 
						|
     int pid;
 | 
						|
     int sig;
 | 
						|
{
 | 
						|
  if(pid == __MYPID)
 | 
						|
    _exit(sig);
 | 
						|
  return 0;
 | 
						|
}
 |