/*
* C4x simulator IO interface routines based on code provided
* by Herman ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
*
* $Id$
*/
#include <stdio.h>
#define SIM_OPEN (0xf0)
#define SIM_CLOSE (0xf1)
#define SIM_READ (0xf2)
#define SIM_WRITE (0xf3)
#define SIM_LSEEK (0xf4)
#define SIM_UNLINK (0xf5)
#define SIM_GETENV (0xf6)
#define SIM_RENAME (0xf7)
#define SIM_GETTIME (0xf8)
#define SIM_GETCLOCK (0xf9)
typedef union _io {
struct _open {
int fd : 16;
int flags : 16;
} open;
struct _openr {
int result : 16;
} openr;
struct _close {
int fd : 16;
} close;
struct _closer {
int result : 16;
} closer;
struct _read {
int fd : 16;
int count : 16;
} read;
struct _readr {
int result : 16;
} readr;
struct _write {
int fd : 16;
int count : 16;
} write;
struct _writer {
int result : 16;
} writer;
struct _lseek {
int fd : 16;
int offsetlow : 16;
int offsethigh : 16;
int orgin : 16;
} lseek;
struct _lseekr {
int result;
} lseekr;
struct _unlinkr {
int result : 16;
} unlinkr;
struct _renamer {
int result : 16;
} renamer;
struct _getenvr {
int result : 16;
} getenvr;
struct _gettimer {
int result;
} gettimer;
struct _getclockr {
int result;
} getclockr;
struct _common {
int word1;
int word2;
} common;
} io;
static void to_sim(int command, io *param, char *data, int length);
static void call_sim(void);
static void from_sim(io *param, char *data);
void sim_exit(void)
{
__asm__(" .global C$$EXIT");
__asm__("C$$EXIT: nop");
__asm__("nop");
}
int sim_open(const char *path, unsigned flags, int fno)
{
io param;
param.open.fd = fno;
param.open.flags = flags;
to_sim(SIM_OPEN,¶m,(char *)path,strlen(path)+1);
call_sim();
from_sim(¶m, NULL);
return param.openr.result;
}
int sim_close(int fno)
{
io param;
param.close.fd = fno;
to_sim(SIM_CLOSE,¶m,NULL,0);
call_sim();
from_sim(¶m, NULL);
return param.closer.result;
}
int sim_read(int fno, char *buf, unsigned count)
{
io param;
param.read.fd = fno;
param.read.count = count;
to_sim(SIM_READ,¶m,NULL,0);
call_sim();
from_sim(¶m, buf);
return param.readr.result;
}
int sim_write(int fno, const char *buf, unsigned count)
{
io param;
param.write.fd = fno;
param.write.count = count;
to_sim(SIM_WRITE,¶m,(char *)buf,count);
call_sim();
from_sim(¶m, NULL);
return param.writer.result;
}
fpos_t sim_lseek(int fno, fpos_t offset, int origin)
{
io param;
param.lseek.fd = fno;
param.lseek.offsetlow = offset & 0xffff;
param.lseek.offsethigh = offset >> 16;
to_sim(SIM_LSEEK,¶m,NULL,0);
call_sim();
from_sim(¶m, NULL);
return param.lseekr.result;
}
int sim_unlink(const char *path)
{
io param;
to_sim(SIM_UNLINK,NULL,(char *)path,strlen(path)+1);
call_sim();
from_sim(¶m, NULL);
return param.unlinkr.result;
}
int sim_rename(const char *old, const char *new)
{
int l;
static char combined[200];
io param;
strcpy(combined,old);
l = strlen(old)+1;
strcpy(combined+l,new);
l += strlen(new) + 1;
to_sim(SIM_RENAME,NULL,combined,l);
call_sim();
from_sim(¶m, NULL);
return param.renamer.result;
}
char *sim_getenv(const char *str)
{
io param;
static char result[200];
to_sim(SIM_GETENV,NULL,(char *)str,strlen(str)+1);
call_sim();
from_sim(¶m, result);
return param.getenvr.result ? result : NULL;
}
int sim_gettime(void)
{
io param;
to_sim(SIM_GETTIME,NULL,NULL,0);
call_sim();
from_sim(¶m, NULL);
return param.gettimer.result;
}
int sim_getclock(void)
{
io param;
to_sim(SIM_GETCLOCK,NULL,NULL,0);
call_sim();
from_sim(¶m, NULL);
return param.getclockr.result;
}
int _CIOBUF_[BUFSIZ+32];
static void to_sim(int command, io *param, char *data, int length)
{
int i;
int n;
int v;
int *ip = &_CIOBUF_[0];
*ip++ = length;
*ip++ = command;
if (param) {
*ip++ = param->common.word1;
*ip++ = param->common.word2;
}
else {
*ip++ = 0;
*ip++ = 0;
}
n = length & ~3;
for (i = 0 ; i < n ; i += 4) {
v = *data++ & 0xff;
v |= (*data++ & 0xff) << 8;
v |= (*data++ & 0xff) << 16;
v |= (*data++ & 0xff) << 24;
*ip++ = v;
}
v = 0;
for ( ; i < length ; i++) {
v |= (*data++ & 0xff) << ((i & 3) << 3);
}
*ip = v;
}
static void call_sim(void)
{
__asm__(" .global C$$IO$$");
__asm__("C$$IO$$: nop");
}
static void from_sim(io *param, char *data)
{
int i;
int l;
int n;
int v;
int *ip = &_CIOBUF_[0];
l = *ip++;
param->common.word1 = *ip++;
param->common.word2 = *ip++;
if (data != NULL) {
n = l & ~3;
for (i = 0 ; i < n ; i += 4) {
v = *ip++;
*data++ = v & 0xff;
*data++ = (v >> 8) & 0xff;
*data++ = (v >> 16) & 0xff;
*data++ = (v >> 24) & 0xff;
}
v = *ip;
for (; i < l ; i++) {
*data++ = v >> ((i & 3) << 3);
}
}
}
#if 0
#include <fcntl.h>
sim_io_test()
{
sim_write(1, "howdy\n", 6);
}
#endif
/*
* Debug junk
*/
#if 0
void printk_wrapper(void)
{
__asm__(" .global _printf");
__asm__("_printf: bu _printk");
}
#endif
#if 1
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
int __svfscanf(
register FILE *fp,
char const *fmt0,
va_list ap
)
{
return 0;
}
#endif