newlib/libgloss/arm/redboot-syscalls.c

285 lines
4.3 KiB
C

/*
* redboot-syscalls.c -- provide system call support for RedBoot
*
* Copyright (c) 1997, 2001, 2002 Red Hat, Inc.
*
* 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 <stdlib.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <errno.h>
#include "syscall.h"
// Use "naked" attribute to suppress C prologue/epilogue
static int __attribute__ ((naked)) __syscall(int func_no, ...)
{
asm ("mov r12, lr\n");
#ifdef __thumb__
asm ("swi 0x18\n");
#else
asm ("swi 0x180001\n");
#endif
asm ("mov pc, r12\n");
}
int
_close(int fd)
{
int err;
err = __syscall(SYS_close, fd);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
void
_exit(int stat)
{
while (1)
__syscall(SYS_exit, stat);
}
int
_stat (const char *filename, struct stat *st)
{
int err;
err = __syscall(SYS_stat, filename, st);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
int
_fstat (int file, struct stat *st)
{
int err;
err = __syscall(SYS_fstat, file, st);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
int
_getpid(void)
{
return 1;
}
int
_gettimeofday (void * tp, void * tzp)
{
int err;
err = __syscall(SYS_gettimeofday, tp, tzp);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
int
_isatty(int fd)
{
int err;
err = __syscall(SYS_isatty, fd);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
int
_kill(int pid, int sig)
{
if(pid == 1)
_exit(sig);
return 0;
}
off_t
_lseek(int fd, off_t offset, int whence)
{
int err;
err = __syscall(SYS_lseek, fd, offset, whence);
if (err<0)
{
errno = -err;
return (off_t)-1;
}
return err;
}
int
_open(const char *buf, int flags, int mode)
{
int err ;
err = __syscall(SYS_open, buf, flags, mode);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
int
_write(int fd, const char *buf, int nbytes)
{
int err;
err = __syscall(SYS_write, fd, buf, nbytes);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
void
print(char *ptr)
{
char *p = ptr;
while (*p != '\0')
p++;
_write (1, ptr, p-ptr);
}
void
_raise (void)
{
return;
}
int
_read(int fd, char *buf, int nbytes)
{
int err;
err = __syscall(SYS_read, fd, buf, nbytes);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
extern char end[]; /* end is set in the linker command file */
char *heap_ptr;
char *
_sbrk (int nbytes)
{
char *base;
if (!heap_ptr)
heap_ptr = (char *)&end;
base = heap_ptr;
heap_ptr += nbytes;
return base;
}
clock_t
_times(struct tms * tp)
{
clock_t utime;
int err;
err = __syscall(SYS_times, &utime);
if (err)
utime = 0;
if (tp) {
tp->tms_utime = utime;
tp->tms_stime = 0;
tp->tms_cutime = 0;
tp->tms_cstime = 0;
}
return utime;
}
int
_rename (const char *oldpath, const char *newpath)
{
int err ;
err = __syscall(SYS_rename, oldpath, newpath);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
int
_unlink (const char *pathname)
{
int err ;
err = __syscall(SYS_unlink, pathname);
if (err<0)
{
errno = -err;
return -1;
}
return err;
}
int
_system (const char *command)
{
int err ;
err = __syscall(SYS_system, command);
return err;
}
#define SYS_meminfo 1001
void *
__get_memtop(void)
{
unsigned long totmem = 0, topmem = 0;
int numbanks;
__syscall(SYS_meminfo, (unsigned long)&totmem, (unsigned long)&topmem, 0);
return (void*)topmem;
}