OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1070 to Rev 1071
    Reverse comparison

Rev 1070 → Rev 1071

/tags/richard_0_1/or1ksim/peripheral/channels/fd.h
0,0 → 1,34
/* generic.h -- Declaration of generic functions for peripheral to
* communicate with host
Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#ifndef FD_H
#define FD_H
 
struct fd_channel
{
int fdin;
int fdout;
};
 
int fd_read(void * data, char * buffer, int size);
int fd_write(void * data, const char * buffer, int size);
 
#endif
/tags/richard_0_1/or1ksim/peripheral/channels/file.c
0,0 → 1,156
/* file.c -- Definition of functions and structures for
peripheral to communicate with host through files
Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#define _GNU_SOURCE /* for strndup */
 
#include <sys/types.h> /* open() */
#include <sys/stat.h> /* open() */
#include <fcntl.h> /* open() */
#include <malloc.h> /* calloc(), free() */
#include <string.h> /* strndup(), strchr() */
#include <errno.h> /* errno */
#include <unistd.h> /* close() */
 
#include "channel.h" /* struct channel_ops */
#include "fd.h" /* struct fd_channel, fd_read(), fd_write() */
 
struct file_channel
{
struct fd_channel fds;
char * namein;
char * nameout;
};
 
static void * file_init(const char * args)
{
struct file_channel * retval;
char * nameout;
 
if(!args)
{
errno = EINVAL;
return NULL;
}
 
retval = (struct file_channel*)calloc(1, sizeof(struct file_channel));
 
if(!retval)
{
return NULL;
}
 
retval->fds.fdin = -1;
retval->fds.fdout = -1;
 
nameout = strchr(args, ',');
 
if(nameout)
{
retval->namein = strndup(args, nameout - args);
retval->nameout = strdup(nameout+1);
}
else
{
retval->nameout = retval->namein = strdup(args);
}
 
return (void*)retval;
}
 
static int file_open(void * data)
{
struct file_channel * files = (struct file_channel *)data;
 
if(!files)
{
errno = ENODEV;
return -1;
}
 
if(files->namein == files->nameout)
{
/* if we have the same name in and out
* it cannot (logically) be a regular files.
* so we wont create one
*/
files->fds.fdin = files->fds.fdout = open(files->namein, O_RDWR);
 
return files->fds.fdin < 0 ? -1 : 0;
}
 
 
files->fds.fdin = open(files->namein, O_RDONLY | O_CREAT, 0664);
 
if(files->fds.fdin < 0)
return -1;
 
files->fds.fdout = open(files->nameout, O_WRONLY | O_CREAT, 0664);
 
if(files->fds.fdout < 0)
{
close(files->fds.fdout);
files->fds.fdout = -1;
return -1;
}
 
return 0;
}
 
static void file_close(void * data)
{
struct file_channel * files = (struct file_channel *)data;
 
if(files->fds.fdin != files->fds.fdout)
close(files->fds.fdin);
 
close(files->fds.fdout);
 
files->fds.fdin = -1;
files->fds.fdout = -1;
}
 
static void file_free(void * data)
{
struct file_channel * files = (struct file_channel *)data;
 
if(files->namein != files->nameout)
free(files->namein);
 
free(files->nameout);
 
free(files);
}
 
struct channel_ops file_channel_ops =
{
init: file_init,
open: file_open,
close: file_close,
read: fd_read,
write: fd_write,
free: file_free,
};
 
/*
* Local variables:
* c-file-style: "linux"
* End:
*/
/tags/richard_0_1/or1ksim/peripheral/channels/xterm.c
0,0 → 1,207
/* xterm.c -- Definition of functions and structures for
peripheral to communicate with host through an xterm.
Inspired from SWI-Prolog by Jan Wielemaker (GPL too)
even if there is really few in common.
Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
/*
* I really dislike using stuff beginning with '_'
* They are suppose to be reserved for the compiler
* as explained in C standards.
*/
#define _XOPEN_SOURCE /* grantpt() and al. */
#define _GNU_SOURCE /* on_exit */
 
#include <sys/types.h> /* waitpid() */
#include <sys/wait.h> /* waitpid() */
#include <stdio.h> /* sprintf() */
#include <stdlib.h> /* kill(), on_exit() */
#include <unistd.h> /* close() */
#include <fcntl.h> /* O_RDWR */
#include <string.h> /* strchr() */
#include <sys/stropts.h> /* grantpt(), unlockpt() */
#include <termios.h> /* struct termios and al. */
#include <signal.h> /* signal() and al. */
#include <libgen.h> /* basename() */
#include <errno.h> /* errno and al. */
 
