source:
rtems-tools/tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch
@
bfd2b7d
Last change on this file since bfd2b7d was bfd2b7d, checked in by Joel Sherrill <joel.sherrill@…>, on 03/26/15 at 18:20:45 | |
---|---|
|
|
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 21 21 TERMCAP_LIB = @TERMCAP@ 22 22 READLINE_LIB = @READLINE@ 23 23 24 SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o 24 SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o leon3.o grlib.o 25 25 SIM_EXTRA_LIBS = $(READLINE_LIB) $(TERMCAP_LIB) -lm 26 26 SIM_EXTRA_ALL = sis 27 27 SIM_EXTRA_INSTALL = install-sis … … SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcroot) 35 35 ## COMMON_POST_CONFIG_FRAG 36 36 37 37 # `sis' doesn't need interf.o. 38 SIS_OFILES = exec.o erc32.o func.o help.o float.o 38 SIS_OFILES = exec.o erc32.o func.o help.o float.o grlib.o leon3.o 39 39 40 40 sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS) 41 41 $(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 2 1. LEON3 emulation 3 4 The file 'leon3.c' contains a model of simple LEON3 sub-system. It 5 contains 16 Mbyte ROM and 16 Mbyte RAM. Standard peripherals 6 such as interrupt controller, UART and timer are provided. 7 The model can execute leon3 binaries that do not require an 8 MMU. 9 10 To start sis in Leon3 mode, add the -leon3 switch. In gdb, 11 use 'target sim -leon3' . 12 13 1.1 UART 14 15 The UART emulates an APBUART and is located at address 0x80000100. 16 The following registers are implemeted: 17 18 - UART RX and TX register (0x80000100) 19 - UART status register (0x80000104) 20 21 The UART generates interrupt 3. 22 23 1.2 Timer unit (GPTIMER) 24 25 The GPTIMER programmable counter is emulated and located at 26 address 0x80000300. It is configured with two timers and separate 27 interrupts (8 and 9). 28 29 1.3 Interrupt controller 30 31 The IRQMP interrupt controller is implemented as described in the 32 GRLIB IP manual, with the exception of the interrupt level register. 33 Extended interrupts are not supported. The registers are located 34 at address 0x80000200. 35 36 1.5 Memory interface 37 38 The following memory areas are valid for the Leon3 simulator: 39 40 0x00000000 - 0x01000000 ROM (16 Mbyte, loaded at start-up) 41 0x40000000 - 0x41000000 RAM (16 Mbyte, loaded at start-up) 42 0x80000000 - 0x81000000 APB bus, including plug&play 43 0xFFFFF000 - 0xFFFFFFFF AHB plug&play area 44 45 Access to non-existing memory will result in a memory exception trap. 46 47 1.8 Power-down mode 48 49 The Leon3 power-down feature (%asr19) is supported. When power-down is 50 entered, time is skipped forward until the next event in the event queue. 51 However, if the simulator event queue is empty, power-down mode is not 52 entered since no interrupt would be generated to exit from the mode. A 53 Ctrl-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 1 1 2 SIS - Sparc Instruction Simulator README file (v2. 0, 05-02-1996)2 SIS - Sparc Instruction Simulator README file (v2.8, 10-11-2014) 3 3 ------------------------------------------------------------------- 4 4 5 5 1. Introduction 6 6 7 The SIS is a SPARC V7 architecture simulator. It consist of two parts,7 The SIS is a SPARC V7/V8 architecture simulator. It consist of two parts, 8 8 the simulator core and a user defined memory module. The simulator 9 9 core executes the instructions while the memory module emulates memory 10 10 and peripherals. … … and peripherals. 13 13 14 14 The simulator is started as follows: 15 15 16 sis [- uart1 uart_device1] [-uart2 uart_device2]16 sis [-leon3] [-uart1 uart_device1] [-uart2 uart_device2] 17 17 [-nfp] [-freq frequency] [-c batch_file] [files] 18 18 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. 19 By default, SIS emulates an ERC32 system. The -leon3 switch 20 enables emulation of a LEON3 SOC system. 21 22 The emulated console uart is connected to stdin/stdout. The -uart[1,2] 23 switch can be used to connect the uarts to other devices. 24 22 25 The '-nfp' will disable the simulated FPU, so each FPU instruction will 23 26 generate a FPU disabled trap. The '-freq' switch can be used to define 24 27 which "frequency" the simulator runs at. This is used by the 'perf' 25 28 command to calculated the MIPS figure for a particular configuration. 26 The givefrequency must be an integer indicating the frequency in MHz.29 The frequency must be an integer indicating the frequency in MHz. 27 30 28 31 The -c option indicates that sis commands should be read from 'batch_file' 29 32 at startup. 30 33 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. 34 Files to be loaded must be in one of the supported formats (elf, a.out, srec), 35 and will be loaded into the simulated memory. 34 36 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 37 Below is description of commands that are recognized by 38 38 the simulator. The command-line is parsed using GNU readline. A command 39 39 history of 64 commands is maintained. Use the up/down arrows to recall 40 40 previous commands. For more details, see the readline documentation. … … Prints the FPU registers 77 77 go <address> [inst_count] 78 78 79 79 The 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 specifiednumber of instructions.80 execution. If inst_count is given, execution will stop after the specified 81 number of instructions. 82 82 83 83 help 84 84 … … interpreted as 'cont'. 146 146 147 147 3. Simulator core 148 148 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 is152 maintained and in remented according the IU and FPU instruction timing.149 In ERC32 mode, SIS emulates the behavior of the 90C601E and 90C602E 150 sparc IU and FPU from Matra MHS. These are roughly equivalent to the 151 Cypress C601 and C602. The simulator is cycle true, i.e a simulator time is 152 maintained and incremented according the IU and FPU instruction timing. 153 153 The 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: 154 stalls due to operand dependencies (FPU). 155 156 In Leon3 mode, the core emulates the Leon3 SPARC V8 core from 157 Gaisler Research. All SPARC V8 instructions are supported but 158 emulation is not fully cycle-true as the cache is not emulated. 159 160 The core interacts with the user-defined memory modules through 161 a number of functions. The memory module must provide the following 162 functions: 157 163 158 164 int memory_read(asi,addr,data,ws) 159 165 int asi; … … See 'erc32.c' for examples on how to use events and interrupts. 272 278 273 279 5. Memory module 274 280 275 The suppliedmemory module (erc32.c) emulates the functions of memory and281 The ERC32 memory module (erc32.c) emulates the functions of memory and 276 282 the MEC asic developed for the 90C601/2. It includes the following functions: 277 283 278 284 * UART A & B … … the MEC asic developed for the 90C601/2. It includes the following functions: 284 290 * 512 Kbyte ROM 285 291 * 4 Mbyte RAM 286 292 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: 293 See README.erc32 on how the MEC functions are emulated. 289 294 290 http://www.estec.esa.nl/wsmwww/erc32 295 The Leon3 memory module (leon3.c) emulates on-chip peripherals and 296 external memory for a simple Leon3 system. The modules includes the 297 following functions: 291 298 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 293 305 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. 306 See README.leon3 for further details on Leon3 emulation. 301 307 302 The programs are linked with a start-up file, srt0.S. This file includes 303 the traptable and window underflow/overflow trap routines. 308 6. Compile and linking programs 304 309 305 310 7. IU and FPU instruction timing. 306 311 307 The simulator provides cycle true simulation . The following table shows308 the emulated instruction timing for 90C601E & 90C602E:312 The simulator provides cycle true simulation for ERC32. The following table 313 shows the emulated instruction timing for 90C601E & 90C602E: 309 314 310 315 Instructions Cycles 311 316 -
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) 1636 1636 } 1637 1637 1638 1638 static int 1639 memory_read(asi, addr, data, sz, ws) 1640 int32 asi; 1639 memory_read(addr, data, sz, ws) 1641 1640 uint32 addr; 1642 1641 uint32 *data; 1643 1642 int32 sz; 1644 1643 int32 *ws; 1645 1644 { 1646 1645 int32 mexc; 1646 int32 asi; 1647 1647 1648 1648 #ifdef ERRINJ 1649 1649 if (errmec) { 1650 1650 if (sis_verbose) 1651 1651 printf("Inserted MEC error %d\n",errmec); 1652 if (sregs.psr & 0x080) asi = 11; else asi = 10; 1652 1653 set_sfsr(errmec, addr, asi, 1); 1653 1654 if (errmec == 5) mecparerror(); 1654 1655 if (errmec == 6) iucomperr(); … … memory_read(asi, addr, data, sz, ws) 1662 1663 *ws = mem_ramr_ws; 1663 1664 return (0); 1664 1665 } else if ((addr >= MEC_START) && (addr < MEC_END)) { 1666 if (sregs.psr & 0x080) asi = 11; else asi = 10; 1665 1667 mexc = mec_read(addr, asi, data); 1666 1668 if (mexc) { 1667 1669 set_sfsr(MEC_ACC, addr, asi, 1); … … memory_read(asi, addr, data, sz, ws) 1701 1703 } 1702 1704 1703 1705 printf("Memory exception at %x (illegal address)\n", addr); 1706 if (sregs.psr & 0x080) asi = 11; else asi = 10; 1704 1707 set_sfsr(UIMP_ACC, addr, asi, 1); 1705 1708 *ws = MEM_EX_WS; 1706 1709 return (1); 1707 1710 } 1708 1711 1709 1712 static int 1710 memory_ write(asi, addr, data, sz, ws)1713 memory_read_asi(asi, addr, data, sz, ws) 1711 1714 int32 asi; 1712 1715 uint32 addr; 1713 1716 uint32 *data; 1714 1717 int32 sz; 1715 1718 int32 *ws; 1716 1719 { 1720 return(memory_read(addr, data, sz, ws)); 1721 } 1722 1723 static int 1724 memory_write(addr, data, sz, ws) 1725 uint32 addr; 1726 uint32 *data; 1727 int32 sz; 1728 int32 *ws; 1729 { 1717 1730 uint32 byte_addr; 1718 1731 uint32 byte_mask; 1719 1732 uint32 waddr; … … memory_write(asi, addr, data, sz, ws) 1721 1734 int32 mexc; 1722 1735 int i; 1723 1736 int wphit[2]; 1737 int32 asi; 1724 1738 1725 1739 #ifdef ERRINJ 1726 1740 if (errmec) { 1727 1741 if (sis_verbose) 1728 1742 printf("Inserted MEC error %d\n",errmec); 1743 if (sregs.psr & 0x080) asi = 11; else asi = 10; 1729 1744 set_sfsr(errmec, addr, asi, 0); 1730 1745 if (errmec == 5) mecparerror(); 1731 1746 if (errmec == 6) iucomperr(); … … memory_write(asi, addr, data, sz, ws) 1738 1753 if (mem_accprot) { 1739 1754 1740 1755 waddr = (addr & 0x7fffff) >> 2; 1756 if (sregs.psr & 0x080) asi = 11; else asi = 10; 1741 1757 for (i = 0; i < 2; i++) 1742 1758 wphit[i] = 1743 1759 (((asi == 0xa) && (mec_wpr[i] & 1)) || … … memory_write(asi, addr, data, sz, ws) 1761 1777 return (0); 1762 1778 1763 1779 } else if ((addr >= MEC_START) && (addr < MEC_END)) { 1780 if (sregs.psr & 0x080) asi = 11; else asi = 10; 1764 1781 if ((sz != 2) || (asi != 0xb)) { 1765 1782 set_sfsr(MEC_ACC, addr, asi, 0); 1766 1783 *ws = MEM_EX_WS; … … memory_write(asi, addr, data, sz, ws) 1817 1834 } 1818 1835 1819 1836 *ws = MEM_EX_WS; 1837 if (sregs.psr & 0x080) asi = 11; else asi = 10; 1820 1838 set_sfsr(UIMP_ACC, addr, asi, 0); 1821 1839 return (1); 1822 1840 } 1823 1841 1842 static int 1843 memory_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 1824 1853 static unsigned char * 1825 1854 get_mem_ptr(addr, size) 1826 1855 uint32 addr; … … sis_memory_read(addr, data, length) 1864 1893 uint32 length; 1865 1894 { 1866 1895 char *mem; 1896 int ws; 1897 1898 if (length == 4) { 1899 memory_read(addr, data, length, &ws); 1900 return(4); 1901 } 1867 1902 1868 1903 if ((mem = get_mem_ptr(addr, length)) == ((char *) -1)) 1869 1904 return (0); … … sis_memory_read(addr, data, length) 1872 1907 return (length); 1873 1908 } 1874 1909 1875 void1910 static void 1876 1911 boot_init (void) 1877 1912 { 1878 1913 mec_write(MEC_WCR, 0); /* zero waitstates */ … … struct memsys erc32sys = { 1896 1931 restore_stdio, 1897 1932 memory_iread, 1898 1933 memory_read, 1934 memory_read_asi, 1899 1935 memory_write, 1936 memory_write_asi, 1900 1937 sis_memory_write, 1901 sis_memory_read 1938 sis_memory_read, 1939 boot_init 1902 1940 }; -
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) 1065 1065 *rdd = sregs->psr; 1066 1066 break; 1067 1067 case RDY: 1068 if ( !sparclite)1068 if ((!sparclite) && (cputype != CPU_LEON3)) 1069 1069 *rdd = sregs->y; 1070 1070 else { 1071 1071 int rs1_is_asr = (sregs->inst >> 14) & 0x1f; 1072 1072 if ( 0 == rs1_is_asr ) 1073 1073 *rdd = sregs->y; 1074 else if ( 17 == rs1_is_asr ) 1074 else if ( 17 == rs1_is_asr ) { 1075 1075 *rdd = sregs->asr17; 1076 } 1076 1077 else { 1077 1078 sregs->trap = TRAP_UNIMP; 1078 break;1079 1079 } 1080 1080 } 1081 1081 break; … … dispatch_instruction(sregs) 1121 1121 ((rs1 ^ operand2) & 0xfffff000); 1122 1122 break; 1123 1123 case WRY: 1124 if ( !sparclite)1124 if ((!sparclite) && (cputype != CPU_LEON3)) 1125 1125 sregs->y = (rs1 ^ operand2); 1126 1126 else { 1127 1127 if ( 0 == rd ) 1128 1128 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 } 1131 1137 else { 1132 1138 sregs->trap = TRAP_UNIMP; 1133 1139 break; … … dispatch_instruction(sregs) 1227 1233 switch (op3) { 1228 1234 case LDDA: 1229 1235 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; 1230 1262 case LDD: 1231 1263 if (address & 0x7) { 1232 1264 sregs->trap = TRAP_UNALI; … … dispatch_instruction(sregs) 1239 1271 else 1240 1272 rdd = &(sregs->g[rd]); 1241 1273 } 1242 mexc = ms->memory_read(a si, address, ddata, 2, &ws);1274 mexc = ms->memory_read(address, ddata, 2, &ws); 1243 1275 sregs->hold += ws; 1244 mexc |= ms->memory_read(a si, address+4, &ddata[1], 2, &ws);1276 mexc |= ms->memory_read(address+4, &ddata[1], 2, &ws); 1245 1277 sregs->hold += ws; 1246 1278 sregs->icnt = T_LDD; 1247 1279 if (mexc) { … … dispatch_instruction(sregs) 1257 1289 1258 1290 case LDA: 1259 1291 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; 1260 1304 case LD: 1261 1305 if (address & 0x3) { 1262 1306 sregs->trap = TRAP_UNALI; 1263 1307 break; 1264 1308 } 1265 mexc = ms->memory_read(a si, address, &data, 2, &ws);1309 mexc = ms->memory_read(address, &data, 2, &ws); 1266 1310 sregs->hold += ws; 1267 1311 if (mexc) { 1268 1312 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1272 1316 break; 1273 1317 case LDSTUBA: 1274 1318 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; 1275 1338 case LDSTUB: 1276 mexc = ms->memory_read(a si, address, &data, 0, &ws);1339 mexc = ms->memory_read(address, &data, 0, &ws); 1277 1340 sregs->hold += ws; 1278 1341 sregs->icnt = T_LDST; 1279 1342 if (mexc) { … … dispatch_instruction(sregs) 1283 1346 data = extract_byte(data, address); 1284 1347 *rdd = data; 1285 1348 data = 0x0ff; 1286 mexc = ms->memory_write(a si, address, &data, 0, &ws);1349 mexc = ms->memory_write(address, &data, 0, &ws); 1287 1350 sregs->hold += ws; 1288 1351 if (mexc) { 1289 1352 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1295 1358 case LDSBA: 1296 1359 case LDUBA: 1297 1360 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; 1298 1373 case LDSB: 1299 1374 case LDUB: 1300 mexc = ms->memory_read(a si, address, &data, 0, &ws);1375 mexc = ms->memory_read(address, &data, 0, &ws); 1301 1376 sregs->hold += ws; 1302 1377 if (mexc) { 1303 1378 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1312 1387 case LDSHA: 1313 1388 case LDUHA: 1314 1389 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; 1315 1406 case LDSH: 1316 1407 case LDUH: 1317 1408 if (address & 0x1) { 1318 1409 sregs->trap = TRAP_UNALI; 1319 1410 break; 1320 1411 } 1321 mexc = ms->memory_read(a si, address, &data, 1, &ws);1412 mexc = ms->memory_read(address, &data, 1, &ws); 1322 1413 sregs->hold += ws; 1323 1414 if (mexc) { 1324 1415 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1344 1435 (sregs->frs2 == rd)) 1345 1436 sregs->fhold += (sregs->ftime - ebase.simtime); 1346 1437 } 1347 mexc = ms->memory_read(a si, address, &data, 2, &ws);1438 mexc = ms->memory_read(address, &data, 2, &ws); 1348 1439 sregs->hold += ws; 1349 1440 sregs->flrd = rd; 1350 1441 sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD + … … dispatch_instruction(sregs) 1370 1461 ((sregs->frs2 >> 1) == (rd >> 1))) 1371 1462 sregs->fhold += (sregs->ftime - ebase.simtime); 1372 1463 } 1373 mexc = ms->memory_read(a si, address, ddata, 2, &ws);1464 mexc = ms->memory_read(address, ddata, 2, &ws); 1374 1465 sregs->hold += ws; 1375 mexc |= ms->memory_read(a si, address+4, &ddata[1], 2, &ws);1466 mexc |= ms->memory_read(address+4, &ddata[1], 2, &ws); 1376 1467 sregs->hold += ws; 1377 1468 sregs->icnt = T_LDD; 1378 1469 if (mexc) { … … dispatch_instruction(sregs) 1401 1492 sregs->trap = TRAP_UNALI; 1402 1493 break; 1403 1494 } 1404 mexc = ms->memory_read(a si, address, &data, 2, &ws);1495 mexc = ms->memory_read(address, &data, 2, &ws); 1405 1496 sregs->hold += ws; 1406 1497 if (mexc) { 1407 1498 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1423 1514 if (ebase.simtime < sregs->ftime) { 1424 1515 sregs->fhold += (sregs->ftime - ebase.simtime); 1425 1516 } 1426 mexc = ms->memory_write(a si, address, &sregs->fsr, 2, &ws);1517 mexc = ms->memory_write(address, &sregs->fsr, 2, &ws); 1427 1518 sregs->hold += ws; 1428 1519 if (mexc) { 1429 1520 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1432 1523 1433 1524 case STA: 1434 1525 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; 1435 1536 case ST: 1436 1537 if (address & 0x3) { 1437 1538 sregs->trap = TRAP_UNALI; 1438 1539 break; 1439 1540 } 1440 mexc = ms->memory_write(a si, address, rdd, 2, &ws);1541 mexc = ms->memory_write(address, rdd, 2, &ws); 1441 1542 sregs->hold += ws; 1442 1543 if (mexc) { 1443 1544 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1445 1546 break; 1446 1547 case STBA: 1447 1548 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; 1448 1555 case STB: 1449 mexc = ms->memory_write(a si, address, rdd, 0, &ws);1556 mexc = ms->memory_write(address, rdd, 0, &ws); 1450 1557 sregs->hold += ws; 1451 1558 if (mexc) { 1452 1559 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1454 1561 break; 1455 1562 case STDA: 1456 1563 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; 1457 1586 case STD: 1458 1587 if (address & 0x7) { 1459 1588 sregs->trap = TRAP_UNALI; … … dispatch_instruction(sregs) 1466 1595 else 1467 1596 rdd = &(sregs->g[rd]); 1468 1597 } 1469 mexc = ms->memory_write(a si, address, rdd, 3, &ws);1598 mexc = ms->memory_write(address, rdd, 3, &ws); 1470 1599 sregs->hold += ws; 1471 1600 sregs->icnt = T_STD; 1472 1601 #ifdef STAT … … dispatch_instruction(sregs) 1495 1624 break; 1496 1625 } 1497 1626 rdd = &(sregs->fpq[0]); 1498 mexc = ms->memory_write(a si, address, rdd, 3, &ws);1627 mexc = ms->memory_write(address, rdd, 3, &ws); 1499 1628 sregs->hold += ws; 1500 1629 sregs->icnt = T_STD; 1501 1630 #ifdef STAT … … dispatch_instruction(sregs) 1511 1640 break; 1512 1641 case STHA: 1513 1642 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; 1514 1653 case STH: 1515 1654 if (address & 0x1) { 1516 1655 sregs->trap = TRAP_UNALI; 1517 1656 break; 1518 1657 } 1519 mexc = ms->memory_write(a si, address, rdd, 1, &ws);1658 mexc = ms->memory_write(address, rdd, 1, &ws); 1520 1659 sregs->hold += ws; 1521 1660 if (mexc) { 1522 1661 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1535 1674 if (sregs->frd == rd) 1536 1675 sregs->fhold += (sregs->ftime - ebase.simtime); 1537 1676 } 1538 mexc = ms->memory_write(a si, address, &sregs->fsi[rd], 2, &ws);1677 mexc = ms->memory_write(address, &sregs->fsi[rd], 2, &ws); 1539 1678 sregs->hold += ws; 1540 1679 if (mexc) { 1541 1680 sregs->trap = TRAP_DEXC; … … dispatch_instruction(sregs) 1555 1694 if ((sregs->frd == rd) || (sregs->frd + 1 == rd)) 1556 1695 sregs->fhold += (sregs->ftime - ebase.simtime); 1557 1696 } 1558 mexc = ms->memory_write(a si, address, &sregs->fsi[rd], 3, &ws);1697 mexc = ms->memory_write(address, &sregs->fsi[rd], 3, &ws); 1559 1698 sregs->hold += ws; 1560 1699 sregs->icnt = T_STD; 1561 1700 #ifdef STAT … … dispatch_instruction(sregs) 1567 1706 break; 1568 1707 case SWAPA: 1569 1708 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; 1570 1731 case SWAP: 1571 1732 if (address & 0x3) { 1572 1733 sregs->trap = TRAP_UNALI; 1573 1734 break; 1574 1735 } 1575 mexc = ms->memory_read(a si, address, &data, 2, &ws);1736 mexc = ms->memory_read(address, &data, 2, &ws); 1576 1737 sregs->hold += ws; 1577 1738 if (mexc) { 1578 1739 sregs->trap = TRAP_DEXC; 1579 1740 break; 1580 1741 } 1581 mexc = ms->memory_write(a si, address, rdd, 2, &ws);1742 mexc = ms->memory_write(address, rdd, 2, &ws); 1582 1743 sregs->hold += ws; 1583 1744 sregs->icnt = T_LDST; 1584 1745 if (mexc) { … … fpexec(op3, rd, rs1, rs2, sregs) 1814 1975 sregs->ftime += T_FDIVd; 1815 1976 break; 1816 1977 case FMOVs: 1817 sregs->fs [rd] = sregs->fs[rs2];1978 sregs->fsi[rd] = sregs->fsi[rs2]; 1818 1979 sregs->ftime += T_FMOVs; 1819 1980 sregs->frs1 = 32; /* rs1 ignored */ 1820 1981 break; … … execute_trap(sregs) 1996 2157 sregs->pc = sregs->tbr; 1997 2158 sregs->npc = sregs->tbr + 4; 1998 2159 1999 if ( 0 != (1 & sregs->asr17) ) {2160 if ( 0 != (1 & (sregs->asr17 >> 13)) ) { 2000 2161 /* single vector trapping! */ 2001 2162 sregs->pc = sregs->tbr & 0xfffff000; 2002 2163 sregs->npc = sregs->pc + 4; … … init_regs(sregs) 2043 2204 sregs->npc = 4; 2044 2205 sregs->trap = 0; 2045 2206 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 */ 2047 2211 sregs->breakpoint = 0; 2048 2212 sregs->annul = 0; 2049 2213 sregs->fpstate = FP_EXE_MODE; … … init_regs(sregs) 2072 2236 2073 2237 sregs->rett_err = 0; 2074 2238 sregs->jmpltime = 0; 2239 if (cputype == CPU_LEON3) { 2240 sregs->asr17 = 0x107; 2241 if (!nfp) sregs->asr17 |= (3 << 10); /* Meiko FPU */ 2242 } 2075 2243 } -
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]; 46 46 47 47 int ctrl_c = 0; 48 48 int sis_verbose = 0; 49 char *sis_version = "2. 7.5";49 char *sis_version = "2.8"; 50 50 int nfp = 0; 51 51 int ift = 0; 52 52 int wrp = 0; … … uint32 last_load_addr = 0; 61 61 int nouartrx = 0; 62 62 host_callback *sim_callback; 63 63 struct memsys *ms = &erc32sys; 64 int cputype = 0; /* 0 = erc32, 3 = leon3 */ 64 65 65 66 #ifdef ERRINJ 66 67 uint32 errcnt = 0; … … exec_cmd(sregs, cmd) 482 483 sregs->pc = len & ~3; 483 484 sregs->npc = sregs->pc + 4; 484 485 if ((sregs->pc != 0) && (ebase.simtime == 0)) 485 boot_init();486 ms->boot_init(); 486 487 printf("resuming at 0x%08x\n",sregs->pc); 487 488 if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { 488 489 stat = run_sim(sregs, VAL(cmd2), 0); … … exec_cmd(sregs, cmd) 558 559 ebase.simtime = 0; 559 560 reset_all(); 560 561 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(); 561 567 if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { 562 568 stat = run_sim(sregs, UINT64_MAX, 0); 563 569 } else { … … exec_cmd(sregs, cmd) 609 615 ebase.simtime = 0; 610 616 reset_all(); 611 617 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(); 612 623 sregs->tlimit = limcalc(sregs->freq); 613 624 stat = run_sim(sregs, UINT64_MAX, 0); 614 625 daddr = sregs->pc; … … void 646 657 show_stat(sregs) 647 658 struct pstate *sregs; 648 659 { 649 uint 32iinst;650 uint 32stime;660 uint64 iinst; 661 uint64 stime; 651 662 652 663 if (sregs->tottime == 0.0) 653 664 sregs->tottime += 1E-6; … … show_stat(sregs) 662 673 printf(" Instructions : %9" PRIu64 "\n", sregs->ninst); 663 674 664 675 #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); 666 677 printf(" load : %9.2f %%\n", 667 100.0 * ( float) sregs->nload / (float) sregs->ninst);678 100.0 * (double) sregs->nload / (double) sregs->ninst); 668 679 printf(" store : %9.2f %%\n", 669 100.0 * ( float) sregs->nstore / (float) sregs->ninst);680 100.0 * (double) sregs->nstore / (double) sregs->ninst); 670 681 printf(" branch : %9.2f %%\n", 671 100.0 * ( float) sregs->nbranch / (float) sregs->ninst);682 100.0 * (double) sregs->nbranch / (double) sregs->ninst); 672 683 printf(" float : %9.2f %%\n", 673 100.0 * ( float) sregs->finst / (float) sregs->ninst);684 100.0 * (double) sregs->finst / (double) sregs->ninst); 674 685 printf(" Integer CPI : %9.2f\n", 675 (( float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))686 ((double) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst)) 676 687 / 677 ( float) (sregs->ninst - sregs->finst));688 (double) (sregs->ninst - sregs->finst)); 678 689 printf(" Float CPI : %9.2f\n", 679 (( float) sregs->fholdt / (float) sregs->finst) + 1.0);690 ((double) sregs->fholdt / (double) sregs->finst) + 1.0); 680 691 #endif 681 692 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); 690 701 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))); 692 703 printf(" Real-time performance : %.2f %%\n", 693 704 100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6)))); 694 705 printf(" Simulator performance : %.2f MIPS\n", 695 706 (double)(sregs->ninst) / sregs->tottime / 1E6); 696 707 printf(" Used time (sys + user) : %.2f s\n\n", sregs->tottime); 697 708 } 698 709 -
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 28 static uint32 apbppmem[32*2]; /* 32-entry APB PP AREA */ 29 static int apbppindex; 30 31 int 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 39 uint32 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 50 static uint32 ahbppmem[128*8]; /* 128-entry AHB PP AREA */ 51 static int ahbmppindex; 52 static int ahbsppindex = 64*8; 53 54 int 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 62 int 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 75 uint32 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 85 void 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 51 int grlib_apbpp_add(uint32 id, uint32 addr); 52 int grlib_ahbmpp_add(uint32 id); 53 int grlib_ahbspp_add(uint32 id, uint32 addr1, uint32 addr2, 54 uint32 addr3, uint32 addr4); 55 uint32 grlib_ahbpnp_read(uint32 addr); 56 uint32 grlib_apbpnp_read(uint32 addr); 57 void 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) 52 52 ms->init_stdio(); 53 53 sregs->starttime = get_time(); 54 54 irq = 0; 55 if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();55 if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init(); 56 56 while (!sregs->err_mode & (icount > 0)) { 57 57 58 58 sregs->fhold = 0; … … sim_open (kind, callback, abfd, argv) 187 187 if (strcmp(argv[stat], "-nouartrx") == 0) { 188 188 nouartrx = 1; 189 189 } else 190 if (strcmp(argv[stat], "-leon3") == 0) { 191 ms = &leon3; 192 cputype = CPU_LEON3; 193 } else 190 194 if (strcmp(argv[stat], "-wrp") == 0) { 191 195 wrp = 1; 192 196 } else … … sim_open (kind, callback, abfd, argv) 224 228 stat++; 225 229 } 226 230 231 if (cputype == CPU_LEON3) 232 sregs.freq = freq ? freq : 50; 233 else 234 sregs.freq = freq ? freq : 14; 235 227 236 if (sis_verbose) { 228 237 (*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 } 230 246 if (nfp) 231 247 (*sim_callback->printf_filtered) (sim_callback, "no FPU\n"); 232 248 if (sparclite) … … sim_open (kind, callback, abfd, argv) 235 251 (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n"); 236 252 if (sis_gdb_break == 0) 237 253 (*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); 240 255 } 241 256 242 sregs.freq = freq ? freq : 15;243 257 termsave = fcntl(0, F_GETFL, 0); 244 258 INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf); 245 259 #ifdef HOST_LITTLE_ENDIAN … … flush_windows () 457 471 #endif 458 472 459 473 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, 461 475 &ws); 462 476 463 477 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 38 static 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 86 static uint32 irqmp_ipr; 87 static uint32 irqmp_imr; 88 static uint32 irqmp_ifr; 89 90 /* GPTIMER registers */ 91 92 #define NGPTIMERS 2 93 #define GPTIMER_IRQ 8 94 95 static uint32 gpt_scaler; 96 static uint32 gpt_scaler_start; 97 static uint32 gpt_counter[NGPTIMERS]; 98 static uint32 gpt_reload[NGPTIMERS]; 99 static 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 113 static unsigned char romb[ROM_END - ROM_START]; 114 static unsigned char ramb[RAM_END - RAM_START]; 115 static uint32 cache_ctrl; 116 117 118 /* UART support variables */ 119 120 static int32 fd1, fd2; /* file descriptor for input file */ 121 static int32 Ucontrol; /* UART status register */ 122 static unsigned char aq[UARTBUF], bq[UARTBUF]; 123 static int32 anum, aind = 0; 124 static int32 bnum, bind = 0; 125 static char wbufa[UARTBUF], wbufb[UARTBUF]; 126 static unsigned wnuma; 127 static unsigned wnumb; 128 static FILE *f1in, *f1out; 129 static struct termios ioc1, ioc2, iocold1, iocold2; 130 static int f1open = 0; 131 132 static char uarta_sreg, uarta_hreg; 133 static uint32 uart_stat_reg; 134 static uint32 uarta_data; 135 136 /* Forward declarations */ 137 138 static void mem_init (void); 139 static void close_port (void); 140 static void leon3_reset (void); 141 static void irqmp_intack (int32 level); 142 static void chk_irq (void); 143 static void set_irq (int32 level); 144 static int32 apb_read (uint32 addr, uint32 *data); 145 static int apb_write (uint32 addr, uint32 data); 146 static void port_init (void); 147 static uint32 grlib_read_uart (uint32 addr); 148 static void grlib_write_uart (uint32 addr, uint32 data); 149 static void flush_uart (void); 150 static void uarta_tx (void); 151 static void uart_rx (caddr_t arg); 152 static void uart_intr (caddr_t arg); 153 static void uart_irq_start (void); 154 static void gpt_intr (caddr_t arg); 155 static void gpt_init (void); 156 static void gpt_reset (void); 157 static void gpt_scaler_set (uint32 val); 158 static void timer_ctrl (uint32 val, int i); 159 static unsigned char * 160 get_mem_ptr (uint32 addr, uint32 size); 161 static void store_bytes (unsigned char *mem, uint32 waddr, 162 uint32 *data, int sz, int32 *ws); 163 164 static host_callback *callback; 165 166 167 /* One-time init */ 168 169 static void 170 init_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 181 static void 182 reset() 183 { 184 leon3_reset(); 185 uart_irq_start(); 186 gpt_reset(); 187 } 188 189 /* IU error mode manager */ 190 191 static void 192 error_mode(pc) 193 uint32 pc; 194 { 195 196 } 197 198 199 /* Memory init */ 200 201 static void 202 mem_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 219 static void 220 sim_halt() 221 { 222 #ifdef FAST_UART 223 flush_uart(); 224 #endif 225 } 226 227 static void 228 close_port() 229 { 230 if (f1open && f1in != stdin) 231 fclose(f1in); 232 } 233 234 static void 235 exit_sim() 236 { 237 close_port(); 238 } 239 240 static void 241 leon3_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 264 static void 265 irqmp_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 279 static void 280 chk_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 302 static void 303 set_irq(level) 304 int32 level; 305 { 306 irqmp_ipr |= (1 << level); 307 chk_irq(); 308 } 309 310 static int32 311 apb_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 382 static int 383 apb_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 448 static int ifd1 = -1, ofd1 = -1; 449 450 static void 451 init_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 461 static void 462 restore_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 478 static void 479 port_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 525 static uint32 526 grlib_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 608 static void 609 grlib_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 658 static void 659 flush_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 673 static void 674 uarta_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 694 static void 695 uart_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 718 static void 719 uart_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 728 static void 729 uart_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 742 static void 743 gpt_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 763 static void 764 gpt_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 773 static void 774 gpt_reset() 775 { 776 event(gpt_intr, 0, gpt_scaler + 1); 777 gpt_scaler_start = now(); 778 } 779 780 static void 781 gpt_scaler_set(val) 782 uint32 val; 783 { 784 gpt_scaler = val & 0x0ffff; /* 16-bit scaler */ 785 } 786 787 static void 788 timer_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 804 static void 805 store_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 842 static int 843 memory_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 863 static int 864 memory_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 907 static int 908 memory_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 925 static int 926 memory_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 965 static int 966 memory_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 982 static unsigned char * 983 get_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 996 static int 997 sis_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 1011 static int 1012 sis_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 1032 static void 1033 boot_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 1050 struct 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) 142 142 for (i = 0; i < 64; i++) 143 143 cmdq[i] = 0; 144 144 printf("\n SIS - SPARC instruction simulator %s, copyright Jiri Gaisler 1995\n", sis_version); 145 printf(" Bug-reports to j gais@wd.estec.esa.nl\n\n");145 printf(" Bug-reports to jiri@gaisler.se\n\n"); 146 146 while (stat < argc) { 147 147 if (argv[stat][0] == '-') { 148 148 if (strcmp(argv[stat], "-v") == 0) { … … main(argc, argv) 181 181 dumbio = 1; 182 182 } else if (strcmp(argv[stat], "-nouartrx") == 0) { 183 183 nouartrx = 1; 184 } else if (strcmp(argv[stat], "-leon3") == 0) { 185 ms = &leon3; 186 if (freq == 14) freq = 50; 187 cputype = CPU_LEON3; 184 188 } else if (strcmp(argv[stat], "-v") == 0) { 185 189 sis_verbose += 1; 186 190 } else { … … main(argc, argv) 193 197 } 194 198 stat++; 195 199 } 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 196 209 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"); 202 211 sregs.freq = freq; 212 printf("\n"); 203 213 204 214 INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf); 205 215 #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 { 159 159 int32 arg; 160 160 }; 161 161 162 struct 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 162 186 163 187 #define OK 0 164 188 #define TIME_OUT 1 … … struct irqcell { 166 190 #define ERROR 3 167 191 #define CTRL_C 4 168 192 193 #define CPU_LEON3 3 194 169 195 /* Prototypes */ 170 196 171 197 /* erc32.c */ … … extern int nouartrx; 221 247 extern host_callback *sim_callback; 222 248 extern int current_target_byte_order; 223 249 extern int dumbio; 250 extern int cputype; 224 251 225 252 /* exec.c */ 226 253 extern int dispatch_instruction (struct pstate *sregs); … … extern void set_fsr (uint32 fsr); 241 268 extern void usage (void); 242 269 extern void gen_help (void); 243 270 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 263 271 extern struct memsys *ms; 272 273 /* leon3.c */ 274 extern struct memsys leon3;
Note: See TracBrowser
for help on using the repository browser.