summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Gaisler <jiri@gaisler.se>2020-10-25 11:27:31 -0400
committerJiri Gaisler <jiri@gaisler.se>2020-10-28 13:38:31 -0400
commit66efed88eff45dca65661ab65327ee47f2732cfa (patch)
tree17d58ad35d7fa967347bd99bd4005721de2e8716
parentAdd -rt option to synch sim to wall time (diff)
downloadsis-66efed88eff45dca65661ab65327ee47f2732cfa.tar.bz2
Add networking support using host tap device2.23
* Emulation of GRETH 10/100 Mbit MAC and PHY * Supported only on linux
-rw-r--r--Makefile.am1
-rw-r--r--Makefile.in10
-rwxr-xr-xconfigure20
-rw-r--r--configure.ac2
-rw-r--r--func.c13
-rw-r--r--greth.c310
-rw-r--r--grlib.c4
-rw-r--r--grlib.h1
-rw-r--r--help.c2
-rw-r--r--interf.c4
-rw-r--r--leon3.c20
-rw-r--r--riscv.c24
-rw-r--r--sis.c7
-rw-r--r--sis.h14
-rw-r--r--sis.info194
-rw-r--r--sis.texi121
-rw-r--r--sparc.c2
-rw-r--r--tap.c222
-rw-r--r--version.texi8
19 files changed, 905 insertions, 74 deletions
diff --git a/Makefile.am b/Makefile.am
index 59d1b20..a7c9c0d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,6 +7,7 @@ endif
bin_PROGRAMS = sis
sis_SOURCES = erc32.c grlib.c leon3.c exec.c func.c help.c \
sparc.c riscv.c leon2.c sis.c interf.c remote.c elf.c \
+ greth.c tap.c \
$(LN_SRC)
AM_CFLAGS = -DFAST_UART
diff --git a/Makefile.in b/Makefile.in
index c6c5762..53b0a67 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -78,13 +78,14 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(infodir)"
PROGRAMS = $(bin_PROGRAMS)
am__sis_SOURCES_DIST = erc32.c grlib.c leon3.c exec.c func.c help.c \
- sparc.c riscv.c leon2.c sis.c interf.c remote.c elf.c \
- linenoise.c
+ sparc.c riscv.c leon2.c sis.c interf.c remote.c elf.c greth.c \
+ tap.c linenoise.c
@LINENOISE_TRUE@am__objects_1 = linenoise.$(OBJEXT)
am_sis_OBJECTS = erc32.$(OBJEXT) grlib.$(OBJEXT) leon3.$(OBJEXT) \
exec.$(OBJEXT) func.$(OBJEXT) help.$(OBJEXT) sparc.$(OBJEXT) \
riscv.$(OBJEXT) leon2.$(OBJEXT) sis.$(OBJEXT) interf.$(OBJEXT) \
- remote.$(OBJEXT) elf.$(OBJEXT) $(am__objects_1)
+ remote.$(OBJEXT) elf.$(OBJEXT) greth.$(OBJEXT) tap.$(OBJEXT) \
+ $(am__objects_1)
sis_OBJECTS = $(am_sis_OBJECTS)
sis_DEPENDENCIES =
DEFAULT_INCLUDES = -I.@am__isrc@
@@ -265,6 +266,7 @@ top_srcdir = @top_srcdir@
@LINENOISE_TRUE@LN_SRC = linenoise.c
sis_SOURCES = erc32.c grlib.c leon3.c exec.c func.c help.c \
sparc.c riscv.c leon2.c sis.c interf.c remote.c elf.c \
+ greth.c tap.c \
$(LN_SRC)
AM_CFLAGS = -DFAST_UART
@@ -379,6 +381,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/erc32.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exec.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/func.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/greth.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grlib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interf.Po@am__quote@
@@ -389,6 +392,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sis.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tap.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/configure b/configure
index 920b411..2a5c40b 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sis 2.22.
+# Generated by GNU Autoconf 2.69 for sis 2.23.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sis'
PACKAGE_TARNAME='sis'
-PACKAGE_VERSION='2.22'
-PACKAGE_STRING='sis 2.22'
+PACKAGE_VERSION='2.23'
+PACKAGE_STRING='sis 2.23'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1283,7 +1283,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures sis 2.22 to adapt to many kinds of systems.
+\`configure' configures sis 2.23 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1354,7 +1354,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sis 2.22:";;
+ short | recursive ) echo "Configuration of sis 2.23:";;
esac
cat <<\_ACEOF
@@ -1444,7 +1444,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sis configure 2.22
+sis configure 2.23
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1742,7 +1742,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by sis $as_me 2.22, which was
+It was created by sis $as_me 2.23, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2569,7 +2569,7 @@ fi
# Define the identity of the package.
PACKAGE='sis'
- VERSION='2.22'
+ VERSION='2.23'
cat >>confdefs.h <<_ACEOF
@@ -4911,7 +4911,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by sis $as_me 2.22, which was
+This file was extended by sis $as_me 2.23, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -4977,7 +4977,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-sis config.status 2.22
+sis config.status 2.23
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 2e17cf7..7ace20e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([sis], [2.22])
+AC_INIT([sis], [2.23])
AC_CONFIG_SRCDIR([sis.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS(config.h)
diff --git a/func.c b/func.c
index 07f585c..4f72f59 100644
--- a/func.c
+++ b/func.c
@@ -64,6 +64,7 @@ int nouartrx = 0;
int port = 1234;
int sim_run = 0;
int sync_rt = 0;
+char bridge[32] = "";
/* RAM and ROM for all systems */
char romb[ROM_SIZE];
@@ -1056,7 +1057,7 @@ pwd_enter (struct pstate *sregs)
}
void
-rt_sync()
+rt_sync ()
{
double walltime, realtime, dtime;
int64 stime;
@@ -1065,11 +1066,11 @@ rt_sync()
walltime = ebase.tottime + get_time () - ebase.starttime;
dtime = (realtime - walltime);
if (dtime > 0.001)
- {
- if (dtime > 1.0)
- dtime = 0.1;
- usleep ((useconds_t) (dtime * 1E6));
- }
+ {
+ if (dtime > 1.0)
+ dtime = 0.1;
+ usleep ((useconds_t) (dtime * 1E6));
+ }
}
int
diff --git a/greth.c b/greth.c
new file mode 100644
index 0000000..9d09087
--- /dev/null
+++ b/greth.c
@@ -0,0 +1,310 @@
+/*
+ * This file is part of SIS.
+ *
+ * SIS, SPARC/RISCV instruction simulator. Copyright (C) 2020 Jiri Gaisler
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+/* Emulation of GRETH 10/100 Mbit network interface */
+/* Based on grlib-gpl-2018.1-b4217/doc/grip.pdf */
+/* Multicast not supported for now ... */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+
+#include "sis.h"
+
+#define MDIO_WRITE 1
+#define MDIO_READ 2
+#define CTRL_SPEED 0x80
+#define CTRL_RST 0x40
+#define CTRL_RI 8
+#define CTRL_TI 4
+#define CTRL_RE 2
+#define CTRL_TE 1
+#define STATUS_TI 8
+#define STATUS_RI 4
+
+#define BASE_PNT 0x3f8
+#define DESC_EN (1 << 11)
+#define DESC_WRAP (1 << 12)
+#define DESC_IE (1 << 13)
+
+static uint32 greth_ctrl;
+static uint32 greth_status;
+static uint32 greth_macmsb;
+static uint32 greth_maclsb;
+static uint32 greth_mdio;
+static uint32 greth_txbase;
+static uint32 greth_txdesc;
+static uint32 greth_txbuf;
+static unsigned char *greth_txbufptr;
+static uint32 greth_rxbase;
+static uint32 greth_rxdesc;
+static uint32 greth_rxbuf;
+static unsigned char *greth_rxbufptr;
+static unsigned char greth_mac[6];
+static long unsigned mac;
+static const char broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+/* Simple emulation of Microchip KSZ8041NL/RNL PHY */
+
+static uint32
+mdio_read (uint32 address)
+{
+ uint32 res;
+
+ switch (address & 0x1F)
+ {
+ case 0:
+ res = 0x3100;
+ break;
+ case 1:
+ res = 0x7865;
+ break;
+ case 2:
+ res = 0x0022;
+ break;
+ case 3:
+ res = 0x1512;
+ break;
+ case 4:
+ res = 0x01ef;
+ break;
+ case 5:
+ res = 0x41e1;
+ break;
+ default:
+ res = 0;
+ }
+
+ if (sis_verbose > 1)
+ printf ("%8lu cpu %d MDIO read a: %02x, d: %04x\n",
+ ebase.simtime, cpu, address, res);
+ return res;
+}
+
+static void
+mdio_write (uint32 address, uint32 data)
+{
+ if (sis_verbose > 1)
+ printf ("%8lu cpu %d MDIO write a: %02x, d: %04x\n",
+ ebase.simtime, cpu, address, data);
+}
+
+static void
+greth_tx (void)
+{
+ int32 ws;
+ uint32 tmpdesc;
+ unsigned char buffer[2048];
+ int len, wlen, i;
+
+ if (greth_ctrl & CTRL_TE)
+ {
+ ms->memory_read (greth_txbase, &greth_txdesc, &ws);
+ if (greth_txdesc & DESC_EN)
+ {
+ ms->memory_read (greth_txbase + 4, &greth_txbuf, &ws);
+ greth_txbufptr = ms->get_mem_ptr (greth_txbuf, 1536);
+ len = greth_txdesc & 0x7ff;
+ /* endian swap on host/target endian mismatch */
+ if (arch->bswap)
+ {
+ wlen = (len + 3) & ~3; // align up to 32-bit word
+ for (i = 0; i < wlen; i++)
+ buffer[i] = greth_txbufptr[arch->bswap ^ i];
+ sis_tap_write ((unsigned char *) buffer, len);
+ }
+ else
+ sis_tap_write (greth_txbufptr, greth_txdesc & 0x7ff);
+ greth_status |= STATUS_TI;
+ if ((greth_ctrl & CTRL_TI) && (greth_txdesc & DESC_IE))
+ ms->set_irq (6);
+ if (sis_verbose)
+ printf ("packet transmitted, len %d, desc %d\n",
+ greth_txdesc & 0x7ff, (greth_txbase & BASE_PNT) >> 3);
+ tmpdesc = greth_txdesc & 0x7ff;
+ ms->memory_write (greth_txbase, &tmpdesc, 2, &ws);
+ if ((greth_txdesc & DESC_WRAP) ||
+ ((greth_txbase & BASE_PNT) == BASE_PNT))
+ greth_txbase &= ~BASE_PNT;
+ else
+ greth_txbase += 8;
+ ms->memory_read (greth_txbase, &greth_txdesc, &ws);
+ }
+ }
+ event (greth_tx, 1, 5000);
+}
+
+/* Write GRETH APB registers */
+
+void
+greth_write (uint32 address, uint32 data)
+{
+ int32 ws;
+
+ switch (address & 0xFC)
+ {
+ case 0:
+ if (data & CTRL_RST)
+ {
+ greth_ctrl = CTRL_SPEED;
+ }
+ else
+ {
+ if ((data & CTRL_RE) && !(greth_ctrl & CTRL_RE) && !mac)
+ {
+ mac = greth_macmsb;
+ mac <<= 32;
+ mac |= greth_maclsb;
+ sis_tap_init (mac);
+ mac = 1;
+ event (greth_tx, 1, 100);
+ sync_rt = 1;
+ }
+ greth_ctrl = data;
+ }
+ break;
+ case 4:
+ greth_status &= ~data;
+ break;
+ case 8:
+ greth_macmsb = data & 0x0ffff;
+ greth_mac[0] = (data >> 8) & 0x0ff;
+ greth_mac[1] = data & 0x0ff;
+ break;
+ case 0x0c:
+ greth_maclsb = data;
+ greth_mac[2] = (data >> 24) & 0x0ff;
+ greth_mac[3] = (data >> 16) & 0x0ff;
+ greth_mac[4] = (data >> 8) & 0x0ff;
+ greth_mac[5] = data & 0x0ff;
+ break;
+ case 0x10:
+ greth_mdio = data & 0xfffffff0;
+ if (data & MDIO_WRITE)
+ {
+ mdio_write ((data >> 6) & 0x1f, data >> 16);
+ }
+ else if (data & MDIO_READ)
+ {
+ greth_mdio = mdio_read ((data >> 6) & 0x1f) << 16;
+ }
+ break;
+ case 0x14:
+ greth_txbase = data & 0xfffffff8;
+ break;
+ case 0x18:
+ greth_rxbase = data & 0xfffffff8;
+ break;
+ }
+ if (sis_verbose > 1)
+ printf ("%8lu cpu %d APB write a: %08x, d: %08x\n",
+ ebase.simtime, cpu, address, data);
+}
+
+/* Read GRETH APB registers */
+
+uint32
+greth_read (uint32 address)
+{
+ uint32 res;
+
+ switch (address & 0xFC)
+ {
+ case 0:
+ res = greth_ctrl;
+ break;
+ case 4:
+ res = greth_status;
+ break;
+ case 8:
+ res = greth_macmsb;
+ break;
+ case 0x0c:
+ res = greth_maclsb;
+ break;
+ case 0x10:
+ res = greth_mdio;
+ break;
+ case 0x14:
+ res = greth_txbase;
+ break;
+ case 0x18:
+ res = greth_rxbase;
+ break;
+ default:
+ res = 0;
+ }
+ if (sis_verbose > 1)
+ printf ("%8lu cpu %d APB read a: %08x, d: %08x\n",
+ ebase.simtime, cpu, address, res);
+ return res;
+}
+
+void
+greth_rxready (unsigned char *buffer, int len)
+{
+ uint32 tmpdesc, ws;
+ int i, wlen;
+
+ if (sis_verbose > 1)
+ {
+ printf ("net: read %d bytes from device\n", len);
+ for (i = 0; i < len; i++)
+ printf ("%02x", buffer[i]);
+ printf ("\n");
+ }
+ /* accept only unicast or broadcast packets */
+ if (((strncmp (greth_mac, buffer, 6) == 0) ||
+ (strncmp (buffer, broadcast, 6) == 0)) && (greth_ctrl & CTRL_RE))
+ {
+ ms->memory_read (greth_rxbase, &greth_rxdesc, &ws);
+ if (greth_rxdesc & DESC_EN)
+ {
+ ms->memory_read (greth_rxbase + 4, &greth_rxbuf, &ws);
+ greth_rxbufptr = ms->get_mem_ptr (greth_rxbuf, 1536);
+ /* endian swap on host/target endian mismatch */
+ if (arch->bswap)
+ {
+ wlen = (len + 3) & ~3; // align up to 32-bit word
+ for (i = 0; i < wlen; i++)
+ greth_rxbufptr[i] = buffer[arch->bswap ^ i];
+ }
+ else
+ memcpy (greth_rxbufptr, buffer, len);
+ tmpdesc = len & 0x7ff;
+ ms->memory_write (greth_rxbase, &tmpdesc, 2, &ws);
+ greth_status |= STATUS_RI;
+ if ((greth_rxdesc & DESC_WRAP)
+ || ((greth_rxbase & BASE_PNT) == BASE_PNT))
+ greth_rxbase &= ~BASE_PNT;
+ else
+ greth_rxbase += 8;
+
+ if ((greth_ctrl & CTRL_RI) && (greth_rxdesc & DESC_IE))
+ ms->set_irq (6);
+ }
+ else if (sis_verbose > 1)
+ printf ("net: received packet dropped!\n");
+ }
+}
diff --git a/grlib.c b/grlib.c
index 9932360..64ed9c0 100644
--- a/grlib.c
+++ b/grlib.c
@@ -103,4 +103,8 @@ grlib_init ()
grlib_apbpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_IRQMP, 2, 0),
GRLIB_PP_APBADDR (0x80000200, 0xFFF));
+ grlib_ahbmpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_GRETH, 0, 0));
+ grlib_apbpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_GRETH, 0, 6),
+ GRLIB_PP_APBADDR (0x80000B00, 0xFFF));
+
}
diff --git a/grlib.h b/grlib.h
index d261b3b..a895c11 100644
--- a/grlib.h
+++ b/grlib.h
@@ -36,6 +36,7 @@
#define GAISLER_APBUART 0x00C
#define GAISLER_IRQMP 0x00D
#define GAISLER_GPTIMER 0x011
+#define GAISLER_GRETH 0x01D
#define ESA_MCTRL 0x00F
/* How to build entries in the plug&play area */
diff --git a/help.c b/help.c
index b3f5407..b836878 100644
--- a/help.c
+++ b/help.c
@@ -29,7 +29,7 @@ sis_usage ()
printf ("[-cov] [-nfp] [-ift] [-wrp] [-rom8] [-uben]\n");
printf ("[-freq frequency] [-c batch_file]\n");
printf ("[-erc32] [-leon2] [-leon3] [-ricsv]\n");
- printf ("[-d] [-v] [files]\n");
+ printf ("[-d] [-v] [-rt] [-bridge name] [files]\n");
}
void
diff --git a/interf.c b/interf.c
index 672388c..421c0ac 100644
--- a/interf.c
+++ b/interf.c
@@ -367,7 +367,7 @@ sim_insert_swbreakpoint (uint32 addr, int len)
breakinsn = CEBREAK;
ms->sis_memory_write (addr, (char *) &breakinsn, 2);
}
- if (sis_verbose)
+ if (sis_verbose > 1)
printf ("sim_insert_swbreakpoint: added breakpoint %d at 0x%08x\n",
ebase.bptnum + 1, addr);
ebase.bptnum += 1;
@@ -391,7 +391,7 @@ sim_remove_swbreakpoint (uint32 addr, int len)
{
/* write back saved opcode */
ms->sis_memory_write (addr, (char *) &ebase.bpsave[i], len);
- if (sis_verbose)
+ if (sis_verbose > 1)
printf ("sim_remove_swbreakpoint: remove breakpoint %d at 0x%08x\n",
i, addr);
/* shift down remaining breakpoints */
diff --git a/leon3.c b/leon3.c
index 16b185e..5d79381 100644
--- a/leon3.c
+++ b/leon3.c
@@ -150,7 +150,6 @@ static void close_port (void);
static void leon3_reset (void);
static void irqmp_intack (int level, int cpu);
static void chk_irq (void);
-static void set_irq (int32 level);
static int32 apb_read (uint32 addr, uint32 * data);
static int apb_write (uint32 addr, uint32 data);
static void port_init (void);
@@ -170,6 +169,7 @@ static char *get_mem_ptr (uint32 addr, uint32 size);
static void store_bytes (char *mem, uint32 waddr,
uint32 * data, int sz, int32 * ws);
static void gpt_add_intr (int i);
+static void set_irq (int32 level);
/* One-time init. */
@@ -443,7 +443,9 @@ apb_read (uint32 addr, uint32 * data)
default:
*data = 0;
- if (sis_verbose > 1)
+ if ((addr & 0xF00) == 0xB00)
+ *data = greth_read (addr);
+ else if (sis_verbose > 1)
printf ("%8" PRIu64
" cpu %d APB read a: %08x, d: %08x unimplemented!\n",
ebase.simtime, cpu, addr, *data);
@@ -582,7 +584,9 @@ apb_write (uint32 addr, uint32 data)
break;
default:
- if (sis_verbose)
+ if ((addr & 0xF00) == 0xB00)
+ greth_write (addr, data);
+ else if (sis_verbose)
printf ("%8" PRIu64
" cpu %d APB write a: %08x, d: %08x unimplemented!\n",
ebase.simtime, cpu, addr, data);
@@ -1136,7 +1140,7 @@ get_mem_ptr (uint32 addr, uint32 size)
return &ramb[addr & RAM_MASK];
}
- return (char *) -1;
+ return NULL;
}
static int
@@ -1145,7 +1149,7 @@ sis_memory_write (uint32 addr, const char *data, uint32 length)
char *mem;
int32 ws;
- if ((mem = get_mem_ptr (addr, length)) != ((char *) -1))
+ if ((mem = get_mem_ptr (addr, length)) != NULL)
{
memcpy (mem, data, length);
return length;
@@ -1167,7 +1171,7 @@ sis_memory_read (uint32 addr, char *data, uint32 length)
return 4;
}
- if ((mem = get_mem_ptr (addr, length)) == ((char *) -1))
+ if ((mem = get_mem_ptr (addr, length)) == NULL)
return 0;
memcpy (data, mem, length);
@@ -1211,5 +1215,7 @@ const struct memsys leon3 = {
memory_write,
sis_memory_write,
sis_memory_read,
- boot_init
+ boot_init,
+ get_mem_ptr,
+ set_irq
};
diff --git a/riscv.c b/riscv.c
index 100f7ad..715850d 100644
--- a/riscv.c
+++ b/riscv.c
@@ -1374,6 +1374,8 @@ riscv_dispatch_instruction (sregs)
break;
case 5: /* wfi */
pwd_enter (sregs);
+ if (sync_rt)
+ rt_sync ();
break;
default:
sregs->trap = TRAP_ILLEG;
@@ -1721,22 +1723,20 @@ riscv_dispatch_instruction (sregs)
case 0: /* FSGNJ */
sregs->fsi[frd + BEH] = sregs->fsi[frs1 + BEH];
sregs->fsi[frd + 1 - BEH] =
- (sregs->fsi[frs1 + 1 - BEH] & 0x7fffffff) | (sregs->
- fsi[frs2
- + 1 -
- BEH]
- &
- 0x80000000);
+ (sregs->
+ fsi[frs1 + 1 -
+ BEH] & 0x7fffffff) | (sregs->fsi[frs2 + 1 -
+ BEH] &
+ 0x80000000);
break;
case 1: /* FSGNJN */
sregs->fsi[frd + BEH] = sregs->fsi[frs1 + BEH];
sregs->fsi[frd + 1 - BEH] =
- (sregs->fsi[frs1 + 1 - BEH] & 0x7fffffff) | (~sregs->
- fsi[frs2
- + 1 -
- BEH]
- &
- 0x80000000);
+ (sregs->
+ fsi[frs1 + 1 -
+ BEH] & 0x7fffffff) | (~sregs->fsi[frs2 + 1 -
+ BEH] &
+ 0x80000000);
break;
case 2: /* FSGNJX */
sregs->fsi[frd + BEH] = sregs->fsi[frs1 + BEH];
diff --git a/sis.c b/sis.c
index 2dc76ce..51005f6 100644
--- a/sis.c
+++ b/sis.c
@@ -63,7 +63,7 @@ main (argc, argv)
int lcputype = 0;
printf
- ("\n SIS - SPARC/RISCV instruction simulator %s, copyright Jiri Gaisler 2019\n",
+ ("\n SIS - SPARC/RISCV instruction simulator %s, copyright Jiri Gaisler 2020\n",
sis_version);
printf (" Bug-reports to jiri@gaisler.se\n\n");
@@ -99,6 +99,11 @@ main (argc, argv)
cfile = argv[++stat];
}
}
+ else if (strcmp (argv[stat], "-bridge") == 0)
+ {
+ if ((stat + 1) < argc)
+ strncpy (bridge, argv[++stat], 31);
+ }
else if (strcmp (argv[stat], "-cov") == 0)
ebase.coven = 1;
else if (strcmp (argv[stat], "-nfp") == 0)
diff --git a/sis.h b/sis.h
index 4eccb83..e1df142 100644
--- a/sis.h
+++ b/sis.h
@@ -325,6 +325,7 @@ extern void int_handler (int sig);
extern uint32 daddr;
extern void l1data_update (uint32 address, uint32 cpu);
extern void l1data_snoop (uint32 address, uint32 cpu);
+extern char bridge[];
extern int sync_rt;
extern void rt_sync();
@@ -359,6 +360,8 @@ struct memsys
int (*sis_memory_write) (uint32 addr, const char *data, uint32 length);
int (*sis_memory_read) (uint32 addr, char *data, uint32 length);
void (*boot_init) (void);
+ char *(*get_mem_ptr) (uint32 addr, uint32 size);
+ void (*set_irq) (int32 level);
};
extern const struct memsys *ms;
@@ -368,7 +371,6 @@ extern const struct memsys leon2;
/* leon3.c */
extern const struct memsys leon3;
-
/* remote.c */
extern void gdb_remote (int port);
@@ -390,6 +392,16 @@ extern int sim_clear_watchpoint (uint32 mem, int length, int type);
/* sparc.c */
extern int gdb_sp_read (uint32 mem, char *buf, int length);
+/* greth.c */
+extern uint32 greth_read (uint32 address);
+extern void greth_write (uint32 address, uint32 data);
+extern void greth_rxready(unsigned char *buffer, int len);
+
+/* tap.c */
+
+extern int sis_tap_init (long unsigned emac);
+extern int sis_tap_write (unsigned char *buffer, int len);
+
/* FPU timing based on Meiko */
#define T_FABSs 2
diff --git a/sis.info b/sis.info
index 2aba13c..8a03051 100644
--- a/sis.info
+++ b/sis.info
@@ -1,8 +1,8 @@
This is sis.info, produced by makeinfo version 6.5 from sis.texi.
-This manual is for SIS (version 2.22, 31 May 2019).
+This manual is for SIS (version 2.23, 25 October 2020).
- Copyright (C) 2019 Free Software Foundation, Inc.
+ Copyright (C) 2020 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
@@ -21,7 +21,7 @@ File: sis.info, Node: Top, Next: Introduction, Up: (dir)
SIS
***
-This manual is for SIS (version 2.22, 31 May 2019).
+This manual is for SIS (version 2.23, 25 October 2020).
* Menu:
@@ -30,6 +30,7 @@ This manual is for SIS (version 2.22, 31 May 2019).
* Commands ::
* Emulated Systems ::
* Multi-processing ::
+* Networking ::
* Interfacing to GDB ::
* Code coverage ::
* Building SIS ::
@@ -75,6 +76,11 @@ The simulator is started as follows:
The following options are recognized:
+'-bridge BRIDGE'
+ Connect the tap device used for networking to the host BRIDGE.
+ Typical values are br0 or lxcbr0. Requires running SIS with
+ sudo/root.
+
'-c FILE'
Read sis commands from FILE at startup.
@@ -118,6 +124,11 @@ The simulator is started as follows:
Start execution immediately without an interactive shell. This is
useful for automated testing.
+'-rt'
+ Real-time mode. When enabled, the simulator tries to synchronize
+ the simulator time to the wall (host) time. Useful for interactive
+ programs. Enabled by default when networking is used.
+
'-riscv'
Emulate a RISC-V RV32IMACFD processor
@@ -568,8 +579,8 @@ power-down mode.
In LEON3 mode, SIS emulates a LEON3 system as defined in the GRLIP IP
manual. The emulated system includes the standard peripherals such as
-APBUART, GPTIMER, IRQMP and SRCTRL. The emulated system includes 16
-Mbyte ROM and 16 Mbyte RAM. The SPARC emulation supports an FPU but not
+APBUART, GPTIMER, IRQMP and SRCTRL. The emulated system includes 32
+Mbyte ROM and 32 Mbyte RAM. The SPARC emulation supports an FPU but not
the LEON3 MMU.
To start sis in LEON3 mode, use the -leon3 switch.
@@ -585,6 +596,7 @@ APBMAST 0x80000000 -
APBUART 0x80000100 3
IRQMP 0x80000200 -
GPTIMER 0x80000300 8, 9
+GRETH 0x80000B00 6
4.3.2 Memory interface
----------------------
@@ -637,7 +649,7 @@ time and timeh CSR. The timer does not generare any interrupt and the
timecmp register is not implemented.

-File: sis.info, Node: Multi-processing, Next: Interfacing to GDB, Prev: Emulated Systems, Up: Top
+File: sis.info, Node: Multi-processing, Next: Networking, Prev: Emulated Systems, Up: Top
5 Multi-processing
******************
@@ -651,9 +663,145 @@ time-slices can be selected using -d <clocks>.
simulator where n can be 2 - 4.

-File: sis.info, Node: Interfacing to GDB, Next: Code coverage, Prev: Multi-processing, Up: Top
+File: sis.info, Node: Networking, Next: Interfacing to GDB, Prev: Multi-processing, Up: Top
+
+6 Networking
+************
+
+6.1 Introduction
+================
+
+SIS supports the emulation of the GRLIB/GRETH 10/100 Mbit network
+interface, for leon3 and RISC-V targets. The network interface creates
+a tun/tap interface on the host, through which ethernet packets can be
+sent and received.
+
+ The tap device is automatically created when the application enables
+the GRETH core. The tap can optionally be connected to a host bridge
+using -bridge br0 or similar at invocation. Networking requires SIS to
+be run as root or with sudo.
+
+ Networking is currently only supported on 64-bit linux hosts. On
+other hosts, the networking emaultion is disabled during compilation.
+
+6.2 Emulation of GRETH
+======================
+
+The 10/100 Mbit GRETH interface is emulated accurately and allows
+execution of unmodified target applications using the network interface.
+An ethernet PHY connected to the GRETH MDIO interface is also emulated
+and indicates 100 Mbit connection when accessed.
+
+ The ethernet address of the host tap is equal to what the application
+programs into the GRETH MAC registers. Care has to be taken so that a
+valid ethernet address is choosen or the host can reject the address and
+a mismatch error will occur. The ethernet address cannot be changed
+once it has been set.
+
+ DMA operation and interrupt generation operates as defind in the
+GRETH specification. There is no support for multi-cast or the EDCL
+debug support link.
+
+6.3 Usage
+=========
+
+To simplify operation, a bridge should be created on the linux host
+using brctl or similar. This will create an isolated environment for
+network applications. Installing the lxc package on the host will in
+most cases automatically create a bridge called lxcbr0 with subnet
+10.0.3.1. The network applications should then be configured to use an
+IP on the bridge subnet. Below is an example of SIS runnig the ttcp
+performance application under RTEMS:
+
+ $ sudo ./sis -riscv ./ttcp.exe -bridge lxcbr0
+
+ SIS - SPARC/RISCV instruction simulator 2.23
+ RISCV emulation enabled, 1 cpus online, delta 50 clocks
+ Loaded ttcp.exe, entry 0x40000000
+
+ sis> run
+
+ net: using tap0, ether 829991919191, bridge lxcbr0
+ greth: driver attached
+ **** PHY ****
+ Vendor: 885 Device: 11 Revision: 2
+ Current Operating Mode: 100 Mbit Full Duplex
+ Autonegotiation Time: 0ms
+ >>> ttcp -rs
+ ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
+ ttcp-r: socket
+ ttcp-r: accept from 10.0.3.1
+ ttcp-r: 3012285 bytes in 0.53 real seconds = 5580.46 KB/sec +++
+ ttcp-r: 453 I/O calls, msec/call = 1.19, calls/sec = 859.35
+ ttcp-r: 0.0user 0.0sys 0:00real 100% 0i+0d 0maxrss 0+0pf 0+0csw
+ -----------------------------------------------------------------------
+ CPU USAGE BY THREAD
+ ------------+--------------------------------+---------------+---------
+ ID | NAME | SECONDS | PERCENT
+ ------------+--------------------------------+---------------+---------
+ 0x09010001 | IDLE | 5.643012 | 91.406
+ 0x0a010001 | UI1 | 0.000000 | 0.000
+ 0x0a010002 | ntwk | 0.118958 | 1.926
+ 0x0a010003 | DCrx | 0.337919 | 5.472
+ 0x0a010004 | TTCP | 0.074758 | 1.210
+ ------------+--------------------------------+---------------+---------
+ TIME SINCE LAST CPU USAGE RESET IN SECONDS: 6.174651
+ -----------------------------------------------------------------------
+ ************ MBUF STATISTICS ************
+ mbufs:2048 clusters: 128 free: 96
+ drops: 0 waits: 0 drains: 0
+ free:2015 data:33 header:0 socket:0
+ pcb:0 rtable:0 htable:0 atable:0
+ soname:0 soopts:0 ftable:0 rights:0
+ ifaddr:0 control:0 oobdata:0
+ ************ INTERFACE STATISTICS ************
+ ***** lo0 *****
+ Address:127.0.0.1 Net mask:255.0.0.0
+ Flags: Up Loopback Running Multicast
+ Send queue limit:50 length:0 Dropped:0
+ ***** gr_eth1 *****
+ Ethernet Address: 82:99:91:91:91:91
+ Address:10.0.3.2 Broadcast Address:10.0.3.255 Net mask:255.255.255.0
+ Flags: Up Broadcast Running Simplex
+ Send queue limit:50 length:0 Dropped:0
+ Rx Interrupts:186 Rx Packets:2234 Length:0 Non-octet:0
+ Bad CRC:0 Overrun:0 Tx Interrupts:0 Maximal Frags:1 GBIT MAC:0
+ ************ IP Statistics ************
+ total packets received 2233
+ datagrams delivered to upper level 2233
+ total ip packets generated here 369
+ ************ TCP Statistics ************
+ connections accepted 1
+ connections established 1
+ conn. closed (includes drops) 1
+ segs where we tried to get rtt 2
+ times we succeeded 2
+ delayed acks sent 3
+ total packets sent 369
+ ack-only packets sent 5
+ window update-only packets sent 363
+ control (SYN|FIN|RST) packets sent 1
+ total packets received 2233
+ packets received in sequence 2230
+ bytes received in sequence 3012285
+ rcvd ack packets 2
+ bytes acked by rcvd acks 2
+ times hdr predict ok for data pkts 2228
+ *** FATAL ***
+ fatal source: 5 (RTEMS_FATAL_SOURCE_EXIT)
+ fatal code: 0 (0x00000000)
+ RTEMS version: 6.0.0.c1164b650a2754335b15910e6408a9b144aa5162
+ RTEMS tools: 10.2.1 20200918 (RTEMS 6, RSB ed5030bc24dbfdfac52074ed78cf4231bf1f353d, Newlib 749cbcc)
+ executing thread ID: 0x08a010004
+ executing thread name: TTCP
+ cpu 0 in error mode (tt = 0x101)
+ 445299412 4004af30: 00000073 ecall
+ sis>
+
+
+File: sis.info, Node: Interfacing to GDB, Next: Code coverage, Prev: Networking, Up: Top
-6 Interfacing to GDB
+7 Interfacing to GDB
********************
SIS can be connected to gdb through a network socket using the gdb
@@ -664,7 +812,7 @@ localhost:1234'. The port can be changed using the -port option.

File: sis.info, Node: Code coverage, Next: Building SIS, Prev: Interfacing to GDB, Up: Top
-7 Code coverage
+8 Code coverage
***************
Code coverage data will be produce if sis is started with the -cov
@@ -689,7 +837,7 @@ i.e. the C-extension can not be used when code coverage is measured.

File: sis.info, Node: Building SIS, Next: GNU Free Documentation License, Prev: Code coverage, Up: Top
-8 Building SIS
+9 Building SIS
**************
SIS uses the GNU autoconf system, and can simply be build using
@@ -698,7 +846,7 @@ do 'make sis.pdf'.
The following custom configure options are recognized:
-'-enable-l1cache'
+'--enable-l1cache'
Enable the emulation of a L1 cache in multi-processor systems.
Each core in an MP LEON3/RISC-V system will have a 4Kbyte
instruction cache and a 4 Kbyte data cache. The cache only affects
@@ -1203,21 +1351,23 @@ Index
* Introduction: Introduction. (line 6)
* invoking sis: Invoking sis. (line 6)
* Multi-processing: Multi-processing. (line 6)
+* Networking: Networking. (line 5)
* sis: Invoking sis. (line 6)

Tag Table:
-Node: Top696
-Node: Introduction1029
-Node: Invoking sis1653
-Node: Commands3706
-Node: Emulated Systems7810
-Node: Multi-processing20477
-Node: Interfacing to GDB20973
-Node: Code coverage21383
-Node: Building SIS22388
-Node: GNU Free Documentation License23037
-Node: Index48181
+Node: Top700
+Node: Introduction1053
+Node: Invoking sis1677
+Node: Commands4109
+Node: Emulated Systems8213
+Node: Multi-processing20925
+Node: Networking21413
+Node: Interfacing to GDB27723
+Node: Code coverage28127
+Node: Building SIS29132
+Node: GNU Free Documentation License29782
+Node: Index54926

End Tag Table
diff --git a/sis.texi b/sis.texi
index abc7e68..51d20c8 100644
--- a/sis.texi
+++ b/sis.texi
@@ -50,6 +50,7 @@ This manual is for SIS (version @value{VERSION}, @value{UPDATED}).
* Commands ::
* Emulated Systems ::
* Multi-processing ::
+* Networking ::
* Interfacing to GDB ::
* Code coverage ::
* Building SIS ::
@@ -100,6 +101,9 @@ sis [options] [file]
The following options are recognized:
@table @code
+@item -bridge @var{bridge}
+Connect the tap device used for networking to the host @var{bridge}. Typical values are br0 or lxcbr0. Requires running SIS with sudo/root.
+
@item -c @var{file}
Read sis commands from @var{file} at startup.
@@ -142,6 +146,9 @@ Use @var{port} for the gdb server. Default is port 1234.
Start execution immediately without an interactive shell. This is useful
for automated testing.
+@item -rt
+Real-time mode. When enabled, the simulator tries to synchronize the simulator time to the wall (host) time. Useful for interactive programs. Enabled by default when networking is used.
+
@item -riscv
Emulate a RISC-V RV32IMACFD processor
@@ -576,8 +583,8 @@ A Ctrl-C in the simulator window will exit the power-down mode.
@section LEON3 emulation
In LEON3 mode, SIS emulates a LEON3 system as defined in the GRLIP IP manual.
-The emulated system includes the standard peripherals such as APBUART, GPTIMER, IRQMP and SRCTRL. The emulated system includes 16 Mbyte ROM
-and 16 Mbyte RAM. The SPARC emulation supports an FPU but not the LEON3 MMU.
+The emulated system includes the standard peripherals such as APBUART, GPTIMER, IRQMP and SRCTRL. The emulated system includes 32 Mbyte ROM
+and 32 Mbyte RAM. The SPARC emulation supports an FPU but not the LEON3 MMU.
To start sis in LEON3 mode, use the -leon3 switch.
@@ -591,6 +598,7 @@ The following IP cores from GRLIB are emulated in LEON3 mode:
@item APBUART @tab 0x80000100 @tab 3
@item IRQMP @tab 0x80000200 @tab -
@item GPTIMER @tab 0x80000300 @tab 8, 9
+@item GRETH @tab 0x80000B00 @tab 6
@end multitable
@subsection Memory interface
@@ -650,6 +658,113 @@ using -d <clocks>.
To start SIS with SMP, use the switch -m <n> when starting the simulator
where n can be 2 - 4.
+@node Networking
+@chapter Networking
+@cindex Networking
+@section Introduction
+SIS supports the emulation of the GRLIB/GRETH 10/100 Mbit network interface, for leon3 and RISC-V targets. The network interface creates a tun/tap interface on the host, through which ethernet packets can be sent and received.
+
+The tap device is automatically created when the application enables the GRETH core. The tap can optionally be connected to a host bridge using -bridge br0 or similar at invocation. Networking requires SIS to be run as root or with sudo.
+
+Networking is currently only supported on 64-bit linux hosts. On other hosts, the networking emaultion is disabled during compilation.
+
+@section Emulation of GRETH
+The 10/100 Mbit GRETH interface is emulated accurately and allows execution of unmodified target applications using the network interface. An ethernet PHY connected to the GRETH MDIO interface is also emulated and indicates 100 Mbit connection when accessed.
+
+The ethernet address of the host tap is equal to what the application programs into the GRETH MAC registers. Care has to be taken so that a valid ethernet address is choosen or the host can reject the address and a mismatch error will occur. The ethernet address cannot be changed once it has been set.
+
+DMA operation and interrupt generation operates as defind in the GRETH specification. There is no support for multi-cast or the EDCL debug support link.
+
+@section Usage
+To simplify operation, a bridge should be created on the linux host using brctl or similar. This will create an isolated environment for network applications. Installing the lxc package on the host will in most cases automatically create a bridge called lxcbr0 with subnet 10.0.3.1. The network applications should then be configured to use an IP on the bridge subnet. Below is an example of SIS runnig the ttcp performance application under RTEMS:
+
+@example
+$ sudo ./sis -riscv ./ttcp.exe -bridge lxcbr0
+
+ SIS - SPARC/RISCV instruction simulator 2.23
+ RISCV emulation enabled, 1 cpus online, delta 50 clocks
+ Loaded ttcp.exe, entry 0x40000000
+
+sis> run
+
+net: using tap0, ether 829991919191, bridge lxcbr0
+greth: driver attached
+**** PHY ****
+Vendor: 885 Device: 11 Revision: 2
+Current Operating Mode: 100 Mbit Full Duplex
+Autonegotiation Time: 0ms
+>>> ttcp -rs
+ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
+ttcp-r: socket
+ttcp-r: accept from 10.0.3.1
+ttcp-r: 3012285 bytes in 0.53 real seconds = 5580.46 KB/sec +++
+ttcp-r: 453 I/O calls, msec/call = 1.19, calls/sec = 859.35
+ttcp-r: 0.0user 0.0sys 0:00real 100% 0i+0d 0maxrss 0+0pf 0+0csw
+-----------------------------------------------------------------------
+ CPU USAGE BY THREAD
+------------+--------------------------------+---------------+---------
+ ID | NAME | SECONDS | PERCENT
+------------+--------------------------------+---------------+---------
+ 0x09010001 | IDLE | 5.643012 | 91.406
+ 0x0a010001 | UI1 | 0.000000 | 0.000
+ 0x0a010002 | ntwk | 0.118958 | 1.926
+ 0x0a010003 | DCrx | 0.337919 | 5.472
+ 0x0a010004 | TTCP | 0.074758 | 1.210
+------------+--------------------------------+---------------+---------
+ TIME SINCE LAST CPU USAGE RESET IN SECONDS: 6.174651
+-----------------------------------------------------------------------
+************ MBUF STATISTICS ************
+mbufs:2048 clusters: 128 free: 96
+drops: 0 waits: 0 drains: 0
+ free:2015 data:33 header:0 socket:0
+ pcb:0 rtable:0 htable:0 atable:0
+ soname:0 soopts:0 ftable:0 rights:0
+ ifaddr:0 control:0 oobdata:0
+************ INTERFACE STATISTICS ************
+***** lo0 *****
+Address:127.0.0.1 Net mask:255.0.0.0
+Flags: Up Loopback Running Multicast
+Send queue limit:50 length:0 Dropped:0
+***** gr_eth1 *****
+Ethernet Address: 82:99:91:91:91:91
+Address:10.0.3.2 Broadcast Address:10.0.3.255 Net mask:255.255.255.0
+Flags: Up Broadcast Running Simplex
+Send queue limit:50 length:0 Dropped:0
+Rx Interrupts:186 Rx Packets:2234 Length:0 Non-octet:0
+Bad CRC:0 Overrun:0 Tx Interrupts:0 Maximal Frags:1 GBIT MAC:0
+************ IP Statistics ************
+ total packets received 2233
+ datagrams delivered to upper level 2233
+ total ip packets generated here 369
+************ TCP Statistics ************
+ connections accepted 1
+ connections established 1
+ conn. closed (includes drops) 1
+ segs where we tried to get rtt 2
+ times we succeeded 2
+ delayed acks sent 3
+ total packets sent 369
+ ack-only packets sent 5
+ window update-only packets sent 363
+ control (SYN|FIN|RST) packets sent 1
+ total packets received 2233
+ packets received in sequence 2230
+ bytes received in sequence 3012285
+ rcvd ack packets 2
+ bytes acked by rcvd acks 2
+ times hdr predict ok for data pkts 2228
+*** FATAL ***
+fatal source: 5 (RTEMS_FATAL_SOURCE_EXIT)
+fatal code: 0 (0x00000000)
+RTEMS version: 6.0.0.c1164b650a2754335b15910e6408a9b144aa5162
+RTEMS tools: 10.2.1 20200918 (RTEMS 6, RSB ed5030bc24dbfdfac52074ed78cf4231bf1f353d, Newlib 749cbcc)
+executing thread ID: 0x08a010004
+executing thread name: TTCP
+cpu 0 in error mode (tt = 0x101)
+ 445299412 4004af30: 00000073 ecall
+sis>
+@end example
+
@node Interfacing to GDB
@chapter Interfacing to GDB
@cindex Interfacing to GDB
@@ -691,7 +806,7 @@ manual, do @code{make sis.pdf}.
The following custom configure options are recognized:
@table @code
-@item -enable-l1cache
+@item --enable-l1cache
Enable the emulation of a L1 cache in multi-processor systems. Each core in an
MP LEON3/RISC-V system will have a 4Kbyte instruction cache and a 4 Kbyte data
cache. The cache only affects instruction timing, and has no effect on instruction
diff --git a/sparc.c b/sparc.c
index 01cbe04..82a9ed4 100644
--- a/sparc.c
+++ b/sparc.c
@@ -917,7 +917,7 @@ sparc_dispatch_instruction (sregs)
{
pwd_enter (sregs);
if (sync_rt)
- rt_sync();
+ rt_sync ();
}
}
break;
diff --git a/tap.c b/tap.c
new file mode 100644
index 0000000..a3958af
--- /dev/null
+++ b/tap.c
@@ -0,0 +1,222 @@
+/* Based on Documentation/networking/tuntap.txt */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "sis.h"
+#ifdef __linux__
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/if_tun.h>
+#include <linux/if_bridge.h>
+#include <net/if_arp.h> /* for ARPHRD_ETHER */
+#include <arpa/inet.h>
+#include <poll.h>
+
+#define POLLTIME 5000
+
+static struct ifreq ifr;
+static int fd, err, sockfd;
+static char dev[64];
+static int tun_fd, nread, br_socket_fd;
+static int br_add_interface (const char *bridge, const char *dev);
+static void sis_tap_poll ();
+
+int
+sis_tap_init (long unsigned emac)
+{
+ int i;
+ long unsigned xmac, xmac2;
+ if (fd)
+ return 1;
+ if ((fd = open ("/dev/net/tun", O_RDWR)) < 0)
+ {
+ printf ("Cannot open TUN/TAP dev\n");
+ return 0;
+ }
+
+ memset (&ifr, 0, sizeof (ifr));
+
+ /* Flags: IFF_TUN - TUN device (no Ethernet headers)
+ * IFF_TAP - TAP device
+ *
+ * IFF_NO_PI - Do not provide packet information
+ */
+
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+
+ if ((err = ioctl (fd, TUNSETIFF, (void *) &ifr)) < 0)
+ {
+ printf ("ERR: Could not ioctl tun: %s\n", strerror (errno));
+ close (fd);
+ return 0;
+ }
+
+ strcpy (dev, ifr.ifr_name);
+
+ sockfd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
+
+ ifr.ifr_flags = IFF_UP;
+ if ((err = ioctl (sockfd, SIOCSIFFLAGS, (void *) &ifr)) < 0)
+ {
+ printf ("net: could not enable tun %s\n", strerror (errno));
+ close (fd);
+ close (sockfd);
+ return 0;
+ }
+
+ ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
+
+ xmac = 0;
+ for (i = 0; i < 6; i++)
+ {
+ xmac <<= 8;
+ xmac |= (emac >> (i * 8)) & 0x0ff;
+ }
+
+ xmac2 = xmac;
+
+ memcpy (ifr.ifr_hwaddr.sa_data, &xmac, 6);
+ if (ioctl (sockfd, SIOCSIFHWADDR, &ifr) < 0)
+ {
+ printf ("net: hwaddr error\n");
+ close (fd);
+ close (sockfd);
+ return 0;
+ }
+
+ if (ioctl (sockfd, SIOCGIFHWADDR, &ifr) < 0)
+ {
+ printf ("net: hwaddr error\n");
+ close (fd);
+ close (sockfd);
+ return 0;
+ }
+ memcpy (&xmac, ifr.ifr_hwaddr.sa_data, 6);
+
+ if (xmac != xmac2)
+ {
+ printf ("net: could not set hwaddr\n");
+ close (fd);
+ close (sockfd);
+ return 0;
+ }
+
+ printf ("net: using %s, ether %lx", dev, emac);
+ if (bridge[0])
+ {
+ if (br_add_interface (bridge, dev))
+ {
+ printf ("ERR: Could not attach %s to bridge %s: %s\n",
+ dev, bridge, strerror (errno));
+ /*
+ close (fd);
+ close (sockfd);
+ return 0;
+ */
+ }
+ else
+ printf (", bridge %s\n", bridge);
+ }
+ printf ("\n");
+ tun_fd = fd;
+ event (sis_tap_poll, 0, POLLTIME);
+ return 1;
+}
+
+int
+sis_tap_write (unsigned char *buffer, int len)
+{
+ int i, nwrite;
+ nwrite = write (tun_fd, buffer, len);
+ if (nread < 0)
+ {
+ perror ("Writing from interface");
+ close (tun_fd);
+ exit (1);
+ }
+ if (sis_verbose)
+ {
+ printf ("Write %d bytes to device %s\n", len, dev);
+ for (i = 0; i < len; i++)
+ printf ("%02x", buffer[i]);
+ printf ("\n");
+ }
+}
+
+static void
+sis_tap_poll ()
+{
+ struct pollfd fds[1];
+ int ret;
+ unsigned char buffer[1536];
+
+ fds[0].fd = tun_fd;
+ fds[0].events = POLLRDNORM;
+ ret = poll (fds, 1, 0);
+
+ if (ret > 0)
+ {
+ if (fds[0].revents & POLLRDNORM)
+ {
+ nread = read (tun_fd, buffer, 1536);
+ if (nread < 0)
+ {
+ perror ("Reading from interface");
+ close (tun_fd);
+ exit (1);
+ }
+ greth_rxready (buffer, nread);
+ }
+ }
+ event (sis_tap_poll, 0, POLLTIME);
+}
+
+/* Attach tap device to bridge */
+/* Taken from bridge-utils-1.6 */
+static int
+br_add_interface (const char *bridge, const char *dev)
+{
+ struct ifreq ifr;
+ int err;
+ int ifindex = if_nametoindex (dev);
+
+ if ((br_socket_fd = socket (AF_LOCAL, SOCK_STREAM, 0)) < 0)
+ return ENODEV;
+ if (ifindex == 0)
+ return ENODEV;
+
+ strncpy (ifr.ifr_name, bridge, IFNAMSIZ);
+#ifdef SIOCBRADDIF
+ ifr.ifr_ifindex = ifindex;
+ err = ioctl (br_socket_fd, SIOCBRADDIF, &ifr);
+#endif
+ {
+ unsigned long args[4] = { BRCTL_ADD_IF, ifindex, 0, 0 };
+
+ ifr.ifr_data = (char *) args;
+ err = ioctl (br_socket_fd, SIOCDEVPRIVATE, &ifr);
+ }
+
+ return err < 0 ? errno : 0;
+}
+
+#else
+
+int
+sis_tap_init (long unsigned emac)
+{
+ printf ("Error: networking not supported on this host\n");
+}
+
+int
+sis_tap_write (unsigned char *buffer, int len)
+{
+ printf ("Error: networking not supported on this host\n");
+}
+#endif
diff --git a/version.texi b/version.texi
index 07ecec6..d00f73d 100644
--- a/version.texi
+++ b/version.texi
@@ -1,4 +1,4 @@
-@set UPDATED 9 September 2020
-@set UPDATED-MONTH September 2020
-@set EDITION 2.22
-@set VERSION 2.22
+@set UPDATED 25 October 2020
+@set UPDATED-MONTH October 2020
+@set EDITION 2.23
+@set VERSION 2.23