#include "channel.h"
#include "generic.h"
#include "fd.h"
 
 
struct xterm_channel
{
struct fd_channel fds;
int pid;
};
 
 
static void xterm_close(void * data)
{
struct xterm_channel * xt = data;
 
if(!xt)
return;
 
if(xt->fds.fdin != -1)
close(xt->fds.fdin);
 
if(xt->pid != -1)
{
kill(xt->pid, SIGKILL);
waitpid(xt->pid, NULL, 0);
}
xt->fds.fdin = -1;
xt->fds.fdout = -1;
xt->pid = -1;
}
 
static void xterm_exit(int i, void * data)
{
xterm_close(data);
}
 
static void * xterm_init(const char * input)
{
struct xterm_channel * retval = malloc(sizeof(struct xterm_channel));
if(retval)
{
retval->fds.fdin = -1;
retval->fds.fdout = -1;
retval->pid = -1;
/* reset cause exit(1), leaving an xterm opened */
on_exit(xterm_exit, retval);
}
return (void*)retval;
}
 
 
 
static int xterm_open(void * data)
{
struct xterm_channel * xt = data;
int master, retval;
char * slavename;
struct termios termio;
char arg[64], * fin;
 
if(!data)
{
errno = ENODEV;
return -1;
}
 
 
master = open("/dev/ptmx", O_RDWR);
 
if(master < 0)
return -1;
 
grantpt(master);
unlockpt(master);
slavename = (char*)ptsname(master);
 
if(!slavename)
{
errno = ENOTTY;
goto closemastererror;
}
 
xt->fds.fdout = xt->fds.fdin = open(slavename, O_RDWR);
if(xt->fds.fdout < 0) goto closemastererror;
 
retval = ioctl(xt->fds.fdin, I_PUSH, "ptem");
if(retval < 0) goto closeslaveerror;
 
retval = ioctl(xt->fds.fdin, I_PUSH, "ldterm");
if(retval < 0) goto closeslaveerror;
retval = tcgetattr(xt->fds.fdin, &termio);
if(retval < 0) goto closeslaveerror;
 
 
termio.c_lflag &= ~ECHO;
retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
if(retval < 0) goto closeslaveerror;
 
xt->pid = fork();
 
if(xt->pid == -1) goto closeslaveerror;
 
if(xt->pid == 0)
{
/* Ctrl-C on sim still kill the xterm, grrr */
signal(SIGINT, SIG_IGN);
 
fin = slavename+strlen(slavename)-2;
if (strchr(fin, '/' ))
{
sprintf(arg, "-S%s/%d",
basename(slavename),
master);
}
else
{
sprintf(arg, "-S%c%c%d", fin[0], fin[1], master);
}
execlp("xterm", "xterm", arg, NULL);
write(master, "\n", 1);
exit(1);
}
 
do retval = read(xt->fds.fdin, &arg, 1);
while(retval >= 0 && arg[0] != '\n');
 
if(retval < 0) goto closeslaveerror;
 
termio.c_lflag |= ECHO;
retval = tcsetattr(xt->fds.fdin, TCSADRAIN, &termio);
 
if(retval < 0) goto closeslaveerror;
return 0;
 
closeslaveerror:
close(xt->fds.fdin);
 
closemastererror:
close(master);
xt->pid = xt->fds.fdin = xt->fds.fdout = -1;
return -1;
}
struct channel_ops xterm_channel_ops =
{
init: xterm_init,
open: xterm_open,
close: xterm_close,
read: fd_read,
write: fd_write,
free: generic_free,
};
 
/*
* Local variables:
* c-file-style: "linux"
* End:
*/
 
/tags/richard_0_1/or1ksim/peripheral/channels/Makefile.in
0,0 → 1,339
# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
 
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
 
# Makefile -- Makefile for peripherals channels to host
# Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
#
# This file is part of OpenRISC 1000 Architectural Simulator.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
 
 
SHELL = @SHELL@
 
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
 
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
 
DESTDIR =
 
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
 
top_builddir = ../..
 
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
 
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
 
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
AR = @AR@
ARFLAGS = @ARFLAGS@
BUILD_DIR = @BUILD_DIR@
CC = @CC@
CFLAGS = @CFLAGS@
CPU_ARCH = @CPU_ARCH@
INCLUDES = @INCLUDES@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
MAKEINFO = @MAKEINFO@
MAKE_SHELL = @MAKE_SHELL@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
SUMVERSION = @SUMVERSION@
TERMCAP_LIB = @TERMCAP_LIB@
VERSION = @VERSION@
host = @host@
host_cpu = @host_cpu@
host_os = @host_os@
 
