X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Ferc32%2Ferc32.c;h=b9c04d1dbe4c7ae216aca90af9be56995226a061;hb=3922b302645fda04da42a5279399578ae2f6206c;hp=0b3f3ac9f18ea8d44c5f661577d9e06c28d8463a;hpb=72ec28b8afa357cdde70c612b4e0e9f37a34f8e4;p=deliverable%2Fbinutils-gdb.git
diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 0b3f3ac9f1..b9c04d1dbe 100644
--- a/sim/erc32/erc32.c
+++ b/sim/erc32/erc32.c
@@ -1,35 +1,32 @@
-/*
- * This file is part of SIS.
- *
- * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler,
- * European Space Agency
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- *
- */
+/* This file is part of SIS (SPARC instruction simulator)
+
+ Copyright (C) 1995-2020 Free Software Foundation, Inc.
+ Contributed by Jiri Gaisler, European Space Agency
+
+ 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 . */
/* The control space devices */
+#include "config.h"
#include
#include
+#include
#include
#include
#include
#include
#include "sis.h"
-#include "end.h"
#include "sim-config.h"
extern int ctrl_c;
@@ -54,11 +51,6 @@ int dumbio = 0; /* normal, smart, terminal oriented IO by default */
extern int errmec;
#endif
-/* The target's byte order is big-endian by default until we load a
- little-endian program. */
-
-int current_target_byte_order = BIG_ENDIAN;
-
#define MEC_WS 0 /* Waitstates per MEC access (0 ws) */
#define MOK 0
@@ -255,52 +247,49 @@ int erareg;
/* Forward declarations */
-static void decode_ersr PARAMS ((void));
+static void decode_ersr (void);
#ifdef ERRINJ
-static void iucomperr PARAMS ((void));
+static void iucomperr (void);
#endif
-static void mecparerror PARAMS ((void));
-static void decode_memcfg PARAMS ((void));
-static void decode_wcr PARAMS ((void));
-static void decode_mcr PARAMS ((void));
-static void close_port PARAMS ((void));
-static void mec_reset PARAMS ((void));
-static void mec_intack PARAMS ((int32 level));
-static void chk_irq PARAMS ((void));
-static void mec_irq PARAMS ((int32 level));
-static void set_sfsr PARAMS ((uint32 fault, uint32 addr,
- uint32 asi, uint32 read));
-static int32 mec_read PARAMS ((uint32 addr, uint32 asi, uint32 *data));
-static int mec_write PARAMS ((uint32 addr, uint32 data));
-static void port_init PARAMS ((void));
-static uint32 read_uart PARAMS ((uint32 addr));
-static void write_uart PARAMS ((uint32 addr, uint32 data));
-static void flush_uart PARAMS ((void));
-static void uarta_tx PARAMS ((void));
-static void uartb_tx PARAMS ((void));
-static void uart_rx PARAMS ((caddr_t arg));
-static void uart_intr PARAMS ((caddr_t arg));
-static void uart_irq_start PARAMS ((void));
-static void wdog_intr PARAMS ((caddr_t arg));
-static void wdog_start PARAMS ((void));
-static void rtc_intr PARAMS ((caddr_t arg));
-static void rtc_start PARAMS ((void));
-static uint32 rtc_counter_read PARAMS ((void));
-static void rtc_scaler_set PARAMS ((uint32 val));
-static void rtc_reload_set PARAMS ((uint32 val));
-static void gpt_intr PARAMS ((caddr_t arg));
-static void gpt_start PARAMS ((void));
-static uint32 gpt_counter_read PARAMS ((void));
-static void gpt_scaler_set PARAMS ((uint32 val));
-static void gpt_reload_set PARAMS ((uint32 val));
-static void timer_ctrl PARAMS ((uint32 val));
+static void mecparerror (void);
+static void decode_memcfg (void);
+static void decode_wcr (void);
+static void decode_mcr (void);
+static void close_port (void);
+static void mec_reset (void);
+static void mec_intack (int32 level);
+static void chk_irq (void);
+static void mec_irq (int32 level);
+static void set_sfsr (uint32 fault, uint32 addr,
+ uint32 asi, uint32 read);
+static int32 mec_read (uint32 addr, uint32 asi, uint32 *data);
+static int mec_write (uint32 addr, uint32 data);
+static void port_init (void);
+static uint32 read_uart (uint32 addr);
+static void write_uart (uint32 addr, uint32 data);
+static void flush_uart (void);
+static void uarta_tx (void);
+static void uartb_tx (void);
+static void uart_rx (caddr_t arg);
+static void uart_intr (caddr_t arg);
+static void uart_irq_start (void);
+static void wdog_intr (caddr_t arg);
+static void wdog_start (void);
+static void rtc_intr (caddr_t arg);
+static void rtc_start (void);
+static uint32 rtc_counter_read (void);
+static void rtc_scaler_set (uint32 val);
+static void rtc_reload_set (uint32 val);
+static void gpt_intr (caddr_t arg);
+static void gpt_start (void);
+static uint32 gpt_counter_read (void);
+static void gpt_scaler_set (uint32 val);
+static void gpt_reload_set (uint32 val);
+static void timer_ctrl (uint32 val);
static unsigned char *
- get_mem_ptr PARAMS ((uint32 addr, uint32 size));
-
-static void fetch_bytes PARAMS ((int asi, unsigned char *mem,
- uint32 *data, int sz));
-
-static void store_bytes PARAMS ((unsigned char *mem, uint32 *data, int sz));
+ get_mem_ptr (uint32 addr, uint32 size);
+static void store_bytes (unsigned char *mem, uint32 waddr,
+ uint32 *data, int sz, int32 *ws);
extern int ext_irl;
@@ -732,7 +721,7 @@ mec_read(addr, asi, data)
case MEC_UARTB: /* 0xE4 */
if (asi != 0xb) {
set_sfsr(MEC_ACC, addr, asi, 1);
- return (1);
+ return 1;
}
*data = read_uart(addr);
break;
@@ -742,12 +731,20 @@ mec_read(addr, asi, data)
*data = read_uart(addr);
break;
+ case 0xF4: /* simulator RAM size in bytes */
+ *data = 4096*1024;
+ break;
+
+ case 0xF8: /* simulator ROM size in bytes */
+ *data = 1024*1024;
+ break;
+
default:
set_sfsr(MEC_ACC, addr, asi, 1);
- return (1);
+ return 1;
break;
}
- return (MOK);
+ return MOK;
}
static int
@@ -923,10 +920,10 @@ mec_write(addr, data)
default:
set_sfsr(MEC_ACC, addr, 0xb, 0);
- return (1);
+ return 1;
break;
}
- return (MOK);
+ return MOK;
}
@@ -1078,7 +1075,7 @@ read_uart(addr)
return tmp;
#endif
#else
- return(0);
+ return 0;
#endif
break;
@@ -1110,7 +1107,7 @@ read_uart(addr)
return tmp;
#endif
#else
- return(0);
+ return 0;
#endif
break;
@@ -1145,12 +1142,12 @@ read_uart(addr)
}
Ucontrol |= 0x00060006;
- return (Ucontrol);
+ return Ucontrol;
#else
- return (uart_stat_reg);
+ return uart_stat_reg;
#endif
#else
- return(0x00060006);
+ return 0x00060006;
#endif
break;
default:
@@ -1158,7 +1155,7 @@ read_uart(addr)
printf("Read from unimplemented MEC register (%x)\n", addr);
}
- return (0);
+ return 0;
}
static void
@@ -1420,7 +1417,7 @@ rtc_start()
static uint32
rtc_counter_read()
{
- return (rtc_counter);
+ return rtc_counter;
}
static void
@@ -1473,7 +1470,7 @@ gpt_start()
static uint32
gpt_counter_read()
{
- return (gpt_counter);
+ return gpt_counter;
}
static void
@@ -1516,128 +1513,68 @@ timer_ctrl(val)
gpt_start();
}
-
-/* Retrieve data from target memory. MEM points to location from which
- to read the data; DATA points to words where retrieved data will be
- stored in host byte order. 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). */
+/* 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
-fetch_bytes (asi, mem, data, sz)
- int asi;
- unsigned char *mem;
- uint32 *data;
- int sz;
+store_bytes (unsigned char *mem, uint32 waddr, uint32 *data, int32 sz,
+ int32 *ws)
{
- if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
- || asi == 8 || asi == 9) {
- switch (sz) {
- case 3:
- data[1] = (((uint32) mem[7]) & 0xff) |
- ((((uint32) mem[6]) & 0xff) << 8) |
- ((((uint32) mem[5]) & 0xff) << 16) |
- ((((uint32) mem[4]) & 0xff) << 24);
- /* Fall through to 2 */
- case 2:
- data[0] = (((uint32) mem[3]) & 0xff) |
- ((((uint32) mem[2]) & 0xff) << 8) |
- ((((uint32) mem[1]) & 0xff) << 16) |
- ((((uint32) mem[0]) & 0xff) << 24);
+ switch (sz) {
+ case 0:
+ waddr ^= EBT;
+ mem[waddr] = *data & 0x0ff;
+ *ws = mem_ramw_ws + 3;
break;
case 1:
- data[0] = (((uint32) mem[1]) & 0xff) |
- ((((uint32) mem[0]) & 0xff) << 8);
- break;
- case 0:
- data[0] = mem[0] & 0xff;
+#ifdef HOST_LITTLE_ENDIAN
+ waddr ^= 2;
+#endif
+ memcpy (&mem[waddr], data, 2);
+ *ws = mem_ramw_ws + 3;
break;
-
- }
- } else {
- switch (sz) {
- case 3:
- data[1] = ((((uint32) mem[7]) & 0xff) << 24) |
- ((((uint32) mem[6]) & 0xff) << 16) |
- ((((uint32) mem[5]) & 0xff) << 8) |
- (((uint32) mem[4]) & 0xff);
- /* Fall through to 4 */
case 2:
- data[0] = ((((uint32) mem[3]) & 0xff) << 24) |
- ((((uint32) mem[2]) & 0xff) << 16) |
- ((((uint32) mem[1]) & 0xff) << 8) |
- (((uint32) mem[0]) & 0xff);
- break;
- case 1:
- data[0] = ((((uint32) mem[1]) & 0xff) << 8) |
- (((uint32) mem[0]) & 0xff);
+ memcpy (&mem[waddr], data, 4);
+ *ws = mem_ramw_ws;
break;
- case 0:
- data[0] = mem[0] & 0xff;
+ case 3:
+ memcpy (&mem[waddr], data, 8);
+ *ws = 2 * mem_ramw_ws + STD_WS;
break;
- }
}
}
-/* Store data in target byte order. MEM points to location to store data;
- 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). */
+/* Memory emulation */
-static void
-store_bytes (mem, data, sz)
- unsigned char *mem;
- uint32 *data;
- int sz;
+int
+memory_iread (uint32 addr, uint32 *data, int32 *ws)
{
- if (CURRENT_TARGET_BYTE_ORDER == LITTLE_ENDIAN) {
- switch (sz) {
- case 3:
- mem[7] = (data[1] >> 24) & 0xff;
- mem[6] = (data[1] >> 16) & 0xff;
- mem[5] = (data[1] >> 8) & 0xff;
- mem[4] = data[1] & 0xff;
- /* Fall through to 2 */
- case 2:
- mem[3] = (data[0] >> 24) & 0xff;
- mem[2] = (data[0] >> 16) & 0xff;
- /* Fall through to 1 */
- case 1:
- mem[1] = (data[0] >> 8) & 0xff;
- /* Fall through to 0 */
- case 0:
- mem[0] = data[0] & 0xff;
- break;
- }
- } else {
- switch (sz) {
- case 3:
- mem[7] = data[1] & 0xff;
- mem[6] = (data[1] >> 8) & 0xff;
- mem[5] = (data[1] >> 16) & 0xff;
- mem[4] = (data[1] >> 24) & 0xff;
- /* Fall through to 2 */
- case 2:
- mem[3] = data[0] & 0xff;
- mem[2] = (data[0] >> 8) & 0xff;
- mem[1] = (data[0] >> 16) & 0xff;
- mem[0] = (data[0] >> 24) & 0xff;
- break;
- case 1:
- mem[1] = data[0] & 0xff;
- mem[0] = (data[0] >> 8) & 0xff;
- break;
- case 0:
- mem[0] = data[0] & 0xff;
- break;
-
- }
+ uint32 asi;
+ if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
+ memcpy (data, &ramb[addr & mem_rammask & ~3], 4);
+ *ws = mem_ramr_ws;
+ return 0;
+ } else if (addr < mem_romsz) {
+ memcpy (data, &romb[addr & ~3], 4);
+ *ws = mem_romr_ws;
+ return 0;
}
-}
-
-/* Memory emulation */
+ if (sis_verbose)
+ printf ("Memory exception at %x (illegal address)\n", addr);
+ if (sregs.psr & 0x080)
+ asi = 9;
+ else
+ asi = 8;
+ set_sfsr (UIMP_ACC, addr, asi, 1);
+ *ws = MEM_EX_WS;
+ return 1;
+}
int
memory_read(asi, addr, data, sz, ws)
@@ -1657,14 +1594,14 @@ memory_read(asi, addr, data, sz, ws)
if (errmec == 5) mecparerror();
if (errmec == 6) iucomperr();
errmec = 0;
- return(1);
+ return 1;
}
-#endif;
+#endif
if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
- fetch_bytes (asi, &ramb[addr & mem_rammask], data, sz);
+ memcpy (data, &ramb[addr & mem_rammask & ~3], 4);
*ws = mem_ramr_ws;
- return (0);
+ return 0;
} else if ((addr >= MEC_START) && (addr < MEC_END)) {
mexc = mec_read(addr, asi, data);
if (mexc) {
@@ -1673,41 +1610,41 @@ memory_read(asi, addr, data, sz, ws)
} else {
*ws = 0;
}
- return (mexc);
+ return mexc;
#ifdef ERA
} else if (era) {
if ((addr < 0x100000) ||
((addr>= 0x80000000) && (addr < 0x80100000))) {
- fetch_bytes (asi, &romb[addr & ROM_MASK], data, sz);
+ memcpy (data, &romb[addr & ROM_MASK & ~3], 4);
*ws = 4;
- return (0);
+ return 0;
} else if ((addr >= 0x10000000) &&
(addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
(mec_iocr & 0x10)) {
*data = erareg;
- return (0);
+ return 0;
}
} else if (addr < mem_romsz) {
- fetch_bytes (asi, &romb[addr], data, sz);
- *ws = mem_romr_ws;
- return (0);
-
+ memcpy (data, &romb[addr & ~3], 4);
+ *ws = mem_romr_ws;
+ return 0;
#else
} else if (addr < mem_romsz) {
- fetch_bytes (asi, &romb[addr], data, sz);
+ memcpy (data, &romb[addr & ~3], 4);
*ws = mem_romr_ws;
- return (0);
+ return 0;
#endif
}
- printf("Memory exception at %x (illegal address)\n", addr);
+ if (sis_verbose)
+ printf ("Memory exception at %x (illegal address)\n", addr);
set_sfsr(UIMP_ACC, addr, asi, 1);
*ws = MEM_EX_WS;
- return (1);
+ return 1;
}
int
@@ -1734,9 +1671,9 @@ memory_write(asi, addr, data, sz, ws)
if (errmec == 5) mecparerror();
if (errmec == 6) iucomperr();
errmec = 0;
- return(1);
+ return 1;
}
-#endif;
+#endif
if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
if (mem_accprot) {
@@ -1756,30 +1693,17 @@ memory_write(asi, addr, data, sz, ws)
printf("Memory access protection error at 0x%08x\n", addr);
set_sfsr(PROT_EXC, addr, asi, 0);
*ws = MEM_EX_WS;
- return (1);
+ return 1;
}
}
-
- store_bytes (&ramb[addr & mem_rammask], data, sz);
-
- switch (sz) {
- case 0:
- case 1:
- *ws = mem_ramw_ws + 3;
- break;
- case 2:
- *ws = mem_ramw_ws;
- break;
- case 3:
- *ws = 2 * mem_ramw_ws + STD_WS;
- break;
- }
- return (0);
+ waddr = addr & mem_rammask;
+ store_bytes (ramb, waddr, data, sz, ws);
+ return 0;
} else if ((addr >= MEC_START) && (addr < MEC_END)) {
if ((sz != 2) || (asi != 0xb)) {
set_sfsr(MEC_ACC, addr, asi, 0);
*ws = MEM_EX_WS;
- return (1);
+ return 1;
}
mexc = mec_write(addr, *data);
if (mexc) {
@@ -1788,7 +1712,7 @@ memory_write(asi, addr, data, sz, ws)
} else {
*ws = 0;
}
- return (mexc);
+ return mexc;
#ifdef ERA
@@ -1797,13 +1721,13 @@ memory_write(asi, addr, data, sz, ws)
((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) {
addr &= ROM_MASK;
*ws = sz == 3 ? 8 : 4;
- store_bytes (&romb[addr], data, sz);
- return (0);
+ store_bytes (romb, addr, data, sz, ws);
+ return 0;
} else if ((addr >= 0x10000000) &&
(addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
(mec_iocr & 0x10)) {
erareg = *data & 0x0e;
- return (0);
+ return 0;
}
} else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) &&
@@ -1813,8 +1737,8 @@ memory_write(asi, addr, data, sz, ws)
*ws = mem_romw_ws + 1;
if (sz == 3)
*ws += mem_romw_ws + STD_WS;
- store_bytes (&romb[addr], data, sz);
- return (0);
+ store_bytes (romb, addr, data, sz, ws);
+ return 0;
#else
} else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) &&
@@ -1824,8 +1748,8 @@ memory_write(asi, addr, data, sz, ws)
*ws = mem_romw_ws + 1;
if (sz == 3)
*ws += mem_romw_ws + STD_WS;
- store_bytes (&romb[addr], data, sz);
- return (0);
+ store_bytes (romb, addr, data, sz, ws);
+ return 0;
#endif
@@ -1833,7 +1757,7 @@ memory_write(asi, addr, data, sz, ws)
*ws = MEM_EX_WS;
set_sfsr(UIMP_ACC, addr, asi, 0);
- return (1);
+ return 1;
}
static unsigned char *
@@ -1842,34 +1766,34 @@ get_mem_ptr(addr, size)
uint32 size;
{
if ((addr + size) < ROM_SZ) {
- return (&romb[addr]);
+ return &romb[addr];
} else if ((addr >= mem_ramstart) && ((addr + size) < mem_ramend)) {
- return (&ramb[addr & mem_rammask]);
+ return &ramb[addr & mem_rammask];
}
#ifdef ERA
else if ((era) && ((addr <0x100000) ||
((addr >= (unsigned) 0x80000000) && ((addr + size) < (unsigned) 0x80100000)))) {
- return (&romb[addr & ROM_MASK]);
+ return &romb[addr & ROM_MASK];
}
#endif
- return ((char *) -1);
+ return (char *) -1;
}
int
sis_memory_write(addr, data, length)
- uint32 addr;
- char *data;
- uint32 length;
+ uint32 addr;
+ const unsigned char *data;
+ uint32 length;
{
char *mem;
if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
- return (0);
+ return 0;
memcpy(mem, data, length);
- return (length);
+ return length;
}
int
@@ -1881,8 +1805,24 @@ sis_memory_read(addr, data, length)
char *mem;
if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
- return (0);
+ return 0;
memcpy(data, mem, length);
- return (length);
+ return length;
+}
+
+extern struct pstate sregs;
+
+void
+boot_init (void)
+{
+ mec_write(MEC_WCR, 0); /* zero waitstates */
+ mec_write(MEC_TRAPD, 0); /* turn off watch-dog */
+ mec_write(MEC_RTC_SCALER, sregs.freq - 1); /* generate 1 MHz RTC tick */
+ mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
+ sregs.wim = 2;
+ sregs.psr = 0x110010e0;
+ sregs.r[30] = RAM_END;
+ sregs.r[14] = sregs.r[30] - 96 * 4;
+ mec_mcr |= 1; /* power-down enabled */
}