GDB copyright headers update after running GDB's copyright.py script.
[deliverable/binutils-gdb.git] / sim / erc32 / erc32.c
index 0b3f3ac9f18ea8d44c5f661577d9e06c28d8463a..c24b652e05544ffbc565b5fb10cb7339bca807fa 100644 (file)
@@ -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-2016 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 <http://www.gnu.org/licenses/>.  */
 
 /* The control space devices */
 
+#include "config.h"
 #include <sys/types.h>
 #include <stdio.h>
+#include <string.h>
 #include <termios.h>
 #include <sys/fcntl.h>
 #include <sys/file.h>
 #include <unistd.h>
 #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 */
 }
This page took 0.032953 seconds and 4 git commands to generate.