noinst_LIBRARIES = libchannels.a
libchannels_a_SOURCES = \
channel.c \
fd.c \
file.c \
generic.c \
xterm.c
 
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
 
 
DEFS = @DEFS@ -I. -I$(srcdir) -I../..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libchannels_a_LIBADD =
libchannels_a_OBJECTS = channel.o fd.o file.o generic.o xterm.o
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = Makefile.am Makefile.in
 
 
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
TAR = gtar
GZIP_ENV = --best
DEP_FILES = .deps/channel.P .deps/fd.P .deps/file.P .deps/generic.P \
.deps/xterm.P
SOURCES = $(libchannels_a_SOURCES)
OBJECTS = $(libchannels_a_OBJECTS)
 
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu peripheral/channels/Makefile
 
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
 
mostlyclean-noinstLIBRARIES:
 
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
 
distclean-noinstLIBRARIES:
 
maintainer-clean-noinstLIBRARIES:
 
.s.o:
$(COMPILE) -c $<
 
.S.o:
$(COMPILE) -c $<
 
mostlyclean-compile:
-rm -f *.o core *.core
 
clean-compile:
 
distclean-compile:
-rm -f *.tab.c
 
maintainer-clean-compile:
 
libchannels.a: $(libchannels_a_OBJECTS) $(libchannels_a_DEPENDENCIES)
-rm -f libchannels.a
$(AR) cru libchannels.a $(libchannels_a_OBJECTS) $(libchannels_a_LIBADD)
$(RANLIB) libchannels.a
 
tags: TAGS
 
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
 
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
 
mostlyclean-tags:
 
clean-tags:
 
distclean-tags:
-rm -f TAGS ID
 
maintainer-clean-tags:
 
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 
subdir = peripheral/channels
 
distdir: $(DISTFILES)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(top_distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu peripheral/channels/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
 
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
 
-include $(DEP_FILES)
 
mostlyclean-depend:
 
clean-depend:
 
distclean-depend:
-rm -rf .deps
 
maintainer-clean-depend:
 
%.o: %.c
@echo '$(COMPILE) -c $<'; \
$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-cp .deps/$(*F).pp .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*F).P; \
rm .deps/$(*F).pp
 
%.lo: %.c
@echo '$(LTCOMPILE) -c $<'; \
$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*F).pp > .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*F).P; \
rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
 
install-data-am:
install-data: install-data-am
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(LIBRARIES)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
 
 
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
 
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-tags mostlyclean-depend mostlyclean-generic
 
mostlyclean: mostlyclean-am
 
clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
clean-generic mostlyclean-am
 
clean: clean-am
 
distclean-am: distclean-noinstLIBRARIES distclean-compile \
distclean-tags distclean-depend distclean-generic \
clean-am
 
distclean: distclean-am
 
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-depend maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
 
maintainer-clean: maintainer-clean-am
 
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
clean-tags maintainer-clean-tags distdir mostlyclean-depend \
distclean-depend clean-depend maintainer-clean-depend info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/tags/richard_0_1/or1ksim/peripheral/channels/generic.h
0,0 → 1,29
/* generic.h -- Declaration of generic functions for peripheral to
* communicate with host
Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#ifndef GENERIC_H
#define GENERIC_H
 
int generic_open(void * data);
void generic_close(void * data);
void generic_free(void * data);
 
#endif
/tags/richard_0_1/or1ksim/peripheral/channels/channel.c
0,0 → 1,243
/* channel.h -- Definition of types and structures for
peripheral to communicate with host. Addapted from UML.
Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#define _GNU_SOURCE /* for strndup */
 
#include <stdio.h> /* perror */
#include <stdlib.h> /* exit */
#include <malloc.h> /* calloc, free */
#include <string.h> /* strndup, strcmp, strlen, strchr */
#include <errno.h> /* errno */
 
#include "channel.h"
 
struct channel_factory
{
const char * name;
const struct channel_ops * ops;
struct channel_factory * next;
};
 
extern struct channel_ops fd_channel_ops, file_channel_ops, xterm_channel_ops;
 
static struct channel_factory preloaded[] =
{
{ "fd", &fd_channel_ops, &preloaded[1] },
{ "file", &file_channel_ops, &preloaded[2] },
{ "xterm", &xterm_channel_ops, NULL }
};
 
