From 48e74f46fc26ce0a4068f2b718eca09501f5d6e2 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 12 Nov 2016 19:20:58 +0100 Subject: [PATCH] Add the very experimental qemuppc plat, intended to generate minimal images which can be emulated using qemu (for, hopefully, a test suite). Currently it generates images which won't run because there's no RAM. --- build.lua | 1 + plat/linuxppc/descr | 3 +- plat/qemuppc/README | 42 ++++++++++ plat/qemuppc/boot.s | 74 +++++++++++++++++ plat/qemuppc/build-pkg.lua | 25 ++++++ plat/qemuppc/build-tools.lua | 33 ++++++++ plat/qemuppc/descr | 89 ++++++++++++++++++++ plat/qemuppc/include/ack/config.h | 14 ++++ plat/qemuppc/include/build.lua | 24 ++++++ plat/qemuppc/include/sys/ioctl.h | 76 +++++++++++++++++ plat/qemuppc/include/unistd.h | 123 ++++++++++++++++++++++++++++ plat/qemuppc/libsys/_hol0.s | 20 +++++ plat/qemuppc/libsys/_sys_rawread.s | 19 +++++ plat/qemuppc/libsys/_sys_rawwrite.s | 20 +++++ plat/qemuppc/libsys/brk.c | 43 ++++++++++ plat/qemuppc/libsys/build.lua | 16 ++++ plat/qemuppc/libsys/close.c | 14 ++++ plat/qemuppc/libsys/creat.c | 15 ++++ plat/qemuppc/libsys/getpid.c | 13 +++ plat/qemuppc/libsys/isatty.c | 8 ++ plat/qemuppc/libsys/kill.c | 14 ++++ plat/qemuppc/libsys/libsys.h | 11 +++ plat/qemuppc/libsys/lseek.c | 14 ++++ plat/qemuppc/libsys/open.c | 14 ++++ plat/qemuppc/libsys/read.c | 38 +++++++++ plat/qemuppc/libsys/signal.c | 15 ++++ plat/qemuppc/libsys/time.c | 17 ++++ plat/qemuppc/libsys/trap.s | 105 ++++++++++++++++++++++++ plat/qemuppc/libsys/write.c | 48 +++++++++++ 29 files changed, 946 insertions(+), 2 deletions(-) create mode 100644 plat/qemuppc/README create mode 100644 plat/qemuppc/boot.s create mode 100644 plat/qemuppc/build-pkg.lua create mode 100644 plat/qemuppc/build-tools.lua create mode 100644 plat/qemuppc/descr create mode 100644 plat/qemuppc/include/ack/config.h create mode 100644 plat/qemuppc/include/build.lua create mode 100644 plat/qemuppc/include/sys/ioctl.h create mode 100644 plat/qemuppc/include/unistd.h create mode 100644 plat/qemuppc/libsys/_hol0.s create mode 100644 plat/qemuppc/libsys/_sys_rawread.s create mode 100644 plat/qemuppc/libsys/_sys_rawwrite.s create mode 100644 plat/qemuppc/libsys/brk.c create mode 100644 plat/qemuppc/libsys/build.lua create mode 100644 plat/qemuppc/libsys/close.c create mode 100644 plat/qemuppc/libsys/creat.c create mode 100644 plat/qemuppc/libsys/getpid.c create mode 100644 plat/qemuppc/libsys/isatty.c create mode 100644 plat/qemuppc/libsys/kill.c create mode 100644 plat/qemuppc/libsys/libsys.h create mode 100644 plat/qemuppc/libsys/lseek.c create mode 100644 plat/qemuppc/libsys/open.c create mode 100644 plat/qemuppc/libsys/read.c create mode 100644 plat/qemuppc/libsys/signal.c create mode 100644 plat/qemuppc/libsys/time.c create mode 100644 plat/qemuppc/libsys/trap.s create mode 100644 plat/qemuppc/libsys/write.c diff --git a/build.lua b/build.lua index 05a4eafcd..fd8582fd9 100644 --- a/build.lua +++ b/build.lua @@ -9,6 +9,7 @@ vars.plats = { "linux386", "linux68k", "linuxppc", + "qemuppc", "pc86", "rpi", } diff --git a/plat/linuxppc/descr b/plat/linuxppc/descr index 79188640a..12bece6e9 100644 --- a/plat/linuxppc/descr +++ b/plat/linuxppc/descr @@ -33,8 +33,7 @@ var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi name be from .m.g to .s - # Change this back to ncg to revert to the old code generator - program {EM}/lib/ack/{PLATFORM}/mcg + program {EM}/lib/ack/{PLATFORM}/ncg mapflag -gdb GF=-gdb args {GF?} < stdout diff --git a/plat/qemuppc/README b/plat/qemuppc/README new file mode 100644 index 000000000..412e33ad1 --- /dev/null +++ b/plat/qemuppc/README @@ -0,0 +1,42 @@ +# $Source: /cvsroot/tack/Ack/plat/linux386/README,v $ +# $State: Exp $ +# $Revision: 1.2 $ + + +The linux386 platform +===================== + +linux386 is an i386-based BSP that produces Linux ELF executables. + +This port only implements a very limited number of system calls; basically, +just enough to make the demo apps run. Adding more is easy, but there are some +subtleties that require more thought. The port should be considered only in +proof-of-concept stage right now. + +Important note: you *can't* link access ELF shared libraries from these +executables. In other words, you have to all your work from inside ACK. + +IEEE floating point is available, but requires an FPU. + +The executables are generated with aelfslod and are extremely simple; there's +one rwx ELF section which contains all the application's code and data. This +is not optimal, but it does work. + + +Bugs +==== + +isatty() is a stub and always returns 0. + + +Example command line +==================== + +ack -mlinux386 -O -o linux386.exe examples/paranoia.c + +The file linux386.exe can then be run on a i386 Linux machine (or on an +emulation thereof). + + +David Given +dg@cowlark.com diff --git a/plat/qemuppc/boot.s b/plat/qemuppc/boot.s new file mode 100644 index 000000000..dbd61ec1b --- /dev/null +++ b/plat/qemuppc/boot.s @@ -0,0 +1,74 @@ +# +! $Source: /cvsroot/tack/Ack/plat/linux386/boot.s,v $ +! $State: Exp $ +! $Revision: 1.3 $ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +begtext: + ! This code is placed at the beginning of the ELF executable and is the + ! first thing that runs. + ! + ! On entry, the stack looks like this: + ! + ! sp+... NULL + ! sp+8+(4*argc) env (X quads) + ! sp+4+(4*argc) NULL + ! sp+4 argv (argc quads) + ! sp argc + ! + ! The ACK actually expects: + ! + ! sp+8 argc + ! sp+4 ptr to argv + ! sp ptr to env + + li32 r3, envp + stwu r3, -4(sp) + + li32 r3, argv + stwu r3, -4(sp) + + li32 r3, 1 ! argc + stwu r3, -4(sp) + + bl __m_a_i_n + ! falls through + +.define __exit +.extern __exit +.define EXIT +.extern EXIT +__exit: +EXIT: + b EXIT + +! Define symbols at the beginning of our various segments, so that we can find +! them. (Except .text, which has already been done.) + +.sect .data; begdata: +.sect .rom; begrom: +.sect .bss; begbss: + +! Some magic data. All EM systems need these. + +.define _errno +.comm _errno, 4 ! Posix errno storage + +! The argv and env arrays. + +.sect .rom +argv: .data4 exename, 0 +envp: .data4 0 +exename: .asciz 'qemuppc.img' + +.define .trppc, .ignmask +.comm .trppc, 4 ! ptr to user trap handler +.comm .ignmask, 4 ! user trap ignore mask diff --git a/plat/qemuppc/build-pkg.lua b/plat/qemuppc/build-pkg.lua new file mode 100644 index 000000000..e30e83efc --- /dev/null +++ b/plat/qemuppc/build-pkg.lua @@ -0,0 +1,25 @@ +include("plat/build.lua") + +ackfile { + name = "boot", + srcs = { "./boot.s" }, + vars = { plat = "qemuppc" } +} + +build_plat_libs { + name = "libs", + arch = "powerpc", + plat = "qemuppc", +} + +installable { + name = "pkg", + map = { + "+tools", + "+libs", + "./include+pkg", + ["$(PLATIND)/qemuppc/boot.o"] = "+boot", + ["$(PLATIND)/qemuppc/libsys.a"] = "./libsys+lib", + } +} + diff --git a/plat/qemuppc/build-tools.lua b/plat/qemuppc/build-tools.lua new file mode 100644 index 000000000..e4f3f534b --- /dev/null +++ b/plat/qemuppc/build-tools.lua @@ -0,0 +1,33 @@ +include("plat/build.lua") + +build_as { + name = "as", + arch = "powerpc", +} + +build_mcg { + name = "mcg", + arch = "powerpc", +} + +build_ncg { + name = "ncg", + arch = "powerpc", +} + +build_top { + name = "top", + arch = "powerpc", +} + +return installable { + name = "tools", + map = { + ["$(PLATDEP)/qemuppc/as"] = "+as", + ["$(PLATDEP)/qemuppc/ncg"] = "+ncg", + ["$(PLATDEP)/qemuppc/mcg"] = "+mcg", + ["$(PLATDEP)/qemuppc/top"] = "+top", + ["$(PLATIND)/descr/qemuppc"] = "./descr", + "util/opt+pkg", + } +} diff --git a/plat/qemuppc/descr b/plat/qemuppc/descr new file mode 100644 index 000000000..f28e7482d --- /dev/null +++ b/plat/qemuppc/descr @@ -0,0 +1,89 @@ +# plat/linuxppc/descr + +var w=4 +var wa=4 +var p={w} +var pa={w} +var s=2 +var sa={s} +var l={w} +var la={w} +var f={w} +var fa={w} +var d=8 +var da={d} +var x=8 +var xa={x} +var ARCH=powerpc +var PLATFORM=qemuppc +var PLATFORMDIR={EM}/share/ack/{PLATFORM} +var CPP_F=-D__unix +var ALIGN=-a0:4 -a1:4 -a2:4 -a3:4 -b0:0x01000000 +var C_LIB={PLATFORMDIR}/libc-ansi.a +# bitfields reversed for compatibility with (g)cc. +var CC_ALIGN=-Vr +var OLD_C_LIB={C_LIB} +var MACHOPT_F= + +# Override the setting in fe so that files compiled for qemuppc can see +# the platform-specific headers. + +var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi + +name be + from .m.g + to .s + # Change this back to ncg to revert to the old code generator + program {EM}/lib/ack/{PLATFORM}/ncg + mapflag -gdb GF=-gdb + args {GF?} < + stdout + need .e +end +name asopt + from .s + to .so + program {EM}/lib/ack/{PLATFORM}/top + args + optimizer + stdin + stdout +end +name as + from .s.so + to .o + program {EM}/lib/ack/{PLATFORM}/as + args - -o > < + prep cond +end +name led + from .o.a + to .out + program {EM}/lib/ack/em_led + mapflag -l* LNAME={PLATFORMDIR}/lib* + mapflag -fp FLOATS={EM}/{LIB}fp + args {ALIGN} {SEPID?} \ + (.e:{HEAD}={PLATFORMDIR}/boot.o) \ + ({RTS}:.ocm.b={PLATFORMDIR}/c-ansi.o) \ + ({RTS}:.c={PLATFORMDIR}/c-ansi.o) \ + ({RTS}:.mod={PLATFORMDIR}/modula2.o) \ + ({RTS}:.p={PLATFORMDIR}/pascal.o) \ + -o > < \ + (.p:{TAIL}={PLATFORMDIR}/libpascal.a) \ + (.b:{TAIL}={PLATFORMDIR}/libbasic.a) \ + (.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \ + (.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \ + (.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \ + {FLOATS?} \ + (.e:{TAIL}={PLATFORMDIR}/libem.a \ + {PLATFORMDIR}/libsys.a \ + {PLATFORMDIR}/libend.a) + linker +end +name cv + from .out + to .exe + program {EM}/bin/aslod + args < > + outfile qemuppc.img +end diff --git a/plat/qemuppc/include/ack/config.h b/plat/qemuppc/include/ack/config.h new file mode 100644 index 000000000..f58ee3a43 --- /dev/null +++ b/plat/qemuppc/include/ack/config.h @@ -0,0 +1,14 @@ +/* $Source: /cvsroot/tack/Ack/plat/linux386/include/ack/config.h,v $ + * $State: Exp $ + * $Revision: 1.1 $ + */ + +#ifndef _ACK_CONFIG_H +#define _ACK_CONFIG_H + +/* We're providing a time() system call rather than wanting a wrapper around + * gettimeofday() in the libc. */ + +#define ACKCONF_TIME_IS_A_SYSCALL + +#endif diff --git a/plat/qemuppc/include/build.lua b/plat/qemuppc/include/build.lua new file mode 100644 index 000000000..dc1b0bb43 --- /dev/null +++ b/plat/qemuppc/include/build.lua @@ -0,0 +1,24 @@ +include("plat/build.lua") + +headermap = {} +packagemap = {} + +local function addheader(h) + headermap[h] = "./"..h + packagemap["$(PLATIND)/qemuppc/include/"..h] = "./"..h +end + +addheader("ack/config.h") +addheader("sys/ioctl.h") +addheader("unistd.h") + +acklibrary { + name = "headers", + hdrs = headermap +} + +installable { + name = "pkg", + map = packagemap +} + diff --git a/plat/qemuppc/include/sys/ioctl.h b/plat/qemuppc/include/sys/ioctl.h new file mode 100644 index 000000000..af41165d7 --- /dev/null +++ b/plat/qemuppc/include/sys/ioctl.h @@ -0,0 +1,76 @@ +/* $Source: /cvsroot/tack/Ack/plat/linux386/include/sys/ioctl.h,v $ + * $State: Exp $ + * $Revision: 1.1 $ + */ + +#ifndef _SYS_IOCTL_H +#define _SYS_IOCTL_H + +/* These are copied from the ioctl_list(2) man page. */ + +/* */ + +#define FIOSETOWN 0x00008901 +#define SIOCSPGRP 0x00008902 +#define FIOGETOWN 0x00008903 +#define SIOCGPGRP 0x00008904 +#define SIOCATMARK 0x00008905 +#define SIOCGSTAMP 0x00008906 + +/* */ + +#define TCGETS 0x00005401 +#define TCSETS 0x00005402 +#define TCSETSW 0x00005403 +#define TCSETSF 0x00005404 +#define TCGETA 0x00005405 +#define TCSETA 0x00005406 +#define TCSETAW 0x00005407 +#define TCSETAF 0x00005408 +#define TCSBRK 0x00005409 +#define TCXONC 0x0000540A +#define TCFLSH 0x0000540B +#define TIOCEXCL 0x0000540C +#define TIOCNXCL 0x0000540D +#define TIOCSCTTY 0x0000540E +#define TIOCGPGRP 0x0000540F +#define TIOCSPGRP 0x00005410 +#define TIOCOUTQ 0x00005411 +#define TIOCSTI 0x00005412 +#define TIOCGWINSZ 0x00005413 +#define TIOCSWINSZ 0x00005414 +#define TIOCMGET 0x00005415 +#define TIOCMBIS 0x00005416 +#define TIOCMBIC 0x00005417 +#define TIOCMSET 0x00005418 +#define TIOCGSOFTCAR 0x00005419 +#define TIOCSSOFTCAR 0x0000541A +#define FIONREAD 0x0000541B +#define TIOCINQ 0x0000541B +#define TIOCLINUX 0x0000541C +#define TIOCCONS 0x0000541D +#define TIOCGSERIAL 0x0000541E +#define TIOCSSERIAL 0x0000541F +#define TIOCPKT 0x00005420 +#define FIONBIO 0x00005421 +#define TIOCNOTTY 0x00005422 +#define TIOCSETD 0x00005423 +#define TIOCGETD 0x00005424 +#define TCSBRKP 0x00005425 +#define TIOCTTYGSTRUCT 0x00005426 +#define FIONCLEX 0x00005450 +#define FIOCLEX 0x00005451 +#define FIOASYNC 0x00005452 +#define TIOCSERCONFIG 0x00005453 +#define TIOCSERGWILD 0x00005454 +#define TIOCSERSWILD 0x00005455 +#define TIOCGLCKTRMIOS 0x00005456 +#define TIOCSLCKTRMIOS 0x00005457 +#define TIOCSERGSTRUCT 0x00005458 +#define TIOCSERGETLSR 0x00005459 +#define TIOCSERGETMULTI 0x0000545A +#define TIOCSERSETMULTI 0x0000545B + + + +#endif diff --git a/plat/qemuppc/include/unistd.h b/plat/qemuppc/include/unistd.h new file mode 100644 index 000000000..5cbdc1b5d --- /dev/null +++ b/plat/qemuppc/include/unistd.h @@ -0,0 +1,123 @@ +/* + * unistd.h - standard system calls + */ +/* $Id$ */ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#include +#include + +/* Types */ + +typedef int pid_t; +typedef int mode_t; + +typedef long suseconds_t; + +/* Time handling. */ + +struct timeval +{ + time_t tv_sec; + suseconds_t tv_usec; +}; + +struct timezone +{ + int tz_minuteswest; + int tz_dsttime; +}; /* obsolete, unused */ + +extern int gettimeofday(struct timeval* tv, struct timezone* tz); +extern int settimeofday(const struct timeval* tv, const struct timezone* tz); + +/* File access. */ + +enum +{ + O_ACCMODE = 0x3, + + O_RDONLY = 0, + O_WRONLY = 1, + O_RDWR = 2, + + O_CREAT = 0x10, + O_TRUNC = 0x20, + O_APPEND = 0x40 +}; + +extern int open(const char* path, int access, ...); +extern int creat(const char* path, mode_t mode); +extern int close(int d); +extern int read(int fd, void* buffer, size_t count); +extern int write(int fd, void* buffer, size_t count); +extern off_t lseek(int fildes, off_t offset, int whence); +extern int fcntl(int fd, int op, ...); + +/* Special variables */ + +extern char** environ; + +/* Implemented system calls */ + +extern void _exit(int); +extern pid_t getpid(void); +extern int brk(void* ptr); +extern void* sbrk(intptr_t increment); +extern int isatty(int d); + +/* Signal handling */ + +typedef int sig_atomic_t; + +#define SIG_ERR ((sighandler_t) -1) /* Error return. */ +#define SIG_DFL ((sighandler_t) 0) /* Default action. */ +#define SIG_IGN ((sighandler_t) 1) /* Ignore signal. */ + +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGABRT 6 /* Abort (ANSI). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGBUS 7 /* BUS error (4.2 BSD). */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGSTKFLT 16 /* Stack fault. */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGCHLD 17 /* Child status has changed (POSIX). */ +#define SIGCONT 18 /* Continue (POSIX). */ +#define SIGSTOP 19 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 20 /* Keyboard stop (POSIX). */ +#define SIGTTIN 21 /* Background read from tty (POSIX). */ +#define SIGTTOU 22 /* Background write to tty (POSIX). */ +#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ +#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ +#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ +#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ +#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ +#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ +#define SIGPOLL SIGIO /* Pollable event occurred (System V). */ +#define SIGIO 29 /* I/O now possible (4.2 BSD). */ +#define SIGPWR 30 /* Power failure restart (System V). */ +#define SIGSYS 31 /* Bad system call. */ +#define SIGUNUSED 31 + +#define _NSIG 32 /* Biggest signal number + 1 + (not including real-time signals). */ +typedef void (*sighandler_t)(int); +extern sighandler_t signal(int signum, sighandler_t handler); +extern int raise(int signum); + + + +#endif diff --git a/plat/qemuppc/libsys/_hol0.s b/plat/qemuppc/libsys/_hol0.s new file mode 100644 index 000000000..fcb58727b --- /dev/null +++ b/plat/qemuppc/libsys/_hol0.s @@ -0,0 +1,20 @@ +# +! $Source: /cvsroot/tack/Ack/plat/linux386/libsys/_hol0.s,v $ +! $State: Exp $ +! $Revision: 1.1 $ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! +! This data block is used to store information about the current line number +! and file. + +.define hol0 +.comm hol0, 8 diff --git a/plat/qemuppc/libsys/_sys_rawread.s b/plat/qemuppc/libsys/_sys_rawread.s new file mode 100644 index 000000000..1f2cd9d1f --- /dev/null +++ b/plat/qemuppc/libsys/_sys_rawread.s @@ -0,0 +1,19 @@ +# +#include "powerpc.h" + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! Reads a single byte. + +.define __sys_rawread +__sys_rawread: + li32 r3, 0 + bclr ALWAYS, 0, 0 + \ No newline at end of file diff --git a/plat/qemuppc/libsys/_sys_rawwrite.s b/plat/qemuppc/libsys/_sys_rawwrite.s new file mode 100644 index 000000000..e9a1cc7ec --- /dev/null +++ b/plat/qemuppc/libsys/_sys_rawwrite.s @@ -0,0 +1,20 @@ +# +#include "powerpc.h" + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! Writes a single byte to the console. + +.define __sys_rawwrite +.extern __sys_rawwrite + +__sys_rawwrite: + bclr ALWAYS, 0, 0 + \ No newline at end of file diff --git a/plat/qemuppc/libsys/brk.c b/plat/qemuppc/libsys/brk.c new file mode 100644 index 000000000..02e213399 --- /dev/null +++ b/plat/qemuppc/libsys/brk.c @@ -0,0 +1,43 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +#define OUT_OF_MEMORY (void*)(-1) /* sbrk returns this on failure */ +#define STACK_BUFFER 128 /* number of bytes to leave for stack */ + +extern char _end[1]; +static char* current = _end; + +int brk(void* newend) +{ + /* This variable is used to figure out the current stack pointer, + * by taking its address. */ + char dummy; + char* p = newend; + + if ((p > (&dummy - STACK_BUFFER)) || + (p < _end)) + return -1; + + current = p; + return 0; +} + +void* sbrk(intptr_t increment) +{ + char* old; + + if (increment == 0) + return current; + + old = current; + if (brk(old + increment) < 0) + return OUT_OF_MEMORY; + + return old; +} diff --git a/plat/qemuppc/libsys/build.lua b/plat/qemuppc/libsys/build.lua new file mode 100644 index 000000000..7281bbc61 --- /dev/null +++ b/plat/qemuppc/libsys/build.lua @@ -0,0 +1,16 @@ +acklibrary { + name = "lib", + srcs = { + "./*.s", + "./*.c", + }, + deps = { + "lang/cem/libcc.ansi/headers+headers", + "plat/qemuppc/include+headers", + "mach/powerpc/libem+headers_qemuppc", + }, + vars = { + plat = "qemuppc" + } +} + \ No newline at end of file diff --git a/plat/qemuppc/libsys/close.c b/plat/qemuppc/libsys/close.c new file mode 100644 index 000000000..1c570029b --- /dev/null +++ b/plat/qemuppc/libsys/close.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +int close(int fd) +{ + errno = EBADF; + return -1; +} diff --git a/plat/qemuppc/libsys/creat.c b/plat/qemuppc/libsys/creat.c new file mode 100644 index 000000000..34ace747c --- /dev/null +++ b/plat/qemuppc/libsys/creat.c @@ -0,0 +1,15 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int open(const char* path, int access, ...) +{ + errno = EACCES; + return -1; +} diff --git a/plat/qemuppc/libsys/getpid.c b/plat/qemuppc/libsys/getpid.c new file mode 100644 index 000000000..5e6eb003e --- /dev/null +++ b/plat/qemuppc/libsys/getpid.c @@ -0,0 +1,13 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +pid_t getpid(void) +{ + return 0; +} diff --git a/plat/qemuppc/libsys/isatty.c b/plat/qemuppc/libsys/isatty.c new file mode 100644 index 000000000..8bee360e0 --- /dev/null +++ b/plat/qemuppc/libsys/isatty.c @@ -0,0 +1,8 @@ +#include +#include +#include + +int isatty(int fd) +{ + return 1; +} diff --git a/plat/qemuppc/libsys/kill.c b/plat/qemuppc/libsys/kill.c new file mode 100644 index 000000000..4a179c47c --- /dev/null +++ b/plat/qemuppc/libsys/kill.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +int kill(pid_t pid, int sig) +{ + errno = EINVAL; + return -1; +} diff --git a/plat/qemuppc/libsys/libsys.h b/plat/qemuppc/libsys/libsys.h new file mode 100644 index 000000000..d4095cada --- /dev/null +++ b/plat/qemuppc/libsys/libsys.h @@ -0,0 +1,11 @@ +#ifndef LIBSYS_H +#define LIBSYS_H + +extern void _sys_rawwrite(unsigned char b); +extern unsigned char _sys_rawread(void); + +extern void _sys_write_tty(char c); + +/* extern int _sys_ttyflags; */ + +#endif diff --git a/plat/qemuppc/libsys/lseek.c b/plat/qemuppc/libsys/lseek.c new file mode 100644 index 000000000..ecbc4b520 --- /dev/null +++ b/plat/qemuppc/libsys/lseek.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +off_t lseek(int fd, off_t offset, int whence) +{ + errno = EINVAL; + return -1; +} diff --git a/plat/qemuppc/libsys/open.c b/plat/qemuppc/libsys/open.c new file mode 100644 index 000000000..8f18317c5 --- /dev/null +++ b/plat/qemuppc/libsys/open.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int creat(const char* path, int mode) +{ + return open(path, O_CREAT|O_WRONLY|O_TRUNC, mode); +} diff --git a/plat/qemuppc/libsys/read.c b/plat/qemuppc/libsys/read.c new file mode 100644 index 000000000..21fe90ebb --- /dev/null +++ b/plat/qemuppc/libsys/read.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include "libsys.h" + +int read(int fd, void* buffer, size_t count) +{ + char i; + + /* We're only allowed to read from fd 0, 1 or 2. */ + + if ((fd < 0) || (fd > 2)) + { + errno = EBADF; + return -1; + } + + /* Empty buffer? */ + + if (count == 0) + return 0; + + /* Read one byte. */ + + i = _sys_rawread(); +#if 0 + if ((i == '\r') && !(_sys_ttyflags & RAW)) + i = '\n'; + if (_sys_ttyflags & ECHO) + _sys_write_tty(i); +#endif + if (i == '\r') + i = '\n'; + _sys_write_tty(i); + + *(char*)buffer = i; + return 1; +} diff --git a/plat/qemuppc/libsys/signal.c b/plat/qemuppc/libsys/signal.c new file mode 100644 index 000000000..a87b9ced2 --- /dev/null +++ b/plat/qemuppc/libsys/signal.c @@ -0,0 +1,15 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include +#include "libsys.h" + +sighandler_t signal(int signum, sighandler_t handler) +{ + return SIG_DFL; +} diff --git a/plat/qemuppc/libsys/time.c b/plat/qemuppc/libsys/time.c new file mode 100644 index 000000000..5ef17b841 --- /dev/null +++ b/plat/qemuppc/libsys/time.c @@ -0,0 +1,17 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include +#include "libsys.h" + +time_t time(time_t* t) +{ + if (t) + *t = 0; + return 0; +} diff --git a/plat/qemuppc/libsys/trap.s b/plat/qemuppc/libsys/trap.s new file mode 100644 index 000000000..09d3b0b21 --- /dev/null +++ b/plat/qemuppc/libsys/trap.s @@ -0,0 +1,105 @@ +# +! $Source: /cvsroot/tack/Ack/plat/linux386/libsys/_syscall.s,v $ +! $State: Exp $ +! $Revision: 1.1 $ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +#define IFFALSE 4 +#define IFTRUE 12 +#define ALWAYS 20 + +#define LT 0 +#define GT 1 +#define EQ 2 +#define OV 3 + +EARRAY = 0 +ERANGE = 1 +ESET = 2 +EIOVFL = 3 +EFOVFL = 4 +EFUNFL = 5 +EIDIVZ = 6 +EFDIVZ = 7 +EIUND = 8 +EFUND = 9 +ECONV = 10 +ESTACK = 16 +EHEAP = 17 +EILLINS = 18 +EODDZ = 19 +ECASE = 20 +EMEMFLT = 21 +EBADPTR = 22 +EBADPC = 23 +EBADLAE = 24 +EBADMON = 25 +EBADLIN = 26 +EBADGTO = 27 +EUNIMPL = 63 ! unimplemented em-instruction called + +! EM trap handling. + +.define .trap_ecase +.trap_ecase: + addi r3, r0, ECASE + b .trap + +.define .trap_earray +.trap_earray: + addi r3, r0, EARRAY + b .trap + +.define .trap +.trap: + cmpi cr0, 0, r3, 15 ! traps >15 can't be ignored + bc IFTRUE, LT, 1f + + addi r4, r0, 1 + rlwnm r4, r4, r3, 0, 31 ! calculate trap bit + li32 r5, .ignmask + lwz r5, 0(r5) ! load ignore mask + and. r4, r4, r5 ! compare + bclr IFFALSE, EQ, 0 ! return if non-zero + +1: + li32 r4, .trppc + lwz r5, 0(r4) ! load user trap routine + or. r5, r5, r5 ! test + bc IFTRUE, EQ, fatal ! if no user trap routine, bail out + + addi r0, r0, 0 + stw r0, 0(r4) ! reset trap routine + + mfspr r0, lr + stwu r0, -4(sp) ! save old lr + + stwu r3, -4(sp) + mtspr ctr, r5 + bcctrl ALWAYS, 0, 0 ! call trap routine + + lwz r0, 4(sp) ! load old lr again + addi sp, sp, 8 ! retract over stack usage + bclr ALWAYS, 0, 0 ! return + +fatal: + addi r3, r0, 1 + li32 r4, message + addi r5, r0, 6 + addi r0, r0, 4 ! write() + sc 0 + + addi r0, r0, 1 ! exit() + sc 0 + +.sect .rom +message: + .ascii "TRAP!\n" diff --git a/plat/qemuppc/libsys/write.c b/plat/qemuppc/libsys/write.c new file mode 100644 index 000000000..8d2dd0d74 --- /dev/null +++ b/plat/qemuppc/libsys/write.c @@ -0,0 +1,48 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +void _sys_write_tty(char c) +{ + _sys_rawwrite(c); +#if 0 + if ((c == '\n') && !(_sys_ttyflags & RAW)) + _sys_rawwrite('\r'); +#endif + if (c == '\n') + _sys_rawwrite('\r'); +} + +int write(int fd, void* buffer, size_t count) +{ + int i; + char* p = buffer; + + /* We're only allowed to write to fd 0, 1 or 2. */ + + if ((fd < 0) || (fd > 2)) + { + errno = EBADF; + return -1; + } + + /* Write all data. */ + + i = 0; + while (i < count) + { + _sys_write_tty(*p++); + + i++; + } + + /* No failures. */ + + return count; +} -- 2.34.1