Files
TZFS/zOS/MZ2000/common/syscalls.c.old

524 lines
11 KiB
C
Vendored

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "zpu-types.h"
#include "zpu_soc.h"
//#include "uart.h"
#include "spi.h"
#include "fat.h"
#include "rafile.h"
#include "malloc.h"
#include "fileio.h"
#include "xprintf.h"
//#include "small_printf.h"
#define DISABLE_FILESYSTEM 1
#define SYS_ftruncate 3000
#define SYS_isatty 3001
/* Set to 1 if we are running on hardware. The config instruction is
* always emulated on the simulator. The emulation code pokes this
* variable to 1.
*/
extern int _hardware;
/* _cpu_config==0 => Abel
* _cpu_config==1 => Zeta
* _cpu_config==2 => Phi
*/
extern int _cpu_config;
extern int main(int argc, char **argv);
static char *args[]={"dummy.exe"};
// File table
#define MAX_FILES 8
static RAFile *Files[MAX_FILES];
#define File(x) Files[(x)-2]
// FIXME - bring these in.
extern void _init(void);
// Hardware initialisation
// Sets up RS232 baud rate and attempts to initialise the SD card, if present.
static int sdcard_present;
uint32_t sdcard_id;
static int filesystem_present;
static int _init_sd()
{
filesystem_present=0;
#ifdef DISABLE_FILESYSTEM
xprintf("Filesystem disabled\n");
#else
if(spi_init(SPI0))
{
sdcard_present = 1;
sdcard_id = SPI0;
}
else if(spi_init(SPI1))
{
sdcard_present = 1;
sdcard_id = SPI1;
}
else if(spi_init(SPI2))
{
sdcard_present = 1;
sdcard_id = SPI2;
}
else if(spi_init(SPI3))
{
sdcard_present = 1;
sdcard_id = SPI3;
}
else
xprintf("No SD card found\n");
if(sdcard_present)
{
xprintf("SD card %d successfully initialised\n", sdcard_id);
filesystem_present=FindDrive();
}
#endif
return(filesystem_present);
}
static void _initIO(void)
{
// HW_PER(PER_UART_CLKDIV)=1250000/1152;
_init_sd();
}
extern char _end; // Defined by the linker script
extern char *heap_ptr;
int _stack;
extern int __bss_start__;
extern int __bss_end__;
extern int __ctors_start__;
extern int __ctors_end__;
extern int __dtors_start__;
extern int __dtors_end__;
// Identify RAM size by searching for aliases - up to a maximum of 64 megabytes
#define ADDRCHECKWORD 0x55aa44bb
#define ADDRCHECKWORD2 0xf0e1d2c3
static unsigned int addresscheck(volatile int *base,int cachesize)
{
int i,j,k;
int a1,a2;
int aliases=0;
unsigned int size=64;
// Seed the RAM;
a1=19;
*base=ADDRCHECKWORD;
for(j=18;j<25;++j)
{
base[a1]=ADDRCHECKWORD;
a1<<=1;
}
// If we have a cache we need to flush it here.
// Now check for aliases
a1=1;
*base=ADDRCHECKWORD2;
for(j=1;j<25;++j)
{
if(base[a1]==ADDRCHECKWORD2)
aliases|=a1;
a1<<=1;
}
aliases<<=2;
while(aliases)
{
aliases=(aliases<<1)&0x3ffffff; // Test currently supports up to 16m longwords = 64 megabytes.
size>>=1;
}
xprintf("SDRAM size (assuming no address faults) is 0x%d megabytes\n",size);
return(size*(1<<20));
}
void _break();
void __attribute__ ((weak)) _premain()
{
int t;
int *ctors;
char *ramtop;
// Clear BSS data
int *bss=&__bss_start__;
while(bss<&__bss_end__)
*bss++=0;
_initIO();
xprintf("Initialising files\n");
for(t=0;t<MAX_FILES;++t)
Files[t]=0;
// xprintf("_end is %d, RAMTOP is %d\n",&_end,RAMTOP);
// malloc_add(&_end,(char *)RAMTOP-&_end); // Add the entire RAM to the free memory pool
ramtop=(char *)addresscheck((volatile int *)&_end,0);
malloc_add(&_end,ramtop-&_end); // Add the entire RAM to the free memory pool
// _init();
// Run global constructors...
ctors=&__ctors_start__;
xprintf("Running global constructors");
while(ctors<&__ctors_end__)
{
xprintf(".");
void (*fp)();
fp=(void (*)())(*ctors);
fp();
++ctors;
}
xprintf("\n");
t=main(1, args);
// Run global destructors...
ctors=&__dtors_start__;
while(ctors<&__dtors_end__)
{
void (*fp)();
fp=(void (*)())(*ctors);
fp();
++ctors;
}
_exit(t);
}
// Re-implement sbrk, since the libgloss version doesn't know about our memory map.
char *_sbrk(int nbytes)
{
// Since we add the entire memory in _premain() we can skip this.
xprintf("Custom sbrk asking for %d bytes\n",nbytes);
return(0);
#if 0
char *base;
if (!heap_ptr)
heap_ptr = (char *)&_end;
base = heap_ptr;
heap_ptr += nbytes;
if ((int)heap_ptr>RAMTOP)
return (char *)-1;
return base;
#endif
}
//char *sbrk(int nbytes)
//{
// return(_sbrk(nbytes));
//}
/* NOTE!!!! compiled with -fomit-frame-pointer to make sure that 'status' has the
* correct value when breakpointing at _exit
*/
void __attribute__ ((weak)) _exit (int status)
{
/* end of the universe, cause memory fault */
__asm("breakpoint");
for(;;);
// _break();
}
void __attribute__ ((weak)) _zpu_interrupt(void)
{
/* not implemented in libgloss */
// __asm("breakpoint");
for (;;);
}
// Rudimentary filesystem support
int __attribute__ ((weak))
_DEFUN (write, (fd, buf, nbytes),
int fd _AND
char *buf _AND
int nbytes)
{
if((fd==1) || (fd==2)) // stdout/stderr
{
int c=nbytes;
// Write to UART
// FIXME - need to save any received bytes in a ring buffer.
// FIXME - ultimately need to use interrupts here.
while(nbytes--)
{
putchar(*buf++);
//while(!(HW_UART(REG_UART)&(1<<REG_UART_TXREADY)))
// ;
//HW_UART(REG_UART)=*buf++;
}
return(nbytes);
}
else
{
if(File(fd))
{
// We have a file - but we don't yet support writing.
errno=EACCES;
}
errno=EBADF;
}
return (nbytes);
}
/*
* read -- read bytes from the serial port if fd==0, otherwise try and read from SD card
int __attribute__ ((weak))
_DEFUN (read, (fd, buf, nbytes),
int fd _AND
char *buf _AND
int nbytes)
{
xprintf("Reading %d bytes from fd %d\n",nbytes,fd);
if(fd==0) // stdin
{
// Read from UART
while(nbytes--)
{
int in;
//while(!((in=HW_UART(REG_UART))&(1<<REG_UART_RXINT)))
// ;
//*buf++=in&0xff;
*buf++=getserial()&0xff;
}
return(nbytes);
}
else
{
#ifndef DISABLE_FILESYSTEM
// Handle reading from SD card
if(File(fd))
{
if(RARead(File(fd),buf,nbytes))
return(nbytes);
else
{
errno=EIO;
return(-1);
}
}
else
#endif
errno=EBADF;
}
return(0);
}
*/
/*
* open -- open a file descriptor.
int __attribute__ ((weak)) open(const char *buf,
int flags,
...)
{
// FIXME - Take mode from the first varargs argument
xprintf("in open()\n");
if(filesystem_present) // Only support reads at present.
{
#ifndef DISABLE_FILESYSTEM
// Find a free FD
int fd=3;
while((fd-2)<MAX_FILES)
{
if(!File(fd))
{
xprintf("Found spare fd: %d\n",fd);
File(fd)=malloc(sizeof(RAFile));
if(File(fd))
{
if(RAOpen(File(fd),buf))
return(fd);
else
free(File(fd));
errno = ENOENT;
return(-1);
}
}
++fd;
}
#endif
}
else
{
xprintf("open() - no filesystem present\n");
errno = EIO;
}
return (-1);
}
*/
/*
* close
int __attribute__ ((weak))
_DEFUN (close ,(fd),
int fd)
{
if(fd>2 && File(fd))
free(File(fd));
return (0);
}
*/
/*
int __attribute__ ((weak))
ftruncate (int file, off_t length)
{
return -1;
}
*/
/*
* unlink -- we just return an error since we don't support writes yet.
int __attribute__ ((weak))
_DEFUN (unlink, (path),
char * path)
{
errno = EIO;
return (-1);
}
*/
/*
* lseek -- Since a serial port is non-seekable, we return an error.
off_t __attribute__ ((weak))
_DEFUN (lseek, (fd, offset, whence),
int fd _AND
off_t offset _AND
int whence)
{
if(fd<3)
{
errno = ESPIPE;
return ((off_t)-1);
}
else if(File(fd))
{
switch(whence)
{
case SEEK_SET:
case SEEK_CUR:
#ifndef DISABLE_FILESYSTEM
RASeek(File(fd),offset,whence);
#endif
return((off_t)File(fd)->ptr);
break;
case SEEK_END:
errno = EINVAL;
xprintf("SEEK_END not yet supported\n");
return((off_t)-1);
break;
default:
break;
}
}
}
*/
/* we convert from bigendian to smallendian*/
static long conv(char *a, int len)
{
long t=0;
int i;
for (i=0; i<len; i++)
{
t|=(((int)a[i])&0xff)<<((len-1-i)*8);
}
return t;
}
static void convert(struct fio_stat *gdb_stat, struct stat *buf)
{
memset(buf, 0, sizeof(*buf));
buf->st_dev=conv(gdb_stat->fst_dev, sizeof(gdb_stat->fst_dev));
buf->st_ino=conv(gdb_stat->fst_ino, sizeof(gdb_stat->fst_ino));
buf->st_mode=conv(gdb_stat->fst_mode, sizeof(gdb_stat->fst_mode));
buf->st_nlink=conv(gdb_stat->fst_nlink, sizeof(gdb_stat->fst_nlink));
buf->st_uid=conv(gdb_stat->fst_uid, sizeof(gdb_stat->fst_uid));
buf->st_gid=conv(gdb_stat->fst_gid, sizeof(gdb_stat->fst_gid));
buf->st_rdev=conv(gdb_stat->fst_rdev, sizeof(gdb_stat->fst_rdev));
buf->st_size=conv(gdb_stat->fst_size, sizeof(gdb_stat->fst_size));
}
int __attribute__ ((weak))
_DEFUN (fstat, (fd, buf),
int fd _AND
struct stat *buf)
{
/*
* fstat -- Since we have no file system, we just return an error.
*/
memset(buf,0,sizeof(struct stat));
if(fd<3)
{
buf->st_mode = S_IFCHR; /* Always pretend to be a tty */
buf->st_blksize = 0;
}
else if(File(fd))
{
buf->st_size = File(fd)->size;
}
return (0);
}
int __attribute__ ((weak))
_DEFUN (stat, (path, buf),
const char *path _AND
struct stat *buf)
{
errno = EIO;
return (-1);
}
int __attribute__ ((weak))
_DEFUN (isatty, (fd),
int fd)
{
/*
* 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 and return a 1.
*/
return (1);
}