static struct channel_factory * head = &preloaded[0];
 
static struct channel_factory * find_channel_factory(const char * name);
 
struct channel * channel_init(const char * descriptor)
{
struct channel * retval;
struct channel_factory * current;
char * args, * name;
int count;
 
if(!descriptor)
{
return NULL;
}
 
retval = (struct channel*)calloc(1, sizeof(struct channel));
 
if(!retval)
{
perror(descriptor);
exit(1);
}
 
args = strchr(descriptor, ':');
 
if(args)
{
count = args - descriptor;
args++;
}
else
{
count = strlen(descriptor);
}
 
name = (char*)strndup(descriptor, count);
 
if(!name)
{
perror(name);
exit(1);
}
 
current = find_channel_factory(name);
if(!current)
{
errno = ENODEV;
perror(descriptor);
exit(1);
}
 
retval->ops = current->ops;
 
free(name);
 
if(!retval->ops)
{
errno = ENODEV;
perror(descriptor);
exit(1);
}
 
if(retval->ops->init)
{
retval->data = (retval->ops->init)(args);
 
if(!retval->data)
{
perror(descriptor);
exit(1);
}
}
 
return retval;
}
 
int channel_open(struct channel * channel)
{
if(channel && channel->ops && channel->ops->open)
{
return (channel->ops->open)(channel->data);
}
errno = ENOSYS;
return -1;
}
 
int channel_read(struct channel * channel, char * buffer, int size)
{
if(channel && channel->ops && channel->ops->read)
{
return (channel->ops->read)(channel->data, buffer, size);
}
errno = ENOSYS;
return -1;
}
 
int channel_write(struct channel * channel, const char * buffer, int size)
{
if(channel && channel->ops && channel->ops->write)
{
return (channel->ops->write)(channel->data, buffer, size);
}
errno = ENOSYS;
return -1;
}
 
void channel_close(struct channel * channel)
{
if(channel && channel->ops && channel->ops->close)
{
(channel->ops->close)(channel->data);
}
}
 
void channel_free(struct channel * channel)
{
if(channel && channel->ops && channel->ops->close)
{
(channel->ops->free)(channel->data);
free(channel);
}
}
 
 
int channel_ok(struct channel * channel)
{
if(channel && channel->ops)
{
if(channel->ops->isok)
return (channel->ops->isok)(channel->data);
else
return 1;
}
return 0;
}
 
char * channel_status(struct channel * channel)
{
if(channel && channel->ops && channel->ops->status)
{
return (channel->ops->status)(channel->data);
}
return "";
}
 
 
 
static struct channel_factory * find_channel_factory(const char * name)
{
struct channel_factory * current = head;
 
current = head;
while(current && strcmp(current->name, name))
{
current = current->next;
}
 
return current;
}
 
int register_channel(const char * name, const struct channel_ops * ops)
{
struct channel_factory * new;
 
 
if(find_channel_factory(name))
{
errno = EEXIST;
perror(name);
exit(1);
}
 
new = (struct channel_factory *)calloc(1, sizeof(struct channel_factory));
 
if(!new)
{
perror(name);
exit(1);
}
 
new->name = name;
new->ops = ops;
new->next = head;
head = new;
 
return (int)new; /* dummy */
}
 
/*
* Local variables:
* c-file-style: "linux"
* End:
*/
 
/tags/richard_0_1/or1ksim/peripheral/channels/Makefile.am
0,0 → 1,27
# Makefile -- Makefile for peripherals channels to host
# Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
#
# This file is part of OpenRISC 1000 Architectural Simulator.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
 
noinst_LIBRARIES = libchannels.a
libchannels_a_SOURCES = \
channel.c \
fd.c \
file.c \
generic.c \
xterm.c
/tags/richard_0_1/or1ksim/peripheral/channels/fd.c
0,0 → 1,154
/* fd.c -- Definition of functions and structures for
peripheral to communicate with host through file descriptors
Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#include <sys/time.h> /* struct timeval */
#include <sys/types.h> /* fd_set */
#include <stdio.h> /* perror */
#include <stdlib.h> /* atoi */
#include <unistd.h> /* read, write, select */
#include <malloc.h> /* calloc, free */
#include <string.h> /* strchr */
#include <errno.h> /* errno */
 
#include "channel.h"
#include "generic.h"
#include "fd.h"
 
