summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Gaisler <jiri@gaisler.se>2021-04-11 20:20:15 +0200
committerJiri Gaisler <jiri@gaisler.se>2021-06-10 22:04:11 +0200
commit88914409e05680b1bf0731f6a2abb6716fb2020f (patch)
tree5e258c8978535f7a0ef63142848ddcb2e487b2e0
parentFix build failures on windows (diff)
downloadsis-88914409e05680b1bf0731f6a2abb6716fb2020f.tar.bz2
Added simple RISC-V PLIC functionality for NS16550 interrupt
* RTEMS spconsole01 test now passes
-rwxr-xr-xconfigure20
-rw-r--r--configure.ac2
-rw-r--r--grlib.c263
-rw-r--r--riscv.c9
-rw-r--r--rv32.c4
-rw-r--r--sis.info11
-rw-r--r--version.texi6
7 files changed, 228 insertions, 87 deletions
diff --git a/configure b/configure
index 023ecd8..34a8e0e 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.26.
+# Generated by GNU Autoconf 2.69 for sis 2.27.
#
#
# 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.26'
-PACKAGE_STRING='sis 2.26'
+PACKAGE_VERSION='2.27'
+PACKAGE_STRING='sis 2.27'
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.26 to adapt to many kinds of systems.
+\`configure' configures sis 2.27 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.26:";;
+ short | recursive ) echo "Configuration of sis 2.27:";;
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.26
+sis configure 2.27
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.26, which was
+It was created by sis $as_me 2.27, 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.26'
+ VERSION='2.27'
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.26, which was
+This file was extended by sis $as_me 2.27, 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.26
+sis config.status 2.27
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index b824fba..6396586 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([sis], [2.26])
+AC_INIT([sis], [2.27])
AC_CONFIG_SRCDIR([sis.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS(config.h)
diff --git a/grlib.c b/grlib.c
index fc99df9..7982059 100644
--- a/grlib.c
+++ b/grlib.c
@@ -244,7 +244,7 @@ greth_add (int irq, uint32 addr, uint32 mask)
GRLIB_PP_APBADDR (addr, mask));
greth_irq = irq;
if (sis_verbose)
- printf(" GRETH 10/100 Mbit Ethernet core 0x%08x %d\n", addr, irq);
+ printf (" GRETH 10/100 Mbit Ethernet core 0x%08x %d\n", addr, irq);
}
const struct grlib_ipcore greth = {
@@ -259,7 +259,7 @@ leon3_add ()
{
grlib_ahbmpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_LEON3, 0, 0));
if (sis_verbose)
- printf(" LEON3 SPARC V8 processor \n");
+ printf (" LEON3 SPARC V8 processor \n");
}
const struct grlib_ipcore leon3s = {
@@ -334,7 +334,7 @@ apbmst_add (int irq, uint32 addr, uint32 mask)
grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_APBMST, 0, 0),
GRLIB_PP_AHBADDR (addr, mask, 0, 0, 2), 0, 0, 0);
if (sis_verbose)
- printf(" AHB/APB Bridge 0x%08x\n", addr);
+ printf (" AHB/APB Bridge 0x%08x\n", addr);
}
const struct grlib_ipcore apbmst = {
@@ -598,7 +598,7 @@ irqmp_add (int irq, uint32 addr, uint32 mask)
grlib_apbpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_IRQMP, 2, 0),
GRLIB_PP_APBADDR (addr, mask));
if (sis_verbose)
- printf(" IRQMP Interrupt controller 0x%08x\n", addr);
+ printf (" IRQMP Interrupt controller 0x%08x\n", addr);
}
const struct grlib_ipcore irqmp = {
@@ -671,7 +671,7 @@ gpt_add (int irq, uint32 addr, uint32 mask)
GRLIB_PP_APBADDR (addr, mask));
gpt_irq = irq;
if (sis_verbose)
- printf(" GPTIMER timer unit 0x%08x %d\n", addr, irq);
+ printf (" GPTIMER timer unit 0x%08x %d\n", addr, irq);
}
static void
@@ -1223,7 +1223,7 @@ apbuart_add (int irq, uint32 addr, uint32 mask)
grlib_apbpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_APBUART, 1, irq),
GRLIB_PP_APBADDR (addr, mask));
if (sis_verbose)
- printf(" APBUART serial port 0x%08x %d\n", addr, irq);
+ printf (" APBUART serial port 0x%08x %d\n", addr, irq);
}
const struct grlib_ipcore apbuart = {
@@ -1280,7 +1280,7 @@ sdctrl_add (int irq, uint32 addr, uint32 mask)
grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_SDCTRL, 0, 0),
GRLIB_PP_AHBADDR (addr, mask, 1, 1, 2), 0, 0, 0);
if (sis_verbose)
- printf(" SDRAM controller %d M 0x%08x\n",
+ printf (" SDRAM controller %d M 0x%08x\n",
(~(mask << 20) + 1) >> 20, addr);
}
@@ -1311,7 +1311,7 @@ srctrl_add (int irq, uint32 addr, uint32 mask)
grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_SRCTRL, 0, 0),
GRLIB_PP_AHBADDR (addr, mask, 1, 1, 2), 0, 0, 0);
if (sis_verbose)
- printf(" PROM controller %d M 0x%08x\n",
+ printf (" PROM controller %d M 0x%08x\n",
(~(mask << 20) + 1) >> 20, addr);
}
@@ -1334,48 +1334,69 @@ grlib_boot_init (void)
}
/* ------------------- ns16550 -----------------------*/
-
-static int32 uart_lcr;
+static void plic_irq (int irq);
+static int32 uart_lcr, uart_ie, uart_mcr, ns16550_irq, uart_txctrl;
static void
ns16550_add (int irq, uint32 addr, uint32 mask)
{
grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_CONTRIB, CONTRIB_NS16550, 0, 0),
GRLIB_PP_AHBADDR (addr, mask, 0, 0, 2), 0, 0, 0);
+ ns16550_irq = irq;
if (sis_verbose)
- printf(" NS16550 UART 0x%08x %d\n", addr, irq);
+ printf (" NS16550 UART 0x%08x %d\n", addr, irq);
}
static int
ns16550_write (uint32 addr, uint32 * data, uint32 sz)
{
- switch (addr & 0xff)
+ switch (addr & 0xff)
+ {
+ case 0:
+ if (!uart_lcr)
{
- case 0:
- if (!uart_lcr)
- putchar (*data & 0xff);
- break;
- case 0x0c:
- uart_lcr = *data & 0x80;
- break;
+ putchar (*data & 0xff);
}
+ break;
+ case 4:
+ if (!uart_lcr)
+ uart_ie = *data & 0xff;
+ break;
+ case 0x08:
+ uart_txctrl = *data & 0xff;
+ break;
+ case 0x0c:
+ uart_lcr = *data & 0x80;
+ break;
+ case 0x10:
+ uart_mcr = *data & 0xff;
+ break;
+ }
+ if ((uart_ie & 0x2) && (uart_mcr & 0x8))
+ plic_irq (ns16550_irq);
return 1;
}
static int
ns16550_read (uint32 addr, uint32 * data)
{
- *data = 0;
- switch (addr & 0xff)
- {
- case 0x10:
- *data = 0x03;
- break;
- case 0x14:
- *data = 0x60;
- break;
- }
+ *data = 0;
+ switch (addr & 0xff)
+ {
+ case 0x04:
+ *data = uart_ie;
+ break;
+ case 0x08:
+ *data = uart_txctrl;
+ break;
+ case 0x10:
+ *data = uart_mcr; //0x03;
+ break;
+ case 0x14:
+ *data = 0x60;
+ break;
+ }
return 4;
}
@@ -1383,6 +1404,8 @@ static void
ns16550_reset (void)
{
uart_lcr = 0;
+ uart_ie = 0;
+ uart_mcr = 0;
}
const struct grlib_ipcore ns16550 = {
@@ -1397,7 +1420,7 @@ clint_add (int irq, uint32 addr, uint32 mask)
grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_CONTRIB, CONTRIB_CLINT, 0, 0),
GRLIB_PP_AHBADDR (addr, mask, 0, 0, 2), 0, 0, 0);
if (sis_verbose)
- printf(" CLINT Interrupt controller 0x%08x %d\n", addr, irq);
+ printf (" CLINT Interrupt controller 0x%08x %d\n", addr, irq);
}
#define CLINTSTART 0x00000
@@ -1410,29 +1433,29 @@ clint_read (uint32 addr, uint32 * data)
uint64 tmp;
int reg, cpuid;
- reg = (addr >> 2) & 1;
- cpuid = ((addr >> 3) % NCPU);
- if ((addr >= CLINT_TIMEBASE) && (addr < CLINTEND))
- {
- tmp = ebase.simtime >> 32;
- if (reg)
- *data = tmp & 0xffffffff;
- else
- *data = ebase.simtime & 0xffffffff;
- }
- else if ((addr >= CLINT_TIMECMP) && (addr < CLINT_TIMEBASE))
- {
- tmp = sregs[cpuid].mtimecmp >> 32;
- if (reg)
- *data = tmp & 0xffffffff;
- else
- *data = sregs[cpuid].mtimecmp & 0xffffffff;
- }
- else if ((addr >= 0) && (addr < CLINT_TIMECMP))
- {
- cpuid = ((addr >> 2) % NCPU);
- *data = ((sregs[cpuid].mip & MIP_MSIP) >> 4) & 1;
- }
+ reg = (addr >> 2) & 1;
+ cpuid = ((addr >> 3) % NCPU);
+ if ((addr >= CLINT_TIMEBASE) && (addr < CLINTEND))
+ {
+ tmp = ebase.simtime >> 32;
+ if (reg)
+ *data = tmp & 0xffffffff;
+ else
+ *data = ebase.simtime & 0xffffffff;
+ }
+ else if ((addr >= CLINT_TIMECMP) && (addr < CLINT_TIMEBASE))
+ {
+ tmp = sregs[cpuid].mtimecmp >> 32;
+ if (reg)
+ *data = tmp & 0xffffffff;
+ else
+ *data = sregs[cpuid].mtimecmp & 0xffffffff;
+ }
+ else if ((addr >= 0) && (addr < CLINT_TIMECMP))
+ {
+ cpuid = ((addr >> 2) % NCPU);
+ *data = ((sregs[cpuid].mip & MIP_MSIP) >> 4) & 1;
+ }
return 4;
}
@@ -1495,7 +1518,115 @@ const struct grlib_ipcore clint = {
};
/* ------------------- plic --------------------------*/
-/* no functionality supported for now */
+/* simplified functionality supported for now */
+
+#define PLIC_PRIO 0
+#define PLIC_IPEND 0x1000
+#define PLIC_IENA 0x2000
+#define PLIC_THRES 0x200000
+#define PLIC_CLAIM 0x200004
+#define PLIC_MASK1 0xFC
+
+static unsigned char plic_prio[64];
+static uint32 plic_ie[NCPU][2];
+static uint32 plic_ip[2];
+static uint32 plic_thres[NCPU];
+static uint32 plic_claim[NCPU];
+
+static void
+plic_check_irq (uint32 hart)
+{
+ int i, irq;
+ if (irq = (plic_ie[hart][0] & plic_ip[0]))
+ {
+ for (i = 1; i < 32; i++)
+ {
+ if ((irq >> i) & 1)
+ plic_claim[hart] = i;
+ }
+ sregs[hart].mip |= MIP_MEIP;
+ }
+}
+
+static void
+plic_irq (int irq)
+{
+ int i;
+ plic_ip[0] |= (1 << irq);
+ for (i = 0; i < NCPU; i++)
+ {
+ plic_check_irq (i);
+ rv32_check_lirq (i);
+ }
+}
+
+static int
+plic_read (uint32 addr, uint32 * data)
+{
+ int hart;
+ if (addr >= PLIC_THRES)
+ {
+ hart = ((addr >> 12) & 0x0F) % NCPU;
+ if ((addr & PLIC_MASK1) == 0)
+ *data = plic_thres[hart]; // irq threshold, not used for now
+ else
+ {
+ *data = plic_claim[hart];
+ plic_claim[hart] = 0;
+ plic_ip[0] &= ~(1 << *data);
+ }
+ }
+ else if (addr >= PLIC_IENA)
+ {
+ hart = ((addr >> 7) & 0x0F) % NCPU;
+ if (addr & 4)
+ *data = plic_ie[hart][1]; // irq enable
+ else
+ *data = plic_ie[hart][0];
+ }
+ else if (addr >= PLIC_IPEND)
+ {
+ hart = ((addr >> 7) & 0x0F) % NCPU;
+ if (addr & 4)
+ *data = plic_ip[1]; // irq pending
+ else
+ *data = plic_ip[0];
+ }
+ else if (addr < PLIC_IPEND)
+ {
+ *data = plic_prio[(addr & 0x0ff) >> 2]; // irq priority, not used for now
+ }
+ if (sis_verbose)
+ printf (" PLIC read 0x%08x %d\n", addr, *data);
+ return 4;
+}
+
+static int
+plic_write (uint32 addr, uint32 * data, uint32 sz)
+{
+ int hart;
+ if (addr >= PLIC_THRES)
+ {
+ hart = ((addr >> 12) & 0x0F) % NCPU;
+ if ((addr & PLIC_MASK1) == 0)
+ plic_thres[hart] = *data; // irq threshold, not used for now
+ else
+ plic_check_irq (hart); // irq completion
+ }
+ else if (addr >= PLIC_IENA)
+ {
+ hart = ((addr >> 7) & 0x0F) % NCPU;
+ if (addr & 4)
+ plic_ie[hart][1] = *data; // irq enable
+ else
+ plic_ie[hart][0] = *data;
+ }
+ else if (addr < PLIC_IPEND)
+ {
+ plic_prio[(addr & 0x0ff) >> 2] = *data; // irq priority, not used for now
+ }
+ return 1;
+}
static void
plic_add (int irq, uint32 addr, uint32 mask)
@@ -1503,11 +1634,11 @@ plic_add (int irq, uint32 addr, uint32 mask)
grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_CONTRIB, CONTRIB_PLIC, 0, 0),
GRLIB_PP_AHBADDR (addr, mask, 0, 0, 2), 0, 0, 0);
if (sis_verbose)
- printf(" PLIC Interrupt controller 0x%08x %d\n", addr, irq);
+ printf (" PLIC Interrupt controller 0x%08x %d\n", addr, irq);
}
const struct grlib_ipcore plic = {
- NULL, NULL, NULL, NULL, plic_add
+ NULL, NULL, plic_read, plic_write, plic_add
};
/* ------------------- sifive test module --------------*/
@@ -1518,17 +1649,17 @@ s5test_write (uint32 addr, uint32 * data, uint32 sz)
{
int i;
- switch (addr & 0xff)
+ switch (addr & 0xff)
+ {
+ case 0:
+ if (*data == 0x5555)
{
- case 0:
- if (*data == 0x5555)
- {
- printf ("Power-off issued, exiting ...\n");
- for (i=0; i< ncpu; i++)
- sregs[i].trap = ERROR_TRAP;
- }
- break;
+ printf ("Power-off issued, exiting ...\n");
+ for (i = 0; i < ncpu; i++)
+ sregs[i].trap = ERROR_TRAP;
}
+ break;
+ }
return 1;
}
@@ -1539,7 +1670,7 @@ s5test_add (int irq, uint32 addr, uint32 mask)
grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_CONTRIB, CONTRIB_S5TEST, 0, 0),
GRLIB_PP_AHBADDR (addr, mask, 0, 0, 2), 0, 0, 0);
if (sis_verbose)
- printf(" S5 Test module 0x%08x %d\n", addr, irq);
+ printf (" S5 Test module 0x%08x %d\n", addr, irq);
}
const struct grlib_ipcore s5test = {
diff --git a/riscv.c b/riscv.c
index 6d8fa98..b36fa1e 100644
--- a/riscv.c
+++ b/riscv.c
@@ -201,7 +201,9 @@ rv32_check_lirq (int cpu)
if (sregs[cpu].mstatus & MSTATUS_MIE)
{
tmpirq = sregs[cpu].mip & sregs[cpu].mie;
- if (tmpirq & MIP_MSIP)
+ if (tmpirq & MIP_MEIP)
+ ext_irl[cpu] = 0x1b;
+ else if (tmpirq & MIP_MSIP)
ext_irl[cpu] = 0x13;
else if (tmpirq & MIP_MTIP)
ext_irl[cpu] = 0x17;
@@ -2080,7 +2082,8 @@ riscv_execute_trap (sregs)
}
if (((sregs->trap >= 16) && (sregs->trap < 32))
- || ((sregs->trap == 0x23) || (sregs->trap == 0x27)))
+ || ((sregs->trap == 0x23) || (sregs->trap == 0x27)
+ || (sregs->trap == 0x2b)))
{
sregs->mcause &= 0x1f; // filter trap cause
sregs->mcause |= 0x80000000; // indicate async interrupt
@@ -2093,6 +2096,8 @@ riscv_execute_trap (sregs)
sregs->mip &= ~MIP_MSIP;
if (sregs->trap == 0x27)
sregs->mip &= ~MIP_MTIP;
+ if (sregs->trap == 0x2b)
+ sregs->mip &= ~MIP_MEIP;
// save mstatus.mie in mstatus.mpie
sregs->mstatus |= (sregs->mstatus << 4) & MSTATUS_MPIE;
diff --git a/rv32.c b/rv32.c
index 305fd1e..73cc523 100644
--- a/rv32.c
+++ b/rv32.c
@@ -69,7 +69,7 @@ init_sim (void)
grlib_ahbs_add (&s5test, 0, TESTSTART, 0xFFF);
grlib_ahbs_add (&clint, 0, CLINT_START, 0xFFF);
grlib_ahbs_add (&plic, 0, PLIC_START, PLIC_MASK);
- grlib_ahbs_add (&ns16550, 0, NS16550_START, 0xFFF);
+ grlib_ahbs_add (&ns16550, 10, NS16550_START, 0xFFF);
grlib_ahbs_add (&srctrl, 0, ROM_START, ROM_MASKPP);
grlib_ahbs_add (&sdctrl, 0, RAM_START, RAM_MASKPP);
@@ -174,7 +174,7 @@ memory_write (uint32 addr, uint32 * data, int32 sz, int32 * ws)
*ws = 4;
}
- if (sis_verbose > 0)
+ if (sis_verbose > 2)
printf ("AHB write a: %08x, d: %08x\n", addr, *data);
if (sis_verbose && mexc)
{
diff --git a/sis.info b/sis.info
index cc0750e..44a5c99 100644
--- a/sis.info
+++ b/sis.info
@@ -1,6 +1,6 @@
-This is sis.info, produced by makeinfo version 6.5 from sis.texi.
+This is sis.info, produced by makeinfo version 6.7 from sis.texi.
-This manual is for SIS (version 2.26, 15 December 2020).
+This manual is for SIS (version 2.27, 18 December 2020).
Copyright (C) 2020 Free Software Foundation, Inc.
@@ -21,7 +21,7 @@ File: sis.info, Node: Top, Next: Introduction, Up: (dir)
SIS
***
-This manual is for SIS (version 2.26, 15 December 2020).
+This manual is for SIS (version 2.27, 18 December 2020).
* Menu:
@@ -1433,3 +1433,8 @@ Node: GNU Free Documentation License31926
Node: Index57070

End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/version.texi b/version.texi
index 0aad4bb..702b422 100644
--- a/version.texi
+++ b/version.texi
@@ -1,4 +1,4 @@
-@set UPDATED 15 December 2020
+@set UPDATED 18 December 2020
@set UPDATED-MONTH December 2020
-@set EDITION 2.26
-@set VERSION 2.26
+@set EDITION 2.27
+@set VERSION 2.27