source: rtems-tools/tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch @ bfd2b7d

4.104.115
Last change on this file since bfd2b7d was bfd2b7d, checked in by Joel Sherrill <joel.sherrill@…>, on 03/26/15 at 18:20:45

Add Jiri Gaisler SIS patch set for gdb 7.9

This patch set adds a lot of new capability including support for
the leon2 and leon3. It also eliminates the difference between
the initial state of the simulated erc32 and the real hardware.

  • Property mode set to 100644
File size: 66.7 KB
  • sim/erc32/Makefile.in

    From d3e77f683adc96e3fc8395f21b8e440ee923a092 Mon Sep 17 00:00:00 2001
    From: Jiri Gaisler <jiri@gaisler.se>
    Date: Wed, 18 Feb 2015 22:47:49 +0100
    Subject: [PATCH 18/23] sim/erc32: Add support for LEON3 processor emulation.
    
    	Added memory and I/O sub-system to emulate a LEON3 processor.
    	The cache and MMU are not emulated but enough functionallity
    	is provided to run any RTEMS and BCC compiled application.
    	The code is based on erc32.c and modified to emulate the
    	LEON3 address space and peripheral operations.
    ---
     sim/erc32/Makefile.in  |    4 +-
     sim/erc32/README.leon3 |   53 +++
     sim/erc32/README.sis   |   81 ++--
     sim/erc32/erc32.c      |   48 ++-
     sim/erc32/exec.c       |  228 +++++++++--
     sim/erc32/func.c       |   57 +--
     sim/erc32/grlib.c      |   98 +++++
     sim/erc32/grlib.h      |   57 +++
     sim/erc32/interf.c     |   26 +-
     sim/erc32/leon3.c      | 1066 ++++++++++++++++++++++++++++++++++++++++++++++++
     sim/erc32/sis.c        |   22 +-
     sim/erc32/sis.h        |   49 ++-
     12 files changed, 1660 insertions(+), 129 deletions(-)
     create mode 100644 sim/erc32/README.leon3
     create mode 100644 sim/erc32/grlib.c
     create mode 100644 sim/erc32/grlib.h
     create mode 100644 sim/erc32/leon3.c
    
    diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in
    index 4f86017..e40eb79 100644
    a b  
    2121TERMCAP_LIB = @TERMCAP@
    2222READLINE_LIB = @READLINE@
    2323
    24 SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o
     24SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o leon3.o grlib.o
    2525SIM_EXTRA_LIBS = $(READLINE_LIB) $(TERMCAP_LIB) -lm
    2626SIM_EXTRA_ALL = sis
    2727SIM_EXTRA_INSTALL = install-sis
    SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcroot) 
    3535## COMMON_POST_CONFIG_FRAG
    3636
    3737# `sis' doesn't need interf.o.
    38 SIS_OFILES = exec.o erc32.o func.o help.o float.o
     38SIS_OFILES = exec.o erc32.o func.o help.o float.o grlib.o leon3.o
    3939
    4040sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS)
    4141        $(CC) $(ALL_CFLAGS) -o sis \
  • new file sim/erc32/README.leon3

    diff --git a/sim/erc32/README.leon3 b/sim/erc32/README.leon3
    new file mode 100644
    index 0000000..f6701a5
    - +  
     1
     21. LEON3 emulation
     3
     4The file 'leon3.c' contains a model of simple LEON3 sub-system. It
     5contains 16 Mbyte ROM and 16 Mbyte RAM. Standard peripherals
     6such as interrupt controller, UART and timer are provided.
     7The model can execute leon3 binaries that do not require an
     8MMU.
     9
     10To start sis in Leon3 mode, add the -leon3 switch. In gdb,
     11use 'target sim -leon3' .
     12
     131.1 UART
     14
     15The UART emulates an APBUART and is located at address 0x80000100.
     16The following registers are implemeted:
     17
     18- UART RX and TX register       (0x80000100)
     19- UART status register          (0x80000104)
     20
     21The UART generates interrupt 3.
     22
     231.2 Timer unit (GPTIMER)
     24
     25The GPTIMER programmable counter is emulated and located at
     26address 0x80000300. It is configured with two timers and separate
     27interrupts (8 and 9).
     28
     291.3 Interrupt controller
     30
     31The IRQMP interrupt controller is implemented as described in the
     32GRLIB IP manual, with the exception of the interrupt level register.
     33Extended interrupts are not supported. The registers are located
     34at address 0x80000200.
     35
     361.5 Memory interface
     37
     38The following memory areas are valid for the Leon3 simulator:
     39
     400x00000000 - 0x01000000         ROM (16 Mbyte, loaded at start-up)
     410x40000000 - 0x41000000         RAM (16 Mbyte, loaded at start-up)
     420x80000000 - 0x81000000         APB bus, including plug&play
     430xFFFFF000 - 0xFFFFFFFF         AHB plug&play area
     44
     45Access to non-existing memory will result in a memory exception trap.
     46
     471.8 Power-down mode
     48
     49The Leon3 power-down feature (%asr19) is supported. When power-down is
     50entered, time is skipped forward until the next event in the event queue.
     51However, if the simulator event queue is empty, power-down mode is not
     52entered since no interrupt would be generated to exit from the mode. A
     53Ctrl-C in the simulator window will exit the power-down mode.
  • sim/erc32/README.sis

    diff --git a/sim/erc32/README.sis b/sim/erc32/README.sis
    index b119f03..124e577 100644
    a b  
    11
    2 SIS - Sparc Instruction Simulator README file  (v2.0, 05-02-1996)
     2SIS - Sparc Instruction Simulator README file  (v2.8, 10-11-2014)
    33-------------------------------------------------------------------
    44
    551. Introduction
    66
    7 The SIS is a SPARC V7 architecture simulator. It consist of two parts,
     7The SIS is a SPARC V7/V8 architecture simulator. It consist of two parts,
    88the simulator core and a user defined memory module. The simulator
    99core executes the instructions while the memory module emulates memory
    1010and peripherals.
    and peripherals. 
    1313
    1414The simulator is started as follows:
    1515
    16 sis [-uart1 uart_device1] [-uart2 uart_device2]
     16sis [-leon3] [-uart1 uart_device1] [-uart2 uart_device2]
    1717    [-nfp] [-freq frequency] [-c batch_file] [files]
    1818
    19 The default uart devices for SIS are /dev/ptypc and /dev/ptypd. The
    20 -uart[1,2] switch can be used to connect the uarts to other devices.
    21 Use 'tip /dev/ttypc'  to connect a terminal emulator to the uarts.
     19By default, SIS emulates an ERC32 system. The -leon3 switch
     20enables emulation of a LEON3 SOC system.
     21
     22The emulated console uart is connected to stdin/stdout. The -uart[1,2]
     23switch can be used to connect the uarts to other devices.
     24
    2225The '-nfp' will disable the simulated FPU, so each FPU instruction will
    2326generate a FPU disabled trap. The '-freq' switch can be used to define
    2427which "frequency" the simulator runs at. This is used by the 'perf'
    2528command to calculated the MIPS figure for a particular configuration.
    26 The give frequency must be an integer indicating the frequency in MHz.
     29The frequency must be an integer indicating the frequency in MHz.
    2730
    2831The -c option indicates that sis commands should be read from 'batch_file'
    2932at startup.
    3033
    31 Files to be loaded must be in one of the supported formats (see INSTALLATION),
    32 and will be loaded into the simulated memory. The file formats are
    33 automatically recognised.
     34Files to be loaded must be in one of the supported formats (elf, a.out, srec),
     35and will be loaded into the simulated memory.
    3436
    35 The script 'startsim' will start the simulator in one xterm window and
    36 open a terminal emulator (tip) connected to the UART A in a second
    37 xterm window. Below is description of commands  that are recognized by
     37Below is description of commands  that are recognized by
    3838the simulator. The command-line is parsed using GNU readline. A command
    3939history of 64 commands is maintained. Use the up/down arrows to recall
    4040previous commands. For more details, see the readline documentation.
    Prints the FPU registers 
    7777go <address> [inst_count]
    7878
    7979The go command will set pc to <address> and npc to <address> + 4, and start
    80 execution. No other initialisation will be done. If inst_count is given,
    81 execution will stop after the specified number of instructions.
     80execution. If inst_count is given, execution will stop after the specified
     81number of instructions.
    8282
    8383help
    8484
    interpreted as 'cont'. 
    146146
    1471473. Simulator core
    148148
    149 The SIS emulates the behavior of the 90C601E and 90C602E sparc IU and
    150 FPU from Matra MHS. These are roughly equivalent to the Cypress C601
    151 and C602. The simulator is cycle true, i.e a simulator time is
    152 maintained and inremented according the IU and FPU instruction timing.
     149In ERC32 mode, SIS emulates the behavior of the 90C601E and 90C602E
     150sparc IU and FPU from Matra MHS. These are roughly equivalent to the
     151Cypress C601 and C602. The simulator is cycle true, i.e a simulator time is
     152maintained and incremented according the IU and FPU instruction timing.
    153153The parallel execution between the IU and FPU is modelled, as well as
    154 stalls due to operand dependencies (FPU). The core interacts with the
    155 user-defined memory modules through a number of functions. The memory
    156 module must provide the following functions:
     154stalls due to operand dependencies (FPU).
     155
     156In Leon3 mode, the core emulates the Leon3 SPARC V8 core from
     157Gaisler Research. All SPARC V8 instructions are supported but
     158emulation is not fully cycle-true as the cache is not emulated.
     159
     160The core interacts with the user-defined memory modules through
     161a number of functions. The memory module must provide the following
     162functions:
    157163
    158164int memory_read(asi,addr,data,ws)
    159165int asi;
    See 'erc32.c' for examples on how to use events and interrupts. 
    272278
    2732795. Memory module
    274280
    275 The supplied memory module (erc32.c) emulates the functions of memory and
     281The ERC32 memory module (erc32.c) emulates the functions of memory and
    276282the MEC asic developed for the 90C601/2. It includes the following functions:
    277283
    278284* UART A & B
    the MEC asic developed for the 90C601/2. It includes the following functions: 
    284290* 512 Kbyte ROM
    285291* 4 Mbyte RAM
    286292
    287 See README.erc32 on how the MEC functions are emulated.  For a detailed MEC
    288 specification, look at the ERC32 home page at URL:
     293See README.erc32 on how the MEC functions are emulated.
    289294
    290 http://www.estec.esa.nl/wsmwww/erc32
     295The Leon3 memory module (leon3.c) emulates on-chip peripherals and
     296external memory for a simple Leon3 system. The modules includes the
     297following functions:
    291298
    292 6. Compile and linking programs
     299* AHB and APB buses with plug&play
     300* UART (APBUART)
     301* Interrupt controller (IRQMP)
     302* Timer unit with two timers (GPTIMER)
     303* PROM/SRAM memory controller (SRCTRL)
     304* 16 Mbyte PROM, 16 Mbyte SRAM
    293305
    294 The directory 'examples' contain some code fragments for SIS.
    295 The script gccx indicates how the native sunos gcc and linker can be used
    296 to produce executables for the simulator. To compile and link the provided
    297 'hello.c', type 'gccx hello.c'. This will build the executable 'hello'.
    298 Start the simulator by running 'startsim hello', and issue the command 'run.
    299 After the program is terminated, the IU will be force to error mode through
    300 a software trap and halt.
     306See README.leon3 for further details on Leon3 emulation.
    301307
    302 The programs are linked with a start-up file, srt0.S. This file includes
    303 the traptable and window underflow/overflow trap routines.
     3086. Compile and linking programs
    304309
    3053107. IU and FPU instruction timing.
    306311
    307 The simulator provides cycle true simulation. The following table shows
    308 the emulated instruction timing for 90C601E & 90C602E:
     312The simulator provides cycle true simulation for ERC32. The following table
     313shows the emulated instruction timing for 90C601E & 90C602E:
    309314
    310315Instructions          Cycles
    311316
  • sim/erc32/erc32.c

    diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
    index 89c745a..0e1a2ed 100644
    a b memory_iread(addr, data, ws) 
    16361636}
    16371637
    16381638static int
    1639 memory_read(asi, addr, data, sz, ws)
    1640     int32           asi;
     1639memory_read(addr, data, sz, ws)
    16411640    uint32          addr;
    16421641    uint32         *data;
    16431642    int32           sz;
    16441643    int32          *ws;
    16451644{
    16461645    int32           mexc;
     1646    int32           asi;
    16471647
    16481648#ifdef ERRINJ
    16491649    if (errmec) {
    16501650        if (sis_verbose)
    16511651            printf("Inserted MEC error %d\n",errmec);
     1652        if (sregs.psr & 0x080) asi = 11; else asi = 10;
    16521653        set_sfsr(errmec, addr, asi, 1);
    16531654        if (errmec == 5) mecparerror();
    16541655        if (errmec == 6) iucomperr();
    memory_read(asi, addr, data, sz, ws) 
    16621663        *ws = mem_ramr_ws;
    16631664        return (0);
    16641665    } else if ((addr >= MEC_START) && (addr < MEC_END)) {
     1666        if (sregs.psr & 0x080) asi = 11; else asi = 10;
    16651667        mexc = mec_read(addr, asi, data);
    16661668        if (mexc) {
    16671669            set_sfsr(MEC_ACC, addr, asi, 1);
    memory_read(asi, addr, data, sz, ws) 
    17011703    }
    17021704
    17031705    printf("Memory exception at %x (illegal address)\n", addr);
     1706    if (sregs.psr & 0x080) asi = 11; else asi = 10;
    17041707    set_sfsr(UIMP_ACC, addr, asi, 1);
    17051708    *ws = MEM_EX_WS;
    17061709    return (1);
    17071710}
    17081711
    17091712static int
    1710 memory_write(asi, addr, data, sz, ws)
     1713memory_read_asi(asi, addr, data, sz, ws)
    17111714    int32           asi;
    17121715    uint32          addr;
    17131716    uint32         *data;
    17141717    int32           sz;
    17151718    int32          *ws;
    17161719{
     1720    return(memory_read(addr, data, sz, ws));
     1721}
     1722
     1723static int
     1724memory_write(addr, data, sz, ws)
     1725    uint32          addr;
     1726    uint32         *data;
     1727    int32           sz;
     1728    int32          *ws;
     1729{
    17171730    uint32          byte_addr;
    17181731    uint32          byte_mask;
    17191732    uint32          waddr;
    memory_write(asi, addr, data, sz, ws) 
    17211734    int32           mexc;
    17221735    int             i;
    17231736    int             wphit[2];
     1737    int32           asi;
    17241738
    17251739#ifdef ERRINJ
    17261740    if (errmec) {
    17271741        if (sis_verbose)
    17281742            printf("Inserted MEC error %d\n",errmec);
     1743        if (sregs.psr & 0x080) asi = 11; else asi = 10;
    17291744        set_sfsr(errmec, addr, asi, 0);
    17301745        if (errmec == 5) mecparerror();
    17311746        if (errmec == 6) iucomperr();
    memory_write(asi, addr, data, sz, ws) 
    17381753        if (mem_accprot) {
    17391754
    17401755            waddr = (addr & 0x7fffff) >> 2;
     1756            if (sregs.psr & 0x080) asi = 11; else asi = 10;
    17411757            for (i = 0; i < 2; i++)
    17421758                wphit[i] =
    17431759                    (((asi == 0xa) && (mec_wpr[i] & 1)) ||
    memory_write(asi, addr, data, sz, ws) 
    17611777        return (0);
    17621778
    17631779    } else if ((addr >= MEC_START) && (addr < MEC_END)) {
     1780        if (sregs.psr & 0x080) asi = 11; else asi = 10;
    17641781        if ((sz != 2) || (asi != 0xb)) {
    17651782            set_sfsr(MEC_ACC, addr, asi, 0);
    17661783            *ws = MEM_EX_WS;
    memory_write(asi, addr, data, sz, ws) 
    18171834    }
    18181835       
    18191836    *ws = MEM_EX_WS;
     1837    if (sregs.psr & 0x080) asi = 11; else asi = 10;
    18201838    set_sfsr(UIMP_ACC, addr, asi, 0);
    18211839    return (1);
    18221840}
    18231841
     1842static int
     1843memory_write_asi(asi, addr, data, sz, ws)
     1844    int32           asi;
     1845    uint32          addr;
     1846    uint32         *data;
     1847    int32           sz;
     1848    int32          *ws;
     1849{
     1850    return(memory_write(addr, data, sz, ws));
     1851}
     1852
    18241853static unsigned char  *
    18251854get_mem_ptr(addr, size)
    18261855    uint32          addr;
    sis_memory_read(addr, data, length) 
    18641893    uint32          length;
    18651894{
    18661895    char           *mem;
     1896    int            ws;
     1897
     1898    if (length == 4) {
     1899      memory_read(addr, data, length, &ws);
     1900      return(4);
     1901    }
    18671902
    18681903    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
    18691904        return (0);
    sis_memory_read(addr, data, length) 
    18721907    return (length);
    18731908}
    18741909
    1875 void
     1910static void
    18761911boot_init (void)
    18771912{
    18781913    mec_write(MEC_WCR, 0);      /* zero waitstates */
    struct memsys erc32sys = { 
    18961931    restore_stdio,
    18971932    memory_iread,
    18981933    memory_read,
     1934    memory_read_asi,
    18991935    memory_write,
     1936    memory_write_asi,
    19001937    sis_memory_write,
    1901     sis_memory_read
     1938    sis_memory_read,
     1939    boot_init
    19021940};
  • sim/erc32/exec.c

    diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
    index 6d80306..6292998 100644
    a b dispatch_instruction(sregs) 
    10651065                *rdd = sregs->psr;
    10661066                break;
    10671067            case RDY:
    1068                 if (!sparclite)
     1068                if ((!sparclite) && (cputype != CPU_LEON3))
    10691069                    *rdd = sregs->y;
    10701070                else {
    10711071                    int rs1_is_asr = (sregs->inst >> 14) & 0x1f;
    10721072                    if ( 0 == rs1_is_asr )
    10731073                        *rdd = sregs->y;
    1074                     else if ( 17 == rs1_is_asr )
     1074                    else if ( 17 == rs1_is_asr ) {
    10751075                        *rdd = sregs->asr17;
     1076                    }
    10761077                    else {
    10771078                        sregs->trap = TRAP_UNIMP;
    1078                         break;
    10791079                    }
    10801080                }
    10811081                break;
    dispatch_instruction(sregs) 
    11211121                    ((rs1 ^ operand2) & 0xfffff000);
    11221122                break;
    11231123            case WRY:
    1124                 if (!sparclite)
     1124                if ((!sparclite) && (cputype != CPU_LEON3))
    11251125                    sregs->y = (rs1 ^ operand2);
    11261126                else {
    11271127                    if ( 0 == rd )
    11281128                        sregs->y = (rs1 ^ operand2);
    1129                     else if ( 17 == rd )
    1130                         sregs->asr17 = (rs1 ^ operand2);
     1129                    else if ( 17 == rd ) {
     1130                        if (sparclite)
     1131                            sregs->asr17 = (rs1 ^ operand2);
     1132                    }
     1133                    else if ( 19 == rd ) {
     1134                        if (cputype == CPU_LEON3)
     1135                            wait_for_irq();
     1136                    }
    11311137                    else {
    11321138                        sregs->trap = TRAP_UNIMP;
    11331139                        break;
    dispatch_instruction(sregs) 
    12271233        switch (op3) {
    12281234        case LDDA:
    12291235            if (!chk_asi(sregs, &asi, op3)) break;
     1236            if (address & 0x7) {
     1237                sregs->trap = TRAP_UNALI;
     1238                break;
     1239            }
     1240            if (rd & 1) {
     1241                rd &= 0x1e;
     1242                if (rd > 7)
     1243                    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
     1244                else
     1245                    rdd = &(sregs->g[rd]);
     1246            }
     1247            mexc = ms->memory_read_asi(asi, address, ddata, 2, &ws);
     1248            sregs->hold += ws;
     1249            mexc |= ms->memory_read_asi(asi, address+4, &ddata[1], 2, &ws);
     1250            sregs->hold += ws;
     1251            sregs->icnt = T_LDD;
     1252            if (mexc) {
     1253                sregs->trap = TRAP_DEXC;
     1254            } else {
     1255                rdd[0] = ddata[0];
     1256                rdd[1] = ddata[1];
     1257#ifdef STAT
     1258                sregs->nload++; /* Double load counts twice */
     1259#endif
     1260            }
     1261            break;
    12301262        case LDD:
    12311263            if (address & 0x7) {
    12321264                sregs->trap = TRAP_UNALI;
    dispatch_instruction(sregs) 
    12391271                else
    12401272                    rdd = &(sregs->g[rd]);
    12411273            }
    1242             mexc = ms->memory_read(asi, address, ddata, 2, &ws);
     1274            mexc = ms->memory_read(address, ddata, 2, &ws);
    12431275            sregs->hold += ws;
    1244             mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws);
     1276            mexc |= ms->memory_read(address+4, &ddata[1], 2, &ws);
    12451277            sregs->hold += ws;
    12461278            sregs->icnt = T_LDD;
    12471279            if (mexc) {
    dispatch_instruction(sregs) 
    12571289
    12581290        case LDA:
    12591291            if (!chk_asi(sregs, &asi, op3)) break;
     1292            if (address & 0x3) {
     1293                sregs->trap = TRAP_UNALI;
     1294                break;
     1295            }
     1296            mexc = ms->memory_read_asi(asi, address, &data, 2, &ws);
     1297            sregs->hold += ws;
     1298            if (mexc) {
     1299                sregs->trap = TRAP_DEXC;
     1300            } else {
     1301                *rdd = data;
     1302            }
     1303            break;
    12601304        case LD:
    12611305            if (address & 0x3) {
    12621306                sregs->trap = TRAP_UNALI;
    12631307                break;
    12641308            }
    1265             mexc = ms->memory_read(asi, address, &data, 2, &ws);
     1309            mexc = ms->memory_read(address, &data, 2, &ws);
    12661310            sregs->hold += ws;
    12671311            if (mexc) {
    12681312                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    12721316            break;
    12731317        case LDSTUBA:
    12741318            if (!chk_asi(sregs, &asi, op3)) break;
     1319            mexc = ms->memory_read_asi(asi, address, &data, 0, &ws);
     1320            sregs->hold += ws;
     1321            sregs->icnt = T_LDST;
     1322            if (mexc) {
     1323                sregs->trap = TRAP_DEXC;
     1324                break;
     1325            }
     1326            data = extract_byte(data, address);
     1327            *rdd = data;
     1328            data = 0x0ff;
     1329            mexc = ms->memory_write_asi(asi, address, &data, 0, &ws);
     1330            sregs->hold += ws;
     1331            if (mexc) {
     1332                sregs->trap = TRAP_DEXC;
     1333            }
     1334#ifdef STAT
     1335            sregs->nload++;
     1336#endif
     1337            break;
    12751338        case LDSTUB:
    1276             mexc = ms->memory_read(asi, address, &data, 0, &ws);
     1339            mexc = ms->memory_read(address, &data, 0, &ws);
    12771340            sregs->hold += ws;
    12781341            sregs->icnt = T_LDST;
    12791342            if (mexc) {
    dispatch_instruction(sregs) 
    12831346            data = extract_byte(data, address);
    12841347            *rdd = data;
    12851348            data = 0x0ff;
    1286             mexc = ms->memory_write(asi, address, &data, 0, &ws);
     1349            mexc = ms->memory_write(address, &data, 0, &ws);
    12871350            sregs->hold += ws;
    12881351            if (mexc) {
    12891352                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    12951358        case LDSBA:
    12961359        case LDUBA:
    12971360            if (!chk_asi(sregs, &asi, op3)) break;
     1361            mexc = ms->memory_read_asi(asi, address, &data, 0, &ws);
     1362            sregs->hold += ws;
     1363            if (mexc) {
     1364                sregs->trap = TRAP_DEXC;
     1365                break;
     1366            }
     1367            if (op3 == LDSB)
     1368                data = extract_byte_signed(data, address);
     1369            else
     1370                data = extract_byte(data, address);
     1371            *rdd = data;
     1372            break;
    12981373        case LDSB:
    12991374        case LDUB:
    1300             mexc = ms->memory_read(asi, address, &data, 0, &ws);
     1375            mexc = ms->memory_read(address, &data, 0, &ws);
    13011376            sregs->hold += ws;
    13021377            if (mexc) {
    13031378                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    13121387        case LDSHA:
    13131388        case LDUHA:
    13141389            if (!chk_asi(sregs, &asi, op3)) break;
     1390            if (address & 0x1) {
     1391                sregs->trap = TRAP_UNALI;
     1392                break;
     1393            }
     1394            mexc = ms->memory_read_asi(asi, address, &data, 1, &ws);
     1395            sregs->hold += ws;
     1396            if (mexc) {
     1397                sregs->trap = TRAP_DEXC;
     1398                break;
     1399            }
     1400            if (op3 == LDSH)
     1401                data = extract_short_signed(data, address);
     1402            else
     1403                data = extract_short(data, address);
     1404            *rdd = data;
     1405            break;
    13151406        case LDSH:
    13161407        case LDUH:
    13171408            if (address & 0x1) {
    13181409                sregs->trap = TRAP_UNALI;
    13191410                break;
    13201411            }
    1321             mexc = ms->memory_read(asi, address, &data, 1, &ws);
     1412            mexc = ms->memory_read(address, &data, 1, &ws);
    13221413            sregs->hold += ws;
    13231414            if (mexc) {
    13241415                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    13441435                    (sregs->frs2 == rd))
    13451436                    sregs->fhold += (sregs->ftime - ebase.simtime);
    13461437            }
    1347             mexc = ms->memory_read(asi, address, &data, 2, &ws);
     1438            mexc = ms->memory_read(address, &data, 2, &ws);
    13481439            sregs->hold += ws;
    13491440            sregs->flrd = rd;
    13501441            sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
    dispatch_instruction(sregs) 
    13701461                    ((sregs->frs2 >> 1) == (rd >> 1)))
    13711462                    sregs->fhold += (sregs->ftime - ebase.simtime);
    13721463            }
    1373             mexc = ms->memory_read(asi, address, ddata, 2, &ws);
     1464            mexc = ms->memory_read(address, ddata, 2, &ws);
    13741465            sregs->hold += ws;
    1375             mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws);
     1466            mexc |= ms->memory_read(address+4, &ddata[1], 2, &ws);
    13761467            sregs->hold += ws;
    13771468            sregs->icnt = T_LDD;
    13781469            if (mexc) {
    dispatch_instruction(sregs) 
    14011492                sregs->trap = TRAP_UNALI;
    14021493                break;
    14031494            }
    1404             mexc = ms->memory_read(asi, address, &data, 2, &ws);
     1495            mexc = ms->memory_read(address, &data, 2, &ws);
    14051496            sregs->hold += ws;
    14061497            if (mexc) {
    14071498                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    14231514            if (ebase.simtime < sregs->ftime) {
    14241515                sregs->fhold += (sregs->ftime - ebase.simtime);
    14251516            }
    1426             mexc = ms->memory_write(asi, address, &sregs->fsr, 2, &ws);
     1517            mexc = ms->memory_write(address, &sregs->fsr, 2, &ws);
    14271518            sregs->hold += ws;
    14281519            if (mexc) {
    14291520                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    14321523
    14331524        case STA:
    14341525            if (!chk_asi(sregs, &asi, op3)) break;
     1526            if (address & 0x3) {
     1527                sregs->trap = TRAP_UNALI;
     1528                break;
     1529            }
     1530            mexc = ms->memory_write_asi(asi, address, rdd, 2, &ws);
     1531            sregs->hold += ws;
     1532            if (mexc) {
     1533                sregs->trap = TRAP_DEXC;
     1534            }
     1535            break;
    14351536        case ST:
    14361537            if (address & 0x3) {
    14371538                sregs->trap = TRAP_UNALI;
    14381539                break;
    14391540            }
    1440             mexc = ms->memory_write(asi, address, rdd, 2, &ws);
     1541            mexc = ms->memory_write(address, rdd, 2, &ws);
    14411542            sregs->hold += ws;
    14421543            if (mexc) {
    14431544                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    14451546            break;
    14461547        case STBA:
    14471548            if (!chk_asi(sregs, &asi, op3)) break;
     1549            mexc = ms->memory_write_asi(asi, address, rdd, 0, &ws);
     1550            sregs->hold += ws;
     1551            if (mexc) {
     1552                sregs->trap = TRAP_DEXC;
     1553            }
     1554            break;
    14481555        case STB:
    1449             mexc = ms->memory_write(asi, address, rdd, 0, &ws);
     1556            mexc = ms->memory_write(address, rdd, 0, &ws);
    14501557            sregs->hold += ws;
    14511558            if (mexc) {
    14521559                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    14541561            break;
    14551562        case STDA:
    14561563            if (!chk_asi(sregs, &asi, op3)) break;
     1564            if (address & 0x7) {
     1565                sregs->trap = TRAP_UNALI;
     1566                break;
     1567            }
     1568            if (rd & 1) {
     1569                rd &= 0x1e;
     1570                if (rd > 7)
     1571                    rdd = &(sregs->r[(cwp + rd) & 0x7f]);
     1572                else
     1573                    rdd = &(sregs->g[rd]);
     1574            }
     1575            mexc = ms->memory_write_asi(asi, address, rdd, 3, &ws);
     1576            sregs->hold += ws;
     1577            sregs->icnt = T_STD;
     1578#ifdef STAT
     1579            sregs->nstore++;    /* Double store counts twice */
     1580#endif
     1581            if (mexc) {
     1582                sregs->trap = TRAP_DEXC;
     1583                break;
     1584            }
     1585            break;
    14571586        case STD:
    14581587            if (address & 0x7) {
    14591588                sregs->trap = TRAP_UNALI;
    dispatch_instruction(sregs) 
    14661595                else
    14671596                    rdd = &(sregs->g[rd]);
    14681597            }
    1469             mexc = ms->memory_write(asi, address, rdd, 3, &ws);
     1598            mexc = ms->memory_write(address, rdd, 3, &ws);
    14701599            sregs->hold += ws;
    14711600            sregs->icnt = T_STD;
    14721601#ifdef STAT
    dispatch_instruction(sregs) 
    14951624                break;
    14961625            }
    14971626            rdd = &(sregs->fpq[0]);
    1498             mexc = ms->memory_write(asi, address, rdd, 3, &ws);
     1627            mexc = ms->memory_write(address, rdd, 3, &ws);
    14991628            sregs->hold += ws;
    15001629            sregs->icnt = T_STD;
    15011630#ifdef STAT
    dispatch_instruction(sregs) 
    15111640            break;
    15121641        case STHA:
    15131642            if (!chk_asi(sregs, &asi, op3)) break;
     1643            if (address & 0x1) {
     1644                sregs->trap = TRAP_UNALI;
     1645                break;
     1646            }
     1647            mexc = ms->memory_write_asi(asi, address, rdd, 1, &ws);
     1648            sregs->hold += ws;
     1649            if (mexc) {
     1650                sregs->trap = TRAP_DEXC;
     1651            }
     1652            break;
    15141653        case STH:
    15151654            if (address & 0x1) {
    15161655                sregs->trap = TRAP_UNALI;
    15171656                break;
    15181657            }
    1519             mexc = ms->memory_write(asi, address, rdd, 1, &ws);
     1658            mexc = ms->memory_write(address, rdd, 1, &ws);
    15201659            sregs->hold += ws;
    15211660            if (mexc) {
    15221661                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    15351674                if (sregs->frd == rd)
    15361675                    sregs->fhold += (sregs->ftime - ebase.simtime);
    15371676            }
    1538             mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 2, &ws);
     1677            mexc = ms->memory_write(address, &sregs->fsi[rd], 2, &ws);
    15391678            sregs->hold += ws;
    15401679            if (mexc) {
    15411680                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    15551694                if ((sregs->frd == rd) || (sregs->frd + 1 == rd))
    15561695                    sregs->fhold += (sregs->ftime - ebase.simtime);
    15571696            }
    1558             mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 3, &ws);
     1697            mexc = ms->memory_write(address, &sregs->fsi[rd], 3, &ws);
    15591698            sregs->hold += ws;
    15601699            sregs->icnt = T_STD;
    15611700#ifdef STAT
    dispatch_instruction(sregs) 
    15671706            break;
    15681707        case SWAPA:
    15691708            if (!chk_asi(sregs, &asi, op3)) break;
     1709            if (address & 0x3) {
     1710                sregs->trap = TRAP_UNALI;
     1711                break;
     1712            }
     1713            mexc = ms->memory_read_asi(asi, address, &data, 2, &ws);
     1714            sregs->hold += ws;
     1715            if (mexc) {
     1716                sregs->trap = TRAP_DEXC;
     1717                break;
     1718            }
     1719            mexc = ms->memory_write_asi(asi, address, rdd, 2, &ws);
     1720            sregs->hold += ws;
     1721            sregs->icnt = T_LDST;
     1722            if (mexc) {
     1723                sregs->trap = TRAP_DEXC;
     1724                break;
     1725            } else
     1726                *rdd = data;
     1727#ifdef STAT
     1728            sregs->nload++;
     1729#endif
     1730            break;
    15701731        case SWAP:
    15711732            if (address & 0x3) {
    15721733                sregs->trap = TRAP_UNALI;
    15731734                break;
    15741735            }
    1575             mexc = ms->memory_read(asi, address, &data, 2, &ws);
     1736            mexc = ms->memory_read(address, &data, 2, &ws);
    15761737            sregs->hold += ws;
    15771738            if (mexc) {
    15781739                sregs->trap = TRAP_DEXC;
    15791740                break;
    15801741            }
    1581             mexc = ms->memory_write(asi, address, rdd, 2, &ws);
     1742            mexc = ms->memory_write(address, rdd, 2, &ws);
    15821743            sregs->hold += ws;
    15831744            sregs->icnt = T_LDST;
    15841745            if (mexc) {
    fpexec(op3, rd, rs1, rs2, sregs) 
    18141975        sregs->ftime += T_FDIVd;
    18151976        break;
    18161977    case FMOVs:
    1817         sregs->fs[rd] = sregs->fs[rs2];
     1978        sregs->fsi[rd] = sregs->fsi[rs2];
    18181979        sregs->ftime += T_FMOVs;
    18191980        sregs->frs1 = 32;       /* rs1 ignored */
    18201981        break;
    execute_trap(sregs) 
    19962157        sregs->pc = sregs->tbr;
    19972158        sregs->npc = sregs->tbr + 4;
    19982159
    1999         if ( 0 != (1 & sregs->asr17) ) {
     2160        if ( 0 != (1 & (sregs->asr17 >> 13)) ) {
    20002161            /* single vector trapping! */
    20012162            sregs->pc = sregs->tbr & 0xfffff000;
    20022163            sregs->npc = sregs->pc + 4;
    init_regs(sregs) 
    20432204    sregs->npc = 4;
    20442205    sregs->trap = 0;
    20452206    sregs->psr &= 0x00f03fdf;
    2046     sregs->psr |= 0x11000080;   /* Set supervisor bit */
     2207    if (cputype == CPU_LEON3)
     2208      sregs->psr |= 0xF3000080; /* Set supervisor bit */
     2209    else
     2210      sregs->psr |= 0x11000080; /* Set supervisor bit */
    20472211    sregs->breakpoint = 0;
    20482212    sregs->annul = 0;
    20492213    sregs->fpstate = FP_EXE_MODE;
    init_regs(sregs) 
    20722236
    20732237    sregs->rett_err = 0;
    20742238    sregs->jmpltime = 0;
     2239    if (cputype == CPU_LEON3) {
     2240        sregs->asr17 = 0x107;
     2241        if (!nfp) sregs->asr17 |= (3 << 10);  /* Meiko FPU */
     2242    }
    20752243}
  • sim/erc32/func.c

    diff --git a/sim/erc32/func.c b/sim/erc32/func.c
    index 0d00f48..a22e800 100644
    a b struct irqcell irqarr[16]; 
    4646
    4747int             ctrl_c = 0;
    4848int             sis_verbose = 0;
    49 char           *sis_version = "2.7.5";
     49char           *sis_version = "2.8";
    5050int             nfp = 0;
    5151int             ift = 0;
    5252int             wrp = 0;
    uint32 last_load_addr = 0; 
    6161int             nouartrx = 0;
    6262host_callback   *sim_callback;
    6363struct memsys *ms = &erc32sys;
     64int             cputype = 0;            /* 0 = erc32, 3 = leon3 */
    6465
    6566#ifdef ERRINJ
    6667uint32          errcnt = 0;
    exec_cmd(sregs, cmd) 
    482483            sregs->pc = len & ~3;
    483484            sregs->npc = sregs->pc + 4;
    484485            if ((sregs->pc != 0) && (ebase.simtime == 0))
    485                 boot_init();
     486                ms->boot_init();
    486487            printf("resuming at 0x%08x\n",sregs->pc);
    487488            if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
    488489                stat = run_sim(sregs, VAL(cmd2), 0);
    exec_cmd(sregs, cmd) 
    558559            ebase.simtime = 0;
    559560            reset_all();
    560561            reset_stat(sregs);
     562            if (last_load_addr != 0) {
     563                sregs->pc = last_load_addr & ~3;
     564                sregs->npc = sregs->pc + 4;
     565            }
     566            if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init();
    561567            if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    562568                stat = run_sim(sregs, UINT64_MAX, 0);
    563569            } else {
    exec_cmd(sregs, cmd) 
    609615            ebase.simtime = 0;
    610616            reset_all();
    611617            reset_stat(sregs);
     618            if (last_load_addr != 0) {
     619                sregs->pc = last_load_addr & ~3;
     620                sregs->npc = sregs->pc + 4;
     621            }
     622            if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init();
    612623            sregs->tlimit = limcalc(sregs->freq);
    613624            stat = run_sim(sregs, UINT64_MAX, 0);
    614625            daddr = sregs->pc;
    void 
    646657show_stat(sregs)
    647658    struct pstate  *sregs;
    648659{
    649     uint32          iinst;
    650     uint32          stime;
     660    uint64          iinst;
     661    uint64          stime;
    651662
    652663    if (sregs->tottime == 0.0)
    653664        sregs->tottime += 1E-6;
    show_stat(sregs) 
    662673    printf(" Instructions : %9" PRIu64 "\n", sregs->ninst);
    663674
    664675#ifdef STAT
    665     printf("   integer    : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
     676    printf("   integer    : %9.2f %%\n", 100.0 * (double) iinst / (double) sregs->ninst);
    666677    printf("   load       : %9.2f %%\n",
    667            100.0 * (float) sregs->nload / (float) sregs->ninst);
     678           100.0 * (double) sregs->nload / (double) sregs->ninst);
    668679    printf("   store      : %9.2f %%\n",
    669            100.0 * (float) sregs->nstore / (float) sregs->ninst);
     680           100.0 * (double) sregs->nstore / (double) sregs->ninst);
    670681    printf("   branch     : %9.2f %%\n",
    671            100.0 * (float) sregs->nbranch / (float) sregs->ninst);
     682           100.0 * (double) sregs->nbranch / (double) sregs->ninst);
    672683    printf("   float      : %9.2f %%\n",
    673            100.0 * (float) sregs->finst / (float) sregs->ninst);
     684           100.0 * (double) sregs->finst / (double) sregs->ninst);
    674685    printf(" Integer CPI  : %9.2f\n",
    675            ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
     686           ((double) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
    676687           /
    677            (float) (sregs->ninst - sregs->finst));
     688           (double) (sregs->ninst - sregs->finst));
    678689    printf(" Float CPI    : %9.2f\n",
    679            ((float) sregs->fholdt / (float) sregs->finst) + 1.0);
     690           ((double) sregs->fholdt / (double) sregs->finst) + 1.0);
    680691#endif
    681692    printf(" Overall CPI  : %9.2f\n",
    682            (float) (stime - sregs->pwdtime) / (float) sregs->ninst);
    683     printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
    684            sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime),
    685            sregs->freq * (float) (sregs->ninst - sregs->finst) /
    686            (float) (stime - sregs->pwdtime),
    687      sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime));
    688     printf(" Simulated ERC32 time        : %.2f s\n",
    689         (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
     693          (double) (stime - sregs->pwdtime) / (double) sregs->ninst);
     694    printf("\n CPU performance (%4.1f MHz)  : %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
     695          sregs->freq, sregs->freq * (double) sregs->ninst / (double) (stime - sregs->pwdtime),
     696          sregs->freq * (double) (sregs->ninst - sregs->finst) /
     697          (double) (stime - sregs->pwdtime),
     698     sregs->freq * (double) sregs->finst / (double) (stime - sregs->pwdtime));
     699    printf(" Simulated CPU time          : %.2f s\n",
     700        (double) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
    690701    printf(" Processor utilisation       : %.2f %%\n",
    691         100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
     702        100.0 * (1.0 - ((double) sregs->pwdtime / (double) stime)));
    692703    printf(" Real-time performance       : %.2f %%\n",
    693         100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6))));
     704        100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6))));
    694705    printf(" Simulator performance       : %.2f MIPS\n",
    695         (double)(sregs->ninst) / sregs->tottime / 1E6);
     706        (double)(sregs->ninst) / sregs->tottime / 1E6);
    696707    printf(" Used time (sys + user)      : %.2f s\n\n", sregs->tottime);
    697708}
    698709
  • new file sim/erc32/grlib.c

    diff --git a/sim/erc32/grlib.c b/sim/erc32/grlib.c
    new file mode 100644
    index 0000000..edb304e
    - +  
     1/*
     2 * This file is part of SIS.
     3 *
     4 * SIS, SPARC instruction simulator. Copyright (C) 2014 Jiri Gaisler
     5 *
     6 * This program is free software; you can redistribute it and/or modify it under
     7 * the terms of the GNU General Public License as published by the Free
     8 * Software Foundation; either version 3 of the License, or (at your option)
     9 * any later version.
     10 *
     11 * This program is distributed in the hope that it will be useful, but WITHOUT
     12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     14 * more details.
     15 *
     16 * You should have received a copy of the GNU General Public License along with
     17 * this program; if not, see <http://www.gnu.org/licenses/>.
     18 *
     19 */
     20
     21
     22#include "sis.h"
     23#include "grlib.h"
     24
     25
     26/* APB PNP */
     27
     28static uint32 apbppmem[32*2];    /* 32-entry APB PP AREA */
     29static int apbppindex;
     30
     31int grlib_apbpp_add(uint32 id, uint32 addr)
     32{
     33    apbppmem[apbppindex++] = id;
     34    apbppmem[apbppindex++] = addr;
     35    if(apbppindex >= (32*2)) apbppindex = 0; /* prevent overflow of area */
     36    return(apbppindex);
     37}
     38
     39uint32 grlib_apbpnp_read(uint32 addr)
     40{
     41    uint32 read_data;
     42    addr &= 0xff;
     43    read_data = apbppmem[addr>>2];
     44
     45    return read_data;
     46}
     47
     48/* AHB PNP */
     49
     50static uint32 ahbppmem[128*8];    /* 128-entry AHB PP AREA */
     51static int ahbmppindex;
     52static int ahbsppindex = 64*8;
     53
     54int grlib_ahbmpp_add(uint32 id)
     55{
     56    ahbppmem[ahbmppindex] = id;
     57    ahbmppindex += 8;
     58    if(ahbmppindex >= (64*8)) ahbmppindex = 0; /* prevent overflow of area */
     59    return(ahbmppindex);
     60}
     61
     62int grlib_ahbspp_add(uint32 id, uint32 addr1, uint32 addr2,
     63                     uint32 addr3, uint32 addr4)
     64{
     65    ahbppmem[ahbsppindex] = id;
     66    ahbsppindex += 4;
     67    ahbppmem[ahbsppindex++] = addr1;
     68    ahbppmem[ahbsppindex++] = addr2;
     69    ahbppmem[ahbsppindex++] = addr3;
     70    ahbppmem[ahbsppindex++] = addr4;
     71    if(ahbsppindex >= (128*8)) ahbsppindex = 64*8; /* prevent overflow of area */
     72    return(ahbsppindex);
     73}
     74
     75uint32 grlib_ahbpnp_read(uint32 addr)
     76{
     77    uint32 read_data;
     78
     79    addr &= 0xfff;
     80    read_data = ahbppmem[addr>>2];
     81    return read_data;
     82
     83}
     84
     85void grlib_init()
     86{
     87    /* Add PP records for Leon3, APB bridge and interrupt controller
     88       as this is not done elsewhere */
     89
     90    grlib_ahbmpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_LEON3, 0, 0));
     91    grlib_ahbspp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_APBMST, 0, 0),
     92                     GRLIB_PP_AHBADDR(0x80000000, 0xFFF, 0, 0, 2),
     93                     0, 0, 0);
     94
     95    grlib_apbpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_IRQMP, 2, 0),
     96                    GRLIB_PP_APBADDR(0x80000200, 0xFFF));
     97
     98}
  • new file sim/erc32/grlib.h

    diff --git a/sim/erc32/grlib.h b/sim/erc32/grlib.h
    new file mode 100644
    index 0000000..1c03329
    - +  
     1/*
     2 * This file is part of SIS.
     3 *
     4 * SIS, SPARC instruction simulator. Copyright (C) 2014 Jiri Gaisler
     5 *
     6 * This program is free software; you can redistribute it and/or modify it under
     7 * the terms of the GNU General Public License as published by the Free
     8 * Software Foundation; either version 3 of the License, or (at your option)
     9 * any later version.
     10 *
     11 * This program is distributed in the hope that it will be useful, but WITHOUT
     12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     14 * more details.
     15 *
     16 * You should have received a copy of the GNU General Public License along with
     17 * this program; if not, see <http://www.gnu.org/licenses/>.
     18 *
     19 */
     20
     21
     22/* Definitions for AMBA PNP in Gaisler Research GRLIB SOC */
     23
     24/* Vendors */
     25#define VENDOR_GAISLER    1
     26#define VENDOR_PENDER     2
     27#define VENDOR_ESA        4
     28#define VENDOR_DLR       10
     29
     30/* Devices */
     31#define GAISLER_LEON3    0x003
     32#define GAISLER_APBMST   0x006
     33#define GAISLER_SRCTRL   0x008
     34#define GAISLER_APBUART  0x00C
     35#define GAISLER_IRQMP    0x00D
     36#define GAISLER_GPTIMER  0x011
     37#define ESA_MCTRL        0x00F
     38
     39/* How to build entries in the plug&play area */
     40#define GRLIB_PP_ID(v, d, x, i) ((v & 0xff) << 24) | ((d & 0x3ff) << 12) |\
     41                                ((x & 0x1f) << 5) | (i & 0x1f)
     42#define GRLIB_PP_AHBADDR(a, m, p, c, t) (a & 0xfff00000) | ((m & 0xfff) << 4) |\
     43                         ((p & 1) << 17) | ((c & 1) << 16) | (t & 0x3)
     44#define GRLIB_PP_APBADDR(a, m) ((a & 0xfff00)<< 12) | ((m & 0xfff) << 4) | 1
     45
     46#define AHBPP_START   0xFFFFF000
     47#define AHBPP_END     0xFFFFFFFF
     48#define APBPP_START   0x800FF000
     49#define APBPP_END     0x800FFFFF
     50
     51int grlib_apbpp_add(uint32 id, uint32 addr);
     52int grlib_ahbmpp_add(uint32 id);
     53int grlib_ahbspp_add(uint32 id, uint32 addr1, uint32 addr2,
     54                     uint32 addr3, uint32 addr4);
     55uint32 grlib_ahbpnp_read(uint32 addr);
     56uint32 grlib_apbpnp_read(uint32 addr);
     57void grlib_init();
  • sim/erc32/interf.c

    diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
    index ab1a38c..8f3b27d 100644
    a b run_sim(sregs, icount, dis) 
    5252   ms->init_stdio();
    5353   sregs->starttime = get_time();
    5454   irq = 0;
    55    if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
     55   if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init();
    5656   while (!sregs->err_mode & (icount > 0)) {
    5757
    5858        sregs->fhold = 0;
    sim_open (kind, callback, abfd, argv) 
    187187            if (strcmp(argv[stat], "-nouartrx") == 0) {
    188188                nouartrx = 1;
    189189            } else
     190            if (strcmp(argv[stat], "-leon3") == 0) {
     191                ms = &leon3;
     192                cputype = CPU_LEON3;
     193            } else
    190194            if (strcmp(argv[stat], "-wrp") == 0) {
    191195                wrp = 1;
    192196            } else
    sim_open (kind, callback, abfd, argv) 
    224228        stat++;
    225229    }
    226230
     231    if (cputype == CPU_LEON3)
     232        sregs.freq = freq ? freq : 50;
     233    else
     234        sregs.freq = freq ? freq : 14;
     235
    227236    if (sis_verbose) {
    228237        (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
    229         (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
     238        (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jiri@gaisler.se)\n\n");
     239        switch (cputype) {
     240        case CPU_LEON3:
     241            (*sim_callback->printf_filtered) (sim_callback, "LEON3 emulation enabled\n");
     242            break;
     243        default:
     244            (*sim_callback->printf_filtered) (sim_callback, "ERC32 emulation enabled\n");
     245        }
    230246        if (nfp)
    231247          (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
    232248        if (sparclite)
    sim_open (kind, callback, abfd, argv) 
    235251          (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n");
    236252        if (sis_gdb_break == 0)
    237253          (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
    238         if (freq)
    239           (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
     254          (*sim_callback->printf_filtered) (sim_callback, "CPU freq %3.1f MHz\n", sregs.freq);
    240255    }
    241256
    242     sregs.freq = freq ? freq : 15;
    243257    termsave = fcntl(0, F_GETFL, 0);
    244258    INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
    245259#ifdef HOST_LITTLE_ENDIAN
    flush_windows () 
    457471#endif
    458472
    459473      for (i = 0; i < 16; i++)
    460         ms->memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
     474        ms->memory_write (sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
    461475                      &ws);
    462476
    463477      if (win == cwp)
  • new file sim/erc32/leon3.c

    diff --git a/sim/erc32/leon3.c b/sim/erc32/leon3.c
    new file mode 100644
    index 0000000..26ea2b2
    - +  
     1/*
     2 * This file is part of SIS.
     3 *
     4 * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler,
     5 * European Space Agency
     6 *
     7 * This program is free software; you can redistribute it and/or modify it under
     8 * the terms of the GNU General Public License as published by the Free
     9 * Software Foundation; either version 3 of the License, or (at your option)
     10 * any later version.
     11 *
     12 * This program is distributed in the hope that it will be useful, but WITHOUT
     13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     15 * more details.
     16 *
     17 * You should have received a copy of the GNU General Public License along with
     18 * this program; if not, see <http://www.gnu.org/licenses/>.
     19 *
     20 * Leon3 emulation, loosely based on erc32.c .
     21 */
     22
     23/* The control space devices */
     24
     25#include "config.h"
     26#include <errno.h>
     27#include <sys/types.h>
     28#include <stdio.h>
     29#include <string.h>
     30#include <termios.h>
     31#include <sys/fcntl.h>
     32#include <sys/file.h>
     33#include <unistd.h>
     34#include "sis.h"
     35#include "grlib.h"
     36#include "sim-config.h"
     37
     38static int tty_setup = 1; /* default setup if not a tty */
     39
     40/* APB registers */
     41#define APBSTART        0x80000000
     42#define APBEND          0x80100000
     43
     44/* Memory exception waitstates */
     45#define MEM_EX_WS       1
     46
     47#define MOK     0
     48
     49/* LEON3 APB register addresses */
     50
     51#define IRQMP_IPR               0x204
     52#define IRQMP_IMR       0x240
     53#define IRQMP_ICR       0x20C
     54#define IRQMP_IFR       0x208
     55#define GPTIMER_SCALER  0x300
     56#define GPTIMER_SCLOAD  0x304
     57#define GPTIMER_CONFIG  0x308
     58#define GPTIMER_TIMER1  0x310
     59#define GPTIMER_RELOAD1 0x314
     60#define GPTIMER_CTRL1   0x318
     61#define GPTIMER_TIMER2  0x320
     62#define GPTIMER_RELOAD2 0x324
     63#define GPTIMER_CTRL2   0x328
     64
     65#define APBUART_RXTX    0x100
     66#define APBUART_STATUS  0x104
     67
     68/* Size of UART buffers (bytes) */
     69#define UARTBUF 1024
     70
     71/* Number of simulator ticks between flushing the UARTS.         */
     72/* For good performance, keep above 1000                         */
     73#define UART_FLUSH_TIME   3000
     74
     75
     76/* New uart defines */
     77#define UART_TX_TIME    1000
     78#define UART_RX_TIME    1000
     79#define UARTA_DR        0x1
     80#define UARTA_SRE       0x2
     81#define UARTA_HRE       0x4
     82#define UARTA_OR        0x10
     83
     84/* IRQMP registers */
     85
     86static uint32   irqmp_ipr;
     87static uint32   irqmp_imr;
     88static uint32   irqmp_ifr;
     89
     90/* GPTIMER registers */
     91
     92#define NGPTIMERS  2
     93#define GPTIMER_IRQ 8
     94
     95static uint32   gpt_scaler;
     96static uint32   gpt_scaler_start;
     97static uint32   gpt_counter[NGPTIMERS];
     98static uint32   gpt_reload[NGPTIMERS];
     99static uint32   gpt_ctrl[NGPTIMERS];
     100
     101/* ROM size 16 Mbyte */
     102#define ROM_START       0x00000000
     103#define ROM_MASK        0x00ffffff
     104#define ROM_END         (ROM_START + ROM_MASK + 1)
     105
     106/* RAM size 16 Mbyte */
     107#define RAM_START       0x40000000
     108#define RAM_MASK        0x00ffffff
     109#define RAM_END         (RAM_START + RAM_MASK + 1)
     110
     111/* Memory */
     112
     113static unsigned char    romb[ROM_END - ROM_START];
     114static unsigned char    ramb[RAM_END - RAM_START];
     115static uint32   cache_ctrl;
     116
     117
     118/* UART support variables */
     119
     120static int32    fd1, fd2;       /* file descriptor for input file */
     121static int32    Ucontrol;       /* UART status register */
     122static unsigned char aq[UARTBUF], bq[UARTBUF];
     123static int32    anum, aind = 0;
     124static int32    bnum, bind = 0;
     125static char     wbufa[UARTBUF], wbufb[UARTBUF];
     126static unsigned wnuma;
     127static unsigned wnumb;
     128static FILE    *f1in, *f1out;
     129static struct termios ioc1, ioc2, iocold1, iocold2;
     130static int      f1open = 0;
     131
     132static char     uarta_sreg, uarta_hreg;
     133static uint32   uart_stat_reg;
     134static uint32   uarta_data;
     135
     136/* Forward declarations */
     137
     138static void     mem_init (void);
     139static void     close_port (void);
     140static void     leon3_reset (void);
     141static void     irqmp_intack (int32 level);
     142static void     chk_irq (void);
     143static void     set_irq (int32 level);
     144static int32    apb_read (uint32 addr, uint32 *data);
     145static int      apb_write (uint32 addr, uint32 data);
     146static void     port_init (void);
     147static uint32   grlib_read_uart (uint32 addr);
     148static void     grlib_write_uart (uint32 addr, uint32 data);
     149static void     flush_uart (void);
     150static void     uarta_tx (void);
     151static void     uart_rx (caddr_t arg);
     152static void     uart_intr (caddr_t arg);
     153static void     uart_irq_start (void);
     154static void     gpt_intr (caddr_t arg);
     155static void     gpt_init (void);
     156static void     gpt_reset (void);
     157static void     gpt_scaler_set (uint32 val);
     158static void     timer_ctrl (uint32 val, int i);
     159static unsigned char *
     160                get_mem_ptr (uint32 addr, uint32 size);
     161static void     store_bytes (unsigned char *mem, uint32 waddr,
     162                        uint32 *data, int sz, int32 *ws);
     163
     164static host_callback *callback;
     165
     166
     167/* One-time init */
     168
     169static void
     170init_sim()
     171{
     172    callback = sim_callback;
     173    grlib_init();
     174    mem_init();
     175    port_init();
     176    gpt_init();
     177}
     178
     179/* Power-on reset init */
     180
     181static void
     182reset()
     183{
     184    leon3_reset();
     185    uart_irq_start();
     186    gpt_reset();
     187}
     188
     189/* IU error mode manager */
     190
     191static void
     192error_mode(pc)
     193    uint32          pc;
     194{
     195
     196}
     197
     198
     199/* Memory init */
     200
     201static void
     202mem_init()
     203{
     204
     205/* Add AMBA P&P record for SRCTRL memory controller */
     206
     207    grlib_ahbspp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_SRCTRL, 0, 0),
     208                     GRLIB_PP_AHBADDR(0x00000000, 0xE00, 1, 1, 2),
     209                     GRLIB_PP_AHBADDR(0x40000000, 0xC00, 1, 1, 2),
     210                     GRLIB_PP_AHBADDR(0x20000000, 0xE00, 0, 0, 2),
     211                     0);
     212    if (sis_verbose)
     213        printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
     214               RAM_START, (RAM_MASK+1)/1024, (ROM_MASK+1)/1024);
     215}
     216
     217/* Flush ports when simulator stops */
     218
     219static void
     220sim_halt()
     221{
     222#ifdef FAST_UART
     223    flush_uart();
     224#endif
     225}
     226
     227static void
     228close_port()
     229{
     230    if (f1open && f1in != stdin)
     231        fclose(f1in);
     232}
     233
     234static void
     235exit_sim()
     236{
     237    close_port();
     238}
     239
     240static void
     241leon3_reset()
     242{
     243    int             i;
     244
     245    irqmp_ipr = 0;
     246    irqmp_imr = 0;
     247    irqmp_ifr = 0;
     248
     249    wnuma = wnumb = 0;
     250    anum = aind = bnum = bind = 0;
     251
     252    uart_stat_reg = UARTA_SRE | UARTA_HRE;
     253
     254    gpt_counter[0] = 0xffffffff;
     255    gpt_reload[0] = 0xffffffff;
     256    gpt_scaler = 0xffff;
     257    gpt_ctrl[0] = 0;
     258    gpt_ctrl[1] = 0;
     259
     260}
     261
     262
     263
     264static void
     265irqmp_intack(level)
     266    int32           level;
     267{
     268    int             irq_test;
     269
     270    if (sis_verbose > 2)
     271        printf("interrupt %d acknowledged\n", level);
     272    if (irqmp_ifr & (1 << level))
     273        irqmp_ifr &= ~(1 << level);
     274    else
     275        irqmp_ipr &= ~(1 << level);
     276   chk_irq();
     277}
     278
     279static void
     280chk_irq()
     281{
     282    int32           i;
     283    uint32          itmp;
     284    int             old_irl;
     285
     286    old_irl = ext_irl;
     287    itmp = ((irqmp_ipr | irqmp_ifr) & irqmp_imr) & 0x0fffe;
     288    ext_irl = 0;
     289    if (itmp != 0) {
     290        for (i = 15; i > 0; i--) {
     291            if (((itmp >> i) & 1) != 0) {
     292                if ((sis_verbose > 2) && (i > old_irl))
     293                    printf("IU irl: %d\n", i);
     294                ext_irl = i;
     295                set_int(i, irqmp_intack, i);
     296                break;
     297            }
     298        }
     299    }
     300}
     301
     302static void
     303set_irq(level)
     304    int32           level;
     305{
     306    irqmp_ipr |= (1 << level);
     307    chk_irq();
     308}
     309
     310static int32
     311apb_read(addr, data)
     312    uint32          addr;
     313    uint32         *data;
     314{
     315
     316    switch (addr & 0xfff) {
     317
     318    case APBUART_RXTX:          /* 0x100 */
     319    case APBUART_STATUS:        /* 0x104 */
     320        *data = grlib_read_uart(addr);
     321        break;
     322
     323    case IRQMP_IPR:             /* 0x204 */
     324        *data = irqmp_ipr;
     325        break;
     326
     327    case IRQMP_IFR:             /* 0x208 */
     328        *data = irqmp_ifr;
     329        break;
     330
     331    case IRQMP_IMR:             /* 0x240 */
     332        *data = irqmp_imr;
     333        break;
     334
     335    case GPTIMER_SCALER:        /* 0x300 */
     336        *data = gpt_scaler - (now() - gpt_scaler_start);
     337        break;
     338
     339    case GPTIMER_SCLOAD:        /* 0x304 */
     340        *data = gpt_scaler;
     341        break;
     342
     343    case GPTIMER_CONFIG:        /* 0x308 */
     344        *data = 0x100 | (GPTIMER_IRQ << 3) | NGPTIMERS;
     345        break;
     346
     347    case GPTIMER_TIMER1:        /* 0x310 */
     348        *data = gpt_counter[0];
     349        break;
     350
     351    case GPTIMER_RELOAD1:       /* 0x314 */
     352        *data = gpt_reload[0];
     353        break;
     354
     355    case GPTIMER_CTRL1:         /* 0x318 */
     356        *data = gpt_ctrl[0];
     357        break;
     358
     359    case GPTIMER_TIMER2:        /* 0x320 */
     360        *data = gpt_counter[1];
     361        break;
     362
     363    case GPTIMER_RELOAD2:       /* 0x324 */
     364        *data = gpt_reload[1];
     365        break;
     366
     367    case GPTIMER_CTRL2:         /* 0x328 */
     368        *data = gpt_ctrl[1];
     369        break;
     370
     371    default:
     372        *data = 0;
     373        break;
     374    }
     375
     376    if (sis_verbose > 1)
     377        printf("APB read  a: %08x, d: %08x\n", addr, *data);
     378
     379    return (MOK);
     380}
     381
     382static int
     383apb_write(addr, data)
     384    uint32          addr;
     385    uint32          data;
     386{
     387    if (sis_verbose > 1)
     388        printf("APB write a: %08x, d: %08x\n",addr,data);
     389    switch (addr & 0xfff) {
     390
     391    case APBUART_RXTX:          /* 0x100 */
     392    case APBUART_STATUS:        /* 0x104 */
     393        grlib_write_uart(addr, data);
     394        break;
     395
     396    case IRQMP_IFR:             /* 0x208 */
     397        irqmp_ifr = data & 0xfffe;
     398        chk_irq();
     399        break;
     400
     401    case IRQMP_ICR:             /* 0x20C */
     402        irqmp_ipr &= ~data & 0x0fffe;
     403        chk_irq();
     404        break;
     405
     406    case IRQMP_IMR:             /* 0x240 */
     407        irqmp_imr = data & 0x7ffe;
     408        chk_irq();
     409        break;
     410
     411    case GPTIMER_SCLOAD:        /* 0x304 */
     412        gpt_scaler_set(data);
     413        break;
     414
     415    case GPTIMER_TIMER1:        /* 0x310 */
     416        gpt_counter[0] = data;
     417        break;
     418
     419    case GPTIMER_RELOAD1:       /* 0x314 */
     420        gpt_reload[0] = data;
     421        break;
     422
     423    case GPTIMER_CTRL1:         /* 0x318 */
     424        timer_ctrl(data, 0);
     425        break;
     426
     427    case GPTIMER_TIMER2:        /* 0x320 */
     428        gpt_counter[1] = data;
     429        break;
     430
     431    case GPTIMER_RELOAD2:       /* 0x324 */
     432        gpt_reload[1] = data;
     433        break;
     434
     435    case GPTIMER_CTRL2:         /* 0x328 */
     436        timer_ctrl(data, 1);
     437        break;
     438
     439    default:
     440        break;
     441    }
     442    return (MOK);
     443}
     444
     445
     446/* APBUART */
     447
     448static int      ifd1 = -1, ofd1 = -1;
     449
     450static void
     451init_stdio()
     452{
     453    if (dumbio)
     454        return; /* do nothing */
     455    if (ifd1 == 0 && f1open) {
     456        tcsetattr(0, TCSANOW, &ioc1);
     457        tcflush(ifd1, TCIFLUSH);
     458    }
     459}
     460
     461static void
     462restore_stdio()
     463{
     464    if (dumbio)
     465        return; /* do nothing */
     466    if (ifd1 == 0 && f1open && tty_setup)
     467        tcsetattr(0, TCSANOW, &iocold1);
     468}
     469
     470#define DO_STDIO_READ( _fd_, _buf_, _len_ )          \
     471             ( dumbio || nouartrx \
     472               ? (0) /* no bytes read, no delay */   \
     473               : (_fd_) == 1 && callback ? \
     474                 callback->read_stdin (callback, _buf_, _len_) :  \
     475                 read( _fd_, _buf_, _len_ ) )
     476
     477
     478static void
     479port_init()
     480{
     481
     482    f1in = stdin;
     483    f1out = stdout;
     484    if (uart_dev1[0] != 0)
     485        if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) {
     486            printf("Warning, couldn't open output device %s\n", uart_dev1);
     487        } else {
     488            if (sis_verbose)
     489                printf("serial port A on %s\n", uart_dev1);
     490            f1in = f1out = fdopen(fd1, "r+");
     491            setbuf(f1out, NULL);
     492            f1open = 1;
     493        }
     494    if (f1in) ifd1 = fileno(f1in);
     495    if (ifd1 == 0) {
     496        if (callback && !callback->isatty(callback, ifd1)) {
     497            tty_setup = 0;
     498        }
     499        if (sis_verbose)
     500            printf("serial port A on stdin/stdout\n");
     501        if (!dumbio) {
     502            tcgetattr(ifd1, &ioc1);
     503            if (tty_setup) {
     504            iocold1 = ioc1;
     505            ioc1.c_lflag &= ~(ICANON | ECHO);
     506            ioc1.c_cc[VMIN] = 0;
     507            ioc1.c_cc[VTIME] = 0;
     508        }
     509        }
     510        f1open = 1;
     511    }
     512
     513    if (f1out) {
     514        ofd1 = fileno(f1out);
     515        if (!dumbio && tty_setup && ofd1 == 1) setbuf(f1out, NULL);
     516    }
     517
     518    wnuma = 0;
     519
     520
     521    grlib_apbpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_APBUART, 1, 3),
     522                    GRLIB_PP_APBADDR(0x80000100, 0xFFF));
     523}
     524
     525static uint32
     526grlib_read_uart(addr)
     527    uint32          addr;
     528{
     529
     530    unsigned        tmp;
     531
     532    tmp = 0;
     533    switch (addr & 0xff) {
     534
     535    case 0x00:                  /* UART 1 RX/TX */
     536#ifndef _WIN32
     537#ifdef FAST_UART
     538
     539        if (aind < anum) {
     540            if ((aind + 1) < anum)
     541                set_irq(3);
     542            return ((uint32) aq[aind++]);
     543        } else {
     544            if (f1open) {
     545                anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
     546            }
     547      else {
     548          anum = 0;
     549      }
     550            if (anum > 0) {
     551                aind = 0;
     552                if ((aind + 1) < anum)
     553                    set_irq(3);
     554                return ((uint32) aq[aind++]);
     555            } else {
     556                return ((uint32) aq[aind]);
     557            }
     558
     559        }
     560#else
     561        tmp = uarta_data;
     562        uarta_data &= ~UART_DR;
     563        uart_stat_reg &= ~UARTA_DR;
     564        return tmp;
     565#endif
     566#else
     567        return(0);
     568#endif
     569        break;
     570
     571    case 0x04:                  /* UART status register  */
     572#ifndef _WIN32
     573#ifdef FAST_UART
     574
     575        Ucontrol = 0;
     576        if (aind < anum) {
     577            Ucontrol |= 0x00000001;
     578        } else {
     579            if (f1open) {
     580                anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
     581            }
     582            else {
     583                anum = 0;
     584            }
     585            if (anum > 0) {
     586                Ucontrol |= 0x00000001;
     587                aind = 0;
     588                set_irq(3);
     589            }
     590        }
     591        Ucontrol |= 0x00000006;
     592        return (Ucontrol);
     593#else
     594        return (uart_stat_reg);
     595#endif
     596#else
     597        return(0x00060006);
     598#endif
     599        break;
     600    default:
     601        if (sis_verbose)
     602            printf("Read from unimplemented MEC register (%x)\n", addr);
     603
     604    }
     605    return (0);
     606}
     607
     608static void
     609grlib_write_uart(addr, data)
     610    uint32          addr;
     611    uint32          data;
     612{
     613    unsigned char   c;
     614
     615    c = (unsigned char) data;
     616    switch (addr & 0xff) {
     617
     618    case 0x00:                  /* UART A */
     619#ifdef FAST_UART
     620        if (f1open) {
     621            if (wnuma < UARTBUF)
     622                wbufa[wnuma++] = c;
     623            else {
     624                while (wnuma) {
     625              if (ofd1 == 1 && callback)
     626                  wnuma -= callback->write_stdout(callback, wbufa, wnuma);
     627              else
     628                    wnuma -= fwrite(wbufa, 1, wnuma, f1out);
     629          }
     630                wbufa[wnuma++] = c;
     631            }
     632        }
     633        set_irq(3);
     634#else
     635        if (uart_stat_reg & UARTA_SRE) {
     636            uarta_sreg = c;
     637            uart_stat_reg &= ~UARTA_SRE;
     638            event(uarta_tx, 0, UART_TX_TIME);
     639        } else {
     640            uarta_hreg = c;
     641            uart_stat_reg &= ~UARTA_HRE;
     642        }
     643#endif
     644        break;
     645
     646    case 0x04:                  /* UART status register */
     647#ifndef FAST_UART
     648        uart_stat_reg &= 1;
     649#endif
     650        break;
     651    default:
     652        if (sis_verbose)
     653            printf("Write to unimplemented APB register (%x)\n", addr);
     654
     655    }
     656}
     657
     658static void
     659flush_uart()
     660{
     661    while (wnuma && f1open) {
     662        if (ofd1 == 1 && callback) {
     663            wnuma -= callback->write_stdout(callback, wbufa, wnuma);
     664            callback->flush_stdout(callback);
     665        }
     666        else
     667        wnuma -= fwrite(wbufa, 1, wnuma, f1out);
     668    }
     669}
     670
     671
     672
     673static void
     674uarta_tx()
     675{
     676    while (f1open) {
     677        if (ofd1 == 1 && callback) {
     678            while (callback->write_stdout(callback, &uarta_sreg, 1) != 1);
     679        }
     680        else {
     681            while (fwrite(&uarta_sreg, 1, 1, f1out) != 1);
     682        }
     683    }
     684    if (uart_stat_reg & UARTA_HRE) {
     685        uart_stat_reg |= UARTA_SRE;
     686    } else {
     687        uarta_sreg = uarta_hreg;
     688        uart_stat_reg |= UARTA_HRE;
     689        event(uarta_tx, 0, UART_TX_TIME);
     690    }
     691    set_irq(3);
     692}
     693
     694static void
     695uart_rx(arg)
     696    caddr_t         arg;
     697{
     698    int32           rsize;
     699    char            rxd;
     700
     701
     702    rsize = 0;
     703    if (f1open)
     704        rsize = DO_STDIO_READ(ifd1, &rxd, 1);
     705    else
     706        rsize = 0;
     707    if (rsize > 0) {
     708        uarta_data = rxd;
     709        if (uart_stat_reg & UARTA_DR) {
     710            uart_stat_reg |= UARTA_OR;
     711        }
     712        uart_stat_reg |= UARTA_DR;
     713        set_irq(3);
     714    }
     715    event(uart_rx, 0, UART_RX_TIME);
     716}
     717
     718static void
     719uart_intr(arg)
     720    caddr_t         arg;
     721{
     722    grlib_read_uart(APBUART_STATUS); /* Check for UART interrupts every 1000 clk */
     723    flush_uart();               /* Flush UART ports      */
     724    event(uart_intr, 0, UART_FLUSH_TIME);
     725}
     726
     727
     728static void
     729uart_irq_start()
     730{
     731#ifdef FAST_UART
     732    event(uart_intr, 0, UART_FLUSH_TIME);
     733#else
     734#ifndef _WIN32
     735    event(uart_rx, 0, UART_RX_TIME);
     736#endif
     737#endif
     738}
     739
     740/* GPTIMER */
     741
     742static void
     743gpt_intr(arg)
     744    caddr_t         arg;
     745{
     746    int i;
     747
     748    for (i=0; i<NGPTIMERS; i++) {
     749        if (gpt_ctrl[i] & 1) {
     750            gpt_counter[i] -= 1;
     751            if (gpt_counter[i] == -1) {
     752                if (gpt_ctrl[i] & 8)
     753                    set_irq(GPTIMER_IRQ + i);
     754                if (gpt_ctrl[i] & 2)
     755                    gpt_counter[i] = gpt_reload[i];
     756            }
     757        }
     758    }
     759    event(gpt_intr, 0, gpt_scaler + 1);
     760    gpt_scaler_start = now();
     761}
     762
     763static void
     764gpt_init()
     765{
     766    if (sis_verbose)
     767        printf("GPT started (period %d)\n\r", gpt_scaler + 1);
     768
     769    grlib_apbpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_GPTIMER, 0, 8),
     770                    GRLIB_PP_APBADDR(0x80000300, 0xFFF));
     771}
     772
     773static void
     774gpt_reset()
     775{
     776    event(gpt_intr, 0, gpt_scaler + 1);
     777    gpt_scaler_start = now();
     778}
     779
     780static void
     781gpt_scaler_set(val)
     782    uint32          val;
     783{
     784    gpt_scaler = val & 0x0ffff; /* 16-bit scaler */
     785}
     786
     787static void
     788timer_ctrl(val, i)
     789    uint32       val;
     790    int          i;
     791{
     792    if (val & 4) {  /* reload */
     793        gpt_counter[i] = gpt_reload[i];
     794    }
     795    gpt_ctrl[i] = val & 0xb;
     796}
     797
     798/* Store data in host byte order.  MEM points to the beginning of the
     799   emulated memory; WADDR contains the index the emulated memory,
     800   DATA points to words in host byte order to be stored.  SZ contains log(2)
     801   of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
     802   2 (one word), or 3 (two words); WS should return the number of wait-states. */
     803
     804static void
     805store_bytes (mem, waddr, data, sz, ws)
     806    unsigned char  *mem;
     807    uint32         waddr;
     808    uint32         *data;
     809    int32           sz;
     810    int32          *ws;
     811{
     812    switch (sz) {
     813        case 0:
     814#ifdef HOST_LITTLE_ENDIAN
     815            waddr ^= 3;
     816#endif
     817            mem[waddr] = *data & 0x0ff;
     818            *ws = 0;
     819            break;
     820        case 1:
     821#ifdef HOST_LITTLE_ENDIAN
     822            waddr ^= 2;
     823#endif
     824            *((unsigned short *) &(mem[waddr])) = *data & 0x0ffff;
     825            *ws = 0;
     826            break;
     827        case 2:
     828            *((uint32 *) &(mem[waddr])) = *data;
     829            *ws = 0;
     830            break;
     831        case 3:
     832            *((uint32 *) &(mem[waddr])) = data[0];
     833            *((uint32 *) &(mem[waddr + 4])) = data[1];
     834            *ws = 0;
     835            break;
     836    }
     837}
     838
     839
     840/* Memory emulation */
     841
     842static int
     843memory_iread(addr, data, ws)
     844    uint32          addr;
     845    uint32         *data;
     846    int32          *ws;
     847{
     848    if ((addr >= RAM_START) && (addr < RAM_END)) {
     849        *data = *((uint32 *) & (ramb[addr & RAM_MASK]));
     850        *ws = 0;
     851        return (0);
     852    } else if (addr < ROM_END) {
     853        *data = *((uint32 *) & (romb[addr]));
     854        *ws = 0;
     855        return (0);
     856    }
     857
     858    printf("Memory exception at %x (illegal address)\n", addr);
     859    *ws = MEM_EX_WS;
     860    return (1);
     861}
     862
     863static int
     864memory_read(addr, data, sz, ws)
     865    uint32          addr;
     866    uint32         *data;
     867    int32           sz;
     868    int32          *ws;
     869{
     870    int32           mexc;
     871
     872    if ((addr >= RAM_START) && (addr < RAM_END)) {
     873        *data = *((uint32 *) & (ramb[addr & RAM_MASK & ~3]));
     874        *ws = 0;
     875        return (0);
     876    } else if ((addr >= APBPP_START) && (addr <= APBPP_END)) {
     877        *data = grlib_apbpnp_read(addr);
     878        if (sis_verbose > 1)
     879             printf("APB PP read a: %08x, d: %08x\n",addr, *data);
     880        *ws = 4;
     881        return (0);
     882    } else if ((addr >= APBSTART) && (addr < APBEND)) {
     883        mexc = apb_read(addr, data);
     884        if (mexc) {
     885            *ws = MEM_EX_WS;
     886        } else {
     887            *ws = 0;
     888        }
     889        return (mexc);
     890    } else if ((addr >= AHBPP_START) && (addr <= AHBPP_END)) {
     891        if (sis_verbose > 1)
     892             printf("AHB PP read a: %08x, d: %08x\n",addr, *data);
     893        *data = grlib_ahbpnp_read(addr);
     894        *ws = 4;
     895        return (0);
     896    } else if (addr < ROM_END) {
     897        *data = *((uint32 *) & (romb[addr & ~3]));
     898        *ws = 0;
     899        return (0);
     900    }
     901
     902    printf("Memory exception at %x (illegal address)\n", addr);
     903    *ws = MEM_EX_WS;
     904    return (1);
     905}
     906
     907static int
     908memory_read_asi(asi, addr, data, sz, ws)
     909    int32           asi;
     910    uint32          addr;
     911    uint32         *data;
     912    int32           sz;
     913    int32          *ws;
     914{
     915    if (asi == 2) {
     916        if (addr == 0)
     917            *data = cache_ctrl;
     918        else
     919            *data = 0;
     920        return MOK;
     921    } else
     922        return(memory_read(addr, data, sz, ws));
     923}
     924
     925static int
     926memory_write(addr, data, sz, ws)
     927    uint32          addr;
     928    uint32         *data;
     929    int32           sz;
     930    int32          *ws;
     931{
     932    uint32          byte_addr;
     933    uint32          byte_mask;
     934    uint32          waddr;
     935    uint32         *ram;
     936    int32           mexc;
     937    int             i;
     938    int             wphit[2];
     939
     940    if ((addr >= RAM_START) && (addr < RAM_END)) {
     941        waddr = addr & RAM_MASK;
     942        store_bytes (ramb, waddr, data, sz, ws);
     943        return (0);
     944
     945    } else if ((addr >= APBSTART) && (addr < APBEND)) {
     946        if (sz != 2) {
     947            *ws = MEM_EX_WS;
     948            return (1);
     949        }
     950        apb_write(addr, *data);
     951        *ws = 0;
     952        return (0);
     953
     954    } else if (addr < ROM_END) {
     955//        return (1);
     956        *ws = 0;
     957        store_bytes (romb, addr, data, sz, ws);
     958        return (0);
     959    }
     960
     961    *ws = MEM_EX_WS;
     962    return (1);
     963}
     964
     965static int
     966memory_write_asi(asi, addr, data, sz, ws)
     967    int32           asi;
     968    uint32          addr;
     969    uint32         *data;
     970    int32           sz;
     971    int32          *ws;
     972{
     973    if (asi == 2) {
     974        cache_ctrl = *data & 0x81000f;
     975        if (sis_verbose)
     976            printf("cache ctrl reg : 0x%08x\n", cache_ctrl);
     977        return MOK;
     978    } else
     979        return(memory_write(addr, data, sz, ws));
     980}
     981
     982static unsigned char  *
     983get_mem_ptr(addr, size)
     984    uint32          addr;
     985    uint32          size;
     986{
     987    if ((addr + size) < ROM_END) {
     988        return (&romb[addr]);
     989    } else if ((addr >= RAM_START) && ((addr + size) < RAM_END)) {
     990        return (&ramb[addr & RAM_MASK]);
     991    }
     992
     993    return ((char *) -1);
     994}
     995
     996static int
     997sis_memory_write(addr, data, length)
     998    uint32               addr;
     999    const unsigned char *data;
     1000    uint32               length;
     1001{
     1002    char           *mem;
     1003
     1004    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
     1005        return (0);
     1006
     1007    memcpy(mem, data, length);
     1008    return (length);
     1009}
     1010
     1011static int
     1012sis_memory_read(addr, data, length)
     1013    uint32          addr;
     1014    char           *data;
     1015    uint32          length;
     1016{
     1017    char           *mem;
     1018    int            ws;
     1019
     1020    if (length == 4) {
     1021      memory_read(addr, data, length, &ws);
     1022      return(4);
     1023    }
     1024
     1025    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
     1026        return (0);
     1027
     1028    memcpy(data, mem, length);
     1029    return (length);
     1030}
     1031
     1032static void
     1033boot_init ()
     1034{
     1035//    mec_write(MEC_WCR, 0);    /* zero waitstates */
     1036//    mec_write(MEC_TRAPD, 0);  /* turn off watch-dog */
     1037    apb_write(GPTIMER_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
     1038    apb_write(GPTIMER_SCLOAD, sregs.freq-1);
     1039    apb_write(GPTIMER_TIMER1, -1);
     1040    apb_write(GPTIMER_RELOAD1, -1);
     1041    apb_write(GPTIMER_CTRL1, 0x7);
     1042//    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
     1043    sregs.wim = 2;
     1044    sregs.psr = 0xF30010e0;
     1045    sregs.r[30] = RAM_END;
     1046    sregs.r[14] = sregs.r[30] - 96*4;
     1047    cache_ctrl = 0x81000f;
     1048}
     1049
     1050struct memsys leon3 = {
     1051    init_sim,
     1052    reset,
     1053    error_mode,
     1054    sim_halt,
     1055    exit_sim,
     1056    init_stdio,
     1057    restore_stdio,
     1058    memory_iread,
     1059    memory_read,
     1060    memory_read_asi,
     1061    memory_write,
     1062    memory_write_asi,
     1063    sis_memory_write,
     1064    sis_memory_read,
     1065    boot_init
     1066};
  • sim/erc32/sis.c

    diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
    index d833da3..0e19270 100644
    a b main(argc, argv) 
    142142    for (i = 0; i < 64; i++)
    143143        cmdq[i] = 0;
    144144    printf("\n SIS - SPARC instruction simulator %s,  copyright Jiri Gaisler 1995\n", sis_version);
    145     printf(" Bug-reports to jgais@wd.estec.esa.nl\n\n");
     145    printf(" Bug-reports to jiri@gaisler.se\n\n");
    146146    while (stat < argc) {
    147147        if (argv[stat][0] == '-') {
    148148            if (strcmp(argv[stat], "-v") == 0) {
    main(argc, argv) 
    181181                dumbio = 1;
    182182            } else if (strcmp(argv[stat], "-nouartrx") == 0) {
    183183                nouartrx = 1;
     184            } else if (strcmp(argv[stat], "-leon3") == 0) {
     185                ms = &leon3;
     186                if (freq == 14) freq = 50;
     187                cputype = CPU_LEON3;
    184188            } else if (strcmp(argv[stat], "-v") == 0) {
    185189                sis_verbose += 1;
    186190            } else {
    main(argc, argv) 
    193197        }
    194198        stat++;
    195199    }
     200
     201    switch (cputype) {
     202    case CPU_LEON3:
     203        printf(" LEON3 emulation enabled\n");
     204        break;
     205    default:
     206        printf(" ERC32 emulation enabled\n");
     207    }
     208
    196209    if (nfp)
    197         printf("FPU disabled\n");
    198 #ifdef ERA
    199     if (era)
    200         printf("ERA ECC emulation enabled\n");
    201 #endif
     210        printf(" FPU disabled\n");
    202211    sregs.freq = freq;
     212    printf("\n");
    203213
    204214    INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf);
    205215#ifdef HOST_LITTLE_ENDIAN
  • sim/erc32/sis.h

    diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
    index 8a48f29..a551b4a 100644
    a b struct irqcell { 
    159159    int32           arg;
    160160};
    161161
     162struct memsys {
     163    void        (*init_sim) ();
     164    void        (*reset) (void);
     165    void        (*error_mode) (uint32 pc);
     166    void        (*sim_halt) (void);
     167    void        (*exit_sim) (void);
     168    void        (*init_stdio) (void);
     169    void        (*restore_stdio) (void);
     170    int         (*memory_iread) (uint32 addr, uint32 *data, int32 *ws);
     171    int         (*memory_read) (uint32 addr, uint32 *data,
     172                             int32 sz, int32 *ws);
     173    int         (*memory_read_asi) (int32 asi, uint32 addr, uint32 *data,
     174                             int32 sz, int32 *ws);
     175    int         (*memory_write) (uint32 addr, uint32 *data,
     176                              int32 sz, int32 *ws);
     177    int         (*memory_write_asi) (int32 asi, uint32 addr, uint32 *data,
     178                              int32 sz, int32 *ws);
     179    int         (*sis_memory_write) (uint32 addr,
     180                                  const unsigned char *data, uint32 length);
     181    int         (*sis_memory_read) (uint32 addr, char *data,
     182                                 uint32 length);
     183    void        (*boot_init) (void);
     184};
     185
    162186
    163187#define OK 0
    164188#define TIME_OUT 1
    struct irqcell { 
    166190#define ERROR 3
    167191#define CTRL_C 4
    168192
     193#define CPU_LEON3  3
     194
    169195/* Prototypes  */
    170196
    171197/* erc32.c */
    extern int nouartrx; 
    221247extern          host_callback *sim_callback;
    222248extern int      current_target_byte_order;
    223249extern int      dumbio;
     250extern int      cputype;
    224251
    225252/* exec.c */
    226253extern int      dispatch_instruction (struct pstate *sregs);
    extern void set_fsr (uint32 fsr); 
    241268extern void     usage (void);
    242269extern void     gen_help (void);
    243270
    244 struct memsys {
    245     void        (*init_sim) ();
    246     void        (*reset) (void);
    247     void        (*error_mode) (uint32 pc);
    248     void        (*sim_halt) (void);
    249     void        (*exit_sim) (void);
    250     void        (*init_stdio) (void);
    251     void        (*restore_stdio) (void);
    252     int         (*memory_iread) (uint32 addr, uint32 *data, int32 *ws);
    253     int         (*memory_read) (int32 asi, uint32 addr, uint32 *data,
    254                              int32 sz, int32 *ws);
    255     int         (*memory_write) (int32 asi, uint32 addr, uint32 *data,
    256                               int32 sz, int32 *ws);
    257     int         (*sis_memory_write) (uint32 addr,
    258                                   const unsigned char *data, uint32 length);
    259     int         (*sis_memory_read) (uint32 addr, char *data,
    260                                  uint32 length);
    261 };
    262 
    263271extern struct memsys *ms;
     272
     273/* leon3.c */
     274extern struct memsys leon3;
Note: See TracBrowser for help on using the repository browser.