static void * fd_init(const char * args)
{
struct fd_channel * retval;
 
retval = (struct fd_channel*)calloc(1, sizeof(struct fd_channel));
 
if(!retval)
{
return NULL;
}
 
 
retval->fdin = atoi(args); /* so 0 if garbage */
/* TODO: strtoul */
 
args = strchr(args, ',');
 
if(args)
{
retval->fdout = atoi(args+1);
}
else
{
retval->fdout = retval->fdin;
}
 
return (void*)retval;
}
 
int fd_read(void * data, char * buffer, int size)
{
struct fd_channel * fds = (struct fd_channel *)data;
struct timeval timeout = { 0, 0 };
fd_set rfds;
int retval;
 
if(!fds)
{
errno = ENODEV;
return -1;
}
 
FD_ZERO(&rfds);
FD_SET(fds->fdin, &rfds);
 
retval = select(fds->fdin+1, &rfds, NULL, NULL, &timeout);
 
if(retval <= 0)
return retval;
 
return read(fds->fdin, buffer, size);
}
 
int fd_write(void * data, const char * buffer, int size)
{
struct fd_channel * fds = (struct fd_channel *)data;
if(fds)
{
return write(fds->fdout, buffer, size);
}
errno = ENODEV;
return -1;
}
 
static int fd_isok(void * data)
{
struct fd_channel * fds = (struct fd_channel *)data;
if(fds)
{
return fds->fdout != -1 && fds->fdin != -1;
}
return 0;
}
 
static int fd_status_fd(int fd, char * str, int size)
{
if(fd == -1)
return snprintf(str, size, "closed");
 
return snprintf(str, size, "opened(fd=%d)", fd);
}
 
char * fd_status(void * data)
{
static char retval[256];
int index = 0;
 
struct fd_channel * fds = (struct fd_channel *)data;
if(fds)
{
index += snprintf(retval + index, sizeof(retval) - index, "in ");
index += fd_status_fd(fds->fdin, retval + index, sizeof(retval) - index);
 
index += snprintf(retval + index, sizeof(retval) - index, "out ");
index += fd_status_fd(fds->fdout, retval + index, sizeof(retval) - index);
}
else
{
snprintf(retval, sizeof(retval), "(null)");
}
return retval;
}
 
struct channel_ops fd_channel_ops =
{
init: fd_init,
open: generic_open,
close: generic_close,
read: fd_read,
write: fd_write,
free: generic_free,
isok: fd_isok,
status: fd_status,
};
 
/*
* Local variables:
* c-file-style: "linux"
* End:
*/
/tags/richard_0_1/or1ksim/peripheral/channels/generic.c
0,0 → 1,54
/* generic.c -- Definition of generic functions for peripheral to
* communicate with host
Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#include <malloc.h> /* free */
#include <errno.h> /* errno */
 
 
int generic_open(void * data)
{
if(data)
{
return 0;
}
errno = ENODEV;
return -1;
}
 
void generic_close(void * data)
{
return;
}
 
void generic_free(void * data)
{
if(data)
{
free(data);
}
}
 
 
/*
* Local variables:
* c-file-style: "linux"
* End:
*/
/tags/richard_0_1/or1ksim/peripheral/channels/channel.h
0,0 → 1,68
/* channel.h -- Definition of types and structures for
peripheral to communicate with host. Addapted from UML.
Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#ifndef CHANNEL_H
#define CHANNEL_H
 
struct channel_ops
{
void *(*init)(const char *);
int (*open)(void *);
void (*close)(void *);
int (*read)(void *, char *, int);
int (*write)(void *, const char *, int);
void (*free)(void *);
int (*isok)(void*);
char* (*status)(void*);
};
 
struct channel
{
const struct channel_ops * ops;
void * data;
};
 
 
struct channel * channel_init(const char * descriptor);
/* read operation in non-blocking */
int channel_open(struct channel * channel);
int channel_read(struct channel * channel, char * buffer, int size);
int channel_write(struct channel * channel, const char * buffer, int size);
void channel_free(struct channel * channel);
int channel_ok(struct channel * channel);
char * channel_status(struct channel * channel);
 
void channel_close(struct channel * channel);
 
int register_channel(const char * name, const struct channel_ops * ops);
/* TODO: int unregister_channel(const char * name); */
 
/* for those who wants to automatically register at startup */
#define REGISTER_CHANNEL(NAME,OPS) \
static int NAME ## _dummy_register = register_channel(#NAME, OPS)
 
#endif
 
/*
* Local variables:
* c-file-style: "linux"
* End:
*/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.