summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Gaisler <jiri@gaisler.se>2020-11-30 22:52:27 +0100
committerJiri Gaisler <jiri@gaisler.se>2020-12-01 16:44:49 +0100
commit11154be7bec2967b869fe385ab1df93a27efd82c (patch)
tree955b1c03b0ea4bd3bf6d36af9ec0431c27391401
parentAdd %asr22/23 support to leon3 (diff)
downloadsis-11154be7bec2967b869fe385ab1df93a27efd82c.tar.bz2
Make grlib IP cores more modular and move them to grlib.c
-rw-r--r--elf.c6
-rw-r--r--erc32.c2
-rw-r--r--func.c39
-rw-r--r--greth.c3
-rw-r--r--grlib.c1195
-rw-r--r--grlib.h39
-rw-r--r--leon2.c2
-rw-r--r--leon3.c1068
-rw-r--r--sis.h5
9 files changed, 1300 insertions, 1059 deletions
diff --git a/elf.c b/elf.c
index f1d0a37..384502e 100644
--- a/elf.c
+++ b/elf.c
@@ -240,13 +240,13 @@ elf_load (char *fname, int load)
res = read_elf_header (fp);
- if (res < 0)
+ if (res == -1)
printf ("File read error\n");
- if (load && (res >= 0))
+ else if (load)
{
res = read_elf_body ();
- if (res < 0)
+ if (res == -1)
printf ("File read error\n");
else
printf (" Loaded %s, entry 0x%08x\n", fname, res);
diff --git a/erc32.c b/erc32.c
index dd86907..141c200 100644
--- a/erc32.c
+++ b/erc32.c
@@ -17,7 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define ROM_START 0
+#define ROM_SIZE 0x01000000
#define RAM_START 0x02000000
+#define RAM_SIZE 0x01000000
#include "config.h"
#include <errno.h>
diff --git a/func.c b/func.c
index 4f72f59..02fcdec 100644
--- a/func.c
+++ b/func.c
@@ -36,8 +36,6 @@
#include <inttypes.h>
#include <sys/time.h>
-//#define ROM_ENABLED
-
/* set if UART device cannot handle attributes, terminal oriented IO by default */
int dumbio = 0;
@@ -67,8 +65,8 @@ int sync_rt = 0;
char bridge[32] = "";
/* RAM and ROM for all systems */
-char romb[ROM_SIZE];
-char ramb[RAM_SIZE];
+char romb[MAX_ROM_SIZE];
+char ramb[MAX_RAM_SIZE];
const struct memsys *ms = &erc32sys;
int cputype = 0; /* 0 = erc32, 2 = leon2,3 = leon3, 5 = riscv */
int sis_gdb_break;
@@ -301,7 +299,7 @@ exec_cmd (const char *cmd)
sregs[i].pc = len & ~1;
sregs[i].npc = sregs->pc + 4;
}
- if ((sregs->pc != 0) && (ebase.simtime == 0))
+ if (ebase.simtime == 0)
ms->boot_init ();
printf ("resuming at 0x%08x\n", sregs->pc);
if ((cmd2 = strtok (NULL, " \t\n\r")) != NULL)
@@ -468,7 +466,7 @@ exec_cmd (const char *cmd)
sregs[i].npc = sregs[i].pc + 4;
}
}
- if ((sregs->pc != 0) && (ebase.simtime == 0))
+ if (ebase.simtime == 0)
ms->boot_init ();
if ((cmd1 = strtok (NULL, " \t\n\r")) == NULL)
{
@@ -1184,13 +1182,7 @@ run_sim_un (sregs, icount, dis)
irq = arch->check_interrupts (sregs);
if (!irq)
{
-#ifdef ROM_ENABLED
mexc = ms->memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
-#else
- inst = (uint32 *) & ramb[sregs->pc & RAM_MASK];
- sregs->inst = *inst;
- sregs->hold = 0;
-#endif
if (mexc)
{
sregs->trap = I_ACC_EXC;
@@ -1310,12 +1302,7 @@ run_sim_core (sregs, ntime, deb, dis)
else
irq = 0;
sregs->icnt = 1;
-#ifdef ROM_ENABLED
mexc = ms->memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
-#else
- sregs->inst = *((uint32 *) & ramb[sregs->pc & RAM_MASK]);
- sregs->hold = 0;
-#endif
#ifdef ENABLE_L1CACHE
if (sregs->l1itags[(sregs->pc >> L1ILINEBITS) & L1IMASK] !=
(sregs->pc >> L1ILINEBITS))
@@ -1585,39 +1572,39 @@ mygetline (char **lineptr, size_t * n, FILE * stream)
#define COV_BT 8
#define COV_BNT 16
-unsigned char covram[RAM_SIZE / 4];
+unsigned char covram[MAX_RAM_SIZE / 4];
void
cov_start (int address)
{
- covram[(address >> 2) & RAM_MASK] |= (COV_START | COV_EXEC);
+ covram[(address >> 2) & MAX_RAM_MASK] |= (COV_START | COV_EXEC);
}
void
cov_exec (int address)
{
- covram[(address >> 2) & RAM_MASK] |= COV_EXEC;
+ covram[(address >> 2) & MAX_RAM_MASK] |= COV_EXEC;
}
void
cov_bt (int address1, int address2)
{
- covram[(address1 >> 2) & RAM_MASK] |= (COV_BT | COV_EXEC);
- covram[(address2 >> 2) & RAM_MASK] |= (COV_START | COV_EXEC);
+ covram[(address1 >> 2) & MAX_RAM_MASK] |= (COV_BT | COV_EXEC);
+ covram[(address2 >> 2) & MAX_RAM_MASK] |= (COV_START | COV_EXEC);
}
void
cov_bnt (int address)
{
- covram[(address >> 2) & RAM_MASK] |= (COV_BNT | COV_EXEC);
+ covram[(address >> 2) & MAX_RAM_MASK] |= (COV_BNT | COV_EXEC);
}
void
cov_jmp (int address1, int address2)
{
- covram[(address1 >> 2) & RAM_MASK] |= (COV_JMP | COV_EXEC);
- covram[(address2 >> 2) & RAM_MASK] |= (COV_START | COV_EXEC);
+ covram[(address1 >> 2) & MAX_RAM_MASK] |= (COV_JMP | COV_EXEC);
+ covram[(address2 >> 2) & MAX_RAM_MASK] |= (COV_START | COV_EXEC);
}
void
@@ -1631,7 +1618,7 @@ cov_save (char *name)
strcat (filename, ".cov");
fp = fopen (filename, "w");
state = 0;
- for (i = 0; i < RAM_SIZE / 4; i += 32)
+ for (i = 0; i < MAX_RAM_SIZE / 4; i += 32)
{
k = 0;
for (j = 0; j < 32; j++)
diff --git a/greth.c b/greth.c
index 9d09087..0b6d0ca 100644
--- a/greth.c
+++ b/greth.c
@@ -255,9 +255,6 @@ greth_read (uint32 address)
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;
}
diff --git a/grlib.c b/grlib.c
index 64ed9c0..478e9bb 100644
--- a/grlib.c
+++ b/grlib.c
@@ -18,7 +18,17 @@
*
*/
-
+#include "config.h"
+#include <stdio.h>
+#include <inttypes.h>
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#include <sys/file.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <string.h>
#include "sis.h"
#include "grlib.h"
@@ -90,21 +100,1190 @@ grlib_ahbpnp_read (uint32 addr)
}
+static struct grlib_buscore ahbmcores[16];
+static struct grlib_buscore ahbscores[16];
+static struct grlib_buscore apbcores[16];
+static int ahbmi;
+static int ahbsi;
+static int apbi;
+
void
grlib_init ()
{
- /* Add PP records for Leon3, APB bridge and interrupt controller
- as this is not done elsewhere */
+ int i;
+
+ for (i = 0; i < ahbmi; i++)
+ if (ahbmcores[i].core->init)
+ ahbmcores[i].core->init ();
+ for (i = 0; i < ahbsi; i++)
+ if (ahbscores[i].core->init)
+ ahbscores[i].core->init ();
+}
+
+void
+grlib_reset ()
+{
+ int i;
+
+ for (i = 0; i < ahbmi; i++)
+ if (ahbmcores[i].core->reset)
+ ahbmcores[i].core->reset ();
+ for (i = 0; i < ahbsi; i++)
+ if (ahbscores[i].core->reset)
+ ahbscores[i].core->reset ();
+}
+
+
+void
+grlib_ahbm_add (const struct grlib_ipcore *core, int irq)
+{
+ ahbmcores[ahbmi].core = core;
+ if (core->add)
+ core->add (irq, 0, 0);
+ ahbmi++;
+}
+
+void
+grlib_ahbs_add (const struct grlib_ipcore *core, int irq,
+ uint32 addr, uint32 mask)
+{
+ ahbscores[ahbsi].core = core;
+ if (core->add)
+ {
+ ahbscores[ahbsi].start = addr;
+ ahbscores[ahbsi].end = addr + ~(mask << 20) + 1;
+ ahbscores[ahbsi].mask = ~(mask << 20);
+ core->add (irq, addr, mask);
+ }
+ ahbsi++;
+}
+
+int
+grlib_read (uint32 addr, uint32 * data)
+{
+ int i;
+ int res = 0;
+
+ for (i = 0; i < ahbsi; i++)
+ if ((addr >= ahbscores[i].start) && (addr < ahbscores[i].end))
+ {
+ if (ahbscores[i].core->read)
+ res = ahbscores[i].core->read (addr & ahbscores[i].mask, data);
+ if (sis_verbose > 2)
+ printf ("AHB read a: %08x, d: %08x\n", addr, *data);
+ break;
+ }
+
+ if (!res && ((addr >= AHBPP_START) && (addr <= AHBPP_END)))
+ {
+ *data = grlib_ahbpnp_read (addr);
+ if (sis_verbose > 1)
+ printf ("AHB PP read a: %08x, d: %08x\n", addr, *data);
+ return 0;
+ }
+
+ return !res;
+}
+
+int
+grlib_write (uint32 addr, uint32 * data, uint32 sz)
+{
+ int i;
+ int res = 0;
+
+ for (i = 0; i < ahbsi; i++)
+ if ((addr >= ahbscores[i].start) && (addr < ahbscores[i].end))
+ {
+ if (ahbscores[i].core->write)
+ res = ahbscores[i].core->write (addr & ahbscores[i].mask, data, sz);
+ if (sis_verbose > 2)
+ printf ("AHB write a: %08x, d: %08x\n", addr, *data);
+ break;
+ }
+ return !res;
+}
+
+void
+grlib_apb_add (const struct grlib_ipcore *core, int irq,
+ uint32 addr, uint32 mask)
+{
+ apbcores[apbi].core = core;
+ if (core->add)
+ {
+ apbcores[apbi].start = addr & (mask << 8);
+ apbcores[apbi].end =
+ (apbcores[apbi].start + ~(mask << 8) + 1) & 0x0fffff;
+ apbcores[apbi].mask = ~(mask << 8) & 0x0fffff;
+ core->add (irq, addr, mask);
+ }
+ apbi++;
+}
+
+/* ------------------- GRETH -----------------------*/
+
+
+static int
+grlib_greth_read (uint32 addr, uint32 * data)
+{
+ *data = greth_read (addr);
+}
+
+static int
+grlib_greth_write (uint32 addr, uint32 * data, uint32 size)
+{
+ greth_write (addr, *data);
+}
+
+static void
+greth_add (int irq, uint32 addr, uint32 mask)
+{
+ 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 (addr, mask));
+}
+
+const struct grlib_ipcore greth = {
+ NULL, NULL, grlib_greth_read, grlib_greth_write, greth_add
+};
+
+
+/* ------------------- LEON3 -----------------------*/
+static void
+leon3_add ()
+{
grlib_ahbmpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_LEON3, 0, 0));
+}
+
+const struct grlib_ipcore leon3s = {
+ NULL, NULL, NULL, NULL, leon3_add
+};
+
+/* ------------------- APBMST ----------------------*/
+
+static void
+apbmst_init ()
+{
+ int i;
+
+ for (i = 0; i < apbi; i++)
+ if (apbcores[i].core->init)
+ apbcores[i].core->init ();
+}
+
+static void
+apbmst_reset ()
+{
+ int i;
+
+ for (i = 0; i < apbi; i++)
+ if (apbcores[i].core->reset)
+ apbcores[i].core->reset ();
+}
+
+static int
+apbmst_read (uint32 addr, uint32 * data)
+{
+ int i;
+ int res = 0;
+
+ for (i = 0; i < apbi; i++)
+ {
+ if ((addr >= apbcores[i].start) && (addr < apbcores[i].end))
+ {
+ res = 1;
+ if (apbcores[i].core->read)
+ apbcores[i].core->read (addr & apbcores[i].mask, data);
+ break;
+ }
+ }
+ if (!res && (addr >= 0xFF000))
+ {
+ *data = grlib_apbpnp_read (addr);
+ if (sis_verbose > 1)
+ printf ("APB PP read a: %08x, d: %08x\n", addr, *data);
+ }
+ return 1;
+}
+
+static int
+apbmst_write (uint32 addr, uint32 * data, uint32 size)
+{
+ int i;
+
+ for (i = 0; i < apbi; i++)
+ if ((addr >= apbcores[i].start) && (addr < apbcores[i].end))
+ {
+ if (apbcores[i].core->write)
+ apbcores[i].core->write (addr & apbcores[i].mask, data, size);
+ break;
+ }
+ return 1;
+}
+
+static void
+apbmst_add (int irq, uint32 addr, uint32 mask)
+{
grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_APBMST, 0, 0),
- GRLIB_PP_AHBADDR (0x80000000, 0xFFF, 0, 0, 2), 0, 0, 0);
+ GRLIB_PP_AHBADDR (addr, mask, 0, 0, 2), 0, 0, 0);
+}
+
+const struct grlib_ipcore apbmst = {
+ apbmst_init, apbmst_reset, apbmst_read, apbmst_write, apbmst_add
+};
+
+/* ------------------- IRQMP -----------------------*/
+
+#define IRQMP_IPR 0x04
+#define IRQMP_IFR 0x08
+#define IRQMP_ICR 0x0C
+#define IRQMP_ISR 0x10
+#define IRQMP_IBR 0x14
+#define IRQMP_IMR 0x40
+#define IRQMP_IMR1 0x44
+#define IRQMP_IMR2 0x48
+#define IRQMP_IMR3 0x4C
+#define IRQMP_IFR0 0x80
+#define IRQMP_IFR1 0x84
+#define IRQMP_IFR2 0x88
+#define IRQMP_IFR3 0x8C
+
+static void irqmp_intack (int level, int cpu);
+static void chk_irq (void);
+
+/* IRQMP registers. */
+
+static uint32 irqmp_ipr;
+static uint32 irqmp_ibr;
+static uint32 irqmp_imr[NCPU];
+static uint32 irqmp_ifr[NCPU];
+
+static void
+irqmp_init (void)
+{
+ int i;
+
+ for (i = 0; i < NCPU; i++)
+ {
+ sregs[i].intack = irqmp_intack;
+ }
+}
+
+static void
+irqmp_reset (void)
+{
+ int i;
+
+ irqmp_ipr = 0;
+ for (i = 0; i < NCPU; i++)
+ {
+ irqmp_imr[i] = 0;
+ irqmp_ifr[i] = 0;
+ }
+}
+
+static void
+irqmp_intack (int level, int cpu)
+{
+ int irq_test;
+
+ if ((sis_verbose > 2) && (level != 10))
+ printf ("%8" PRIu64 " cpu %d interrupt %d acknowledged\n",
+ ebase.simtime, cpu, level);
+ if (irqmp_ifr[cpu] & (1 << level))
+ irqmp_ifr[cpu] &= ~(1 << level);
+ else
+ irqmp_ipr &= ~(1 << level);
+ chk_irq ();
+}
+
+static void
+chk_irq ()
+{
+ int32 i, cpu;
+ uint32 itmp;
+ int old_irl;
+
+ for (cpu = 0; cpu < ncpu; cpu++)
+ {
+ old_irl = ext_irl[cpu];
+ itmp = ((irqmp_ipr | irqmp_ifr[cpu]) & irqmp_imr[cpu]) & 0x0fffe;
+ ext_irl[cpu] = 0;
+ if (itmp != 0)
+ {
+ for (i = 15; i > 0; i--)
+ {
+ if (((itmp >> i) & 1) != 0)
+ {
+ if ((sis_verbose > 2) && (i != old_irl))
+ printf ("%8" PRIu64 " cpu %d irl: %d\n",
+ ebase.simtime, cpu, i);
+ ext_irl[cpu] = i;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void
+grlib_set_irq (int32 level)
+{
+ int i;
+
+ if ((irqmp_ibr >> level) & 1)
+ for (i = 0; i < ncpu; i++)
+ irqmp_ifr[i] |= (1 << level);
+ else
+ irqmp_ipr |= (1 << level);
+ chk_irq ();
+}
+
+static int
+irqmp_read (uint32 addr, uint32 * data)
+{
+ int i;
+
+ switch (addr & 0xff)
+ {
+ case IRQMP_IPR: /* 0x04 */
+ *data = irqmp_ipr;
+ break;
+
+ case IRQMP_IFR: /* 0x08 */
+ *data = irqmp_ifr[0];
+ break;
+
+ case IRQMP_ISR: /* 0x10 */
+ *data = ((ncpu - 1) << 28);
+ for (i = 0; i < ncpu; i++)
+ *data |= (sregs[i].pwd_mode << i);
+ break;
+
+ case IRQMP_IBR: /* 0x14 */
+ *data = irqmp_ibr;
+ break;
+
+ case IRQMP_IMR: /* 0x40 */
+ *data = irqmp_imr[0];
+ break;
+
+ case IRQMP_IMR1: /* 0x44 */
+ *data = irqmp_imr[1];
+ break;
+ case IRQMP_IMR2: /* 0x48 */
+ *data = irqmp_imr[2];
+ break;
+
+ case IRQMP_IMR3: /* 0x4C */
+ *data = irqmp_imr[3];
+ break;
+
+ case IRQMP_IFR0: /* 0x80 */
+ *data = irqmp_ifr[0];
+ break;
+
+ case IRQMP_IFR1: /* 0x84 */
+ *data = irqmp_ifr[1];
+ break;
+
+ case IRQMP_IFR2: /* 0x88 */
+ *data = irqmp_ifr[2];
+ break;
+
+ case IRQMP_IFR3: /* 0x8C */
+ *data = irqmp_ifr[3];
+ break;
+
+ default:
+ *data = 0;
+ }
+}
+
+static int
+irqmp_write (uint32 addr, uint32 * data, uint32 size)
+{
+ int i;
+
+ switch (addr & 0xff)
+ {
+
+ case IRQMP_IFR: /* 0x08 */
+ irqmp_ifr[0] = *data & 0xfffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_ICR: /* 0x0C */
+ irqmp_ipr &= ~*data & 0x0fffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_ISR: /* 0x10 */
+ for (i = 0; i < ncpu; i++)
+ {
+ if ((*data >> i) & 1)
+ {
+ if (sregs[i].pwd_mode)
+ {
+ sregs[i].simtime = ebase.simtime;
+ if (sis_verbose > 1)
+ printf ("%8" PRIu64 " cpu %d starting\n", ebase.simtime,
+ i);
+ sregs[i].pwdtime += ebase.simtime - sregs[i].pwdstart;
+ }
+ sregs[i].pwd_mode = 0;
+ }
+ }
+ break;
+
+ case IRQMP_IBR: /* 0x14 */
+ irqmp_ibr = *data & 0xfffe;
+ break;
+
+ case IRQMP_IMR: /* 0x40 */
+ irqmp_imr[0] = *data & 0x7ffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_IMR1: /* 0x44 */
+ irqmp_imr[1] = *data & 0x7ffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_IMR2: /* 0x48 */
+ irqmp_imr[2] = *data & 0x7ffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_IMR3: /* 0x4C */
+ irqmp_imr[3] = *data & 0x7ffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_IFR0: /* 0x80 */
+ irqmp_ifr[0] = *data & 0xfffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_IFR1: /* 0x84 */
+ irqmp_ifr[1] = *data & 0xfffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_IFR2: /* 0x88 */
+ irqmp_ifr[2] = *data & 0xfffe;
+ chk_irq ();
+ break;
+
+ case IRQMP_IFR3: /* 0x8C */
+ irqmp_ifr[3] = *data & 0xfffe;
+ chk_irq ();
+ break;
+ }
+}
+
+static void
+irqmp_add (int irq, uint32 addr, uint32 mask)
+{
grlib_apbpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_IRQMP, 2, 0),
- GRLIB_PP_APBADDR (0x80000200, 0xFFF));
+ GRLIB_PP_APBADDR (addr, mask));
+}
- 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));
+const struct grlib_ipcore irqmp = {
+ irqmp_init, irqmp_reset, irqmp_read, irqmp_write, irqmp_add
+};
+
+/* ------------------- GPTIMER -----------------------*/
+
+#define GPTIMER_SCALER 0x00
+#define GPTIMER_SCLOAD 0x04
+#define GPTIMER_CONFIG 0x08
+#define GPTIMER_TIMER1 0x10
+#define GPTIMER_RELOAD1 0x14
+#define GPTIMER_CTRL1 0x18
+#define GPTIMER_TIMER2 0x20
+#define GPTIMER_RELOAD2 0x24
+#define GPTIMER_CTRL2 0x28
+
+#define NGPTIMERS 2
+
+static uint32 gpt_irq;
+static uint32 gpt_scaler;
+static uint64 gpt_scaler_start;
+static uint32 gpt_counter[NGPTIMERS];
+static uint32 gpt_reload[NGPTIMERS];
+static uint64 gpt_counter_start[NGPTIMERS];
+static uint32 gpt_ctrl[NGPTIMERS];
+
+static void gpt_intr (int32 arg);
+
+static void
+gpt_add_intr (int i)
+{
+ if (gpt_ctrl[i] & 1)
+ {
+ event (gpt_intr, i,
+ (uint64) (gpt_scaler + 1) * (uint64) ((uint64) gpt_counter[i] +
+ (uint64) 1));
+ gpt_counter_start[i] = now ();
+ }
+}
+static void
+gpt_intr (int32 i)
+{
+ gpt_counter[i] = -1;
+ if (gpt_ctrl[i] & 1)
+ {
+ if (gpt_ctrl[i] & 2)
+ {
+ gpt_counter[i] = gpt_reload[i];
+ }
+ if (gpt_ctrl[i] & 8)
+ {
+ grlib_set_irq (gpt_irq + i);
+ }
+ gpt_add_intr (i);
+ }
+}
+
+static void
+gpt_init (void)
+{
+}
+
+static void
+gpt_add (int irq, uint32 addr, uint32 mask)
+{
+ grlib_apbpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_GPTIMER, 0, irq),
+ GRLIB_PP_APBADDR (addr, mask));
+ gpt_irq = irq;
+}
+
+static void
+gpt_reset (void)
+{
+ gpt_counter[0] = 0xffffffff;
+ gpt_reload[0] = 0xffffffff;
+ gpt_scaler = 0xffff;
+ gpt_ctrl[0] = 0;
+ gpt_ctrl[1] = 0;
+ remove_event (gpt_intr, -1);
+ gpt_scaler_start = now ();
+ if (sis_verbose)
+ printf ("GPT started (period %d)\n\r", gpt_scaler + 1);
+}
+
+static void
+gpt_add_intr_all ()
+{
+ int i;
+
+ for (i = 0; i < NGPTIMERS; i++)
+ {
+ gpt_add_intr (i);
+ }
+}
+
+static void
+gpt_scaler_set (uint32 val)
+{
+ /* Mask for 16-bit scaler. */
+ if (gpt_scaler != (val & 0x0ffff))
+ {
+ gpt_scaler = val & 0x0ffff;
+ remove_event (gpt_intr, -1);
+ gpt_scaler_start = now ();
+ gpt_add_intr_all ();
+ }
+}
+
+static void
+gpt_ctrl_write (uint32 val, int i)
+{
+ if (val & 4)
+ {
+ /* Reload. */
+ gpt_counter[i] = gpt_reload[i];
+ }
+ if (val & 1)
+ {
+ gpt_ctrl[i] = val & 0xb;
+ remove_event (gpt_intr, i);
+ gpt_add_intr (i);
+ }
+ gpt_ctrl[i] = val & 0xb;
+}
+
+static uint32
+gpt_counter_read (int i)
+{
+ if (gpt_ctrl[i] & 1)
+ return gpt_counter[i] -
+ ((now () - gpt_counter_start[i]) / (gpt_scaler + 1));
+ else
+ return gpt_counter[i];
+}
+
+static uint32
+gpt_scaler_read ()
+{
+ return gpt_scaler - ((now () - gpt_scaler_start) % (gpt_scaler + 1));
+}
+
+static int
+gpt_read (uint32 addr, uint32 * data)
+{
+ int i;
+
+ switch (addr & 0xff)
+ {
+ case GPTIMER_SCALER: /* 0x00 */
+ *data = gpt_scaler_read ();
+ break;
+
+ case GPTIMER_SCLOAD: /* 0x04 */
+ *data = gpt_scaler;
+ break;
+
+ case GPTIMER_CONFIG: /* 0x08 */
+ *data = 0x100 | (gpt_irq << 3) | NGPTIMERS;
+ break;
+
+ case GPTIMER_TIMER1: /* 0x10 */
+ *data = gpt_counter_read (0);
+ break;
+
+ case GPTIMER_RELOAD1: /* 0x14 */
+ *data = gpt_reload[0];
+ break;
+
+ case GPTIMER_CTRL1: /* 0x18 */
+ *data = gpt_ctrl[0];
+ break;
+
+ case GPTIMER_TIMER2: /* 0x20 */
+ *data = gpt_counter_read (1);
+ break;
+
+ case GPTIMER_RELOAD2: /* 0x24 */
+ *data = gpt_reload[1];
+ break;
+
+ case GPTIMER_CTRL2: /* 0x28 */
+ *data = gpt_ctrl[1];
+ break;
+
+ default:
+ *data = 0;
+ }
+}
+
+static int
+gpt_write (uint32 addr, uint32 * data, uint32 sz)
+{
+ int i;
+
+ switch (addr & 0xff)
+ {
+ case GPTIMER_SCLOAD: /* 0x04 */
+ gpt_scaler_set (*data);
+ break;
+
+ case GPTIMER_TIMER1: /* 0x10 */
+ gpt_counter[0] = *data;
+ remove_event (gpt_intr, 0);
+ gpt_add_intr (0);
+ break;
+
+ case GPTIMER_RELOAD1: /* 0x14 */
+ gpt_reload[0] = *data;
+ break;
+
+ case GPTIMER_CTRL1: /* 0x18 */
+ gpt_ctrl_write (*data, 0);
+ break;
+
+ case GPTIMER_TIMER2: /* 0x20 */
+ gpt_counter[1] = *data;
+ remove_event (gpt_intr, 1);
+ gpt_add_intr (1);
+ break;
+
+ case GPTIMER_RELOAD2: /* 0x24 */
+ gpt_reload[1] = *data;
+ break;
+
+ case GPTIMER_CTRL2: /* 0x28 */
+ gpt_ctrl_write (*data, 1);
+ break;
+
+ }
+}
+
+const struct grlib_ipcore gptimer = {
+ gpt_init, gpt_reset, gpt_read, gpt_write, gpt_add
+};
+
+
+/* APBUART. */
+
+#define APBUART_RXTX 0x00
+#define APBUART_STATUS 0x04
+#define APBUART_CTRL 0x08
+
+/* Size of UART buffers (bytes). */
+#define UARTBUF 1024
+
+/* Number of simulator ticks between flushing the UARTS. */
+/* For good performance, keep above 1000. */
+#define UART_FLUSH_TIME 5000
+
+/* New uart defines. */
+#define UART_TX_TIME 1000
+#define UART_RX_TIME 1000
+#define UARTA_DR 0x1
+#define UARTA_SRE 0x2
+#define UARTA_HRE 0x4
+#define UARTA_OR 0x10
+
+/* UART support variables. */
+
+/* File descriptor for input file. */
+static int32 fd1, fd2;
+
+/* UART status register */
+static int32 Ucontrol;
+
+static unsigned char aq[UARTBUF], bq[UARTBUF];
+static int32 anum, aind = 0;
+static int32 bnum, bind = 0;
+static char wbufa[UARTBUF], wbufb[UARTBUF];
+static unsigned wnuma;
+static unsigned wnumb;
+static FILE *f1in, *f1out;
+#ifdef HAVE_TERMIOS_H
+static struct termios ioc1, ioc2, iocold1, iocold2;
+#endif
+#ifndef O_NONBLOCK
+#define O_NONBLOCK 0
+#endif
+
+static int f1open = 0;
+
+static char uarta_sreg, uarta_hreg;
+static uint32 uart_stat_reg;
+static uint32 uarta_data;
+
+static int ifd1 = -1, ofd1 = -1;
+
+void
+apbuart_init_stdio (void)
+{
+ if (dumbio)
+ return;
+#ifdef HAVE_TERMIOS_H
+ if (ifd1 == 0 && f1open)
+ {
+ tcsetattr (0, TCSANOW, &ioc1);
+ tcflush (ifd1, TCIFLUSH);
+ }
+#endif
+}
+
+void
+apbuart_restore_stdio (void)
+{
+ if (dumbio)
+ return;
+#ifdef HAVE_TERMIOS_H
+ if (ifd1 == 0 && f1open && tty_setup)
+ tcsetattr (0, TCSANOW, &iocold1);
+#endif
+}
+
+#define DO_STDIO_READ( _fd_, _buf_, _len_ ) \
+ ( dumbio || nouartrx ? (0) : read( _fd_, _buf_, _len_ ) )
+
+static void
+apbuart_init (void)
+{
+ f1in = stdin;
+ f1out = stdout;
+ if (uart_dev1[0] != 0)
+ {
+ if ((fd1 = open (uart_dev1, O_RDWR | O_NONBLOCK)) < 0)
+ {
+ printf ("Warning, couldn't open output device %s\n", uart_dev1);
+ }
+ else
+ {
+ if (sis_verbose)
+ printf ("serial port A on %s\n", uart_dev1);
+ f1in = f1out = fdopen (fd1, "r+");
+ setbuf (f1out, NULL);
+ f1open = 1;
+ }
+ }
+ if (f1in)
+ ifd1 = fileno (f1in);
+ if (ifd1 == 0)
+ {
+ if (sis_verbose)
+ printf ("serial port A on stdin/stdout\n");
+ if (!dumbio)
+ {
+#ifdef HAVE_TERMIOS_H
+ tcgetattr (ifd1, &ioc1);
+ if (tty_setup)
+ {
+ iocold1 = ioc1;
+ ioc1.c_lflag &= ~(ICANON | ECHO);
+ ioc1.c_cc[VMIN] = 0;
+ ioc1.c_cc[VTIME] = 0;
+ }
+#endif
+ }
+ f1open = 1;
+ }
+
+ if (f1out)
+ {
+ ofd1 = fileno (f1out);
+ if (!dumbio && tty_setup && ofd1 == 1)
+ setbuf (f1out, NULL);
+ }
+
+ wnuma = 0;
+}
+
+static int
+apbuart_read (uint32 addr, uint32 * data)
+{
+ unsigned tmp = 0;
+
+ switch (addr & 0xff)
+ {
+
+ case 0x00: /* UART 1 RX/TX */
+#ifndef _WIN32
+#ifdef FAST_UART
+
+ if (aind < anum)
+ {
+ if ((aind + 1) < anum)
+ grlib_set_irq (3);
+ *data = (uint32) aq[aind++];
+ return 0;
+ }
+ else
+ {
+ if (f1open)
+ anum = DO_STDIO_READ (ifd1, aq, UARTBUF);
+ else
+ anum = 0;
+ if (anum > 0)
+ {
+ aind = 0;
+ if ((aind + 1) < anum)
+ grlib_set_irq (3);
+ *data = (uint32) aq[aind++];
+ return 0;
+ }
+ else
+ {
+ *data = (uint32) aq[aind];
+ return 0;
+ }
+ }
+#else
+ tmp = uarta_data;
+ uarta_data &= ~UART_DR;
+ uart_stat_reg &= ~UARTA_DR;
+ *data = tmp;
+ return 0;
+#endif
+#else
+ *data = 0;
+ return 0;
+#endif
+ break;
+
+ case 0x04: /* UART status register */
+#ifndef _WIN32
+#ifdef FAST_UART
+
+ Ucontrol = 0;
+ if (aind < anum)
+ {
+ Ucontrol |= 0x00000001;
+ }
+ else
+ {
+ if (f1open)
+ anum = DO_STDIO_READ (ifd1, aq, UARTBUF);
+ else
+ anum = 0;
+ if (anum > 0)
+ {
+ Ucontrol |= 0x00000001;
+ aind = 0;
+ grlib_set_irq (3);
+ }
+ }
+ Ucontrol |= 0x00000006;
+ *data = Ucontrol;
+ return 0;
+#else
+ *data = uart_stat_reg;
+ return 0;
+#endif
+#else
+ *data = 0x00060006;
+ return 0;
+#endif
+ break;
+ case 0x08: /* UART control register */
+ *data = 3;
+ return 0;
+ break;
+ default:
+ if (sis_verbose)
+ printf ("Read from unimplemented UART register (%x)\n", addr);
+ }
+
+ *data = 0;
+ return 0;
+}
+
+static int
+apbuart_write (uint32 addr, uint32 * data, uint32 sz)
+{
+ unsigned char c;
+
+ c = (unsigned char) *data;
+ switch (addr & 0xff)
+ {
+
+ case 0x00: /* UART A */
+#ifdef FAST_UART
+ if (f1open)
+ {
+ if (wnuma < UARTBUF)
+ wbufa[wnuma++] = c;
+ else
+ {
+ while (wnuma)
+ {
+ wnuma -= fwrite (wbufa, 1, wnuma, f1out);
+ }
+ wbufa[wnuma++] = c;
+ }
+ }
+ grlib_set_irq (3);
+#else
+ if (uart_stat_reg & UARTA_SRE)
+ {
+ uarta_sreg = c;
+ uart_stat_reg &= ~UARTA_SRE;
+ event (uarta_tx, 0, UART_TX_TIME);
+ }
+ else
+ {
+ uarta_hreg = c;
+ uart_stat_reg &= ~UARTA_HRE;
+ }
+#endif
+ break;
+
+ case 0x04: /* UART status register */
+#ifndef FAST_UART
+ uart_stat_reg &= 1;
+#endif
+ break;
+ case 0x08: /* UART control register */
+ break;
+ default:
+ if (sis_verbose)
+ printf ("Write to unimplemented UART register (%x)\n", addr);
+ }
+}
+
+void
+apbuart_flush (void)
+{
+ while (wnuma && f1open)
+ {
+ wnuma -= fwrite (wbufa, 1, wnuma, f1out);
+ }
+}
+
+static void
+uarta_tx (void)
+{
+ while (f1open)
+ {
+ while (fwrite (&uarta_sreg, 1, 1, f1out) != 1)
+ continue;
+ }
+ if (uart_stat_reg & UARTA_HRE)
+ {
+ uart_stat_reg |= UARTA_SRE;
+ }
+ else
+ {
+ uarta_sreg = uarta_hreg;
+ uart_stat_reg |= UARTA_HRE;
+ event (uarta_tx, 0, UART_TX_TIME);
+ }
+ grlib_set_irq (3);
+}
+
+static void
+uart_rx (int32 arg)
+{
+ char rxd;
+ int32 rsize = 0;
+
+
+ if (f1open)
+ rsize = DO_STDIO_READ (ifd1, &rxd, 1);
+ else
+ rsize = 0;
+ if (rsize > 0)
+ {
+ uarta_data = rxd;
+ if (uart_stat_reg & UARTA_DR)
+ {
+ uart_stat_reg |= UARTA_OR;
+ }
+ uart_stat_reg |= UARTA_DR;
+ grlib_set_irq (3);
+ }
+ event (uart_rx, 0, UART_RX_TIME);
+}
+
+static void
+uart_intr (int32 arg)
+{
+ uint32 tmp;
+ /* Check for UART interrupts every 1000 clk. */
+ apbuart_read (APBUART_STATUS, &tmp);
+ apbuart_flush ();
+ event (uart_intr, 0, UART_FLUSH_TIME);
+}
+
+
+static void
+uart_irq_start (void)
+{
+#ifdef FAST_UART
+ event (uart_intr, 0, UART_FLUSH_TIME);
+#else
+#ifndef _WIN32
+ event (uart_rx, 0, UART_RX_TIME);
+#endif
+#endif
+}
+
+static void
+apbuart_reset (void)
+{
+ wnuma = wnumb = 0;
+ anum = aind = bnum = bind = 0;
+ uart_stat_reg = UARTA_SRE | UARTA_HRE;
+
+ uart_irq_start ();
+}
+
+void
+apbuart_close_port (void)
+{
+ if (f1open && f1in != stdin)
+ fclose (f1in);
+}
+
+static void
+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));
+}
+
+const struct grlib_ipcore apbuart = {
+ apbuart_init, apbuart_reset, apbuart_read, apbuart_write, apbuart_add
+};
+
+/* ------------------- SRCTRL -----------------------*/
+
+/* Store data in host byte order. MEM points to the beginning of the
+ emulated memory; WADDR contains the index the emulated memory,
+ DATA points to words in host byte order to be stored. SZ contains log(2)
+ of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
+ 2 (one word), or 3 (two words); WS should return the number of wait-states. */
+
+void
+grlib_store_bytes (char *mem, uint32 waddr, uint32 * data, int32 sz)
+{
+ if (sz == 2)
+ memcpy (&mem[waddr], data, 4);
+ else
+ switch (sz)
+ {
+ case 0:
+ waddr ^= arch->bswap;
+ mem[waddr] = *data & 0x0ff;
+ break;
+ case 1:
+ waddr ^= arch->bswap & 2;
+ *((uint16 *) & mem[waddr]) = (*data & 0x0ffff);
+ break;
+ case 3:
+ memcpy (&mem[waddr], data, 8);
+ break;
+ }
+}
+
+static int
+srctrl_write (uint32 addr, uint32 * data, uint32 sz)
+{
+ grlib_store_bytes (ramb, addr, data, sz);
+ return 1;
+}
+
+static int
+srctrl_read (uint32 addr, uint32 * data)
+{
+ memcpy (data, &ramb[addr & ~0x3], 4);
+ return 4;
+}
+
+static void
+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 ("RAM start: 0x%x, RAM size: %d K\n",
+ addr, ((~mask << 20) + 1) / 1024);
+}
+
+const struct grlib_ipcore srctrl = {
+ NULL, NULL, srctrl_read, srctrl_write, srctrl_add
+};
+
+void
+grlib_boot_init (void)
+{
+ uint32 tmp;
+ /* Generate 1 MHz RTC tick. */
+// apb_write (GPTIMER_SCALER, ebase.freq - 1);
+ tmp = ebase.freq - 1;
+ gpt_write (GPTIMER_SCLOAD, &tmp, 2);
+ tmp = -1;
+ gpt_write (GPTIMER_TIMER1, &tmp, 2);
+ gpt_write (GPTIMER_RELOAD1, &tmp, 2);
+ tmp = 7;
+ gpt_write (GPTIMER_CTRL1, &tmp, 2);
}
diff --git a/grlib.h b/grlib.h
index a895c11..6d7606b 100644
--- a/grlib.h
+++ b/grlib.h
@@ -52,6 +52,9 @@
#define APBPP_START 0x800FF000
#define APBPP_END 0x800FFFFF
+#define ROM_MASKPP ((~ROM_MASK >> 20) & 0xFFF)
+#define RAM_MASKPP ((~RAM_MASK >> 20) & 0xFFF)
+
extern int grlib_apbpp_add (uint32 id, uint32 addr);
extern int grlib_ahbmpp_add (uint32 id);
extern int grlib_ahbspp_add (uint32 id, uint32 addr1, uint32 addr2,
@@ -60,3 +63,39 @@ extern uint32 grlib_ahbpnp_read (uint32 addr);
extern uint32 grlib_apbpnp_read (uint32 addr);
extern void grlib_init ();
extern uint32 rvtimer_read (int address, int cpu);
+
+struct grlib_ipcore
+{
+ void (*init) (void);
+ void (*reset) (void);
+ int (*read) (uint32 addr, uint32 * data);
+ int (*write) (uint32 addr, uint32 * data, uint32 size);
+ void (*add) (int irq, uint32 addr, uint32 mask);
+};
+
+struct grlib_buscore
+{
+ const struct grlib_ipcore *core;
+ uint32 start;
+ uint32 end;
+ uint32 mask;
+};
+
+extern void grlib_ahbs_add (const struct grlib_ipcore *core, int irq,
+ uint32 addr, uint32 mask);
+extern void grlib_ahbm_add (const struct grlib_ipcore *core, int irq);
+extern void grlib_apb_add (const struct grlib_ipcore *core, int irq,
+ uint32 addr, uint32 mask);
+extern int grlib_read (uint32 addr, uint32 * data);
+extern int grlib_write (uint32 addr, uint32 * data, uint32 sz);
+extern void grlib_set_irq (int32 level);
+extern void grlib_store_bytes (char *mem, uint32 waddr, uint32 * data,
+ int32 sz);
+extern void grlib_boot_init (void);
+extern void grlib_reset (void);
+extern void apbuart_init_stdio (void);
+extern void apbuart_restore_stdio (void);
+extern void apbuart_close_port (void);
+extern void apbuart_flush (void);
+extern const struct grlib_ipcore gptimer, irqmp, apbuart, apbmst,
+ greth, leon3s, srctrl;
diff --git a/leon2.c b/leon2.c
index b1ed1d6..e3d2f09 100644
--- a/leon2.c
+++ b/leon2.c
@@ -20,7 +20,9 @@
*/
#define ROM_START 0x00000000
+#define ROM_SIZE 0x01000000
#define RAM_START 0x40000000
+#define RAM_SIZE 0x02000000
#include "config.h"
#include <errno.h>
diff --git a/leon3.c b/leon3.c
index 5d79381..b4f8dad 100644
--- a/leon3.c
+++ b/leon3.c
@@ -20,14 +20,10 @@
* Leon3 emulation, loosely based on erc32.c.
*/
-#ifdef WORDS_BIGENDIAN
-#define EBT 0
-#else
-#define EBT 3
-#endif
-
#define ROM_START 0x00000000
+#define ROM_SIZE 0x01000000
#define RAM_START 0x40000000
+#define RAM_SIZE 0x04000000
#include "config.h"
#include <errno.h>
@@ -45,141 +41,33 @@
/* APB registers */
#define APBSTART 0x80000000
-#define APBEND 0x80100000
/* Memory exception waitstates. */
#define MEM_EX_WS 1
-#define MOK 0
-
-/* LEON3 APB register addresses. */
-
-#define IRQMP_IPR 0x204
-#define IRQMP_IFR 0x208
-#define IRQMP_ICR 0x20C
-#define IRQMP_ISR 0x210
-#define IRQMP_IBR 0x214
-#define IRQMP_IMR 0x240
-#define IRQMP_IMR1 0x244
-#define IRQMP_IMR2 0x248
-#define IRQMP_IMR3 0x24C
-#define IRQMP_IFR0 0x280
-#define IRQMP_IFR1 0x284
-#define IRQMP_IFR2 0x288
-#define IRQMP_IFR3 0x28C
-#define GPTIMER_SCALER 0x300
-#define GPTIMER_SCLOAD 0x304
-#define GPTIMER_CONFIG 0x308
-#define GPTIMER_TIMER1 0x310
-#define GPTIMER_RELOAD1 0x314
-#define GPTIMER_CTRL1 0x318
-#define GPTIMER_TIMER2 0x320
-#define GPTIMER_RELOAD2 0x324
-#define GPTIMER_CTRL2 0x328
-
-#define APBUART_RXTX 0x100
-#define APBUART_STATUS 0x104
-#define APBUART_CTRL 0x108
-
-/* Size of UART buffers (bytes). */
-#define UARTBUF 1024
-
-/* Number of simulator ticks between flushing the UARTS. */
-/* For good performance, keep above 1000. */
-#define UART_FLUSH_TIME 3000
-
-/* New uart defines. */
-#define UART_TX_TIME 1000
-#define UART_RX_TIME 1000
-#define UARTA_DR 0x1
-#define UARTA_SRE 0x2
-#define UARTA_HRE 0x4
-#define UARTA_OR 0x10
-
-/* IRQMP registers. */
-
-static uint32 irqmp_ipr;
-static uint32 irqmp_ibr;
-static uint32 irqmp_imr[NCPU];
-static uint32 irqmp_ifr[NCPU];
-
-/* GPTIMER registers. */
-
-#define NGPTIMERS 2
-#define GPTIMER_IRQ 8
-
-static uint32 gpt_scaler;
-static uint64 gpt_scaler_start;
-static uint32 gpt_counter[NGPTIMERS];
-static uint32 gpt_reload[NGPTIMERS];
-static uint64 gpt_counter_start[NGPTIMERS];
-static uint32 gpt_ctrl[NGPTIMERS];
-
-/* UART support variables. */
-
-/* File descriptor for input file. */
-static int32 fd1, fd2;
-
-/* UART status register */
-static int32 Ucontrol;
-
-static unsigned char aq[UARTBUF], bq[UARTBUF];
-static int32 anum, aind = 0;
-static int32 bnum, bind = 0;
-static char wbufa[UARTBUF], wbufb[UARTBUF];
-static unsigned wnuma;
-static unsigned wnumb;
-static FILE *f1in, *f1out;
-#ifdef HAVE_TERMIOS_H
-static struct termios ioc1, ioc2, iocold1, iocold2;
-#endif
-#ifndef O_NONBLOCK
-#define O_NONBLOCK 0
-#endif
-
-static int f1open = 0;
-
-static char uarta_sreg, uarta_hreg;
-static uint32 uart_stat_reg;
-static uint32 uarta_data;
-
/* Forward declarations. */
-static void mem_init (void);
-static void close_port (void);
-static void leon3_reset (void);
-static void irqmp_intack (int level, int cpu);
-static void chk_irq (void);
-static int32 apb_read (uint32 addr, uint32 * data);
-static int apb_write (uint32 addr, uint32 data);
-static void port_init (void);
-static uint32 grlib_read_uart (uint32 addr);
-static void grlib_write_uart (uint32 addr, uint32 data);
-static void flush_uart (void);
-static void uarta_tx (void);
-static void uart_rx (int32 arg);
-static void uart_intr (int32 arg);
-static void uart_irq_start (void);
-static void gpt_intr (int32 arg);
-static void gpt_init (void);
-static void gpt_reset (void);
-static void gpt_scaler_set (uint32 val);
-static void timer_ctrl (uint32 val, int i);
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. */
static void
init_sim (void)
{
+ int i;
+
+ for (i = 0; i < NCPU; i++)
+ grlib_ahbm_add (&leon3s, 0);
+
+ grlib_ahbs_add (&apbmst, 0, APBSTART, 0xFFF);
+ grlib_ahbs_add (&srctrl, 0, RAM_START, RAM_MASKPP);
+
+ grlib_apb_add (&apbuart, 3, APBSTART + 0x100, 0xFFF);
+ grlib_apb_add (&irqmp, 0, APBSTART + 0x200, 0xFFF);
+ grlib_apb_add (&gptimer, 8, APBSTART + 0x300, 0xFFF);
+ grlib_apb_add (&greth, 6, APBSTART + 0xB00, 0xFFF);
+
grlib_init ();
- mem_init ();
- port_init ();
- gpt_init ();
ebase.ramstart = RAM_START;
}
@@ -188,9 +76,7 @@ init_sim (void)
static void
reset (void)
{
- leon3_reset ();
- uart_irq_start ();
- gpt_reset ();
+ grlib_reset ();
}
/* IU error mode manager. */
@@ -201,943 +87,97 @@ error_mode (uint32 pc)
}
-/* Memory init. */
-
-static void
-mem_init (void)
-{
-
-/* Add AMBA P&P record for SRCTRL memory controller */
-
- grlib_ahbspp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_SRCTRL, 0, 0),
- GRLIB_PP_AHBADDR (0x00000000, 0xE00, 1, 1, 2),
- GRLIB_PP_AHBADDR (0x40000000, 0xC00, 1, 1, 2),
- GRLIB_PP_AHBADDR (0x20000000, 0xE00, 0, 0, 2), 0);
- if (sis_verbose)
- printf ("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
- RAM_START, (RAM_MASK + 1) / 1024, (ROM_MASK + 1) / 1024);
-}
-
/* Flush ports when simulator stops. */
static void
sim_halt (void)
{
#ifdef FAST_UART
- flush_uart ();
+ apbuart_flush ();
#endif
}
static void
-close_port (void)
-{
- if (f1open && f1in != stdin)
- fclose (f1in);
-}
-
-static void
exit_sim (void)
{
- close_port ();
-}
-
-static void
-leon3_reset (void)
-{
- int i;
-
- irqmp_ipr = 0;
- for (i = 0; i < NCPU; i++)
- {
- irqmp_imr[i] = 0;
- irqmp_ifr[i] = 0;
- sregs[i].intack = irqmp_intack;
- }
- wnuma = wnumb = 0;
- anum = aind = bnum = bind = 0;
-
- uart_stat_reg = UARTA_SRE | UARTA_HRE;
-
- gpt_counter[0] = 0xffffffff;
- gpt_reload[0] = 0xffffffff;
- gpt_scaler = 0xffff;
- gpt_ctrl[0] = 0;
- gpt_ctrl[1] = 0;
-
-}
-
-static void
-irqmp_intack (int level, int cpu)
-{
- int irq_test;
-
- if ((sis_verbose > 2) && (level != 10))
- printf ("%8" PRIu64 " cpu %d interrupt %d acknowledged\n",
- ebase.simtime, cpu, level);
- if (irqmp_ifr[cpu] & (1 << level))
- irqmp_ifr[cpu] &= ~(1 << level);
- else
- irqmp_ipr &= ~(1 << level);
- chk_irq ();
-}
-
-static void
-chk_irq ()
-{
- int32 i, cpu;
- uint32 itmp;
- int old_irl;
-
- for (cpu = 0; cpu < ncpu; cpu++)
- {
- old_irl = ext_irl[cpu];
- itmp = ((irqmp_ipr | irqmp_ifr[cpu]) & irqmp_imr[cpu]) & 0x0fffe;
- ext_irl[cpu] = 0;
- if (itmp != 0)
- {
- for (i = 15; i > 0; i--)
- {
- if (((itmp >> i) & 1) != 0)
- {
- if ((sis_verbose > 2) && (i != old_irl))
- printf ("%8" PRIu64 " cpu %d irl: %d\n",
- ebase.simtime, cpu, i);
- ext_irl[cpu] = i;
- break;
- }
- }
- }
- }
-}
-
-static void
-set_irq (int32 level)
-{
- int i;
-
- if ((irqmp_ibr >> level) & 1)
- for (i = 0; i < ncpu; i++)
- irqmp_ifr[i] |= (1 << level);
- else
- irqmp_ipr |= (1 << level);
- chk_irq ();
-}
-
-static uint32
-gpt_counter_read (int i)
-{
- if (gpt_ctrl[i] & 1)
- return gpt_counter[i] -
- ((now () - gpt_counter_start[i]) / (gpt_scaler + 1));
- else
- return gpt_counter[i];
-}
-
-static uint32
-gpt_scaler_read ()
-{
- return gpt_scaler - ((now () - gpt_scaler_start) % (gpt_scaler + 1));
-}
-
-static int32
-apb_read (uint32 addr, uint32 * data)
-{
- int i;
-
- switch (addr & 0xfff)
- {
-
- case APBUART_RXTX: /* 0x100 */
- case APBUART_STATUS: /* 0x104 */
- *data = grlib_read_uart (addr);
- break;
- case APBUART_CTRL: /* 0x108 */
- *data = 3;
- break;
-
- case IRQMP_IPR: /* 0x204 */
- *data = irqmp_ipr;
- break;
-
- case IRQMP_IFR: /* 0x208 */
- *data = irqmp_ifr[0];
- break;
-
- case IRQMP_ISR: /* 0x210 */
- *data = ((ncpu - 1) << 28);
- for (i = 0; i < ncpu; i++)
- *data |= (sregs[i].pwd_mode << i);
- break;
-
- case IRQMP_IBR: /* 0x214 */
- *data = irqmp_ibr;
- break;
-
- case IRQMP_IMR: /* 0x240 */
- *data = irqmp_imr[0];
- break;
-
- case IRQMP_IMR1: /* 0x244 */
- *data = irqmp_imr[1];
- break;
-
- case IRQMP_IMR2: /* 0x248 */
- *data = irqmp_imr[2];
- break;
-
- case IRQMP_IMR3: /* 0x24C */
- *data = irqmp_imr[3];
- break;
-
- case IRQMP_IFR0: /* 0x280 */
- *data = irqmp_ifr[0];
- break;
-
- case IRQMP_IFR1: /* 0x284 */
- *data = irqmp_ifr[1];
- break;
-
- case IRQMP_IFR2: /* 0x288 */
- *data = irqmp_ifr[2];
- break;
-
- case IRQMP_IFR3: /* 0x28C */
- *data = irqmp_ifr[3];
- break;
-
- case GPTIMER_SCALER: /* 0x300 */
- *data = gpt_scaler_read ();
- break;
-
- case GPTIMER_SCLOAD: /* 0x304 */
- *data = gpt_scaler;
- break;
-
- case GPTIMER_CONFIG: /* 0x308 */
- *data = 0x100 | (GPTIMER_IRQ << 3) | NGPTIMERS;
- break;
-
- case GPTIMER_TIMER1: /* 0x310 */
- *data = gpt_counter_read (0);
- break;
-
- case GPTIMER_RELOAD1: /* 0x314 */
- *data = gpt_reload[0];
- break;
-
- case GPTIMER_CTRL1: /* 0x318 */
- *data = gpt_ctrl[0];
- break;
-
- case GPTIMER_TIMER2: /* 0x320 */
- *data = gpt_counter_read (1);
- break;
-
- case GPTIMER_RELOAD2: /* 0x324 */
- *data = gpt_reload[1];
- break;
-
- case GPTIMER_CTRL2: /* 0x328 */
- *data = gpt_ctrl[1];
- break;
-
- default:
- *data = 0;
- 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);
- break;
- }
-
- if (sis_verbose > 1)
- if ((addr & 0xF00) != 0x100)
- printf ("%8" PRIu64 " cpu %d APB read a: %08x, d: %08x\n",
- ebase.simtime, cpu, addr, *data);
-
- return MOK;
-}
-
-static int
-apb_write (uint32 addr, uint32 data)
-{
- int i;
-
- if (sis_verbose > 1)
- if ((addr & 0xF00) != 0x100)
- printf ("%8" PRIu64 " cpu %d APB write a: %08x, d: %08x\n",
- ebase.simtime, cpu, addr, data);
- switch (addr & 0xfff)
- {
-
- case APBUART_RXTX: /* 0x100 */
- case APBUART_STATUS: /* 0x104 */
- grlib_write_uart (addr, data);
- break;
- case APBUART_CTRL: /* 0x108 */
- break;
-
- case IRQMP_IFR: /* 0x208 */
- irqmp_ifr[0] = data & 0xfffe;
- chk_irq ();
- break;
-
- case IRQMP_ICR: /* 0x20C */
- irqmp_ipr &= ~data & 0x0fffe;
- chk_irq ();
- break;
-
- case IRQMP_ISR: /* 0x210 */
- for (i = 0; i < ncpu; i++)
- {
- if ((data >> i) & 1)
- {
- if (sregs[i].pwd_mode)
- {
- sregs[i].simtime = ebase.simtime;
- if (sis_verbose > 1)
- printf ("%8" PRIu64 " cpu %d starting\n", ebase.simtime,
- i);
- sregs[i].pwdtime += ebase.simtime - sregs[i].pwdstart;
- }
- sregs[i].pwd_mode = 0;
- }
- }
- break;
-
- case IRQMP_IBR: /* 0x214 */
- irqmp_ibr = data & 0xfffe;
- break;
-
- case IRQMP_IMR: /* 0x240 */
- irqmp_imr[0] = data & 0x7ffe;
- chk_irq ();
- break;
-
- case IRQMP_IMR1: /* 0x244 */
- irqmp_imr[1] = data & 0x7ffe;
- chk_irq ();
- break;
-
- case IRQMP_IMR2: /* 0x248 */
- irqmp_imr[2] = data & 0x7ffe;
- chk_irq ();
- break;
-
- case IRQMP_IMR3: /* 0x24C */
- irqmp_imr[3] = data & 0x7ffe;
- chk_irq ();
- break;
-
- case IRQMP_IFR0: /* 0x280 */
- irqmp_ifr[0] = data & 0xfffe;
- chk_irq ();
- break;
-
- case IRQMP_IFR1: /* 0x284 */
- irqmp_ifr[1] = data & 0xfffe;
- chk_irq ();
- break;
-
- case IRQMP_IFR2: /* 0x288 */
- irqmp_ifr[2] = data & 0xfffe;
- chk_irq ();
- break;
-
- case IRQMP_IFR3: /* 0x28C */
- irqmp_ifr[3] = data & 0xfffe;
- chk_irq ();
- break;
-
- case GPTIMER_SCLOAD: /* 0x304 */
- gpt_scaler_set (data);
- break;
-
- case GPTIMER_TIMER1: /* 0x310 */
- gpt_counter[0] = data;
- remove_event (gpt_intr, 0);
- gpt_add_intr (0);
- break;
-
- case GPTIMER_RELOAD1: /* 0x314 */
- gpt_reload[0] = data;
- break;
-
- case GPTIMER_CTRL1: /* 0x318 */
- timer_ctrl (data, 0);
- break;
-
- case GPTIMER_TIMER2: /* 0x320 */
- gpt_counter[1] = data;
- remove_event (gpt_intr, 1);
- gpt_add_intr (1);
- break;
-
- case GPTIMER_RELOAD2: /* 0x324 */
- gpt_reload[1] = data;
- break;
-
- case GPTIMER_CTRL2: /* 0x328 */
- timer_ctrl (data, 1);
- break;
-
- default:
- 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);
- break;
- }
- return MOK;
-}
-
-
-/* APBUART. */
-
-static int ifd1 = -1, ofd1 = -1;
-
-static void
-init_stdio (void)
-{
- if (dumbio)
- return;
-#ifdef HAVE_TERMIOS_H
- if (ifd1 == 0 && f1open)
- {
- tcsetattr (0, TCSANOW, &ioc1);
- tcflush (ifd1, TCIFLUSH);
- }
-#endif
-}
-
-static void
-restore_stdio (void)
-{
- if (dumbio)
- return;
-#ifdef HAVE_TERMIOS_H
- if (ifd1 == 0 && f1open && tty_setup)
- tcsetattr (0, TCSANOW, &iocold1);
-#endif
-}
-
-#define DO_STDIO_READ( _fd_, _buf_, _len_ ) \
- ( dumbio || nouartrx ? (0) : read( _fd_, _buf_, _len_ ) )
-
-static void
-port_init (void)
-{
- f1in = stdin;
- f1out = stdout;
- if (uart_dev1[0] != 0)
- {
- if ((fd1 = open (uart_dev1, O_RDWR | O_NONBLOCK)) < 0)
- {
- printf ("Warning, couldn't open output device %s\n", uart_dev1);
- }
- else
- {
- if (sis_verbose)
- printf ("serial port A on %s\n", uart_dev1);
- f1in = f1out = fdopen (fd1, "r+");
- setbuf (f1out, NULL);
- f1open = 1;
- }
- }
- if (f1in)
- ifd1 = fileno (f1in);
- if (ifd1 == 0)
- {
- if (sis_verbose)
- printf ("serial port A on stdin/stdout\n");
- if (!dumbio)
- {
-#ifdef HAVE_TERMIOS_H
- tcgetattr (ifd1, &ioc1);
- if (tty_setup)
- {
- iocold1 = ioc1;
- ioc1.c_lflag &= ~(ICANON | ECHO);
- ioc1.c_cc[VMIN] = 0;
- ioc1.c_cc[VTIME] = 0;
- }
-#endif
- }
- f1open = 1;
- }
-
- if (f1out)
- {
- ofd1 = fileno (f1out);
- if (!dumbio && tty_setup && ofd1 == 1)
- setbuf (f1out, NULL);
- }
-
- wnuma = 0;
-
- grlib_apbpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_APBUART, 1, 3),
- GRLIB_PP_APBADDR (0x80000100, 0xFFF));
-}
-
-static uint32
-grlib_read_uart (uint32 addr)
-{
- unsigned tmp = 0;
-
- switch (addr & 0xff)
- {
-
- case 0x00: /* UART 1 RX/TX */
-#ifndef _WIN32
-#ifdef FAST_UART
-
- if (aind < anum)
- {
- if ((aind + 1) < anum)
- set_irq (3);
- return (uint32) aq[aind++];
- }
- else
- {
- if (f1open)
- anum = DO_STDIO_READ (ifd1, aq, UARTBUF);
- else
- anum = 0;
- if (anum > 0)
- {
- aind = 0;
- if ((aind + 1) < anum)
- set_irq (3);
- return (uint32) aq[aind++];
- }
- else
- return (uint32) aq[aind];
- }
-#else
- tmp = uarta_data;
- uarta_data &= ~UART_DR;
- uart_stat_reg &= ~UARTA_DR;
- return tmp;
-#endif
-#else
- return 0;
-#endif
- break;
-
- case 0x04: /* UART status register */
-#ifndef _WIN32
-#ifdef FAST_UART
-
- Ucontrol = 0;
- if (aind < anum)
- {
- Ucontrol |= 0x00000001;
- }
- else
- {
- if (f1open)
- anum = DO_STDIO_READ (ifd1, aq, UARTBUF);
- else
- anum = 0;
- if (anum > 0)
- {
- Ucontrol |= 0x00000001;
- aind = 0;
- set_irq (3);
- }
- }
- Ucontrol |= 0x00000006;
- return Ucontrol;
-#else
- return uart_stat_reg;
-#endif
-#else
- return 0x00060006;
-#endif
- break;
- default:
- if (sis_verbose)
- printf ("Read from unimplemented UART register (%x)\n", addr);
- }
-
- return 0;
-}
-
-static void
-grlib_write_uart (uint32 addr, uint32 data)
-{
- unsigned char c;
-
- c = (unsigned char) data;
- switch (addr & 0xff)
- {
-
- case 0x00: /* UART A */
-#ifdef FAST_UART
- if (f1open)
- {
- if (wnuma < UARTBUF)
- wbufa[wnuma++] = c;
- else
- {
- while (wnuma)
- {
- wnuma -= fwrite (wbufa, 1, wnuma, f1out);
- }
- wbufa[wnuma++] = c;
- }
- }
- set_irq (3);
-#else
- if (uart_stat_reg & UARTA_SRE)
- {
- uarta_sreg = c;
- uart_stat_reg &= ~UARTA_SRE;
- event (uarta_tx, 0, UART_TX_TIME);
- }
- else
- {
- uarta_hreg = c;
- uart_stat_reg &= ~UARTA_HRE;
- }
-#endif
- break;
-
- case 0x04: /* UART status register */
-#ifndef FAST_UART
- uart_stat_reg &= 1;
-#endif
- break;
- default:
- if (sis_verbose)
- printf ("Write to unimplemented UART register (%x)\n", addr);
- }
-}
-
-static void
-flush_uart (void)
-{
- while (wnuma && f1open)
- {
- wnuma -= fwrite (wbufa, 1, wnuma, f1out);
- }
-}
-
-static void
-uarta_tx (void)
-{
- while (f1open)
- {
- while (fwrite (&uarta_sreg, 1, 1, f1out) != 1)
- continue;
- }
- if (uart_stat_reg & UARTA_HRE)
- {
- uart_stat_reg |= UARTA_SRE;
- }
- else
- {
- uarta_sreg = uarta_hreg;
- uart_stat_reg |= UARTA_HRE;
- event (uarta_tx, 0, UART_TX_TIME);
- }
- set_irq (3);
-}
-
-static void
-uart_rx (int32 arg)
-{
- char rxd;
- int32 rsize = 0;
-
-
- if (f1open)
- rsize = DO_STDIO_READ (ifd1, &rxd, 1);
- else
- rsize = 0;
- if (rsize > 0)
- {
- uarta_data = rxd;
- if (uart_stat_reg & UARTA_DR)
- {
- uart_stat_reg |= UARTA_OR;
- }
- uart_stat_reg |= UARTA_DR;
- set_irq (3);
- }
- event (uart_rx, 0, UART_RX_TIME);
-}
-
-static void
-uart_intr (int32 arg)
-{
- /* Check for UART interrupts every 1000 clk. */
- grlib_read_uart (APBUART_STATUS);
- flush_uart ();
- event (uart_intr, 0, UART_FLUSH_TIME);
-}
-
-
-static void
-uart_irq_start (void)
-{
-#ifdef FAST_UART
- event (uart_intr, 0, UART_FLUSH_TIME);
-#else
-#ifndef _WIN32
- event (uart_rx, 0, UART_RX_TIME);
-#endif
-#endif
-}
-
-/* GPTIMER. */
-
-static void
-gpt_add_intr (int i)
-{
- if (gpt_ctrl[i] & 1)
- {
- event (gpt_intr, i,
- (uint64) (gpt_scaler + 1) * (uint64) ((uint64) gpt_counter[i] +
- (uint64) 1));
- gpt_counter_start[i] = now ();
- }
-}
-
-static void
-gpt_intr (int32 i)
-{
- gpt_counter[i] = -1;
- if (gpt_ctrl[i] & 1)
- {
- if (gpt_ctrl[i] & 2)
- {
- gpt_counter[i] = gpt_reload[i];
- }
- if (gpt_ctrl[i] & 8)
- {
- set_irq (GPTIMER_IRQ + i);
- }
- gpt_add_intr (i);
- }
-}
-
-static void
-gpt_init (void)
-{
- if (sis_verbose)
- printf ("GPT started (period %d)\n\r", gpt_scaler + 1);
-
- grlib_apbpp_add (GRLIB_PP_ID (VENDOR_GAISLER, GAISLER_GPTIMER, 0, 8),
- GRLIB_PP_APBADDR (0x80000300, 0xFFF));
-}
-
-static void
-gpt_reset (void)
-{
-// event (gpt_intr, 0, gpt_scaler + 1);
- remove_event (gpt_intr, -1);
- gpt_scaler_start = now ();
-}
-
-static void
-gpt_add_intr_all ()
-{
- int i;
-
- for (i = 0; i < NGPTIMERS; i++)
- {
- gpt_add_intr (i);
- }
-}
-
-static void
-gpt_scaler_set (uint32 val)
-{
- /* Mask for 16-bit scaler. */
- if (gpt_scaler != (val & 0x0ffff))
- {
- gpt_scaler = val & 0x0ffff;
- remove_event (gpt_intr, -1);
- gpt_scaler_start = now ();
- gpt_add_intr_all ();
- }
-}
-
-static void
-timer_ctrl (uint32 val, int i)
-{
- if (val & 4)
- {
- /* Reload. */
- gpt_counter[i] = gpt_reload[i];
- }
- if (val & 1)
- {
- gpt_ctrl[i] = val & 0xb;
- remove_event (gpt_intr, i);
- gpt_add_intr (i);
- }
- gpt_ctrl[i] = val & 0xb;
-}
-
-/* Store data in host byte order. MEM points to the beginning of the
- emulated memory; WADDR contains the index the emulated memory,
- DATA points to words in host byte order to be stored. SZ contains log(2)
- of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
- 2 (one word), or 3 (two words); WS should return the number of wait-states. */
-
-static void
-store_bytes (char *mem, uint32 waddr, uint32 * data, int32 sz, int32 * ws)
-{
- if (sz == 2)
- memcpy (&mem[waddr], data, 4);
- else
- switch (sz)
- {
- case 0:
- waddr ^= arch->bswap;
- mem[waddr] = *data & 0x0ff;
- break;
- case 1:
- waddr ^= arch->bswap & 2;
- *((uint16 *) & mem[waddr]) = (*data & 0x0ffff);
- break;
- case 3:
- memcpy (&mem[waddr], data, 8);
- break;
- }
- *ws = 0;
+ apbuart_close_port ();
}
-
/* Memory emulation. */
static int
-memory_iread (uint32 addr, uint32 * data, int32 * ws)
-{
- if ((addr >= RAM_START) && (addr < RAM_END))
- {
- memcpy (data, &ramb[addr & RAM_MASK], 4);
- *ws = 0;
- return 0;
- }
- else if (addr < ROM_END)
- {
- memcpy (data, &romb[addr], 4);
- *ws = 0;
- return 0;
- }
-
- if (sis_verbose)
- printf ("Memory exception at %x (illegal address)\n", addr);
- *ws = MEM_EX_WS;
- return 1;
-}
-
-static int
memory_read (uint32 addr, uint32 * data, int32 * ws)
{
int32 mexc;
+ *ws = 0;
if ((addr >= RAM_START) && (addr < RAM_END))
{
memcpy (data, &ramb[addr & RAM_MASK], 4);
- *ws = 0;
return 0;
}
- else if ((addr >= APBPP_START) && (addr <= APBPP_END))
+ else if ((addr >= ROM_START) && (addr < ROM_END))
{
- *data = grlib_apbpnp_read (addr);
- if (sis_verbose > 1)
- printf ("APB PP read a: %08x, d: %08x\n", addr, *data);
- *ws = 4;
+ memcpy (data, &romb[addr & ROM_MASK], 4);
+ *ws = 2;
return 0;
}
- else if ((addr >= APBSTART) && (addr < APBEND))
- {
- mexc = apb_read (addr, data);
- if (mexc)
- *ws = MEM_EX_WS;
- else
- *ws = 0;
- return mexc;
- }
- else if ((addr >= AHBPP_START) && (addr <= AHBPP_END))
+ else
{
- *data = grlib_ahbpnp_read (addr);
- if (sis_verbose > 1)
- printf ("AHB PP read a: %08x, d: %08x\n", addr, *data);
+ mexc = grlib_read (addr, data);
*ws = 4;
- return 0;
}
- else if (addr < ROM_END)
+
+ if (sis_verbose && mexc)
{
- memcpy (data, &romb[addr], 4);
- *ws = 0;
- return 0;
+ printf ("Memory exception at %x (illegal address)\n", addr);
+ *ws = MEM_EX_WS;
}
-
- if (sis_verbose)
- printf ("Memory exception at %x (illegal address)\n", addr);
- *ws = MEM_EX_WS;
- return 1;
+ return mexc;
}
static int
memory_write (uint32 addr, uint32 * data, int32 sz, int32 * ws)
{
- uint32 byte_addr;
- uint32 byte_mask;
uint32 waddr;
- uint32 *ram;
int32 mexc;
- int i;
- int wphit[2];
+ *ws = 0;
if ((addr >= RAM_START) && (addr < RAM_END))
{
waddr = addr & RAM_MASK;
- store_bytes (ramb, waddr, data, sz, ws);
+ grlib_store_bytes (ramb, waddr, data, sz);
return 0;
}
- else if ((addr >= APBSTART) && (addr < APBEND))
+ else if ((addr >= ROM_START) && (addr < ROM_END))
{
- if (sz != 2)
- {
- *ws = MEM_EX_WS;
- return 1;
- }
- apb_write (addr, *data);
- *ws = 0;
+ grlib_store_bytes (romb, addr, data, sz);
return 0;
-
}
- else if (addr < ROM_END)
+ else
{
- *ws = 0;
- store_bytes (romb, addr, data, sz, ws);
- return 0;
+ mexc = grlib_write (addr, data, sz);
+ *ws = 4;
}
- *ws = MEM_EX_WS;
- return 1;
+ if (sis_verbose && mexc)
+ {
+ printf ("Memory exception at %x (illegal address)\n", addr);
+ *ws = MEM_EX_WS;
+ }
+ return mexc;
}
static char *
get_mem_ptr (uint32 addr, uint32 size)
{
- if ((addr + size) < ROM_END)
+ if ((addr >= RAM_START) && ((addr + size) < RAM_END))
{
- return &romb[addr];
+ return &ramb[addr & RAM_MASK];
}
- else if ((addr >= RAM_START) && ((addr + size) < RAM_END))
+ else if ((addr >= ROM_START) && ((addr + size) < ROM_END))
{
- return &ramb[addr & RAM_MASK];
+ return &romb[addr & ROM_MASK];
}
return NULL;
@@ -1184,13 +224,7 @@ boot_init (void)
int i;
- /* Generate 1 MHz RTC tick. */
-// apb_write (GPTIMER_SCALER, ebase.freq - 1);
- apb_write (GPTIMER_SCLOAD, ebase.freq - 1);
- apb_write (GPTIMER_TIMER1, -1);
- apb_write (GPTIMER_RELOAD1, -1);
- apb_write (GPTIMER_CTRL1, 0x7);
-
+ grlib_boot_init ();
for (i = 0; i < NCPU; i++)
{
sregs[i].wim = 2;
@@ -1208,14 +242,14 @@ const struct memsys leon3 = {
error_mode,
sim_halt,
exit_sim,
- init_stdio,
- restore_stdio,
- memory_iread,
+ apbuart_init_stdio,
+ apbuart_restore_stdio,
+ memory_read,
memory_read,
memory_write,
sis_memory_write,
sis_memory_read,
boot_init,
get_mem_ptr,
- set_irq
+ grlib_set_irq
};
diff --git a/sis.h b/sis.h
index e1df142..44e524b 100644
--- a/sis.h
+++ b/sis.h
@@ -42,12 +42,13 @@
#define NCPU 4
/* size of simulated memory */
-#define ROM_SIZE 0x01000000
#define ROM_MASK (ROM_SIZE - 1)
#define ROM_END (ROM_START + ROM_SIZE)
-#define RAM_SIZE 0x01000000
#define RAM_MASK (RAM_SIZE - 1)
#define RAM_END (RAM_START + RAM_SIZE)
+#define MAX_ROM_SIZE 0x01000000
+#define MAX_RAM_SIZE 0x04000000
+#define MAX_RAM_MASK (MAX_RAM_SIZE - 1)
/* cache config */