From bfd2b7d8f4b966d65e681f9b81749c10a8d83a47 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 26 Mar 2015 13:20:45 -0500 Subject: 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. --- ...isassembly-in-stand-alone-mode-did-not-wo.patch | 61 + ...orrected-wrong-CPU-implementation-and-ver.patch | 27 + ...erform-pseudo-init-if-binary-linked-to-no.patch | 89 + ...-sim-erc32-Use-fenv.h-for-host-FPU-access.patch | 241 ++ ...emove-unused-defines-in-Makefile-and-swit.patch | 27 + ...ix-incorrect-simulator-performance-report.patch | 174 ++ ...ile-loading-via-command-line-did-not-work.patch | 43 + ...dded-v-command-line-switch-for-verbose-ou.patch | 123 + ...2-Removed-type-mismatch-compiler-warnings.patch | 66 + ...witched-emulated-memory-to-host-endian-or.patch | 564 +++++ ...se-SIM_AC_OPTION_HOSTENDIAN-to-probe-for-.patch | 564 +++++ ...se-memory_iread-function-for-instruction-.patch | 119 + ...013-sim-erc32-Fix-a-few-compiler-warnings.patch | 72 + ...se-gdb-callback-for-UART-I-O-when-linked-.patch | 358 +++ ...ccess-memory-subsystem-through-struct-mem.patch | 804 +++++++ ...se-readline.h-for-readline-types-and-func.patch | 55 + ...Move-local-extern-declarations-into-sis.h.patch | 224 ++ ...Add-support-for-LEON3-processor-emulation.patch | 2434 ++++++++++++++++++++ ...Add-support-for-LEON2-processor-emulation.patch | 1188 ++++++++++ .../7.9/0020-sim-erc32-Updated-documentation.patch | 516 +++++ ...021-sim-erc32-Add-data-watchpoint-support.patch | 377 +++ ...hpoint-support-to-gdb-simulator-interface.patch | 1025 +++++++++ ...LF-loading-could-fail-on-unaligned-sectio.patch | 39 + 23 files changed, 9190 insertions(+) create mode 100644 tools/4.11/gdb/sparc/7.9/0001-sim-erc32-Disassembly-in-stand-alone-mode-did-not-wo.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0002-sim-erc32-Corrected-wrong-CPU-implementation-and-ver.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0003-sim-erc32-Perform-pseudo-init-if-binary-linked-to-no.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0005-sim-erc32-Remove-unused-defines-in-Makefile-and-swit.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0006-sim-erc32-Fix-incorrect-simulator-performance-report.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0007-sim-erc32-File-loading-via-command-line-did-not-work.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0008-sim-erc32-Added-v-command-line-switch-for-verbose-ou.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0009-sim-erc32-Removed-type-mismatch-compiler-warnings.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0011-sim-erc32-use-SIM_AC_OPTION_HOSTENDIAN-to-probe-for-.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0012-sim-erc32-Use-memory_iread-function-for-instruction-.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0013-sim-erc32-Fix-a-few-compiler-warnings.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0014-sim-erc32-Use-gdb-callback-for-UART-I-O-when-linked-.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0015-sim-erc32-Access-memory-subsystem-through-struct-mem.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0016-sim-erc32-Use-readline.h-for-readline-types-and-func.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0017-sim-erc32-Move-local-extern-declarations-into-sis.h.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0019-sim-erc32-Add-support-for-LEON2-processor-emulation.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0020-sim-erc32-Updated-documentation.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0022-Add-watchpoint-support-to-gdb-simulator-interface.patch create mode 100644 tools/4.11/gdb/sparc/7.9/0023-sim-erc32-ELF-loading-could-fail-on-unaligned-sectio.patch (limited to 'tools') diff --git a/tools/4.11/gdb/sparc/7.9/0001-sim-erc32-Disassembly-in-stand-alone-mode-did-not-wo.patch b/tools/4.11/gdb/sparc/7.9/0001-sim-erc32-Disassembly-in-stand-alone-mode-did-not-wo.patch new file mode 100644 index 0000000..e48ff75 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0001-sim-erc32-Disassembly-in-stand-alone-mode-did-not-wo.patch @@ -0,0 +1,61 @@ +From 723f3af6060ee39c89f2b79954a39c7bdee39f99 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 22:40:25 +0200 +Subject: [PATCH 01/23] sim/erc32: Disassembly in stand-alone mode did not + work. + + The API to print_insn_sparc() has changed over the years ... + + * func.c (print_insn_sparc_sis) Add helper function for disassembly. + (disp_ctrl) Use helper function. +--- + sim/erc32/func.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index d001c58..e6744ee 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -759,6 +759,17 @@ disp_regs(sregs,cwp) + } + } + ++static void print_insn_sparc_sis(uint32 addr, struct disassemble_info *info) ++{ ++ unsigned char i[4]; ++ ++ sis_memory_read(addr, i, 4); ++ dinfo.buffer_vma = addr; ++ dinfo.buffer_length = 4; ++ dinfo.buffer = i; ++ print_insn_sparc(addr, info); ++} ++ + static void + disp_ctrl(sregs) + struct pstate *sregs; +@@ -770,10 +781,10 @@ disp_ctrl(sregs) + sregs->psr, sregs->wim, sregs->tbr, sregs->y); + sis_memory_read(sregs->pc, i, 4); + printf("\n pc: %08X = %02X%02X%02X%02X ", sregs->pc,i[0],i[1],i[2],i[3]); +- print_insn_sparc(sregs->pc, &dinfo); ++ print_insn_sparc_sis(sregs->pc, &dinfo); + sis_memory_read(sregs->npc, i, 4); + printf("\n npc: %08X = %02X%02X%02X%02X ",sregs->npc,i[0],i[1],i[2],i[3]); +- print_insn_sparc(sregs->npc, &dinfo); ++ print_insn_sparc_sis(sregs->npc, &dinfo); + if (sregs->err_mode) + printf("\n IU in error mode"); + printf("\n\n"); +@@ -821,7 +832,7 @@ dis_mem(addr, len, info) + for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) { + sis_memory_read(i, data, 4); + printf(" %08x %02x%02x%02x%02x ", i, data[0],data[1],data[2],data[3]); +- print_insn_sparc(i, info); ++ print_insn_sparc_sis(i, info); + if (i >= 0xfffffffc) break; + printf("\n"); + } +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0002-sim-erc32-Corrected-wrong-CPU-implementation-and-ver.patch b/tools/4.11/gdb/sparc/7.9/0002-sim-erc32-Corrected-wrong-CPU-implementation-and-ver.patch new file mode 100644 index 0000000..9a93323 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0002-sim-erc32-Corrected-wrong-CPU-implementation-and-ver.patch @@ -0,0 +1,27 @@ +From 7a40f4ae5b9e3a9078d445976c3557fae69c60e5 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 22:52:37 +0200 +Subject: [PATCH 02/23] sim/erc32: Corrected wrong CPU implementation and + version ID in psr + + * exec.c (init_regs) erc32 has vendor ID 1 and version ID 1 in %psr +--- + sim/erc32/exec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index dc86ba3..07f3586 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -2011,7 +2011,7 @@ init_regs(sregs) + sregs->npc = 4; + sregs->trap = 0; + sregs->psr &= 0x00f03fdf; +- sregs->psr |= 0x080; /* Set supervisor bit */ ++ sregs->psr |= 0x11000080; /* Set supervisor bit */ + sregs->breakpoint = 0; + sregs->annul = 0; + sregs->fpstate = FP_EXE_MODE; +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0003-sim-erc32-Perform-pseudo-init-if-binary-linked-to-no.patch b/tools/4.11/gdb/sparc/7.9/0003-sim-erc32-Perform-pseudo-init-if-binary-linked-to-no.patch new file mode 100644 index 0000000..dca67f4 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0003-sim-erc32-Perform-pseudo-init-if-binary-linked-to-no.patch @@ -0,0 +1,89 @@ +From 78a59b9928b59065cbffca153db9620c0ff80036 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 22:53:56 +0200 +Subject: [PATCH 03/23] sim/erc32: Perform pseudo-init if binary linked to + non-zero address. + +Binaries produced by most erc32 tool-chains do not include +system initialization. sis will detect this and initialize +necessary registers for memory and timer control. + + * erc32.c (mec_read) allow simulator memory size to be read + by application. (boot_init) initialize memory and timers if + start address is not 0. + + * erc32,c (exe_cmd) call boot_init if start address not 0 + * interf.c (run_sim) Likewise +--- + sim/erc32/erc32.c | 24 ++++++++++++++++++++++++ + sim/erc32/func.c | 2 ++ + sim/erc32/interf.c | 1 + + 3 files changed, 27 insertions(+) + +diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c +index 4d4177e..0f3e870 100644 +--- a/sim/erc32/erc32.c ++++ b/sim/erc32/erc32.c +@@ -743,6 +743,14 @@ mec_read(addr, asi, data) + *data = read_uart(addr); + break; + ++ case 0xF4: /* simulator RAM size in bytes */ ++ *data = 4096*1024; ++ break; ++ ++ case 0xF8: /* simulator ROM size in bytes */ ++ *data = 1024*1024; ++ break; ++ + default: + set_sfsr(MEC_ACC, addr, asi, 1); + return (1); +@@ -1887,3 +1895,19 @@ sis_memory_read(addr, data, length) + memcpy(data, mem, length); + return (length); + } ++ ++extern struct pstate sregs; ++ ++void ++boot_init (void) ++{ ++ mec_write(MEC_WCR, 0); /* zero waitstates */ ++ mec_write(MEC_TRAPD, 0); /* turn off watch-dog */ ++ mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */ ++ mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */ ++ sregs.wim = 2; ++ sregs.psr = 0x110010e0; ++ sregs.r[30] = RAM_END; ++ sregs.r[14] = sregs.r[30] - 96*4; ++ mec_mcr |= 1; /* power-down enabled */ ++} +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index e6744ee..6526085 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -468,6 +468,8 @@ exec_cmd(sregs, cmd) + } + sregs->pc = len & ~3; + sregs->npc = sregs->pc + 4; ++ if ((sregs->pc != 0) && (ebase.simtime == 0)) ++ boot_init(); + printf("resuming at 0x%08x\n",sregs->pc); + if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { + stat = run_sim(sregs, VAL(cmd2), 0); +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index 63b3f38..9ac455f 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -78,6 +78,7 @@ run_sim(sregs, icount, dis) + init_stdio(); + sregs->starttime = time(NULL); + irq = 0; ++ if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init(); + while (!sregs->err_mode & (icount > 0)) { + + sregs->fhold = 0; +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch b/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch new file mode 100644 index 0000000..2ca90f6 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0004-sim-erc32-Use-fenv.h-for-host-FPU-access.patch @@ -0,0 +1,241 @@ +From 7002592cb4072303c6a286e1c6479df99ae151b3 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Thu, 19 Feb 2015 22:14:36 +0100 +Subject: [PATCH 04/23] sim/erc32: Use fenv.h for host FPU access + + * float.c (get_accex, clear_accex, set_fsr) Use functions from fenv.h + instead of custom assembly. +--- + sim/erc32/float.c | 191 +++++++++--------------------------------------------- + 1 file changed, 30 insertions(+), 161 deletions(-) + +diff --git a/sim/erc32/float.c b/sim/erc32/float.c +index 598b7cc..40c133b 100644 +--- a/sim/erc32/float.c ++++ b/sim/erc32/float.c +@@ -28,53 +28,38 @@ + * 4. Clear host exception bits + * + * +- * This can also be done using ieee_flags() library routine on sun. + */ + + #include "config.h" + #include "sis.h" ++#include + +-/* Forward declarations */ +- +-extern uint32 _get_sw (void); +-extern uint32 _get_cw (void); +-static void __setfpucw (unsigned short fpu_control); +- +-/* This host dependent routine should return the accrued exceptions */ ++/* This routine should return the accrued exceptions */ + int + get_accex() + { +-#ifdef sparc +- return ((_get_fsr_raw() >> 5) & 0x1F); +-#elif i386 +- uint32 accx; +- +- accx = _get_sw() & 0x3f; +- accx = ((accx & 1) << 4) | ((accx & 2) >> 1) | ((accx & 4) >> 1) | +- (accx & 8) | ((accx & 16) >> 2) | ((accx & 32) >> 5); ++ int fexc, accx; ++ ++ fexc = fetestexcept(FE_ALL_EXCEPT); ++ accx = 0; ++ if (fexc & FE_INEXACT) ++ accx |= 1; ++ if (fexc & FE_DIVBYZERO) ++ accx |= 2; ++ if (fexc & FE_UNDERFLOW) ++ accx |= 4; ++ if (fexc & FE_OVERFLOW) ++ accx |= 8; ++ if (fexc & FE_INVALID) ++ accx |= 0x10; + return(accx); +-#else +- return(0); +-#warning no fpu trap support for this target +-#endif +- + } + + /* How to clear the accrued exceptions */ + void + clear_accex() + { +-#ifdef sparc +- set_fsr((_get_fsr_raw() & ~0x3e0)); +-#elif i386 +- asm("\n" +-".text\n" +-" fnclex\n" +-"\n" +-" "); +-#else +-#warning no fpu trap support for this target +-#endif ++ feclearexcept(FE_ALL_EXCEPT); + } + + /* How to map SPARC FSR onto the host */ +@@ -82,138 +67,22 @@ void + set_fsr(fsr) + uint32 fsr; + { +-#ifdef sparc +- _set_fsr_raw(fsr & ~0x0f800000); +-#elif i386 +- void __setfpucw(unsigned short fpu_control); +- uint32 rawfsr; ++ int fround; + +- fsr >>= 30; +- switch (fsr) { ++ fsr >>= 30; ++ switch (fsr) { + case 0: +- case 2: +- break; +- ++ fround = FE_TONEAREST; ++ break; + case 1: +- fsr = 3; +- break; +- ++ fround = FE_TOWARDZERO; ++ break; ++ case 2: ++ fround = FE_UPWARD; ++ break; + case 3: +- fsr = 1; +- break; ++ fround = FE_DOWNWARD; ++ break; + } +- rawfsr = _get_cw(); +- rawfsr |= (fsr << 10) | 0x3ff; +- __setfpucw(rawfsr); +-#else +-#warning no fpu trap support for this target +-#endif +-} +- +- +-/* Host dependent support functions */ +- +-#ifdef sparc +- +- asm("\n" +-"\n" +-".text\n" +-" .align 4\n" +-" .global __set_fsr_raw,_set_fsr_raw\n" +-"__set_fsr_raw:\n" +-"_set_fsr_raw:\n" +-" save %sp,-104,%sp\n" +-" st %i0,[%fp+68]\n" +-" ld [%fp+68], %fsr\n" +-" mov 0,%i0\n" +-" ret\n" +-" restore\n" +-"\n" +-" .align 4\n" +-" .global __get_fsr_raw\n" +-" .global _get_fsr_raw\n" +-"__get_fsr_raw:\n" +-"_get_fsr_raw:\n" +-" save %sp,-104,%sp\n" +-" st %fsr,[%fp+68]\n" +-" ld [%fp+68], %i0\n" +-" ret\n" +-" restore\n" +-"\n" +-" "); +- +-#elif i386 +- +- asm("\n" +-"\n" +-".text\n" +-" .align 8\n" +-".globl _get_sw,__get_sw\n" +-"__get_sw:\n" +-"_get_sw:\n" +-" pushl %ebp\n" +-" movl %esp,%ebp\n" +-" movl $0,%eax\n" +-" fnstsw %ax\n" +-" movl %ebp,%esp\n" +-" popl %ebp\n" +-" ret\n" +-"\n" +-" .align 8\n" +-".globl _get_cw,__get_cw\n" +-"__get_cw:\n" +-"_get_cw:\n" +-" pushl %ebp\n" +-" movl %esp,%ebp\n" +-" subw $2,%esp\n" +-" fnstcw -2(%ebp)\n" +-" movw -2(%ebp),%eax\n" +-" movl %ebp,%esp\n" +-" popl %ebp\n" +-" ret\n" +-"\n" +-"\n" +-" "); +- +- +-#else +-#warning no fpu trap support for this target +-#endif +- +-#if i386 +-/* #if defined _WIN32 || defined __GO32__ */ +-/* This is so floating exception handling works on NT +- These definitions are from the linux fpu_control.h, which +- doesn't exist on NT. +- +- default to: +- - extended precision +- - rounding to nearest +- - exceptions on overflow, zero divide and NaN +-*/ +-#define _FPU_DEFAULT 0x1372 +-#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */ +- +-static void +-__setfpucw(unsigned short fpu_control) +-{ +- volatile unsigned short cw; +- +- /* If user supplied _fpu_control, use it ! */ +- if (!fpu_control) +- { +- /* use defaults */ +- fpu_control = _FPU_DEFAULT; +- } +- /* Get Control Word */ +- __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); +- +- /* mask in */ +- cw &= _FPU_RESERVED; +- cw = cw | (fpu_control & ~_FPU_RESERVED); +- +- /* set cw */ +- __asm__ volatile ("fldcw %0" :: "m" (cw)); ++ fesetround(fround); + } +-/* #endif */ +-#endif +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0005-sim-erc32-Remove-unused-defines-in-Makefile-and-swit.patch b/tools/4.11/gdb/sparc/7.9/0005-sim-erc32-Remove-unused-defines-in-Makefile-and-swit.patch new file mode 100644 index 0000000..94e71b0 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0005-sim-erc32-Remove-unused-defines-in-Makefile-and-swit.patch @@ -0,0 +1,27 @@ +From 03166e64ac4eb1b6b89e80dd5a54d7193ffd9099 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 22:58:33 +0200 +Subject: [PATCH 05/23] sim/erc32: Remove unused defines in Makefile and switch + off statistics + + * Makefile.in Remove unused defines +--- + sim/erc32/Makefile.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in +index 9c166ce..418e7e4 100644 +--- a/sim/erc32/Makefile.in ++++ b/sim/erc32/Makefile.in +@@ -30,7 +30,7 @@ SIM_EXTRA_CLEAN = clean-sis + # UARTS run at about 115200 baud (simulator time). Add -DFAST_UART to + # CFLAGS if faster (infinite) UART speed is desired. Might affect the + # behaviour of UART interrupt routines ... +-SIM_EXTRA_CFLAGS = -DSTAT -DFAST_UART -DIUREV0 -DMECREV0 ++SIM_EXTRA_CFLAGS = -DFAST_UART + + ## COMMON_POST_CONFIG_FRAG + +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0006-sim-erc32-Fix-incorrect-simulator-performance-report.patch b/tools/4.11/gdb/sparc/7.9/0006-sim-erc32-Fix-incorrect-simulator-performance-report.patch new file mode 100644 index 0000000..4244172 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0006-sim-erc32-Fix-incorrect-simulator-performance-report.patch @@ -0,0 +1,174 @@ +From 623a6089a6202cc9fb40c0a7235fb7398ea3dfbe Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 23:00:05 +0200 +Subject: [PATCH 06/23] sim/erc32: Fix incorrect simulator performance report + + * func.c (reset_stat, show_stat) switch to double in time keeping + (get_time) new function to get system time + * sis.h Likewise + * interf.c (run_sim) use get_time() for system time + * sis.c (run_sim) Likewise +--- + sim/erc32/func.c | 35 ++++++++++++++++++++++++++--------- + sim/erc32/interf.c | 5 ++--- + sim/erc32/sis.c | 5 ++--- + sim/erc32/sis.h | 5 +++-- + 4 files changed, 33 insertions(+), 17 deletions(-) + +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index 6526085..06c00b4 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -613,7 +613,7 @@ void + reset_stat(sregs) + struct pstate *sregs; + { +- sregs->tottime = 0; ++ sregs->tottime = 0.0; + sregs->pwdtime = 0; + sregs->ninst = 0; + sregs->fholdt = 0; +@@ -632,9 +632,10 @@ show_stat(sregs) + struct pstate *sregs; + { + uint32 iinst; +- uint32 stime, tottime; ++ uint32 stime; + +- if (sregs->tottime == 0) tottime = 1; else tottime = sregs->tottime; ++ if (sregs->tottime == 0.0) ++ sregs->tottime += 1E-6; + stime = ebase.simtime - sregs->simstart; /* Total simulated time */ + #ifdef STAT + +@@ -669,12 +670,15 @@ show_stat(sregs) + sregs->freq * (float) (sregs->ninst - sregs->finst) / + (float) (stime - sregs->pwdtime), + sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime)); +- printf(" Simulated ERC32 time : %5.2f ms\n", (float) (ebase.simtime - sregs->simstart) / 1000.0 / sregs->freq); +- printf(" Processor utilisation : %5.2f %%\n", 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime))); +- printf(" Real-time / simulator-time : 1/%.2f \n", +- ((float) sregs->tottime) / ((float) (stime) / (sregs->freq * 1.0E6))); +- printf(" Simulator performance : %d KIPS\n",sregs->ninst/tottime/1000); +- printf(" Used time (sys + user) : %3d s\n\n", sregs->tottime); ++ printf(" Simulated ERC32 time : %.2f s\n", ++ (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq); ++ printf(" Processor utilisation : %.2f %%\n", ++ 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime))); ++ printf(" Real-time performance : %.2f %%\n", ++ 100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6)))); ++ printf(" Simulator performance : %.2f MIPS\n", ++ (double)(sregs->ninst) / sregs->tottime / 1E6); ++ printf(" Used time (sys + user) : %.2f s\n\n", sregs->tottime); + } + + +@@ -1128,3 +1132,16 @@ bfd_load(fname) + + return(bfd_get_start_address (pbfd)); + } ++ ++ ++double get_time (void) ++{ ++ double usec; ++ ++ struct timeval tm; ++ ++ gettimeofday (&tm, NULL); ++ usec = ((double) tm.tv_sec) * 1E6 + ((double) tm.tv_usec); ++ return (usec / 1E6); ++ ++} +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index 9ac455f..38a2a0d 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -24,7 +24,6 @@ + #include + #include + #include +-#include + #include + #include "sis.h" + #include "libiberty.h" +@@ -76,7 +75,7 @@ run_sim(sregs, icount, dis) + (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n", + sregs->pc); + init_stdio(); +- sregs->starttime = time(NULL); ++ sregs->starttime = get_time(); + irq = 0; + if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init(); + while (!sregs->err_mode & (icount > 0)) { +@@ -142,7 +141,7 @@ run_sim(sregs, icount, dis) + } + } + sim_halt(); +- sregs->tottime += time(NULL) - sregs->starttime; ++ sregs->tottime += get_time() - sregs->starttime; + restore_stdio(); + clearerr(stdin); + if (sregs->err_mode) +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index 89e6f02..f2aed78 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -26,7 +26,6 @@ + #include + #endif + #include +-#include + #include + #include "sis.h" + #include +@@ -86,7 +85,7 @@ run_sim(sregs, icount, dis) + { + int irq, mexc, deb, asi; + +- sregs->starttime = time(NULL); ++ sregs->starttime = get_time(); + init_stdio(); + if (sregs->err_mode) icount = 0; + deb = dis || sregs->histlen || sregs->bptnum; +@@ -146,7 +145,7 @@ run_sim(sregs, icount, dis) + if (sregs->tlimit <= ebase.simtime) sregs->tlimit = -1; + } + } +- sregs->tottime += time(NULL) - sregs->starttime; ++ sregs->tottime += get_time() - sregs->starttime; + restore_stdio(); + if (sregs->err_mode) + return (ERROR); +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index f49d45d..dc02c65 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -110,14 +110,14 @@ struct pstate { + float32 freq; /* Simulated processor frequency */ + + +- uint64 tottime; ++ double tottime; + uint64 ninst; + uint64 fholdt; + uint64 holdt; + uint64 icntt; + uint64 finst; + uint64 simstart; +- uint64 starttime; ++ double starttime; + uint64 tlimit; /* Simulation time limit */ + uint64 pwdtime; /* Cycles in power-down mode */ + uint64 nstore; /* Number of load instructions */ +@@ -198,6 +198,7 @@ extern void reset_all (void); + extern void sys_reset (void); + extern void sys_halt (void); + extern int bfd_load (char *fname); ++extern double get_time (void); + + /* exec.c */ + extern int dispatch_instruction (struct pstate *sregs); +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0007-sim-erc32-File-loading-via-command-line-did-not-work.patch b/tools/4.11/gdb/sparc/7.9/0007-sim-erc32-File-loading-via-command-line-did-not-work.patch new file mode 100644 index 0000000..e6b4364 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0007-sim-erc32-File-loading-via-command-line-did-not-work.patch @@ -0,0 +1,43 @@ +From bdf71b87a2aff21de63accd86f8814b576f8a766 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 23:00:43 +0200 +Subject: [PATCH 07/23] sim/erc32: File loading via command line did not work + + * sis.c (main) load binary file from argv parameters +--- + sim/erc32/sis.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index f2aed78..d7fa245 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -171,6 +171,7 @@ main(argc, argv) + char *cmdq[HIST_LEN]; + int cmdi = 0; + int i; ++ int lfile = 0; + + cfile = 0; + for (i = 0; i < 64; i++) +@@ -219,7 +220,7 @@ main(argc, argv) + exit(1); + } + } else { +- last_load_addr = bfd_load(argv[stat]); ++ lfile = stat; + } + stat++; + } +@@ -241,6 +242,8 @@ main(argc, argv) + reset_all(); + init_bpt(&sregs); + init_sim(); ++ if (lfile) ++ last_load_addr = bfd_load(argv[lfile]); + #ifdef STAT + reset_stat(&sregs); + #endif +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0008-sim-erc32-Added-v-command-line-switch-for-verbose-ou.patch b/tools/4.11/gdb/sparc/7.9/0008-sim-erc32-Added-v-command-line-switch-for-verbose-ou.patch new file mode 100644 index 0000000..92e6cdb --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0008-sim-erc32-Added-v-command-line-switch-for-verbose-ou.patch @@ -0,0 +1,123 @@ +From f13f6b1731a63b0b79df7232f675f3f8d44be074 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 23:01:13 +0200 +Subject: [PATCH 08/23] sim/erc32: Added -v command line switch for verbose + output + + * help.c (usage) update usage help print-out + + * sis.c (run_sim) increase debug level with -v. Also print + simulation time in long long format. +--- + sim/erc32/func.c | 5 +++-- + sim/erc32/help.c | 2 +- + sim/erc32/sis.c | 9 ++++++--- + sim/erc32/sis.h | 5 +++++ + 4 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index 06c00b4..f1d5bd7 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -29,6 +29,7 @@ + #include "end.h" + #include + #include "sim-config.h" ++#include + + + #define VAL(x) strtoul(x,(char **)NULL,0) +@@ -643,8 +644,8 @@ show_stat(sregs) + sregs->nbranch; + #endif + +- printf("\n Cycles : %9d\n\r", ebase.simtime - sregs->simstart); +- printf(" Instructions : %9d\n", sregs->ninst); ++ printf("\n Cycles : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart); ++ printf(" Instructions : %9" PRIu64 "\n", sregs->ninst); + + #ifdef STAT + printf(" integer : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst); +diff --git a/sim/erc32/help.c b/sim/erc32/help.c +index 21c2a77..9813bda 100644 +--- a/sim/erc32/help.c ++++ b/sim/erc32/help.c +@@ -7,8 +7,8 @@ usage() + { + + printf("usage: sis [-uart1 uart_device1] [-uart2 uart_device2]\n"); ++ printf("[-sparclite] [-dumbio] [-v] \n"); + printf("[-nfp] [-freq frequency] [-c batch_file] [files]\n"); +- printf("[-sparclite] [-dumbio]\n"); + } + + void +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index d7fa245..7c18c1e 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -30,6 +30,7 @@ + #include "sis.h" + #include + #include "sim-config.h" ++#include + + #define VAL(x) strtol(x,(char **)NULL,0) + +@@ -122,7 +123,7 @@ run_sim(sregs, icount, dis) + sregs->histind = 0; + } + if (dis) { +- printf(" %8u ", ebase.simtime); ++ printf(" %8" PRIu64 " ", ebase.simtime); + dis_mem(sregs->pc, 1, &dinfo); + } + } +@@ -214,6 +215,8 @@ main(argc, argv) + #endif + } else if (strcmp(argv[stat], "-dumbio") == 0) { + dumbio = 1; ++ } else if (strcmp(argv[stat], "-v") == 0) { ++ sis_verbose += 1; + } else { + printf("unknown option %s\n", argv[stat]); + usage(); +@@ -280,7 +283,7 @@ main(argc, argv) + case CTRL_C: + printf("\b\bInterrupt!\n"); + case TIME_OUT: +- printf(" Stopped at time %d (%.3f ms)\n", ebase.simtime, ++ printf(" Stopped at time %" PRIu64 " (%.3f ms)\n", ebase.simtime, + ((double) ebase.simtime / (double) sregs.freq) / 1000.0); + break; + case BPT_HIT: +@@ -290,7 +293,7 @@ main(argc, argv) + case ERROR: + printf("IU in error mode (%d)\n", sregs.trap); + stat = 0; +- printf(" %8d ", ebase.simtime); ++ printf(" %8" PRIu64 " ", ebase.simtime); + dis_mem(sregs.pc, 1, &dinfo); + break; + default: +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index dc02c65..1ff6ced 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -52,8 +52,13 @@ typedef float float32; /* 32-bit float */ + typedef double float64; /* 64-bit float */ + + /* FIXME: what about host compilers that don't support 64-bit ints? */ ++#ifdef __LP64__ ++typedef unsigned long uint64; /* 64-bit unsigned int */ ++typedef long int64; /* 64-bit signed int */ ++#else + typedef unsigned long long uint64; /* 64-bit unsigned int */ + typedef long long int64; /* 64-bit signed int */ ++#endif + + #define UINT64_MAX 18446744073709551615ULL + +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0009-sim-erc32-Removed-type-mismatch-compiler-warnings.patch b/tools/4.11/gdb/sparc/7.9/0009-sim-erc32-Removed-type-mismatch-compiler-warnings.patch new file mode 100644 index 0000000..a10b8b7 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0009-sim-erc32-Removed-type-mismatch-compiler-warnings.patch @@ -0,0 +1,66 @@ +From b65439074a4f4b2b6f5e5756124de49d4821656b Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 23:02:01 +0200 +Subject: [PATCH 09/23] sim/erc32: Removed type mismatch compiler warnings + + * func.c (batch, exec_cmd) save return value to avoid warnings. + (batch) replace fgets() with getline(). +--- + sim/erc32/func.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index f1d5bd7..a715f0f 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -81,20 +81,23 @@ batch(sregs, fname) + char *fname; + { + FILE *fp; +- char lbuf[1024]; ++ char *lbuf = NULL; ++ size_t len = 0; ++ ssize_t tmp; + + if ((fp = fopen(fname, "r")) == NULL) { + fprintf(stderr, "couldn't open batch file %s\n", fname); + return (0); + } + while (!feof(fp)) { +- lbuf[0] = 0; +- fgets(lbuf, 1023, fp); +- if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n')) ++ tmp = getline(&lbuf, &len, fp); ++ if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n')) { + lbuf[strlen(lbuf) - 1] = 0; +- printf("sis> %s\n", lbuf); +- exec_cmd(sregs, lbuf); ++ printf("sis> %s\n", lbuf); ++ exec_cmd(sregs, lbuf); ++ } + } ++ if (lbuf) free(lbuf); + fclose(fp); + return (1); + } +@@ -383,7 +386,7 @@ exec_cmd(sregs, cmd) + { + char *cmd1, *cmd2; + int32 stat; +- uint32 len, i, clen, j; ++ uint32 len, i, clen, j, tmp; + static uint32 daddr = 0; + char *cmdsave; + +@@ -555,7 +558,7 @@ exec_cmd(sregs, cmd) + sim_halt(); + } else if (strncmp(cmd1, "shell", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { +- system(&cmdsave[clen]); ++ tmp = system(&cmdsave[clen]); + } + } else if (strncmp(cmd1, "step", clen) == 0) { + stat = run_sim(sregs, 1, 1); +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch b/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch new file mode 100644 index 0000000..04f5e90 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch @@ -0,0 +1,564 @@ +From 335799e56181cd0d1ff8128b20b01835e344ee43 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 23:39:33 +0200 +Subject: [PATCH 10/23] sim/erc32: Switched emulated memory to host endian + order. + + Change data ordering in emulated memory from target order (big endian) + to host order. Improves performance and simplifies most memory + operations. Requires some byte twisting during stores on little + endian hosts (intel). + + * erc32.c (fetch_bytes) Remove. (store_bytes) Remove byte twisting. + (memory_read) Access memory directly. (extract_short, + extract_short_signed, extract_byte, extract_byte_signed) New + function for for sub-word LD instructions. + + * func.c (disp_ctrl, dis_mem) Ajust print-out to new data endian. + + * interf.c (sim_open) Convert endian when gdb writes to memory. +--- + sim/erc32/erc32.c | 167 ++++++++++++----------------------------------------- + sim/erc32/exec.c | 58 ++++++++++++++++--- + sim/erc32/func.c | 33 +++++++---- + sim/erc32/interf.c | 29 ++++++++++ + sim/erc32/sis.c | 4 ++ + 5 files changed, 142 insertions(+), 149 deletions(-) + +diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c +index 0f3e870..7c80e13 100644 +--- a/sim/erc32/erc32.c ++++ b/sim/erc32/erc32.c +@@ -297,11 +297,8 @@ static void gpt_reload_set (uint32 val); + static void timer_ctrl (uint32 val); + static unsigned char * + get_mem_ptr (uint32 addr, uint32 size); +- +-static void fetch_bytes (int asi, unsigned char *mem, +- uint32 *data, int sz); +- +-static void store_bytes (unsigned char *mem, uint32 *data, int sz); ++static void store_bytes (unsigned char *mem, uint32 waddr, ++ uint32 *data, int sz, int32 *ws); + + extern int ext_irl; + +@@ -1525,123 +1522,44 @@ timer_ctrl(val) + gpt_start(); + } + +- +-/* Retrieve data from target memory. MEM points to location from which +- to read the data; DATA points to words where retrieved data will be +- stored in host byte order. SZ contains log(2) of the number of bytes +- to retrieve, and can be 0 (1 byte), 1 (one half-word), 2 (one word), +- or 3 (two words). */ ++/* Store data in host byte order. MEM points to the beginning of the ++ emulated memory; WADDR contains the index the emulated memory, ++ DATA points to words in host byte order to be stored. SZ contains log(2) ++ of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word), ++ 2 (one word), or 3 (two words); WS should return the number of wait-states. */ + + static void +-fetch_bytes (asi, mem, data, sz) +- int asi; ++store_bytes (mem, waddr, data, sz, ws) + unsigned char *mem; ++ uint32 waddr; + uint32 *data; +- int sz; ++ int32 sz; ++ int32 *ws; + { +- if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN +- || asi == 8 || asi == 9) { +- switch (sz) { +- case 3: +- data[1] = (((uint32) mem[7]) & 0xff) | +- ((((uint32) mem[6]) & 0xff) << 8) | +- ((((uint32) mem[5]) & 0xff) << 16) | +- ((((uint32) mem[4]) & 0xff) << 24); +- /* Fall through to 2 */ +- case 2: +- data[0] = (((uint32) mem[3]) & 0xff) | +- ((((uint32) mem[2]) & 0xff) << 8) | +- ((((uint32) mem[1]) & 0xff) << 16) | +- ((((uint32) mem[0]) & 0xff) << 24); +- break; +- case 1: +- data[0] = (((uint32) mem[1]) & 0xff) | +- ((((uint32) mem[0]) & 0xff) << 8); +- break; ++ switch (sz) { + case 0: +- data[0] = mem[0] & 0xff; +- break; +- +- } +- } else { +- switch (sz) { +- case 3: +- data[1] = ((((uint32) mem[7]) & 0xff) << 24) | +- ((((uint32) mem[6]) & 0xff) << 16) | +- ((((uint32) mem[5]) & 0xff) << 8) | +- (((uint32) mem[4]) & 0xff); +- /* Fall through to 4 */ +- case 2: +- data[0] = ((((uint32) mem[3]) & 0xff) << 24) | +- ((((uint32) mem[2]) & 0xff) << 16) | +- ((((uint32) mem[1]) & 0xff) << 8) | +- (((uint32) mem[0]) & 0xff); ++#ifdef HOST_LITTLE_ENDIAN ++ waddr ^= 3; ++#endif ++ mem[waddr] = *data & 0x0ff; ++ *ws = mem_ramw_ws + 3; + break; + case 1: +- data[0] = ((((uint32) mem[1]) & 0xff) << 8) | +- (((uint32) mem[0]) & 0xff); +- break; +- case 0: +- data[0] = mem[0] & 0xff; ++#ifdef HOST_LITTLE_ENDIAN ++ waddr ^= 2; ++#endif ++ *((unsigned short *) &(mem[waddr])) = *data & 0x0ffff; ++ *ws = mem_ramw_ws + 3; + break; +- } +- } +-} +- +- +-/* Store data in target byte order. MEM points to location to store data; +- DATA points to words in host byte order to be stored. SZ contains log(2) +- of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word), +- 2 (one word), or 3 (two words). */ +- +-static void +-store_bytes (mem, data, sz) +- unsigned char *mem; +- uint32 *data; +- int sz; +-{ +- if (CURRENT_TARGET_BYTE_ORDER == LITTLE_ENDIAN) { +- switch (sz) { +- case 3: +- mem[7] = (data[1] >> 24) & 0xff; +- mem[6] = (data[1] >> 16) & 0xff; +- mem[5] = (data[1] >> 8) & 0xff; +- mem[4] = data[1] & 0xff; +- /* Fall through to 2 */ + case 2: +- mem[3] = (data[0] >> 24) & 0xff; +- mem[2] = (data[0] >> 16) & 0xff; +- /* Fall through to 1 */ +- case 1: +- mem[1] = (data[0] >> 8) & 0xff; +- /* Fall through to 0 */ +- case 0: +- mem[0] = data[0] & 0xff; ++ *((uint32 *) &(mem[waddr])) = *data; ++ *ws = mem_ramw_ws; + break; +- } +- } else { +- switch (sz) { + case 3: +- mem[7] = data[1] & 0xff; +- mem[6] = (data[1] >> 8) & 0xff; +- mem[5] = (data[1] >> 16) & 0xff; +- mem[4] = (data[1] >> 24) & 0xff; +- /* Fall through to 2 */ +- case 2: +- mem[3] = data[0] & 0xff; +- mem[2] = (data[0] >> 8) & 0xff; +- mem[1] = (data[0] >> 16) & 0xff; +- mem[0] = (data[0] >> 24) & 0xff; +- break; +- case 1: +- mem[1] = data[0] & 0xff; +- mem[0] = (data[0] >> 8) & 0xff; +- break; +- case 0: +- mem[0] = data[0] & 0xff; ++ *((uint32 *) &(mem[waddr])) = data[0]; ++ *((uint32 *) &(mem[waddr + 4])) = data[1]; ++ *ws = 2 * mem_ramw_ws + STD_WS; + break; +- +- } + } + } + +@@ -1671,7 +1589,7 @@ memory_read(asi, addr, data, sz, ws) + #endif + + if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) { +- fetch_bytes (asi, &ramb[addr & mem_rammask], data, sz); ++ *data = *((uint32 *) & (ramb[addr & mem_rammask & ~3])); + *ws = mem_ramr_ws; + return (0); + } else if ((addr >= MEC_START) && (addr < MEC_END)) { +@@ -1689,7 +1607,7 @@ memory_read(asi, addr, data, sz, ws) + } else if (era) { + if ((addr < 0x100000) || + ((addr>= 0x80000000) && (addr < 0x80100000))) { +- fetch_bytes (asi, &romb[addr & ROM_MASK], data, sz); ++ *data = *((uint32 *) & (romb[addr & ROM_MASK & ~3])); + *ws = 4; + return (0); + } else if ((addr >= 0x10000000) && +@@ -1700,13 +1618,13 @@ memory_read(asi, addr, data, sz, ws) + } + + } else if (addr < mem_romsz) { +- fetch_bytes (asi, &romb[addr], data, sz); ++ *data = *((uint32 *) & (romb[addr & ~3])); + *ws = mem_romr_ws; + return (0); + + #else + } else if (addr < mem_romsz) { +- fetch_bytes (asi, &romb[addr], data, sz); ++ *data = *((uint32 *) & (romb[addr & ~3])); + *ws = mem_romr_ws; + return (0); + #endif +@@ -1769,21 +1687,10 @@ memory_write(asi, addr, data, sz, ws) + } + } + +- store_bytes (&ramb[addr & mem_rammask], data, sz); +- +- switch (sz) { +- case 0: +- case 1: +- *ws = mem_ramw_ws + 3; +- break; +- case 2: +- *ws = mem_ramw_ws; +- break; +- case 3: +- *ws = 2 * mem_ramw_ws + STD_WS; +- break; +- } ++ waddr = addr & mem_rammask; ++ store_bytes (ramb, waddr, data, sz, ws); + return (0); ++ + } else if ((addr >= MEC_START) && (addr < MEC_END)) { + if ((sz != 2) || (asi != 0xb)) { + set_sfsr(MEC_ACC, addr, asi, 0); +@@ -1806,7 +1713,7 @@ memory_write(asi, addr, data, sz, ws) + ((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) { + addr &= ROM_MASK; + *ws = sz == 3 ? 8 : 4; +- store_bytes (&romb[addr], data, sz); ++ store_bytes (romb, addr, data, sz, ws); + return (0); + } else if ((addr >= 0x10000000) && + (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) && +@@ -1822,7 +1729,7 @@ memory_write(asi, addr, data, sz, ws) + *ws = mem_romw_ws + 1; + if (sz == 3) + *ws += mem_romw_ws + STD_WS; +- store_bytes (&romb[addr], data, sz); ++ store_bytes (romb, addr, data, sz, ws); + return (0); + + #else +@@ -1833,7 +1740,7 @@ memory_write(asi, addr, data, sz, ws) + *ws = mem_romw_ws + 1; + if (sz == 3) + *ws += mem_romw_ws + STD_WS; +- store_bytes (&romb[addr], data, sz); ++ store_bytes (romb, addr, data, sz, ws); + return (0); + + #endif +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index 07f3586..e80e02a 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -371,6 +371,36 @@ div64 (uint32 n1_hi, uint32 n1_low, uint32 n2, uint32 *result, int msigned) + } + + ++static int ++extract_short(uint32 data, uint32 address) ++{ ++ return((data>>((2 - (address & 2))*8)) & 0xffff); ++} ++ ++static int ++extract_short_signed(uint32 data, uint32 address) ++{ ++ uint32 tmp; ++ tmp = ((data>>((2 - (address & 2))*8)) & 0xffff); ++ if (tmp & 0x8000) tmp |= 0xffff0000; ++ return(tmp); ++} ++ ++static int ++extract_byte(uint32 data, uint32 address) ++{ ++ return((data>>((3 - (address & 3))*8)) & 0xff); ++} ++ ++static int ++extract_byte_signed(uint32 data, uint32 address) ++{ ++ uint32 tmp; ++ tmp = ((data>>((3 - (address & 3))*8)) & 0xff); ++ if (tmp & 0x80) tmp |= 0xffffff00; ++ return(tmp); ++} ++ + int + dispatch_instruction(sregs) + struct pstate *sregs; +@@ -1078,7 +1108,8 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_PRIVI; + break; + } +- sregs->psr = (rs1 ^ operand2) & 0x00f03fff; ++ sregs->psr = (sregs->psr & 0xff000000) | ++ (rs1 ^ operand2) & 0x00f03fff; + break; + case WRWIM: + if (!(sregs->psr & PSR_S)) { +@@ -1214,8 +1245,10 @@ dispatch_instruction(sregs) + else + rdd = &(sregs->g[rd]); + } +- mexc = memory_read(asi, address, ddata, 3, &ws); +- sregs->hold += ws * 2; ++ mexc = memory_read(asi, address, ddata, 2, &ws); ++ sregs->hold += ws; ++ mexc |= memory_read(asi, address+4, &ddata[1], 2, &ws); ++ sregs->hold += ws; + sregs->icnt = T_LDD; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1253,6 +1286,7 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_DEXC; + break; + } ++ data = extract_byte(data, address); + *rdd = data; + data = 0x0ff; + mexc = memory_write(asi, address, &data, 0, &ws); +@@ -1275,8 +1309,10 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_DEXC; + break; + } +- if ((op3 == LDSB) && (data & 0x80)) +- data |= 0xffffff00; ++ if (op3 == LDSB) ++ data = extract_byte_signed(data, address); ++ else ++ data = extract_byte(data, address); + *rdd = data; + break; + case LDSHA: +@@ -1294,8 +1330,10 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_DEXC; + break; + } +- if ((op3 == LDSH) && (data & 0x8000)) +- data |= 0xffff0000; ++ if (op3 == LDSH) ++ data = extract_short_signed(data, address); ++ else ++ data = extract_short(data, address); + *rdd = data; + break; + case LDF: +@@ -1338,8 +1376,10 @@ dispatch_instruction(sregs) + ((sregs->frs2 >> 1) == (rd >> 1))) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = memory_read(asi, address, ddata, 3, &ws); +- sregs->hold += ws * 2; ++ mexc = memory_read(asi, address, ddata, 2, &ws); ++ sregs->hold += ws; ++ mexc |= memory_read(asi, address+4, &ddata[1], 2, &ws); ++ sregs->hold += ws; + sregs->icnt = T_LDD; + if (mexc) { + sregs->trap = TRAP_DEXC; +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index a715f0f..bcccf6d 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -785,15 +785,15 @@ disp_ctrl(sregs) + struct pstate *sregs; + { + +- unsigned char i[4]; ++ uint32 i; + + printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n", + sregs->psr, sregs->wim, sregs->tbr, sregs->y); +- sis_memory_read(sregs->pc, i, 4); +- printf("\n pc: %08X = %02X%02X%02X%02X ", sregs->pc,i[0],i[1],i[2],i[3]); ++ sis_memory_read(sregs->pc, (char *) &i, 4); ++ printf("\n pc: %08X = %08X ", sregs->pc, i); + print_insn_sparc_sis(sregs->pc, &dinfo); +- sis_memory_read(sregs->npc, i, 4); +- printf("\n npc: %08X = %02X%02X%02X%02X ",sregs->npc,i[0],i[1],i[2],i[3]); ++ sis_memory_read(sregs->npc, (char *) &i, 4); ++ printf("\n npc: %08X = %08X ", sregs->npc, i); + print_insn_sparc_sis(sregs->npc, &dinfo); + if (sregs->err_mode) + printf("\n IU in error mode"); +@@ -808,21 +808,28 @@ disp_mem(addr, len) + + uint32 i; + unsigned char data[4]; ++ uint32 *wdata = (uint32 *) data; + uint32 mem[4], j; + char *p; ++ int end; + ++#ifdef HOST_LITTLE_ENDIAN ++ end = 3; ++#else ++ end = 0; ++#endif + for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) { + printf("\n %8X ", i); + for (j = 0; j < 4; j++) { + sis_memory_read((i + (j * 4)), data, 4); +- printf("%02x%02x%02x%02x ", data[0],data[1],data[2],data[3]); ++ printf("%08x ", *wdata); + mem[j] = *((int *) &data); + } + printf(" "); + p = (char *) mem; + for (j = 0; j < 16; j++) { +- if (isprint(p[j])) +- putchar(p[j]); ++ if (isprint(p[j^end])) ++ putchar(p[j^end]); + else + putchar('.'); + } +@@ -838,10 +845,11 @@ dis_mem(addr, len, info) + { + uint32 i; + unsigned char data[4]; ++ uint32 *wdata = (uint32 *) data; + + for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) { + sis_memory_read(i, data, 4); +- printf(" %08x %02x%02x%02x%02x ", i, data[0],data[1],data[2],data[3]); ++ printf(" %08x %08x ", i, *wdata); + print_insn_sparc_sis(i, info); + if (i >= 0xfffffffc) break; + printf("\n"); +@@ -1040,6 +1048,7 @@ bfd_load(fname) + asection *section; + bfd *pbfd; + const bfd_arch_info_type *arch; ++ int i; + + pbfd = bfd_openr(fname, 0); + +@@ -1113,13 +1122,17 @@ bfd_load(fname) + fptr = 0; + + while (section_size > 0) { +- char buffer[1024]; + int count; ++ char buffer[1024]; ++ uint32 *wbuffer = (uint32 *) buffer; + + count = min(section_size, 1024); + + bfd_get_section_contents(pbfd, section, buffer, fptr, count); + ++#ifdef HOST_LITTLE_ENDIAN ++ for (i=0;i= 4) ++ for (i=0; i= 4) ++ for (i=0; i +Date: Wed, 18 Feb 2015 16:50:55 +0100 +Subject: [PATCH 11/23] sim/erc32: use SIM_AC_OPTION_HOSTENDIAN to probe for + host endianess + + * Makefile.in (end, end.h) Remove target rules. + * end.c Remove unnecessary local checks (end.c) + * configure, config.in : Regenerate. + * configure.ac : Use SIM_AC_OPTION_HOSTENDIAN + * erc32.c : Remove dependecy on end.h + * exec.c : Remove dependecy on end.h. Use HOST_LITTLE_ENDIAN. + * func.c : As above. + * sis.c : As above. +--- + sim/erc32/Makefile.in | 18 +--- + sim/erc32/config.in | 15 +++ + sim/erc32/configure | 260 ++++++++++++++++++++++++++++++++++++++++++++++++- + sim/erc32/configure.ac | 1 + + sim/erc32/end.c | 27 ----- + sim/erc32/erc32.c | 1 - + sim/erc32/exec.c | 7 +- + sim/erc32/func.c | 3 +- + sim/erc32/sis.h | 9 +- + 9 files changed, 284 insertions(+), 57 deletions(-) + delete mode 100644 sim/erc32/end.c + +diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in +index 418e7e4..e0860a0 100644 +--- a/sim/erc32/Makefile.in ++++ b/sim/erc32/Makefile.in +@@ -41,21 +41,13 @@ sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) -o sis \ + sis.o $(SIS_OFILES) $(COMMON_OBJS) $(EXTRA_LIBS) + +-# FIXME: This computes the build host's endianness, doesn't it? +-# There is AC_C_BIGENDIAN but it doesn't handle float endianness. +-# [Are int/float endians every different on a sparc?] +-end: $(srcdir)/end.c +- $(CC_FOR_BUILD) -I. $(srcdir)/end.c -o end +-end.h: end +- ./end > end.h +- + # Copy the files into directories where they will be run. + install-sis: installdirs + n=`echo sis | sed '$(program_transform_name)'`; \ + $(INSTALL_PROGRAM) sis$(EXEEXT) $(DESTDIR)$(bindir)/$$n$(EXEEXT) + + clean-sis: +- rm -f sis end end.h ++ rm -f sis + + configure: + @echo "Rebuilding configure..." +@@ -64,11 +56,3 @@ configure: + else true ; fi ; \ + (cd $${srcdir}; autoconf --localdir=../common) + +-# Circumvent Sun Make bug with VPATH. +-erc32.o: erc32.c sis.h end.h +-exec.o: exec.c sis.h end.h +-float.o: float.c sis.h end.h +-func.o: func.c sis.h end.h +-help.o: help.c sis.h end.h +-interf.o: interf.c sis.h end.h +-sis.o: sis.c sis.h end.h +diff --git a/sim/erc32/config.in b/sim/erc32/config.in +index 5fed8c1..b367e14 100644 +--- a/sim/erc32/config.in ++++ b/sim/erc32/config.in +@@ -1,5 +1,8 @@ + /* config.in. Generated from configure.ac by autoheader. */ + ++/* Define if building universal (internal helper macro) */ ++#undef AC_APPLE_UNIVERSAL_BUILD ++ + /* Define to 1 if translation of program messages to the user's native + language is requested. */ + #undef ENABLE_NLS +@@ -135,6 +138,18 @@ + #endif + + ++/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most ++ significant byte first (like Motorola and SPARC, unlike Intel). */ ++#if defined AC_APPLE_UNIVERSAL_BUILD ++# if defined __BIG_ENDIAN__ ++# define WORDS_BIGENDIAN 1 ++# endif ++#else ++# ifndef WORDS_BIGENDIAN ++# undef WORDS_BIGENDIAN ++# endif ++#endif ++ + /* Define to 1 if on MINIX. */ + #undef _MINIX + +diff --git a/sim/erc32/configure b/sim/erc32/configure +index ba43717..cbdcea5 100755 +--- a/sim/erc32/configure ++++ b/sim/erc32/configure +@@ -761,6 +761,7 @@ enable_sim_trace + enable_sim_profile + with_pkgversion + with_bugurl ++enable_sim_hostendian + ' + ac_precious_vars='build_alias + host_alias +@@ -1403,6 +1404,7 @@ Optional Features: + --enable-sim-stdio Specify whether to use stdio for console input/output. + --enable-sim-trace=opts Enable tracing flags + --enable-sim-profile=opts Enable profiling flags ++ --enable-sim-hostendian=end Specify host byte endian orientation. + + Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +@@ -8121,7 +8123,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; +- 10.[012]*) ++ 10.[012][,.]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; +@@ -10144,7 +10146,7 @@ _LT_EOF + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then +- tmp_addflag= ++ tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler +@@ -12354,7 +12356,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12357 "configure" ++#line 12359 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -12460,7 +12462,7 @@ else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +-#line 12463 "configure" ++#line 12465 "configure" + #include "confdefs.h" + + #if HAVE_DLFCN_H +@@ -13111,6 +13113,255 @@ fi + fi + + ++# Check whether --enable-sim-hostendian was given. ++if test "${enable_sim_hostendian+set}" = set; then : ++ enableval=$enable_sim_hostendian; case "${enableval}" in ++ no) sim_hostendian="-DWITH_HOST_BYTE_ORDER=0";; ++ b*|B*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN";; ++ l*|L*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN";; ++ *) as_fn_error "\"Unknown value $enableval for --enable-sim-hostendian\"" "$LINENO" 5; sim_hostendian="";; ++esac ++if test x"$silent" != x"yes" && test x"$sim_hostendian" != x""; then ++ echo "Setting hostendian flags = $sim_hostendian" 6>&1 ++fi ++else ++ ++if test "x$cross_compiling" = "xno"; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 ++$as_echo_n "checking whether byte ordering is bigendian... " >&6; } ++if test "${ac_cv_c_bigendian+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_cv_c_bigendian=unknown ++ # See if we're dealing with a universal compiler. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#ifndef __APPLE_CC__ ++ not a universal capable compiler ++ #endif ++ typedef int dummy; ++ ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ++ # Check for potential -arch flags. It is not universal unless ++ # there are at least two -arch flags with different values. ++ ac_arch= ++ ac_prev= ++ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do ++ if test -n "$ac_prev"; then ++ case $ac_word in ++ i?86 | x86_64 | ppc | ppc64) ++ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ++ ac_arch=$ac_word ++ else ++ ac_cv_c_bigendian=universal ++ break ++ fi ++ ;; ++ esac ++ ac_prev= ++ elif test "x$ac_word" = "x-arch"; then ++ ac_prev=arch ++ fi ++ done ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ if test $ac_cv_c_bigendian = unknown; then ++ # See if sys/param.h defines the BYTE_ORDER macro. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ #include ++ ++int ++main () ++{ ++#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ ++ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ ++ && LITTLE_ENDIAN) ++ bogus endian macros ++ #endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ # It does; now see whether it defined to BIG_ENDIAN or not. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ #include ++ ++int ++main () ++{ ++#if BYTE_ORDER != BIG_ENDIAN ++ not big endian ++ #endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_c_bigendian=yes ++else ++ ac_cv_c_bigendian=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ fi ++ if test $ac_cv_c_bigendian = unknown; then ++ # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ ++int ++main () ++{ ++#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) ++ bogus endian macros ++ #endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ # It does; now see whether it defined to _BIG_ENDIAN or not. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++ ++int ++main () ++{ ++#ifndef _BIG_ENDIAN ++ not big endian ++ #endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ ac_cv_c_bigendian=yes ++else ++ ac_cv_c_bigendian=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ fi ++ if test $ac_cv_c_bigendian = unknown; then ++ # Compile a test program. ++ if test "$cross_compiling" = yes; then : ++ # Try to guess by grepping values from an object file. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++short int ascii_mm[] = ++ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; ++ short int ascii_ii[] = ++ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; ++ int use_ascii (int i) { ++ return ascii_mm[i] + ascii_ii[i]; ++ } ++ short int ebcdic_ii[] = ++ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; ++ short int ebcdic_mm[] = ++ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; ++ int use_ebcdic (int i) { ++ return ebcdic_mm[i] + ebcdic_ii[i]; ++ } ++ extern int foo; ++ ++int ++main () ++{ ++return use_ascii (foo) == use_ebcdic (foo); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ++ ac_cv_c_bigendian=yes ++ fi ++ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then ++ if test "$ac_cv_c_bigendian" = unknown; then ++ ac_cv_c_bigendian=no ++ else ++ # finding both strings is unlikely to happen, but who knows? ++ ac_cv_c_bigendian=unknown ++ fi ++ fi ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$ac_includes_default ++int ++main () ++{ ++ ++ /* Are we little or big endian? From Harbison&Steele. */ ++ union ++ { ++ long int l; ++ char c[sizeof (long int)]; ++ } u; ++ u.l = 1; ++ return u.c[sizeof (long int) - 1] == 1; ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ ac_cv_c_bigendian=no ++else ++ ac_cv_c_bigendian=yes ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++ ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 ++$as_echo "$ac_cv_c_bigendian" >&6; } ++ case $ac_cv_c_bigendian in #( ++ yes) ++ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ++;; #( ++ no) ++ ;; #( ++ universal) ++ ++$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ++ ++ ;; #( ++ *) ++ as_fn_error "unknown endianness ++ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; ++ esac ++ ++ if test $ac_cv_c_bigendian = yes; then ++ sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN" ++ else ++ sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN" ++ fi ++else ++ sim_hostendian="-DWITH_HOST_BYTE_ORDER=0" ++fi ++fi ++ ++ + ac_sources="$sim_link_files" + ac_dests="$sim_link_links" + while test -n "$ac_sources"; do +@@ -13245,6 +13496,7 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi + ++ + : ${CONFIG_STATUS=./config.status} + ac_write_fail=0 + ac_clean_files_save=$ac_clean_files +diff --git a/sim/erc32/configure.ac b/sim/erc32/configure.ac +index bc46091..854845c 100644 +--- a/sim/erc32/configure.ac ++++ b/sim/erc32/configure.ac +@@ -32,4 +32,5 @@ else + AC_ERROR([the required "readline" library is missing]), $TERMCAP) + fi + AC_SUBST(READLINE) ++SIM_AC_OPTION_HOSTENDIAN + SIM_AC_OUTPUT +diff --git a/sim/erc32/end.c b/sim/erc32/end.c +deleted file mode 100644 +index 9337198..0000000 +--- a/sim/erc32/end.c ++++ /dev/null +@@ -1,27 +0,0 @@ +-#include "config.h" +-#include +- +-int +-main() +-{ +- +- unsigned int u1; +- char *c; +- double d1; +- float *f1; +- +- c = (char *) &u1; +- u1 = 0x0F; +- if (c[0] == 0x0F) +- puts("#define HOST_LITTLE_ENDIAN\n"); +- else +- puts("#define HOST_BIG_ENDIAN\n"); +- +- d1 = 1.0; +- f1 = (float *) &d1; +- if (*((int *) f1) != 0x3ff00000) +- puts("#define HOST_LITTLE_ENDIAN_FLOAT\n"); +- else +- puts("#define HOST_BIG_ENDIAN_FLOAT\n"); +- return 0; +-} +diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c +index 7c80e13..eac49f7 100644 +--- a/sim/erc32/erc32.c ++++ b/sim/erc32/erc32.c +@@ -30,7 +30,6 @@ + #include + #include + #include "sis.h" +-#include "end.h" + #include "sim-config.h" + + extern int ctrl_c; +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index e80e02a..237bb53 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -21,7 +21,6 @@ + + #include "config.h" + #include "sis.h" +-#include "end.h" + #include + #include + +@@ -1736,7 +1735,7 @@ fpexec(op3, rd, rs1, rs2, sregs) + but what about machines where float values are different endianness + from integer values? */ + +-#ifdef HOST_LITTLE_ENDIAN_FLOAT ++#ifdef HOST_LITTLE_ENDIAN + rs1 &= 0x1f; + switch (opf) { + case FADDd: +@@ -1914,7 +1913,7 @@ fpexec(op3, rd, rs1, rs2, sregs) + + accex = get_accex(); + +-#ifdef HOST_LITTLE_ENDIAN_FLOAT ++#ifdef HOST_LITTLE_ENDIAN + switch (opf) { + case FADDd: + case FDIVd: +@@ -2061,7 +2060,7 @@ init_regs(sregs) + sregs->err_mode = 0; + ext_irl = 0; + sregs->g[0] = 0; +-#ifdef HOST_LITTLE_ENDIAN_FLOAT ++#ifdef HOST_LITTLE_ENDIAN + sregs->fdp = (float32 *) sregs->fd; + sregs->fsi = (int32 *) sregs->fs; + #else +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index bcccf6d..ab21e3c 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -26,7 +26,6 @@ + #include + #include + #include "sis.h" +-#include "end.h" + #include + #include "sim-config.h" + #include +@@ -734,7 +733,7 @@ disp_fpu(sregs) + + printf("\n fsr: %08X\n\n", sregs->fsr); + +-#ifdef HOST_LITTLE_ENDIAN_FLOAT ++#ifdef HOST_LITTLE_ENDIAN + for (i = 0; i < 32; i++) + sregs->fdp[i ^ 1] = sregs->fs[i]; + #endif +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index 1ff6ced..ef5b149 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -23,8 +23,13 @@ + #include "ansidecl.h" + #include "gdb/callback.h" + #include "gdb/remote-sim.h" ++#include + +-#include "end.h" ++#if WITH_HOST_BYTE_ORDER==BIG_ENDIAN ++#define HOST_BIG_ENDIAN ++#else ++#define HOST_LITTLE_ENDIAN ++#endif + + #define I_ACC_EXC 1 + +@@ -65,7 +70,7 @@ typedef long long int64; /* 64-bit signed int */ + struct pstate { + + float64 fd[16]; /* FPU registers */ +-#ifdef HOST_LITTLE_ENDIAN_FLOAT ++#ifdef HOST_LITTLE_ENDIAN + float32 fs[32]; + float32 *fdp; + #else +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0012-sim-erc32-Use-memory_iread-function-for-instruction-.patch b/tools/4.11/gdb/sparc/7.9/0012-sim-erc32-Use-memory_iread-function-for-instruction-.patch new file mode 100644 index 0000000..73aa065 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0012-sim-erc32-Use-memory_iread-function-for-instruction-.patch @@ -0,0 +1,119 @@ +From d468feaaf511b29880faa297476ff98a9ef81b32 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 30 Aug 2014 23:47:46 +0200 +Subject: [PATCH 12/23] sim/erc32: Use memory_iread() function for instruction + fetching. + + Use separate memory_iread() function for instruction fetching. + Speeds up execution and allows addition of an MMU at a later stage. + + * erc32.c (memory_iread) New function to fetch instructions. + * interf.c (run_sim) Use memory_iread. + * sis.c (run_sim) As above. +--- + sim/erc32/erc32.c | 24 ++++++++++++++++++++++++ + sim/erc32/interf.c | 5 ++--- + sim/erc32/sis.c | 8 ++------ + sim/erc32/sis.h | 2 ++ + 4 files changed, 30 insertions(+), 9 deletions(-) + +diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c +index eac49f7..03b40dc 100644 +--- a/sim/erc32/erc32.c ++++ b/sim/erc32/erc32.c +@@ -1566,6 +1566,30 @@ store_bytes (mem, waddr, data, sz, ws) + /* Memory emulation */ + + int ++memory_iread(addr, data, ws) ++ uint32 addr; ++ uint32 *data; ++ int32 *ws; ++{ ++ uint32 asi; ++ if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) { ++ *data = *((uint32 *) & (ramb[addr & mem_rammask & ~3])); ++ *ws = mem_ramr_ws; ++ return (0); ++ } else if (addr < mem_romsz) { ++ *data = *((uint32 *) & (romb[addr & ~3])); ++ *ws = mem_romr_ws; ++ return (0); ++ } ++ ++ printf("Memory exception at %x (illegal address)\n", addr); ++ if (sregs.psr & 0x080) asi = 9; else asi = 8; ++ set_sfsr(UIMP_ACC, addr, asi, 1); ++ *ws = MEM_EX_WS; ++ return (1); ++} ++ ++int + memory_read(asi, addr, data, sz, ws) + int32 asi; + uint32 addr; +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index 3a72e7f..981aa11 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -94,9 +94,8 @@ run_sim(sregs, icount, dis) + if (sregs->pc == 0 || sregs->npc == 0) + printf ("bogus pc or npc\n"); + #endif +- mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst, +- 2, &sregs->hold); +-#if 1 /* DELETE ME! for debugging purposes only */ ++ mexc = memory_iread(sregs->pc, &sregs->inst, &sregs->hold); ++#if 0 /* DELETE ME! for debugging purposes only */ + if (sis_verbose > 2) + printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n", + sregs->pc, sregs->npc, +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index 523d8aa..e109874 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -84,7 +84,7 @@ run_sim(sregs, icount, dis) + uint64 icount; + int dis; + { +- int irq, mexc, deb, asi; ++ int irq, mexc, deb; + + sregs->starttime = get_time(); + init_stdio(); +@@ -93,11 +93,7 @@ run_sim(sregs, icount, dis) + irq = 0; + while (icount > 0) { + +- if (sregs->psr & 0x080) +- asi = 9; +- else +- asi = 8; +- mexc = memory_read(asi, sregs->pc, &sregs->inst, 2, &sregs->hold); ++ mexc = memory_iread(sregs->pc, &sregs->inst, &sregs->hold); + sregs->icnt = 1; + if (sregs->annul) { + sregs->annul = 0; +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index ef5b149..fb733de 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -176,6 +176,7 @@ extern void sim_halt (void); + extern void exit_sim (void); + extern void init_stdio (void); + extern void restore_stdio (void); ++extern int memory_iread (uint32 addr, uint32 *data, int32 *ws); + extern int memory_read (int32 asi, uint32 addr, uint32 *data, + int32 sz, int32 *ws); + extern int memory_write (int32 asi, uint32 addr, uint32 *data, +@@ -186,6 +187,7 @@ extern int sis_memory_read (uint32 addr, char *data, + uint32 length); + + /* func.c */ ++extern struct pstate sregs; + extern void set_regi (struct pstate *sregs, int32 reg, + uint32 rval); + extern void get_regi (struct pstate *sregs, int32 reg, char *buf); +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0013-sim-erc32-Fix-a-few-compiler-warnings.patch b/tools/4.11/gdb/sparc/7.9/0013-sim-erc32-Fix-a-few-compiler-warnings.patch new file mode 100644 index 0000000..6e0fd1d --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0013-sim-erc32-Fix-a-few-compiler-warnings.patch @@ -0,0 +1,72 @@ +From e254c756b852c82ee705ff42f921e6dd9ba509e6 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sun, 31 Aug 2014 23:31:52 +0200 +Subject: [PATCH 13/23] sim/erc32: Fix a few compiler warnings + + * func.c Minor edits to remove compiler warnings. + * func.c, sis.h (exec_cmd) make second argument const char. +--- + sim/erc32/func.c | 9 ++++++--- + sim/erc32/sis.h | 3 +-- + 2 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index ab21e3c..70b42c9 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -380,18 +380,19 @@ limcalc (freq) + + int + exec_cmd(sregs, cmd) +- char *cmd; ++ const char *cmd; + struct pstate *sregs; + { + char *cmd1, *cmd2; + int32 stat; + uint32 len, i, clen, j, tmp; + static uint32 daddr = 0; +- char *cmdsave; ++ char *cmdsave, *cmdsave2 = NULL; + + stat = OK; + cmdsave = strdup(cmd); +- if ((cmd1 = strtok(cmd, " \t")) != NULL) { ++ cmdsave2 = strdup(cmd); ++ if ((cmd1 = strtok(cmdsave2, " \t")) != NULL) { + clen = strlen(cmd1); + if (strncmp(cmd1, "bp", clen) == 0) { + for (i = 0; i < sregs->bptnum; i++) { +@@ -606,6 +607,8 @@ exec_cmd(sregs, cmd) + } else + printf("syntax error\n"); + } ++ if (cmdsave2 != NULL) ++ free(cmdsave2); + if (cmdsave != NULL) + free(cmdsave); + return (stat); +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index fb733de..4ecf885 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -191,7 +191,7 @@ extern struct pstate sregs; + extern void set_regi (struct pstate *sregs, int32 reg, + uint32 rval); + extern void get_regi (struct pstate *sregs, int32 reg, char *buf); +-extern int exec_cmd (struct pstate *sregs, char *cmd); ++extern int exec_cmd (struct pstate *sregs, const char *cmd); + extern void reset_stat (struct pstate *sregs); + extern void show_stat (struct pstate *sregs); + extern void init_bpt (struct pstate *sregs); +@@ -209,7 +209,6 @@ extern int check_bpt (struct pstate *sregs); + extern void reset_all (void); + extern void sys_reset (void); + extern void sys_halt (void); +-extern int bfd_load (char *fname); + extern double get_time (void); + + /* exec.c */ +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0014-sim-erc32-Use-gdb-callback-for-UART-I-O-when-linked-.patch b/tools/4.11/gdb/sparc/7.9/0014-sim-erc32-Use-gdb-callback-for-UART-I-O-when-linked-.patch new file mode 100644 index 0000000..cddb450 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0014-sim-erc32-Use-gdb-callback-for-UART-I-O-when-linked-.patch @@ -0,0 +1,358 @@ +From edd201819d2399e2a7dc87e328aa6c5cf3088104 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Wed, 18 Feb 2015 19:14:55 +0100 +Subject: [PATCH 14/23] sim/erc32: Use gdb callback for UART I/O when linked + with gdb. + + Use the host_callback feature for printing when linked with gdb. +--- + sim/erc32/erc32.c | 97 +++++++++++++++++++++++++++++++++++++++++++++--------- + sim/erc32/func.c | 2 ++ + sim/erc32/interf.c | 5 +-- + sim/erc32/sis.c | 2 ++ + sim/erc32/sis.h | 4 ++- + 5 files changed, 92 insertions(+), 18 deletions(-) + +diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c +index 03b40dc..c1ee435 100644 +--- a/sim/erc32/erc32.c ++++ b/sim/erc32/erc32.c +@@ -22,6 +22,7 @@ + /* The control space devices */ + + #include "config.h" ++#include + #include + #include + #include +@@ -39,6 +40,7 @@ extern int rom8,wrp,uben; + extern char uart_dev1[], uart_dev2[]; + + int dumbio = 0; /* normal, smart, terminal oriented IO by default */ ++int tty_setup = 1; /* default setup if not a tty */ + + /* MEC registers */ + #define MEC_START 0x01f80000 +@@ -301,12 +303,15 @@ static void store_bytes (unsigned char *mem, uint32 waddr, + + extern int ext_irl; + ++static host_callback *callback; ++ + + /* One-time init */ + + void + init_sim() + { ++ callback = sim_callback; + port_init(); + } + +@@ -944,10 +949,14 @@ init_stdio() + { + if (dumbio) + return; /* do nothing */ +- if (!ifd1) ++ if (ifd1 == 0 && f1open) { + tcsetattr(0, TCSANOW, &ioc1); +- if (!ifd2) ++ tcflush(ifd1, TCIFLUSH); ++ } ++ if (ifd2 == 0 && f1open) { + tcsetattr(0, TCSANOW, &ioc2); ++ tcflush(ifd2, TCIFLUSH); ++ } + } + + void +@@ -955,16 +964,18 @@ restore_stdio() + { + if (dumbio) + return; /* do nothing */ +- if (!ifd1) ++ if (ifd1 == 0 && f1open && tty_setup) + tcsetattr(0, TCSANOW, &iocold1); +- if (!ifd2) ++ if (ifd2 == 0 && f2open && tty_setup) + tcsetattr(0, TCSANOW, &iocold2); + } + + #define DO_STDIO_READ( _fd_, _buf_, _len_ ) \ +- ( dumbio \ ++ ( dumbio || nouartrx \ + ? (0) /* no bytes read, no delay */ \ +- : read( _fd_, _buf_, _len_ ) ) ++ : (_fd_) == 1 && callback ? \ ++ callback->read_stdin (callback, _buf_, _len_) : \ ++ read( _fd_, _buf_, _len_ ) ) + + + static void +@@ -994,21 +1005,26 @@ port_init() + } + if (f1in) ifd1 = fileno(f1in); + if (ifd1 == 0) { ++ if (callback && !callback->isatty(callback, ifd1)) { ++ tty_setup = 0; ++ } + if (sis_verbose) + printf("serial port A on stdin/stdout\n"); + if (!dumbio) { + tcgetattr(ifd1, &ioc1); ++ if (tty_setup) { + iocold1 = ioc1; + ioc1.c_lflag &= ~(ICANON | ECHO); + ioc1.c_cc[VMIN] = 0; + ioc1.c_cc[VTIME] = 0; + } ++ } + f1open = 1; + } + + if (f1out) { + ofd1 = fileno(f1out); +- if (!dumbio && ofd1 == 1) setbuf(f1out, NULL); ++ if (!dumbio && tty_setup && ofd1 == 1) setbuf(f1out, NULL); + } + + if (uart_dev2[0] != 0) +@@ -1027,17 +1043,19 @@ port_init() + printf("serial port B on stdin/stdout\n"); + if (!dumbio) { + tcgetattr(ifd2, &ioc2); ++ if (tty_setup) { + iocold2 = ioc2; + ioc2.c_lflag &= ~(ICANON | ECHO); + ioc2.c_cc[VMIN] = 0; + ioc2.c_cc[VTIME] = 0; + } ++ } + f2open = 1; + } + + if (f2out) { + ofd2 = fileno(f2out); +- if (!dumbio && ofd2 == 1) setbuf(f2out, NULL); ++ if (!dumbio && tty_setup && ofd2 == 1) setbuf(f2out, NULL); + } + + wnuma = wnumb = 0; +@@ -1066,6 +1084,9 @@ read_uart(addr) + if (f1open) { + anum = DO_STDIO_READ(ifd1, aq, UARTBUF); + } ++ else { ++ anum = 0; ++ } + if (anum > 0) { + aind = 0; + if ((aind + 1) < anum) +@@ -1098,6 +1119,9 @@ read_uart(addr) + if (f2open) { + bnum = DO_STDIO_READ(ifd2, bq, UARTBUF); + } ++ else { ++ bnum = 0; ++ } + if (bnum > 0) { + bind = 0; + if ((bind + 1) < bnum) +@@ -1130,6 +1154,9 @@ read_uart(addr) + if (f1open) { + anum = DO_STDIO_READ(ifd1, aq, UARTBUF); + } ++ else { ++ anum = 0; ++ } + if (anum > 0) { + Ucontrol |= 0x00000001; + aind = 0; +@@ -1142,6 +1169,9 @@ read_uart(addr) + if (f2open) { + bnum = DO_STDIO_READ(ifd2, bq, UARTBUF); + } ++ else { ++ bnum = 0; ++ } + if (bnum > 0) { + Ucontrol |= 0x00010000; + bind = 0; +@@ -1182,8 +1212,12 @@ write_uart(addr, data) + if (wnuma < UARTBUF) + wbufa[wnuma++] = c; + else { +- while (wnuma) ++ while (wnuma) { ++ if (ofd1 == 1 && callback) ++ wnuma -= callback->write_stdout(callback, wbufa, wnuma); ++ else + wnuma -= fwrite(wbufa, 1, wnuma, f1out); ++ } + wbufa[wnuma++] = c; + } + } +@@ -1206,8 +1240,12 @@ write_uart(addr, data) + if (wnumb < UARTBUF) + wbufb[wnumb++] = c; + else { +- while (wnumb) ++ while (wnumb) { ++ if (ofd1 == 1 && callback) ++ wnumb -= callback->write_stdout(callback, wbufb, wnumb); ++ else + wnumb -= fwrite(wbufb, 1, wnumb, f2out); ++ } + wbufb[wnumb++] = c; + } + } +@@ -1245,19 +1283,37 @@ write_uart(addr, data) + static void + flush_uart() + { +- while (wnuma && f1open) ++ while (wnuma && f1open) { ++ if (ofd1 == 1 && callback) { ++ wnuma -= callback->write_stdout(callback, wbufa, wnuma); ++ callback->flush_stdout(callback); ++ } ++ else + wnuma -= fwrite(wbufa, 1, wnuma, f1out); +- while (wnumb && f2open) ++ } ++ while (wnumb && f2open) { ++ if (ofd2 == 1 && callback) { ++ wnuma -= callback->write_stdout(callback, wbufb, wnuma); ++ callback->flush_stdout(callback); ++ } ++ else + wnumb -= fwrite(wbufb, 1, wnumb, f2out); + } ++} + + + + static void + uarta_tx() + { +- +- while (f1open && fwrite(&uarta_sreg, 1, 1, f1out) != 1); ++ while (f1open) { ++ if (ofd1 == 1 && callback) { ++ while (callback->write_stdout(callback, &uarta_sreg, 1) != 1); ++ } ++ else { ++ while (fwrite(&uarta_sreg, 1, 1, f1out) != 1); ++ } ++ } + if (uart_stat_reg & UARTA_HRE) { + uart_stat_reg |= UARTA_SRE; + } else { +@@ -1271,7 +1327,14 @@ uarta_tx() + static void + uartb_tx() + { +- while (f2open && fwrite(&uartb_sreg, 1, 1, f2out) != 1); ++ while (f2open) { ++ if (ofd2 == 1 && callback) { ++ while (callback->write_stdout(callback, &uarta_sreg, 1) != 1); ++ } ++ else { ++ while (fwrite(&uartb_sreg, 1, 1, f2out) != 1); ++ } ++ } + if (uart_stat_reg & UARTB_HRE) { + uart_stat_reg |= UARTB_SRE; + } else { +@@ -1293,6 +1356,8 @@ uart_rx(arg) + rsize = 0; + if (f1open) + rsize = DO_STDIO_READ(ifd1, &rxd, 1); ++ else ++ rsize = 0; + if (rsize > 0) { + uarta_data = UART_DR | rxd; + if (uart_stat_reg & UARTA_HRE) +@@ -1309,6 +1374,8 @@ uart_rx(arg) + rsize = 0; + if (f2open) + rsize = DO_STDIO_READ(ifd2, &rxd, 1); ++ else ++ rsize = 0; + if (rsize) { + uartb_data = UART_DR | rxd; + if (uart_stat_reg & UARTB_HRE) +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index 70b42c9..440bff1 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -52,6 +52,8 @@ char uart_dev1[128] = ""; + char uart_dev2[128] = ""; + extern int ext_irl; + uint32 last_load_addr = 0; ++int nouartrx = 0; ++host_callback *sim_callback; + + #ifdef ERRINJ + uint32 errcnt = 0; +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index 981aa11..004d0bb 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -61,8 +61,6 @@ extern char uart_dev1[], uart_dev2[]; + + int sis_gdb_break = 1; + +-host_callback *sim_callback; +- + int + run_sim(sregs, icount, dis) + struct pstate *sregs; +@@ -209,6 +207,9 @@ sim_open (kind, callback, abfd, argv) + if (strcmp(argv[stat], "-dumbio") == 0) { + dumbio = 1; + } else ++ if (strcmp(argv[stat], "-nouartrx") == 0) { ++ nouartrx = 1; ++ } else + if (strcmp(argv[stat], "-wrp") == 0) { + wrp = 1; + } else +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index e109874..1f834a0 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -211,6 +211,8 @@ main(argc, argv) + #endif + } else if (strcmp(argv[stat], "-dumbio") == 0) { + dumbio = 1; ++ } else if (strcmp(argv[stat], "-nouartrx") == 0) { ++ nouartrx = 1; + } else if (strcmp(argv[stat], "-v") == 0) { + sis_verbose += 1; + } else { +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index 4ecf885..5226666 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -169,7 +169,7 @@ struct irqcell { + /* Prototypes */ + + /* erc32.c */ +-extern void init_sim (void); ++extern void init_sim (); + extern void reset (void); + extern void error_mode (uint32 pc); + extern void sim_halt (void); +@@ -210,6 +210,8 @@ extern void reset_all (void); + extern void sys_reset (void); + extern void sys_halt (void); + extern double get_time (void); ++extern int nouartrx; ++extern host_callback *sim_callback; + + /* exec.c */ + extern int dispatch_instruction (struct pstate *sregs); +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0015-sim-erc32-Access-memory-subsystem-through-struct-mem.patch b/tools/4.11/gdb/sparc/7.9/0015-sim-erc32-Access-memory-subsystem-through-struct-mem.patch new file mode 100644 index 0000000..c925b22 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0015-sim-erc32-Access-memory-subsystem-through-struct-mem.patch @@ -0,0 +1,804 @@ +From 02c87814c10d896ae4946ef7c0358448b4d4eb61 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Wed, 18 Feb 2015 21:48:10 +0100 +Subject: [PATCH 15/23] sim/erc32: Access memory subsystem through struct + memsys. + + Introduce an common API to access emulated memory. This allows + to emulate different types of SPARC-based CPUs. + + * erc32.c : Export memory operations through struct memsys erc32sys. + * exec.c (dispatch_instruction) Access memory through common API. + * func.c, interf.c, sis.c : As above. + * sis.h : Define struct memsys as common memory API +--- + sim/erc32/erc32.c | 54 ++++++++++++++++++++++++++++-------------------------- + sim/erc32/exec.c | 42 +++++++++++++++++++++--------------------- + sim/erc32/func.c | 37 +++++++++++++++++++++---------------- + sim/erc32/interf.c | 39 +++++++++++++++++++++------------------ + sim/erc32/sis.c | 15 ++++++--------- + sim/erc32/sis.h | 46 ++++++++++++++++++++++++++++------------------ + 6 files changed, 125 insertions(+), 108 deletions(-) + +diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c +index c1ee435..d0cacf9 100644 +--- a/sim/erc32/erc32.c ++++ b/sim/erc32/erc32.c +@@ -39,8 +39,7 @@ extern int32 sparclite, sparclite_board; + extern int rom8,wrp,uben; + extern char uart_dev1[], uart_dev2[]; + +-int dumbio = 0; /* normal, smart, terminal oriented IO by default */ +-int tty_setup = 1; /* default setup if not a tty */ ++static int tty_setup = 1; /* default setup if not a tty */ + + /* MEC registers */ + #define MEC_START 0x01f80000 +@@ -56,11 +55,6 @@ int tty_setup = 1; /* default setup if not a tty */ + extern int errmec; + #endif + +-/* The target's byte order is big-endian by default until we load a +- little-endian program. */ +- +-int current_target_byte_order = BIG_ENDIAN; +- + #define MEC_WS 0 /* Waitstates per MEC access (0 ws) */ + #define MOK 0 + +@@ -308,7 +302,7 @@ static host_callback *callback; + + /* One-time init */ + +-void ++static void + init_sim() + { + callback = sim_callback; +@@ -317,7 +311,7 @@ init_sim() + + /* Power-on reset init */ + +-void ++static void + reset() + { + mec_reset(); +@@ -397,7 +391,7 @@ mecparerror() + + /* IU error mode manager */ + +-void ++static void + error_mode(pc) + uint32 pc; + { +@@ -468,7 +462,7 @@ decode_mcr() + + /* Flush ports when simulator stops */ + +-void ++static void + sim_halt() + { + #ifdef FAST_UART +@@ -476,13 +470,6 @@ sim_halt() + #endif + } + +-int +-sim_stop(SIM_DESC sd) +-{ +- ctrl_c = 1; +- return 1; +-} +- + static void + close_port() + { +@@ -492,7 +479,7 @@ close_port() + fclose(f2in); + } + +-void ++static void + exit_sim() + { + close_port(); +@@ -944,7 +931,7 @@ mec_write(addr, data) + + static int ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1; + +-void ++static void + init_stdio() + { + if (dumbio) +@@ -959,7 +946,7 @@ init_stdio() + } + } + +-void ++static void + restore_stdio() + { + if (dumbio) +@@ -1632,7 +1619,7 @@ store_bytes (mem, waddr, data, sz, ws) + + /* Memory emulation */ + +-int ++static int + memory_iread(addr, data, ws) + uint32 addr; + uint32 *data; +@@ -1656,7 +1643,7 @@ memory_iread(addr, data, ws) + return (1); + } + +-int ++static int + memory_read(asi, addr, data, sz, ws) + int32 asi; + uint32 addr; +@@ -1727,7 +1714,7 @@ memory_read(asi, addr, data, sz, ws) + return (1); + } + +-int ++static int + memory_write(asi, addr, data, sz, ws) + int32 asi; + uint32 addr; +@@ -1863,7 +1850,7 @@ get_mem_ptr(addr, size) + return ((char *) -1); + } + +-int ++static int + sis_memory_write(addr, data, length) + uint32 addr; + const unsigned char *data; +@@ -1878,7 +1865,7 @@ sis_memory_write(addr, data, length) + return (length); + } + +-int ++static int + sis_memory_read(addr, data, length) + uint32 addr; + char *data; +@@ -1908,3 +1895,18 @@ boot_init (void) + sregs.r[14] = sregs.r[30] - 96*4; + mec_mcr |= 1; /* power-down enabled */ + } ++ ++struct memsys erc32sys = { ++ init_sim, ++ reset, ++ error_mode, ++ sim_halt, ++ exit_sim, ++ init_stdio, ++ restore_stdio, ++ memory_iread, ++ memory_read, ++ memory_write, ++ sis_memory_write, ++ sis_memory_read ++}; +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index 237bb53..65e10bf 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -1244,9 +1244,9 @@ dispatch_instruction(sregs) + else + rdd = &(sregs->g[rd]); + } +- mexc = memory_read(asi, address, ddata, 2, &ws); ++ mexc = ms->memory_read(asi, address, ddata, 2, &ws); + sregs->hold += ws; +- mexc |= memory_read(asi, address+4, &ddata[1], 2, &ws); ++ mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws); + sregs->hold += ws; + sregs->icnt = T_LDD; + if (mexc) { +@@ -1267,7 +1267,7 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_UNALI; + break; + } +- mexc = memory_read(asi, address, &data, 2, &ws); ++ mexc = ms->memory_read(asi, address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1278,7 +1278,7 @@ dispatch_instruction(sregs) + case LDSTUBA: + if (!chk_asi(sregs, &asi, op3)) break; + case LDSTUB: +- mexc = memory_read(asi, address, &data, 0, &ws); ++ mexc = ms->memory_read(asi, address, &data, 0, &ws); + sregs->hold += ws; + sregs->icnt = T_LDST; + if (mexc) { +@@ -1288,7 +1288,7 @@ dispatch_instruction(sregs) + data = extract_byte(data, address); + *rdd = data; + data = 0x0ff; +- mexc = memory_write(asi, address, &data, 0, &ws); ++ mexc = ms->memory_write(asi, address, &data, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1302,7 +1302,7 @@ dispatch_instruction(sregs) + if (!chk_asi(sregs, &asi, op3)) break; + case LDSB: + case LDUB: +- mexc = memory_read(asi, address, &data, 0, &ws); ++ mexc = ms->memory_read(asi, address, &data, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1323,7 +1323,7 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_UNALI; + break; + } +- mexc = memory_read(asi, address, &data, 1, &ws); ++ mexc = ms->memory_read(asi, address, &data, 1, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1349,7 +1349,7 @@ dispatch_instruction(sregs) + (sregs->frs2 == rd)) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = memory_read(asi, address, &data, 2, &ws); ++ mexc = ms->memory_read(asi, address, &data, 2, &ws); + sregs->hold += ws; + sregs->flrd = rd; + sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD + +@@ -1375,9 +1375,9 @@ dispatch_instruction(sregs) + ((sregs->frs2 >> 1) == (rd >> 1))) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = memory_read(asi, address, ddata, 2, &ws); ++ mexc = ms->memory_read(asi, address, ddata, 2, &ws); + sregs->hold += ws; +- mexc |= memory_read(asi, address+4, &ddata[1], 2, &ws); ++ mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws); + sregs->hold += ws; + sregs->icnt = T_LDD; + if (mexc) { +@@ -1406,7 +1406,7 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_UNALI; + break; + } +- mexc = memory_read(asi, address, &data, 2, &ws); ++ mexc = ms->memory_read(asi, address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1428,7 +1428,7 @@ dispatch_instruction(sregs) + if (ebase.simtime < sregs->ftime) { + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = memory_write(asi, address, &sregs->fsr, 2, &ws); ++ mexc = ms->memory_write(asi, address, &sregs->fsr, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1442,7 +1442,7 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_UNALI; + break; + } +- mexc = memory_write(asi, address, rdd, 2, &ws); ++ mexc = ms->memory_write(asi, address, rdd, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1451,7 +1451,7 @@ dispatch_instruction(sregs) + case STBA: + if (!chk_asi(sregs, &asi, op3)) break; + case STB: +- mexc = memory_write(asi, address, rdd, 0, &ws); ++ mexc = ms->memory_write(asi, address, rdd, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1471,7 +1471,7 @@ dispatch_instruction(sregs) + else + rdd = &(sregs->g[rd]); + } +- mexc = memory_write(asi, address, rdd, 3, &ws); ++ mexc = ms->memory_write(asi, address, rdd, 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; + #ifdef STAT +@@ -1500,7 +1500,7 @@ dispatch_instruction(sregs) + break; + } + rdd = &(sregs->fpq[0]); +- mexc = memory_write(asi, address, rdd, 3, &ws); ++ mexc = ms->memory_write(asi, address, rdd, 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; + #ifdef STAT +@@ -1521,7 +1521,7 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_UNALI; + break; + } +- mexc = memory_write(asi, address, rdd, 1, &ws); ++ mexc = ms->memory_write(asi, address, rdd, 1, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1540,7 +1540,7 @@ dispatch_instruction(sregs) + if (sregs->frd == rd) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = memory_write(asi, address, &sregs->fsi[rd], 2, &ws); ++ mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1560,7 +1560,7 @@ dispatch_instruction(sregs) + if ((sregs->frd == rd) || (sregs->frd + 1 == rd)) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = memory_write(asi, address, &sregs->fsi[rd], 3, &ws); ++ mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; + #ifdef STAT +@@ -1577,13 +1577,13 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_UNALI; + break; + } +- mexc = memory_read(asi, address, &data, 2, &ws); ++ mexc = ms->memory_read(asi, address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } +- mexc = memory_write(asi, address, rdd, 2, &ws); ++ mexc = ms->memory_write(asi, address, rdd, 2, &ws); + sregs->hold += ws; + sregs->icnt = T_LDST; + if (mexc) { +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index 440bff1..e789099 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -33,7 +33,11 @@ + + #define VAL(x) strtoul(x,(char **)NULL,0) + +-extern int current_target_byte_order; ++/* The target's byte order is big-endian by default until we load a ++ little-endian program. */ ++int current_target_byte_order = BIG_ENDIAN; ++ ++int dumbio = 0; /* normal, smart, terminal oriented IO by default */ + struct disassemble_info dinfo; + struct pstate sregs; + extern struct estate ebase; +@@ -54,6 +58,7 @@ extern int ext_irl; + uint32 last_load_addr = 0; + int nouartrx = 0; + host_callback *sim_callback; ++struct memsys *ms = &erc32sys; + + #ifdef ERRINJ + uint32 errcnt = 0; +@@ -432,7 +437,7 @@ exec_cmd(sregs, cmd) + stat = run_sim(sregs, VAL(cmd1), 0); + } + daddr = sregs->pc; +- sim_halt(); ++ ms->sim_halt(); + } else if (strncmp(cmd1, "debug", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + sis_verbose = VAL(cmd1); +@@ -483,7 +488,7 @@ exec_cmd(sregs, cmd) + stat = run_sim(sregs, UINT64_MAX, 0); + } + daddr = sregs->pc; +- sim_halt(); ++ ms->sim_halt(); + } else if (strncmp(cmd1, "help", clen) == 0) { + gen_help(); + } else if (strncmp(cmd1, "history", clen) == 0) { +@@ -557,7 +562,7 @@ exec_cmd(sregs, cmd) + stat = run_sim(sregs, VAL(cmd1), 0); + } + daddr = sregs->pc; +- sim_halt(); ++ ms->sim_halt(); + } else if (strncmp(cmd1, "shell", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + tmp = system(&cmdsave[clen]); +@@ -565,12 +570,12 @@ exec_cmd(sregs, cmd) + } else if (strncmp(cmd1, "step", clen) == 0) { + stat = run_sim(sregs, 1, 1); + daddr = sregs->pc; +- sim_halt(); ++ ms->sim_halt(); + } else if (strncmp(cmd1, "tcont", clen) == 0) { + sregs->tlimit = limcalc(sregs->freq); + stat = run_sim(sregs, UINT64_MAX, 0); + daddr = sregs->pc; +- sim_halt(); ++ ms->sim_halt(); + } else if (strncmp(cmd1, "tgo", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + len = last_load_addr; +@@ -583,7 +588,7 @@ exec_cmd(sregs, cmd) + printf("resuming at 0x%08x\n",sregs->pc); + stat = run_sim(sregs, UINT64_MAX, 0); + daddr = sregs->pc; +- sim_halt(); ++ ms->sim_halt(); + } else if (strncmp(cmd1, "tlimit", clen) == 0) { + sregs->tlimit = limcalc(sregs->freq); + if (sregs->tlimit != (uint32) -1) +@@ -597,7 +602,7 @@ exec_cmd(sregs, cmd) + } + printf("\n"); + daddr = sregs->pc; +- sim_halt(); ++ ms->sim_halt(); + } else if (strncmp(cmd1, "trun", clen) == 0) { + ebase.simtime = 0; + reset_all(); +@@ -605,7 +610,7 @@ exec_cmd(sregs, cmd) + sregs->tlimit = limcalc(sregs->freq); + stat = run_sim(sregs, UINT64_MAX, 0); + daddr = sregs->pc; +- sim_halt(); ++ ms->sim_halt(); + } else + printf("syntax error\n"); + } +@@ -777,7 +782,7 @@ static void print_insn_sparc_sis(uint32 addr, struct disassemble_info *info) + { + unsigned char i[4]; + +- sis_memory_read(addr, i, 4); ++ ms->sis_memory_read(addr, i, 4); + dinfo.buffer_vma = addr; + dinfo.buffer_length = 4; + dinfo.buffer = i; +@@ -793,10 +798,10 @@ disp_ctrl(sregs) + + printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n", + sregs->psr, sregs->wim, sregs->tbr, sregs->y); +- sis_memory_read(sregs->pc, (char *) &i, 4); ++ ms->sis_memory_read(sregs->pc, (char *) &i, 4); + printf("\n pc: %08X = %08X ", sregs->pc, i); + print_insn_sparc_sis(sregs->pc, &dinfo); +- sis_memory_read(sregs->npc, (char *) &i, 4); ++ ms->sis_memory_read(sregs->npc, (char *) &i, 4); + printf("\n npc: %08X = %08X ", sregs->npc, i); + print_insn_sparc_sis(sregs->npc, &dinfo); + if (sregs->err_mode) +@@ -825,7 +830,7 @@ disp_mem(addr, len) + for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) { + printf("\n %8X ", i); + for (j = 0; j < 4; j++) { +- sis_memory_read((i + (j * 4)), data, 4); ++ ms->sis_memory_read((i + (j * 4)), data, 4); + printf("%08x ", *wdata); + mem[j] = *((int *) &data); + } +@@ -852,7 +857,7 @@ dis_mem(addr, len, info) + uint32 *wdata = (uint32 *) data; + + for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) { +- sis_memory_read(i, data, 4); ++ ms->sis_memory_read(i, data, 4); + printf(" %08x %08x ", i, *wdata); + print_insn_sparc_sis(i, info); + if (i >= 0xfffffffc) break; +@@ -1016,7 +1021,7 @@ reset_all() + { + init_event(); /* Clear event queue */ + init_regs(&sregs); +- reset(); ++ ms->reset(); + #ifdef ERRINJ + errinjstart(); + #endif +@@ -1137,7 +1142,7 @@ bfd_load(fname) + #ifdef HOST_LITTLE_ENDIAN + for (i=0;isis_memory_write(section_address, buffer, count); + + section_address += count; + fptr += count; +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index 004d0bb..3f937f3 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -37,17 +37,13 @@ + #define PSR_CWP 0x7 + + extern struct disassemble_info dinfo; +-extern struct pstate sregs; + extern struct estate ebase; + +-extern int current_target_byte_order; +-extern int ctrl_c; + extern int nfp; + extern int ift; + extern int rom8; + extern int wrp; + extern int uben; +-extern int sis_verbose; + extern char *sis_version; + extern struct estate ebase; + extern struct evcell evbuf[]; +@@ -72,7 +68,7 @@ run_sim(sregs, icount, dis) + if (sis_verbose) + (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n", + sregs->pc); +- init_stdio(); ++ ms->init_stdio(); + sregs->starttime = get_time(); + irq = 0; + if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init(); +@@ -92,7 +88,7 @@ run_sim(sregs, icount, dis) + if (sregs->pc == 0 || sregs->npc == 0) + printf ("bogus pc or npc\n"); + #endif +- mexc = memory_iread(sregs->pc, &sregs->inst, &sregs->hold); ++ mexc = ms->memory_iread(sregs->pc, &sregs->inst, &sregs->hold); + #if 0 /* DELETE ME! for debugging purposes only */ + if (sis_verbose > 2) + printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n", +@@ -118,8 +114,8 @@ run_sim(sregs, icount, dis) + if (sis_verbose) + (*sim_callback->printf_filtered) (sim_callback, + "SW BP hit at %x\n", sregs->pc); +- sim_halt(); +- restore_stdio(); ++ ms->sim_halt(); ++ ms->restore_stdio(); + clearerr(stdin); + return (BPT_HIT); + } else +@@ -137,12 +133,12 @@ run_sim(sregs, icount, dis) + icount = 0; + } + } +- sim_halt(); ++ ms->sim_halt(); + sregs->tottime += get_time() - sregs->starttime; +- restore_stdio(); ++ ms->restore_stdio(); + clearerr(stdin); + if (sregs->err_mode) +- error_mode(sregs->pc); ++ ms->error_mode(sregs->pc); + if (sregs->err_mode) + return (ERROR); + if (sregs->bphit) { +@@ -272,7 +268,7 @@ sim_open (kind, callback, abfd, argv) + #endif + reset_all(); + ebase.simtime = 0; +- init_sim(); ++ ms->init_sim(); + init_bpt(&sregs); + reset_stat(&sregs); + +@@ -286,7 +282,7 @@ sim_close(sd, quitting) + int quitting; + { + +- exit_sim(); ++ ms->exit_sim(); + fcntl(0, F_SETFL, termsave); + + }; +@@ -368,9 +364,9 @@ sim_write(sd, mem, buf, length) + for (i=0; isis_memory_write(mem, (char *) ibuf, length)); + #else +- return (sis_memory_write(mem, buf, length)); ++ return (ms->sis_memory_write(mem, buf, length)); + #endif + } + +@@ -385,7 +381,7 @@ sim_read(sd, mem, buf, length) + int *ibuf = (int *) buf; + int i, len; + +- len = sis_memory_read(mem, buf, length); ++ len = ms->sis_memory_read(mem, buf, length); + if (length >= 4) + for (i=0; isis_memory_read(mem, buf, length)); + #endif + } + +@@ -480,7 +476,7 @@ flush_windows () + #endif + + for (i = 0; i < 16; i++) +- memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2, ++ ms->memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2, + &ws); + + if (win == cwp) +@@ -519,6 +515,13 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word) + return NULL; + } + ++int ++sim_stop(SIM_DESC sd) ++{ ++ ctrl_c = 1; ++ return 1; ++} ++ + #if 0 /* FIXME: These shouldn't exist. */ + + int +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index 1f834a0..8c89166 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -52,16 +52,13 @@ extern HIST_ENTRY *remove_history (int which); + #define HIST_LEN 64 + + extern struct disassemble_info dinfo; +-extern struct pstate sregs; + extern struct estate ebase; + +-extern int ctrl_c; + extern int nfp; + extern int ift; + extern int wrp; + extern int rom8; + extern int uben; +-extern int sis_verbose; + extern char *sis_version; + extern struct estate ebase; + extern struct evcell evbuf[]; +@@ -87,13 +84,13 @@ run_sim(sregs, icount, dis) + int irq, mexc, deb; + + sregs->starttime = get_time(); +- init_stdio(); ++ ms->init_stdio(); + if (sregs->err_mode) icount = 0; + deb = dis || sregs->histlen || sregs->bptnum; + irq = 0; + while (icount > 0) { + +- mexc = memory_iread(sregs->pc, &sregs->inst, &sregs->hold); ++ mexc = ms->memory_iread(sregs->pc, &sregs->inst, &sregs->hold); + sregs->icnt = 1; + if (sregs->annul) { + sregs->annul = 0; +@@ -108,7 +105,7 @@ run_sim(sregs, icount, dis) + } else { + if (deb) { + if ((sregs->bphit = check_bpt(sregs)) != 0) { +- restore_stdio(); ++ ms->restore_stdio(); + return (BPT_HIT); + } + if (sregs->histlen) { +@@ -131,7 +128,7 @@ run_sim(sregs, icount, dis) + irq = 0; + sregs->err_mode = execute_trap(sregs); + if (sregs->err_mode) { +- error_mode(sregs->pc); ++ ms->error_mode(sregs->pc); + icount = 0; + } + } +@@ -143,7 +140,7 @@ run_sim(sregs, icount, dis) + } + } + sregs->tottime += get_time() - sregs->starttime; +- restore_stdio(); ++ ms->restore_stdio(); + if (sregs->err_mode) + return (ERROR); + if (ctrl_c) { +@@ -246,7 +243,7 @@ main(argc, argv) + ebase.simtime = 0; + reset_all(); + init_bpt(&sregs); +- init_sim(); ++ ms->init_sim(); + if (lfile) + last_load_addr = bfd_load(argv[lfile]); + #ifdef STAT +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index 5226666..e0390e6 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -169,25 +169,12 @@ struct irqcell { + /* Prototypes */ + + /* erc32.c */ +-extern void init_sim (); +-extern void reset (void); +-extern void error_mode (uint32 pc); +-extern void sim_halt (void); +-extern void exit_sim (void); +-extern void init_stdio (void); +-extern void restore_stdio (void); +-extern int memory_iread (uint32 addr, uint32 *data, int32 *ws); +-extern int memory_read (int32 asi, uint32 addr, uint32 *data, +- int32 sz, int32 *ws); +-extern int memory_write (int32 asi, uint32 addr, uint32 *data, +- int32 sz, int32 *ws); +-extern int sis_memory_write (uint32 addr, +- const unsigned char *data, uint32 length); +-extern int sis_memory_read (uint32 addr, char *data, +- uint32 length); ++extern struct memsys erc32sys; + + /* func.c */ +-extern struct pstate sregs; ++extern struct pstate sregs; ++extern int ctrl_c; ++extern int sis_verbose; + extern void set_regi (struct pstate *sregs, int32 reg, + uint32 rval); + extern void get_regi (struct pstate *sregs, int32 reg, char *buf); +@@ -211,7 +198,9 @@ extern void sys_reset (void); + extern void sys_halt (void); + extern double get_time (void); + extern int nouartrx; +-extern host_callback *sim_callback; ++extern host_callback *sim_callback; ++extern int current_target_byte_order; ++extern int dumbio; + + /* exec.c */ + extern int dispatch_instruction (struct pstate *sregs); +@@ -231,3 +220,24 @@ extern void set_fsr (uint32 fsr); + /* help.c */ + extern void usage (void); + extern void gen_help (void); ++ ++struct memsys { ++ void (*init_sim) (); ++ void (*reset) (void); ++ void (*error_mode) (uint32 pc); ++ void (*sim_halt) (void); ++ void (*exit_sim) (void); ++ void (*init_stdio) (void); ++ void (*restore_stdio) (void); ++ int (*memory_iread) (uint32 addr, uint32 *data, int32 *ws); ++ int (*memory_read) (int32 asi, uint32 addr, uint32 *data, ++ int32 sz, int32 *ws); ++ int (*memory_write) (int32 asi, uint32 addr, uint32 *data, ++ int32 sz, int32 *ws); ++ int (*sis_memory_write) (uint32 addr, ++ const unsigned char *data, uint32 length); ++ int (*sis_memory_read) (uint32 addr, char *data, ++ uint32 length); ++}; ++ ++extern struct memsys *ms; +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0016-sim-erc32-Use-readline.h-for-readline-types-and-func.patch b/tools/4.11/gdb/sparc/7.9/0016-sim-erc32-Use-readline.h-for-readline-types-and-func.patch new file mode 100644 index 0000000..a21bd14 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0016-sim-erc32-Use-readline.h-for-readline-types-and-func.patch @@ -0,0 +1,55 @@ +From 8907865aa0256164fd732c795ce8c9c3c42621a8 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 18 Oct 2014 23:38:02 +0200 +Subject: [PATCH 16/23] sim/erc32: Use readline.h for readline types and + functions. + + Use gdb's readline.h for readline types. + + * Makefile.in : Add include path to readline.h + sis.c : Remove locally define readline types. +--- + sim/erc32/Makefile.in | 2 +- + sim/erc32/sis.c | 13 ++----------- + 2 files changed, 3 insertions(+), 12 deletions(-) + +diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in +index e0860a0..4f86017 100644 +--- a/sim/erc32/Makefile.in ++++ b/sim/erc32/Makefile.in +@@ -30,7 +30,7 @@ SIM_EXTRA_CLEAN = clean-sis + # UARTS run at about 115200 baud (simulator time). Add -DFAST_UART to + # CFLAGS if faster (infinite) UART speed is desired. Might affect the + # behaviour of UART interrupt routines ... +-SIM_EXTRA_CFLAGS = -DFAST_UART ++SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcroot) + + ## COMMON_POST_CONFIG_FRAG + +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index 8c89166..79757ae 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -36,17 +36,8 @@ + + /* Structures and functions from readline library */ + +-typedef struct { +- char *line; +- char *data; +-} HIST_ENTRY; +- +-extern char * readline (char *prompt); +-extern void using_history (void); +-extern void add_history (char *string); +-extern HIST_ENTRY *remove_history (int which); +- +- ++#include "readline/readline.h" ++#include "readline/history.h" + + /* Command history buffer length - MUST be binary */ + #define HIST_LEN 64 +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0017-sim-erc32-Move-local-extern-declarations-into-sis.h.patch b/tools/4.11/gdb/sparc/7.9/0017-sim-erc32-Move-local-extern-declarations-into-sis.h.patch new file mode 100644 index 0000000..efd6636 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0017-sim-erc32-Move-local-extern-declarations-into-sis.h.patch @@ -0,0 +1,224 @@ +From 82bbac32bcd1c2c65930f13daa9de7b327c310ea Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Wed, 18 Feb 2015 21:58:00 +0100 +Subject: [PATCH 17/23] sim/erc32: Move local extern declarations into sis.h + + * erc32.c : Move extern declarations to sis.h + * exec.c, func.c, interf.c, sis.c : As above. +--- + sim/erc32/erc32.c | 10 ---------- + sim/erc32/exec.c | 7 ------- + sim/erc32/func.c | 12 ++++-------- + sim/erc32/interf.c | 19 ------------------- + sim/erc32/sis.c | 20 -------------------- + sim/erc32/sis.h | 20 ++++++++++++++++++++ + 6 files changed, 24 insertions(+), 64 deletions(-) + +diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c +index d0cacf9..89c745a 100644 +--- a/sim/erc32/erc32.c ++++ b/sim/erc32/erc32.c +@@ -33,12 +33,6 @@ + #include "sis.h" + #include "sim-config.h" + +-extern int ctrl_c; +-extern int32 sis_verbose; +-extern int32 sparclite, sparclite_board; +-extern int rom8,wrp,uben; +-extern char uart_dev1[], uart_dev2[]; +- + static int tty_setup = 1; /* default setup if not a tty */ + + /* MEC registers */ +@@ -295,8 +289,6 @@ static unsigned char * + static void store_bytes (unsigned char *mem, uint32 waddr, + uint32 *data, int sz, int32 *ws); + +-extern int ext_irl; +- + static host_callback *callback; + + +@@ -1880,8 +1872,6 @@ sis_memory_read(addr, data, length) + return (length); + } + +-extern struct pstate sregs; +- + void + boot_init (void) + { +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index 65e10bf..6d80306 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -24,7 +24,6 @@ + #include + #include + +-extern int32 sis_verbose, sparclite; + int ext_irl = 0; + + /* Load/store interlock delay */ +@@ -228,10 +227,6 @@ static int fpexec (uint32 op3, uint32 rd, uint32 rs1, uint32 rs2, + struct pstate *sregs); + static int chk_asi (struct pstate *sregs, uint32 *asi, uint32 op3); + +- +-extern struct estate ebase; +-extern int32 nfp,ift; +- + #ifdef ERRINJ + extern uint32 errtt, errftt; + #endif +@@ -2017,8 +2012,6 @@ execute_trap(sregs) + + } + +-extern struct irqcell irqarr[16]; +- + int + check_interrupts(sregs) + struct pstate *sregs; +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index e789099..0d00f48 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -40,7 +40,10 @@ int current_target_byte_order = BIG_ENDIAN; + int dumbio = 0; /* normal, smart, terminal oriented IO by default */ + struct disassemble_info dinfo; + struct pstate sregs; +-extern struct estate ebase; ++struct estate ebase; ++struct evcell evbuf[EVENT_MAX]; ++struct irqcell irqarr[16]; ++ + int ctrl_c = 0; + int sis_verbose = 0; + char *sis_version = "2.7.5"; +@@ -54,7 +57,6 @@ int sparclite = 0; /* emulating SPARClite instructions? */ + int sparclite_board = 0; /* emulating SPARClite board RAM? */ + char uart_dev1[128] = ""; + char uart_dev2[128] = ""; +-extern int ext_irl; + uint32 last_load_addr = 0; + int nouartrx = 0; + host_callback *sim_callback; +@@ -727,12 +729,6 @@ init_signals() + } + + +-extern struct disassemble_info dinfo; +- +-struct estate ebase; +-struct evcell evbuf[EVENT_MAX]; +-struct irqcell irqarr[16]; +- + static int + disp_fpu(sregs) + struct pstate *sregs; +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index 3f937f3..ab1a38c 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -36,25 +36,6 @@ + + #define PSR_CWP 0x7 + +-extern struct disassemble_info dinfo; +-extern struct estate ebase; +- +-extern int nfp; +-extern int ift; +-extern int rom8; +-extern int wrp; +-extern int uben; +-extern char *sis_version; +-extern struct estate ebase; +-extern struct evcell evbuf[]; +-extern struct irqcell irqarr[]; +-extern int irqpend, ext_irl; +-extern int sparclite; +-extern int dumbio; +-extern int sparclite_board; +-extern int termsave; +-extern char uart_dev1[], uart_dev2[]; +- + int sis_gdb_break = 1; + + int +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index 79757ae..d833da3 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -42,26 +42,6 @@ + /* Command history buffer length - MUST be binary */ + #define HIST_LEN 64 + +-extern struct disassemble_info dinfo; +-extern struct estate ebase; +- +-extern int nfp; +-extern int ift; +-extern int wrp; +-extern int rom8; +-extern int uben; +-extern char *sis_version; +-extern struct estate ebase; +-extern struct evcell evbuf[]; +-extern struct irqcell irqarr[]; +-extern int irqpend, ext_irl; +-extern int termsave; +-extern int sparclite; +-extern int dumbio; +-extern char uart_dev1[]; +-extern char uart_dev2[]; +-extern uint32 last_load_addr; +- + #ifdef ERA + extern int era; + #endif +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index e0390e6..8a48f29 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -173,8 +173,27 @@ extern struct memsys erc32sys; + + /* func.c */ + extern struct pstate sregs; ++extern struct estate ebase; ++extern struct evcell evbuf[]; ++extern struct irqcell irqarr[]; ++extern int nfp; ++extern int ift; + extern int ctrl_c; + extern int sis_verbose; ++extern char *sis_version; ++extern int sparclite; ++extern int sparclite_board; ++extern uint32 last_load_addr; ++extern int wrp; ++extern int rom8; ++extern int uben; ++extern int irqpend; ++extern int ext_irl; ++extern int termsave; ++extern int dumbio; ++extern char uart_dev1[]; ++extern char uart_dev2[]; ++ + extern void set_regi (struct pstate *sregs, int32 reg, + uint32 rval); + extern void get_regi (struct pstate *sregs, int32 reg, char *buf); +@@ -185,6 +204,7 @@ extern void init_bpt (struct pstate *sregs); + extern void init_signals (void); + + struct disassemble_info; ++extern struct disassemble_info dinfo; + extern void dis_mem (uint32 addr, uint32 len, + struct disassemble_info *info); + extern void event (void (*cfunc) (), int32 arg, uint64 delta); +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch b/tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch new file mode 100644 index 0000000..8a20bff --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0018-sim-erc32-Add-support-for-LEON3-processor-emulation.patch @@ -0,0 +1,2434 @@ +From d3e77f683adc96e3fc8395f21b8e440ee923a092 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +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/sim/erc32/Makefile.in ++++ b/sim/erc32/Makefile.in +@@ -21,7 +21,7 @@ + TERMCAP_LIB = @TERMCAP@ + READLINE_LIB = @READLINE@ + +-SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o ++SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o leon3.o grlib.o + SIM_EXTRA_LIBS = $(READLINE_LIB) $(TERMCAP_LIB) -lm + SIM_EXTRA_ALL = sis + SIM_EXTRA_INSTALL = install-sis +@@ -35,7 +35,7 @@ SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcroot) + ## COMMON_POST_CONFIG_FRAG + + # `sis' doesn't need interf.o. +-SIS_OFILES = exec.o erc32.o func.o help.o float.o ++SIS_OFILES = exec.o erc32.o func.o help.o float.o grlib.o leon3.o + + sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) -o sis \ +diff --git a/sim/erc32/README.leon3 b/sim/erc32/README.leon3 +new file mode 100644 +index 0000000..f6701a5 +--- /dev/null ++++ b/sim/erc32/README.leon3 +@@ -0,0 +1,53 @@ ++ ++1. LEON3 emulation ++ ++The file 'leon3.c' contains a model of simple LEON3 sub-system. It ++contains 16 Mbyte ROM and 16 Mbyte RAM. Standard peripherals ++such as interrupt controller, UART and timer are provided. ++The model can execute leon3 binaries that do not require an ++MMU. ++ ++To start sis in Leon3 mode, add the -leon3 switch. In gdb, ++use 'target sim -leon3' . ++ ++1.1 UART ++ ++The UART emulates an APBUART and is located at address 0x80000100. ++The following registers are implemeted: ++ ++- UART RX and TX register (0x80000100) ++- UART status register (0x80000104) ++ ++The UART generates interrupt 3. ++ ++1.2 Timer unit (GPTIMER) ++ ++The GPTIMER programmable counter is emulated and located at ++address 0x80000300. It is configured with two timers and separate ++interrupts (8 and 9). ++ ++1.3 Interrupt controller ++ ++The IRQMP interrupt controller is implemented as described in the ++GRLIB IP manual, with the exception of the interrupt level register. ++Extended interrupts are not supported. The registers are located ++at address 0x80000200. ++ ++1.5 Memory interface ++ ++The following memory areas are valid for the Leon3 simulator: ++ ++0x00000000 - 0x01000000 ROM (16 Mbyte, loaded at start-up) ++0x40000000 - 0x41000000 RAM (16 Mbyte, loaded at start-up) ++0x80000000 - 0x81000000 APB bus, including plug&play ++0xFFFFF000 - 0xFFFFFFFF AHB plug&play area ++ ++Access to non-existing memory will result in a memory exception trap. ++ ++1.8 Power-down mode ++ ++The Leon3 power-down feature (%asr19) is supported. When power-down is ++entered, time is skipped forward until the next event in the event queue. ++However, if the simulator event queue is empty, power-down mode is not ++entered since no interrupt would be generated to exit from the mode. A ++Ctrl-C in the simulator window will exit the power-down mode. +diff --git a/sim/erc32/README.sis b/sim/erc32/README.sis +index b119f03..124e577 100644 +--- a/sim/erc32/README.sis ++++ b/sim/erc32/README.sis +@@ -1,10 +1,10 @@ + +-SIS - Sparc Instruction Simulator README file (v2.0, 05-02-1996) ++SIS - Sparc Instruction Simulator README file (v2.8, 10-11-2014) + ------------------------------------------------------------------- + + 1. Introduction + +-The SIS is a SPARC V7 architecture simulator. It consist of two parts, ++The SIS is a SPARC V7/V8 architecture simulator. It consist of two parts, + the simulator core and a user defined memory module. The simulator + core executes the instructions while the memory module emulates memory + and peripherals. +@@ -13,28 +13,28 @@ and peripherals. + + The simulator is started as follows: + +-sis [-uart1 uart_device1] [-uart2 uart_device2] ++sis [-leon3] [-uart1 uart_device1] [-uart2 uart_device2] + [-nfp] [-freq frequency] [-c batch_file] [files] + +-The default uart devices for SIS are /dev/ptypc and /dev/ptypd. The +--uart[1,2] switch can be used to connect the uarts to other devices. +-Use 'tip /dev/ttypc' to connect a terminal emulator to the uarts. ++By default, SIS emulates an ERC32 system. The -leon3 switch ++enables emulation of a LEON3 SOC system. ++ ++The emulated console uart is connected to stdin/stdout. The -uart[1,2] ++switch can be used to connect the uarts to other devices. ++ + The '-nfp' will disable the simulated FPU, so each FPU instruction will + generate a FPU disabled trap. The '-freq' switch can be used to define + which "frequency" the simulator runs at. This is used by the 'perf' + command to calculated the MIPS figure for a particular configuration. +-The give frequency must be an integer indicating the frequency in MHz. ++The frequency must be an integer indicating the frequency in MHz. + + The -c option indicates that sis commands should be read from 'batch_file' + at startup. + +-Files to be loaded must be in one of the supported formats (see INSTALLATION), +-and will be loaded into the simulated memory. The file formats are +-automatically recognised. ++Files to be loaded must be in one of the supported formats (elf, a.out, srec), ++and will be loaded into the simulated memory. + +-The script 'startsim' will start the simulator in one xterm window and +-open a terminal emulator (tip) connected to the UART A in a second +-xterm window. Below is description of commands that are recognized by ++Below is description of commands that are recognized by + the simulator. The command-line is parsed using GNU readline. A command + history of 64 commands is maintained. Use the up/down arrows to recall + previous commands. For more details, see the readline documentation. +@@ -77,8 +77,8 @@ Prints the FPU registers + go
[inst_count] + + The go command will set pc to
and npc to
+ 4, and start +-execution. No other initialisation will be done. If inst_count is given, +-execution will stop after the specified number of instructions. ++execution. If inst_count is given, execution will stop after the specified ++number of instructions. + + help + +@@ -146,14 +146,20 @@ interpreted as 'cont'. + + 3. Simulator core + +-The SIS emulates the behavior of the 90C601E and 90C602E sparc IU and +-FPU from Matra MHS. These are roughly equivalent to the Cypress C601 +-and C602. The simulator is cycle true, i.e a simulator time is +-maintained and inremented according the IU and FPU instruction timing. ++In ERC32 mode, SIS emulates the behavior of the 90C601E and 90C602E ++sparc IU and FPU from Matra MHS. These are roughly equivalent to the ++Cypress C601 and C602. The simulator is cycle true, i.e a simulator time is ++maintained and incremented according the IU and FPU instruction timing. + The parallel execution between the IU and FPU is modelled, as well as +-stalls due to operand dependencies (FPU). The core interacts with the +-user-defined memory modules through a number of functions. The memory +-module must provide the following functions: ++stalls due to operand dependencies (FPU). ++ ++In Leon3 mode, the core emulates the Leon3 SPARC V8 core from ++Gaisler Research. All SPARC V8 instructions are supported but ++emulation is not fully cycle-true as the cache is not emulated. ++ ++The core interacts with the user-defined memory modules through ++a number of functions. The memory module must provide the following ++functions: + + int memory_read(asi,addr,data,ws) + int asi; +@@ -272,7 +278,7 @@ See 'erc32.c' for examples on how to use events and interrupts. + + 5. Memory module + +-The supplied memory module (erc32.c) emulates the functions of memory and ++The ERC32 memory module (erc32.c) emulates the functions of memory and + the MEC asic developed for the 90C601/2. It includes the following functions: + + * UART A & B +@@ -284,28 +290,27 @@ the MEC asic developed for the 90C601/2. It includes the following functions: + * 512 Kbyte ROM + * 4 Mbyte RAM + +-See README.erc32 on how the MEC functions are emulated. For a detailed MEC +-specification, look at the ERC32 home page at URL: ++See README.erc32 on how the MEC functions are emulated. + +-http://www.estec.esa.nl/wsmwww/erc32 ++The Leon3 memory module (leon3.c) emulates on-chip peripherals and ++external memory for a simple Leon3 system. The modules includes the ++following functions: + +-6. Compile and linking programs ++* AHB and APB buses with plug&play ++* UART (APBUART) ++* Interrupt controller (IRQMP) ++* Timer unit with two timers (GPTIMER) ++* PROM/SRAM memory controller (SRCTRL) ++* 16 Mbyte PROM, 16 Mbyte SRAM + +-The directory 'examples' contain some code fragments for SIS. +-The script gccx indicates how the native sunos gcc and linker can be used +-to produce executables for the simulator. To compile and link the provided +-'hello.c', type 'gccx hello.c'. This will build the executable 'hello'. +-Start the simulator by running 'startsim hello', and issue the command 'run. +-After the program is terminated, the IU will be force to error mode through +-a software trap and halt. ++See README.leon3 for further details on Leon3 emulation. + +-The programs are linked with a start-up file, srt0.S. This file includes +-the traptable and window underflow/overflow trap routines. ++6. Compile and linking programs + + 7. IU and FPU instruction timing. + +-The simulator provides cycle true simulation. The following table shows +-the emulated instruction timing for 90C601E & 90C602E: ++The simulator provides cycle true simulation for ERC32. The following table ++shows the emulated instruction timing for 90C601E & 90C602E: + + Instructions Cycles + +diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c +index 89c745a..0e1a2ed 100644 +--- a/sim/erc32/erc32.c ++++ b/sim/erc32/erc32.c +@@ -1636,19 +1636,20 @@ memory_iread(addr, data, ws) + } + + static int +-memory_read(asi, addr, data, sz, ws) +- int32 asi; ++memory_read(addr, data, sz, ws) + uint32 addr; + uint32 *data; + int32 sz; + int32 *ws; + { + int32 mexc; ++ int32 asi; + + #ifdef ERRINJ + if (errmec) { + if (sis_verbose) + printf("Inserted MEC error %d\n",errmec); ++ if (sregs.psr & 0x080) asi = 11; else asi = 10; + set_sfsr(errmec, addr, asi, 1); + if (errmec == 5) mecparerror(); + if (errmec == 6) iucomperr(); +@@ -1662,6 +1663,7 @@ memory_read(asi, addr, data, sz, ws) + *ws = mem_ramr_ws; + return (0); + } else if ((addr >= MEC_START) && (addr < MEC_END)) { ++ if (sregs.psr & 0x080) asi = 11; else asi = 10; + mexc = mec_read(addr, asi, data); + if (mexc) { + set_sfsr(MEC_ACC, addr, asi, 1); +@@ -1701,19 +1703,30 @@ memory_read(asi, addr, data, sz, ws) + } + + printf("Memory exception at %x (illegal address)\n", addr); ++ if (sregs.psr & 0x080) asi = 11; else asi = 10; + set_sfsr(UIMP_ACC, addr, asi, 1); + *ws = MEM_EX_WS; + return (1); + } + + static int +-memory_write(asi, addr, data, sz, ws) ++memory_read_asi(asi, addr, data, sz, ws) + int32 asi; + uint32 addr; + uint32 *data; + int32 sz; + int32 *ws; + { ++ return(memory_read(addr, data, sz, ws)); ++} ++ ++static int ++memory_write(addr, data, sz, ws) ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ + uint32 byte_addr; + uint32 byte_mask; + uint32 waddr; +@@ -1721,11 +1734,13 @@ memory_write(asi, addr, data, sz, ws) + int32 mexc; + int i; + int wphit[2]; ++ int32 asi; + + #ifdef ERRINJ + if (errmec) { + if (sis_verbose) + printf("Inserted MEC error %d\n",errmec); ++ if (sregs.psr & 0x080) asi = 11; else asi = 10; + set_sfsr(errmec, addr, asi, 0); + if (errmec == 5) mecparerror(); + if (errmec == 6) iucomperr(); +@@ -1738,6 +1753,7 @@ memory_write(asi, addr, data, sz, ws) + if (mem_accprot) { + + waddr = (addr & 0x7fffff) >> 2; ++ if (sregs.psr & 0x080) asi = 11; else asi = 10; + for (i = 0; i < 2; i++) + wphit[i] = + (((asi == 0xa) && (mec_wpr[i] & 1)) || +@@ -1761,6 +1777,7 @@ memory_write(asi, addr, data, sz, ws) + return (0); + + } else if ((addr >= MEC_START) && (addr < MEC_END)) { ++ if (sregs.psr & 0x080) asi = 11; else asi = 10; + if ((sz != 2) || (asi != 0xb)) { + set_sfsr(MEC_ACC, addr, asi, 0); + *ws = MEM_EX_WS; +@@ -1817,10 +1834,22 @@ memory_write(asi, addr, data, sz, ws) + } + + *ws = MEM_EX_WS; ++ if (sregs.psr & 0x080) asi = 11; else asi = 10; + set_sfsr(UIMP_ACC, addr, asi, 0); + return (1); + } + ++static int ++memory_write_asi(asi, addr, data, sz, ws) ++ int32 asi; ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ return(memory_write(addr, data, sz, ws)); ++} ++ + static unsigned char * + get_mem_ptr(addr, size) + uint32 addr; +@@ -1864,6 +1893,12 @@ sis_memory_read(addr, data, length) + uint32 length; + { + char *mem; ++ int ws; ++ ++ if (length == 4) { ++ memory_read(addr, data, length, &ws); ++ return(4); ++ } + + if ((mem = get_mem_ptr(addr, length)) == ((char *) -1)) + return (0); +@@ -1872,7 +1907,7 @@ sis_memory_read(addr, data, length) + return (length); + } + +-void ++static void + boot_init (void) + { + mec_write(MEC_WCR, 0); /* zero waitstates */ +@@ -1896,7 +1931,10 @@ struct memsys erc32sys = { + restore_stdio, + memory_iread, + memory_read, ++ memory_read_asi, + memory_write, ++ memory_write_asi, + sis_memory_write, +- sis_memory_read ++ sis_memory_read, ++ boot_init + }; +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index 6d80306..6292998 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -1065,17 +1065,17 @@ dispatch_instruction(sregs) + *rdd = sregs->psr; + break; + case RDY: +- if (!sparclite) ++ if ((!sparclite) && (cputype != CPU_LEON3)) + *rdd = sregs->y; + else { + int rs1_is_asr = (sregs->inst >> 14) & 0x1f; + if ( 0 == rs1_is_asr ) + *rdd = sregs->y; +- else if ( 17 == rs1_is_asr ) ++ else if ( 17 == rs1_is_asr ) { + *rdd = sregs->asr17; ++ } + else { + sregs->trap = TRAP_UNIMP; +- break; + } + } + break; +@@ -1121,13 +1121,19 @@ dispatch_instruction(sregs) + ((rs1 ^ operand2) & 0xfffff000); + break; + case WRY: +- if (!sparclite) ++ if ((!sparclite) && (cputype != CPU_LEON3)) + sregs->y = (rs1 ^ operand2); + else { + if ( 0 == rd ) + sregs->y = (rs1 ^ operand2); +- else if ( 17 == rd ) +- sregs->asr17 = (rs1 ^ operand2); ++ else if ( 17 == rd ) { ++ if (sparclite) ++ sregs->asr17 = (rs1 ^ operand2); ++ } ++ else if ( 19 == rd ) { ++ if (cputype == CPU_LEON3) ++ wait_for_irq(); ++ } + else { + sregs->trap = TRAP_UNIMP; + break; +@@ -1227,6 +1233,32 @@ dispatch_instruction(sregs) + switch (op3) { + case LDDA: + if (!chk_asi(sregs, &asi, op3)) break; ++ if (address & 0x7) { ++ sregs->trap = TRAP_UNALI; ++ break; ++ } ++ if (rd & 1) { ++ rd &= 0x1e; ++ if (rd > 7) ++ rdd = &(sregs->r[(cwp + rd) & 0x7f]); ++ else ++ rdd = &(sregs->g[rd]); ++ } ++ mexc = ms->memory_read_asi(asi, address, ddata, 2, &ws); ++ sregs->hold += ws; ++ mexc |= ms->memory_read_asi(asi, address+4, &ddata[1], 2, &ws); ++ sregs->hold += ws; ++ sregs->icnt = T_LDD; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ } else { ++ rdd[0] = ddata[0]; ++ rdd[1] = ddata[1]; ++#ifdef STAT ++ sregs->nload++; /* Double load counts twice */ ++#endif ++ } ++ break; + case LDD: + if (address & 0x7) { + sregs->trap = TRAP_UNALI; +@@ -1239,9 +1271,9 @@ dispatch_instruction(sregs) + else + rdd = &(sregs->g[rd]); + } +- mexc = ms->memory_read(asi, address, ddata, 2, &ws); ++ mexc = ms->memory_read(address, ddata, 2, &ws); + sregs->hold += ws; +- mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws); ++ mexc |= ms->memory_read(address+4, &ddata[1], 2, &ws); + sregs->hold += ws; + sregs->icnt = T_LDD; + if (mexc) { +@@ -1257,12 +1289,24 @@ dispatch_instruction(sregs) + + case LDA: + if (!chk_asi(sregs, &asi, op3)) break; ++ if (address & 0x3) { ++ sregs->trap = TRAP_UNALI; ++ break; ++ } ++ mexc = ms->memory_read_asi(asi, address, &data, 2, &ws); ++ sregs->hold += ws; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ } else { ++ *rdd = data; ++ } ++ break; + case LD: + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } +- mexc = ms->memory_read(asi, address, &data, 2, &ws); ++ mexc = ms->memory_read(address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1272,8 +1316,27 @@ dispatch_instruction(sregs) + break; + case LDSTUBA: + if (!chk_asi(sregs, &asi, op3)) break; ++ mexc = ms->memory_read_asi(asi, address, &data, 0, &ws); ++ sregs->hold += ws; ++ sregs->icnt = T_LDST; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ break; ++ } ++ data = extract_byte(data, address); ++ *rdd = data; ++ data = 0x0ff; ++ mexc = ms->memory_write_asi(asi, address, &data, 0, &ws); ++ sregs->hold += ws; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ } ++#ifdef STAT ++ sregs->nload++; ++#endif ++ break; + case LDSTUB: +- mexc = ms->memory_read(asi, address, &data, 0, &ws); ++ mexc = ms->memory_read(address, &data, 0, &ws); + sregs->hold += ws; + sregs->icnt = T_LDST; + if (mexc) { +@@ -1283,7 +1346,7 @@ dispatch_instruction(sregs) + data = extract_byte(data, address); + *rdd = data; + data = 0x0ff; +- mexc = ms->memory_write(asi, address, &data, 0, &ws); ++ mexc = ms->memory_write(address, &data, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1295,9 +1358,21 @@ dispatch_instruction(sregs) + case LDSBA: + case LDUBA: + if (!chk_asi(sregs, &asi, op3)) break; ++ mexc = ms->memory_read_asi(asi, address, &data, 0, &ws); ++ sregs->hold += ws; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ break; ++ } ++ if (op3 == LDSB) ++ data = extract_byte_signed(data, address); ++ else ++ data = extract_byte(data, address); ++ *rdd = data; ++ break; + case LDSB: + case LDUB: +- mexc = ms->memory_read(asi, address, &data, 0, &ws); ++ mexc = ms->memory_read(address, &data, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1312,13 +1387,29 @@ dispatch_instruction(sregs) + case LDSHA: + case LDUHA: + if (!chk_asi(sregs, &asi, op3)) break; ++ if (address & 0x1) { ++ sregs->trap = TRAP_UNALI; ++ break; ++ } ++ mexc = ms->memory_read_asi(asi, address, &data, 1, &ws); ++ sregs->hold += ws; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ break; ++ } ++ if (op3 == LDSH) ++ data = extract_short_signed(data, address); ++ else ++ data = extract_short(data, address); ++ *rdd = data; ++ break; + case LDSH: + case LDUH: + if (address & 0x1) { + sregs->trap = TRAP_UNALI; + break; + } +- mexc = ms->memory_read(asi, address, &data, 1, &ws); ++ mexc = ms->memory_read(address, &data, 1, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1344,7 +1435,7 @@ dispatch_instruction(sregs) + (sregs->frs2 == rd)) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = ms->memory_read(asi, address, &data, 2, &ws); ++ mexc = ms->memory_read(address, &data, 2, &ws); + sregs->hold += ws; + sregs->flrd = rd; + sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD + +@@ -1370,9 +1461,9 @@ dispatch_instruction(sregs) + ((sregs->frs2 >> 1) == (rd >> 1))) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = ms->memory_read(asi, address, ddata, 2, &ws); ++ mexc = ms->memory_read(address, ddata, 2, &ws); + sregs->hold += ws; +- mexc |= ms->memory_read(asi, address+4, &ddata[1], 2, &ws); ++ mexc |= ms->memory_read(address+4, &ddata[1], 2, &ws); + sregs->hold += ws; + sregs->icnt = T_LDD; + if (mexc) { +@@ -1401,7 +1492,7 @@ dispatch_instruction(sregs) + sregs->trap = TRAP_UNALI; + break; + } +- mexc = ms->memory_read(asi, address, &data, 2, &ws); ++ mexc = ms->memory_read(address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1423,7 +1514,7 @@ dispatch_instruction(sregs) + if (ebase.simtime < sregs->ftime) { + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = ms->memory_write(asi, address, &sregs->fsr, 2, &ws); ++ mexc = ms->memory_write(address, &sregs->fsr, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1432,12 +1523,22 @@ dispatch_instruction(sregs) + + case STA: + if (!chk_asi(sregs, &asi, op3)) break; ++ if (address & 0x3) { ++ sregs->trap = TRAP_UNALI; ++ break; ++ } ++ mexc = ms->memory_write_asi(asi, address, rdd, 2, &ws); ++ sregs->hold += ws; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ } ++ break; + case ST: + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } +- mexc = ms->memory_write(asi, address, rdd, 2, &ws); ++ mexc = ms->memory_write(address, rdd, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1445,8 +1546,14 @@ dispatch_instruction(sregs) + break; + case STBA: + if (!chk_asi(sregs, &asi, op3)) break; ++ mexc = ms->memory_write_asi(asi, address, rdd, 0, &ws); ++ sregs->hold += ws; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ } ++ break; + case STB: +- mexc = ms->memory_write(asi, address, rdd, 0, &ws); ++ mexc = ms->memory_write(address, rdd, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1454,6 +1561,28 @@ dispatch_instruction(sregs) + break; + case STDA: + if (!chk_asi(sregs, &asi, op3)) break; ++ if (address & 0x7) { ++ sregs->trap = TRAP_UNALI; ++ break; ++ } ++ if (rd & 1) { ++ rd &= 0x1e; ++ if (rd > 7) ++ rdd = &(sregs->r[(cwp + rd) & 0x7f]); ++ else ++ rdd = &(sregs->g[rd]); ++ } ++ mexc = ms->memory_write_asi(asi, address, rdd, 3, &ws); ++ sregs->hold += ws; ++ sregs->icnt = T_STD; ++#ifdef STAT ++ sregs->nstore++; /* Double store counts twice */ ++#endif ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ break; ++ } ++ break; + case STD: + if (address & 0x7) { + sregs->trap = TRAP_UNALI; +@@ -1466,7 +1595,7 @@ dispatch_instruction(sregs) + else + rdd = &(sregs->g[rd]); + } +- mexc = ms->memory_write(asi, address, rdd, 3, &ws); ++ mexc = ms->memory_write(address, rdd, 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; + #ifdef STAT +@@ -1495,7 +1624,7 @@ dispatch_instruction(sregs) + break; + } + rdd = &(sregs->fpq[0]); +- mexc = ms->memory_write(asi, address, rdd, 3, &ws); ++ mexc = ms->memory_write(address, rdd, 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; + #ifdef STAT +@@ -1511,12 +1640,22 @@ dispatch_instruction(sregs) + break; + case STHA: + if (!chk_asi(sregs, &asi, op3)) break; ++ if (address & 0x1) { ++ sregs->trap = TRAP_UNALI; ++ break; ++ } ++ mexc = ms->memory_write_asi(asi, address, rdd, 1, &ws); ++ sregs->hold += ws; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ } ++ break; + case STH: + if (address & 0x1) { + sregs->trap = TRAP_UNALI; + break; + } +- mexc = ms->memory_write(asi, address, rdd, 1, &ws); ++ mexc = ms->memory_write(address, rdd, 1, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1535,7 +1674,7 @@ dispatch_instruction(sregs) + if (sregs->frd == rd) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 2, &ws); ++ mexc = ms->memory_write(address, &sregs->fsi[rd], 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; +@@ -1555,7 +1694,7 @@ dispatch_instruction(sregs) + if ((sregs->frd == rd) || (sregs->frd + 1 == rd)) + sregs->fhold += (sregs->ftime - ebase.simtime); + } +- mexc = ms->memory_write(asi, address, &sregs->fsi[rd], 3, &ws); ++ mexc = ms->memory_write(address, &sregs->fsi[rd], 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; + #ifdef STAT +@@ -1567,18 +1706,40 @@ dispatch_instruction(sregs) + break; + case SWAPA: + if (!chk_asi(sregs, &asi, op3)) break; ++ if (address & 0x3) { ++ sregs->trap = TRAP_UNALI; ++ break; ++ } ++ mexc = ms->memory_read_asi(asi, address, &data, 2, &ws); ++ sregs->hold += ws; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ break; ++ } ++ mexc = ms->memory_write_asi(asi, address, rdd, 2, &ws); ++ sregs->hold += ws; ++ sregs->icnt = T_LDST; ++ if (mexc) { ++ sregs->trap = TRAP_DEXC; ++ break; ++ } else ++ *rdd = data; ++#ifdef STAT ++ sregs->nload++; ++#endif ++ break; + case SWAP: + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } +- mexc = ms->memory_read(asi, address, &data, 2, &ws); ++ mexc = ms->memory_read(address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } +- mexc = ms->memory_write(asi, address, rdd, 2, &ws); ++ mexc = ms->memory_write(address, rdd, 2, &ws); + sregs->hold += ws; + sregs->icnt = T_LDST; + if (mexc) { +@@ -1814,7 +1975,7 @@ fpexec(op3, rd, rs1, rs2, sregs) + sregs->ftime += T_FDIVd; + break; + case FMOVs: +- sregs->fs[rd] = sregs->fs[rs2]; ++ sregs->fsi[rd] = sregs->fsi[rs2]; + sregs->ftime += T_FMOVs; + sregs->frs1 = 32; /* rs1 ignored */ + break; +@@ -1996,7 +2157,7 @@ execute_trap(sregs) + sregs->pc = sregs->tbr; + sregs->npc = sregs->tbr + 4; + +- if ( 0 != (1 & sregs->asr17) ) { ++ if ( 0 != (1 & (sregs->asr17 >> 13)) ) { + /* single vector trapping! */ + sregs->pc = sregs->tbr & 0xfffff000; + sregs->npc = sregs->pc + 4; +@@ -2043,7 +2204,10 @@ init_regs(sregs) + sregs->npc = 4; + sregs->trap = 0; + sregs->psr &= 0x00f03fdf; +- sregs->psr |= 0x11000080; /* Set supervisor bit */ ++ if (cputype == CPU_LEON3) ++ sregs->psr |= 0xF3000080; /* Set supervisor bit */ ++ else ++ sregs->psr |= 0x11000080; /* Set supervisor bit */ + sregs->breakpoint = 0; + sregs->annul = 0; + sregs->fpstate = FP_EXE_MODE; +@@ -2072,4 +2236,8 @@ init_regs(sregs) + + sregs->rett_err = 0; + sregs->jmpltime = 0; ++ if (cputype == CPU_LEON3) { ++ sregs->asr17 = 0x107; ++ if (!nfp) sregs->asr17 |= (3 << 10); /* Meiko FPU */ ++ } + } +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index 0d00f48..a22e800 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -46,7 +46,7 @@ struct irqcell irqarr[16]; + + int ctrl_c = 0; + int sis_verbose = 0; +-char *sis_version = "2.7.5"; ++char *sis_version = "2.8"; + int nfp = 0; + int ift = 0; + int wrp = 0; +@@ -61,6 +61,7 @@ uint32 last_load_addr = 0; + int nouartrx = 0; + host_callback *sim_callback; + struct memsys *ms = &erc32sys; ++int cputype = 0; /* 0 = erc32, 3 = leon3 */ + + #ifdef ERRINJ + uint32 errcnt = 0; +@@ -482,7 +483,7 @@ exec_cmd(sregs, cmd) + sregs->pc = len & ~3; + sregs->npc = sregs->pc + 4; + if ((sregs->pc != 0) && (ebase.simtime == 0)) +- boot_init(); ++ ms->boot_init(); + printf("resuming at 0x%08x\n",sregs->pc); + if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { + stat = run_sim(sregs, VAL(cmd2), 0); +@@ -558,6 +559,11 @@ exec_cmd(sregs, cmd) + ebase.simtime = 0; + reset_all(); + reset_stat(sregs); ++ if (last_load_addr != 0) { ++ sregs->pc = last_load_addr & ~3; ++ sregs->npc = sregs->pc + 4; ++ } ++ if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init(); + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + stat = run_sim(sregs, UINT64_MAX, 0); + } else { +@@ -609,6 +615,11 @@ exec_cmd(sregs, cmd) + ebase.simtime = 0; + reset_all(); + reset_stat(sregs); ++ if (last_load_addr != 0) { ++ sregs->pc = last_load_addr & ~3; ++ sregs->npc = sregs->pc + 4; ++ } ++ if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init(); + sregs->tlimit = limcalc(sregs->freq); + stat = run_sim(sregs, UINT64_MAX, 0); + daddr = sregs->pc; +@@ -646,8 +657,8 @@ void + show_stat(sregs) + struct pstate *sregs; + { +- uint32 iinst; +- uint32 stime; ++ uint64 iinst; ++ uint64 stime; + + if (sregs->tottime == 0.0) + sregs->tottime += 1E-6; +@@ -662,37 +673,37 @@ show_stat(sregs) + printf(" Instructions : %9" PRIu64 "\n", sregs->ninst); + + #ifdef STAT +- printf(" integer : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst); ++ printf(" integer : %9.2f %%\n", 100.0 * (double) iinst / (double) sregs->ninst); + printf(" load : %9.2f %%\n", +- 100.0 * (float) sregs->nload / (float) sregs->ninst); ++ 100.0 * (double) sregs->nload / (double) sregs->ninst); + printf(" store : %9.2f %%\n", +- 100.0 * (float) sregs->nstore / (float) sregs->ninst); ++ 100.0 * (double) sregs->nstore / (double) sregs->ninst); + printf(" branch : %9.2f %%\n", +- 100.0 * (float) sregs->nbranch / (float) sregs->ninst); ++ 100.0 * (double) sregs->nbranch / (double) sregs->ninst); + printf(" float : %9.2f %%\n", +- 100.0 * (float) sregs->finst / (float) sregs->ninst); ++ 100.0 * (double) sregs->finst / (double) sregs->ninst); + printf(" Integer CPI : %9.2f\n", +- ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst)) ++ ((double) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst)) + / +- (float) (sregs->ninst - sregs->finst)); ++ (double) (sregs->ninst - sregs->finst)); + printf(" Float CPI : %9.2f\n", +- ((float) sregs->fholdt / (float) sregs->finst) + 1.0); ++ ((double) sregs->fholdt / (double) sregs->finst) + 1.0); + #endif + printf(" Overall CPI : %9.2f\n", +- (float) (stime - sregs->pwdtime) / (float) sregs->ninst); +- printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n", +- sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime), +- sregs->freq * (float) (sregs->ninst - sregs->finst) / +- (float) (stime - sregs->pwdtime), +- sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime)); +- printf(" Simulated ERC32 time : %.2f s\n", +- (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq); ++ (double) (stime - sregs->pwdtime) / (double) sregs->ninst); ++ printf("\n CPU performance (%4.1f MHz) : %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n", ++ sregs->freq, sregs->freq * (double) sregs->ninst / (double) (stime - sregs->pwdtime), ++ sregs->freq * (double) (sregs->ninst - sregs->finst) / ++ (double) (stime - sregs->pwdtime), ++ sregs->freq * (double) sregs->finst / (double) (stime - sregs->pwdtime)); ++ printf(" Simulated CPU time : %.2f s\n", ++ (double) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq); + printf(" Processor utilisation : %.2f %%\n", +- 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime))); ++ 100.0 * (1.0 - ((double) sregs->pwdtime / (double) stime))); + printf(" Real-time performance : %.2f %%\n", +- 100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6)))); ++ 100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6)))); + printf(" Simulator performance : %.2f MIPS\n", +- (double)(sregs->ninst) / sregs->tottime / 1E6); ++ (double)(sregs->ninst) / sregs->tottime / 1E6); + printf(" Used time (sys + user) : %.2f s\n\n", sregs->tottime); + } + +diff --git a/sim/erc32/grlib.c b/sim/erc32/grlib.c +new file mode 100644 +index 0000000..edb304e +--- /dev/null ++++ b/sim/erc32/grlib.c +@@ -0,0 +1,98 @@ ++/* ++ * This file is part of SIS. ++ * ++ * SIS, SPARC instruction simulator. Copyright (C) 2014 Jiri Gaisler ++ * ++ * This program is free software; you can redistribute it and/or modify it under ++ * the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 3 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, see . ++ * ++ */ ++ ++ ++#include "sis.h" ++#include "grlib.h" ++ ++ ++/* APB PNP */ ++ ++static uint32 apbppmem[32*2]; /* 32-entry APB PP AREA */ ++static int apbppindex; ++ ++int grlib_apbpp_add(uint32 id, uint32 addr) ++{ ++ apbppmem[apbppindex++] = id; ++ apbppmem[apbppindex++] = addr; ++ if(apbppindex >= (32*2)) apbppindex = 0; /* prevent overflow of area */ ++ return(apbppindex); ++} ++ ++uint32 grlib_apbpnp_read(uint32 addr) ++{ ++ uint32 read_data; ++ addr &= 0xff; ++ read_data = apbppmem[addr>>2]; ++ ++ return read_data; ++} ++ ++/* AHB PNP */ ++ ++static uint32 ahbppmem[128*8]; /* 128-entry AHB PP AREA */ ++static int ahbmppindex; ++static int ahbsppindex = 64*8; ++ ++int grlib_ahbmpp_add(uint32 id) ++{ ++ ahbppmem[ahbmppindex] = id; ++ ahbmppindex += 8; ++ if(ahbmppindex >= (64*8)) ahbmppindex = 0; /* prevent overflow of area */ ++ return(ahbmppindex); ++} ++ ++int grlib_ahbspp_add(uint32 id, uint32 addr1, uint32 addr2, ++ uint32 addr3, uint32 addr4) ++{ ++ ahbppmem[ahbsppindex] = id; ++ ahbsppindex += 4; ++ ahbppmem[ahbsppindex++] = addr1; ++ ahbppmem[ahbsppindex++] = addr2; ++ ahbppmem[ahbsppindex++] = addr3; ++ ahbppmem[ahbsppindex++] = addr4; ++ if(ahbsppindex >= (128*8)) ahbsppindex = 64*8; /* prevent overflow of area */ ++ return(ahbsppindex); ++} ++ ++uint32 grlib_ahbpnp_read(uint32 addr) ++{ ++ uint32 read_data; ++ ++ addr &= 0xfff; ++ read_data = ahbppmem[addr>>2]; ++ return read_data; ++ ++} ++ ++void grlib_init() ++{ ++ /* Add PP records for Leon3, APB bridge and interrupt controller ++ as this is not done elsewhere */ ++ ++ grlib_ahbmpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_LEON3, 0, 0)); ++ grlib_ahbspp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_APBMST, 0, 0), ++ GRLIB_PP_AHBADDR(0x80000000, 0xFFF, 0, 0, 2), ++ 0, 0, 0); ++ ++ grlib_apbpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_IRQMP, 2, 0), ++ GRLIB_PP_APBADDR(0x80000200, 0xFFF)); ++ ++} +diff --git a/sim/erc32/grlib.h b/sim/erc32/grlib.h +new file mode 100644 +index 0000000..1c03329 +--- /dev/null ++++ b/sim/erc32/grlib.h +@@ -0,0 +1,57 @@ ++/* ++ * This file is part of SIS. ++ * ++ * SIS, SPARC instruction simulator. Copyright (C) 2014 Jiri Gaisler ++ * ++ * This program is free software; you can redistribute it and/or modify it under ++ * the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 3 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, see . ++ * ++ */ ++ ++ ++/* Definitions for AMBA PNP in Gaisler Research GRLIB SOC */ ++ ++/* Vendors */ ++#define VENDOR_GAISLER 1 ++#define VENDOR_PENDER 2 ++#define VENDOR_ESA 4 ++#define VENDOR_DLR 10 ++ ++/* Devices */ ++#define GAISLER_LEON3 0x003 ++#define GAISLER_APBMST 0x006 ++#define GAISLER_SRCTRL 0x008 ++#define GAISLER_APBUART 0x00C ++#define GAISLER_IRQMP 0x00D ++#define GAISLER_GPTIMER 0x011 ++#define ESA_MCTRL 0x00F ++ ++/* How to build entries in the plug&play area */ ++#define GRLIB_PP_ID(v, d, x, i) ((v & 0xff) << 24) | ((d & 0x3ff) << 12) |\ ++ ((x & 0x1f) << 5) | (i & 0x1f) ++#define GRLIB_PP_AHBADDR(a, m, p, c, t) (a & 0xfff00000) | ((m & 0xfff) << 4) |\ ++ ((p & 1) << 17) | ((c & 1) << 16) | (t & 0x3) ++#define GRLIB_PP_APBADDR(a, m) ((a & 0xfff00)<< 12) | ((m & 0xfff) << 4) | 1 ++ ++#define AHBPP_START 0xFFFFF000 ++#define AHBPP_END 0xFFFFFFFF ++#define APBPP_START 0x800FF000 ++#define APBPP_END 0x800FFFFF ++ ++int grlib_apbpp_add(uint32 id, uint32 addr); ++int grlib_ahbmpp_add(uint32 id); ++int grlib_ahbspp_add(uint32 id, uint32 addr1, uint32 addr2, ++ uint32 addr3, uint32 addr4); ++uint32 grlib_ahbpnp_read(uint32 addr); ++uint32 grlib_apbpnp_read(uint32 addr); ++void grlib_init(); +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index ab1a38c..8f3b27d 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -52,7 +52,7 @@ run_sim(sregs, icount, dis) + ms->init_stdio(); + sregs->starttime = get_time(); + irq = 0; +- if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init(); ++ if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init(); + while (!sregs->err_mode & (icount > 0)) { + + sregs->fhold = 0; +@@ -187,6 +187,10 @@ sim_open (kind, callback, abfd, argv) + if (strcmp(argv[stat], "-nouartrx") == 0) { + nouartrx = 1; + } else ++ if (strcmp(argv[stat], "-leon3") == 0) { ++ ms = &leon3; ++ cputype = CPU_LEON3; ++ } else + if (strcmp(argv[stat], "-wrp") == 0) { + wrp = 1; + } else +@@ -224,9 +228,21 @@ sim_open (kind, callback, abfd, argv) + stat++; + } + ++ if (cputype == CPU_LEON3) ++ sregs.freq = freq ? freq : 50; ++ else ++ sregs.freq = freq ? freq : 14; ++ + if (sis_verbose) { + (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version); +- (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n"); ++ (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jiri@gaisler.se)\n\n"); ++ switch (cputype) { ++ case CPU_LEON3: ++ (*sim_callback->printf_filtered) (sim_callback, "LEON3 emulation enabled\n"); ++ break; ++ default: ++ (*sim_callback->printf_filtered) (sim_callback, "ERC32 emulation enabled\n"); ++ } + if (nfp) + (*sim_callback->printf_filtered) (sim_callback, "no FPU\n"); + if (sparclite) +@@ -235,11 +251,9 @@ sim_open (kind, callback, abfd, argv) + (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n"); + if (sis_gdb_break == 0) + (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n"); +- if (freq) +- (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq); ++ (*sim_callback->printf_filtered) (sim_callback, "CPU freq %3.1f MHz\n", sregs.freq); + } + +- sregs.freq = freq ? freq : 15; + termsave = fcntl(0, F_GETFL, 0); + INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf); + #ifdef HOST_LITTLE_ENDIAN +@@ -457,7 +471,7 @@ flush_windows () + #endif + + for (i = 0; i < 16; i++) +- ms->memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2, ++ ms->memory_write (sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2, + &ws); + + if (win == cwp) +diff --git a/sim/erc32/leon3.c b/sim/erc32/leon3.c +new file mode 100644 +index 0000000..26ea2b2 +--- /dev/null ++++ b/sim/erc32/leon3.c +@@ -0,0 +1,1066 @@ ++/* ++ * This file is part of SIS. ++ * ++ * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler, ++ * European Space Agency ++ * ++ * This program is free software; you can redistribute it and/or modify it under ++ * the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 3 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, see . ++ * ++ * Leon3 emulation, loosely based on erc32.c . ++ */ ++ ++/* The control space devices */ ++ ++#include "config.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sis.h" ++#include "grlib.h" ++#include "sim-config.h" ++ ++static int tty_setup = 1; /* default setup if not a tty */ ++ ++/* APB registers */ ++#define APBSTART 0x80000000 ++#define APBEND 0x80100000 ++ ++/* Memory exception waitstates */ ++#define MEM_EX_WS 1 ++ ++#define MOK 0 ++ ++/* LEON3 APB register addresses */ ++ ++#define IRQMP_IPR 0x204 ++#define IRQMP_IMR 0x240 ++#define IRQMP_ICR 0x20C ++#define IRQMP_IFR 0x208 ++#define GPTIMER_SCALER 0x300 ++#define GPTIMER_SCLOAD 0x304 ++#define GPTIMER_CONFIG 0x308 ++#define GPTIMER_TIMER1 0x310 ++#define GPTIMER_RELOAD1 0x314 ++#define GPTIMER_CTRL1 0x318 ++#define GPTIMER_TIMER2 0x320 ++#define GPTIMER_RELOAD2 0x324 ++#define GPTIMER_CTRL2 0x328 ++ ++#define APBUART_RXTX 0x100 ++#define APBUART_STATUS 0x104 ++ ++/* Size of UART buffers (bytes) */ ++#define UARTBUF 1024 ++ ++/* Number of simulator ticks between flushing the UARTS. */ ++/* For good performance, keep above 1000 */ ++#define UART_FLUSH_TIME 3000 ++ ++ ++/* New uart defines */ ++#define UART_TX_TIME 1000 ++#define UART_RX_TIME 1000 ++#define UARTA_DR 0x1 ++#define UARTA_SRE 0x2 ++#define UARTA_HRE 0x4 ++#define UARTA_OR 0x10 ++ ++/* IRQMP registers */ ++ ++static uint32 irqmp_ipr; ++static uint32 irqmp_imr; ++static uint32 irqmp_ifr; ++ ++/* GPTIMER registers */ ++ ++#define NGPTIMERS 2 ++#define GPTIMER_IRQ 8 ++ ++static uint32 gpt_scaler; ++static uint32 gpt_scaler_start; ++static uint32 gpt_counter[NGPTIMERS]; ++static uint32 gpt_reload[NGPTIMERS]; ++static uint32 gpt_ctrl[NGPTIMERS]; ++ ++/* ROM size 16 Mbyte */ ++#define ROM_START 0x00000000 ++#define ROM_MASK 0x00ffffff ++#define ROM_END (ROM_START + ROM_MASK + 1) ++ ++/* RAM size 16 Mbyte */ ++#define RAM_START 0x40000000 ++#define RAM_MASK 0x00ffffff ++#define RAM_END (RAM_START + RAM_MASK + 1) ++ ++/* Memory */ ++ ++static unsigned char romb[ROM_END - ROM_START]; ++static unsigned char ramb[RAM_END - RAM_START]; ++static uint32 cache_ctrl; ++ ++ ++/* UART support variables */ ++ ++static int32 fd1, fd2; /* file descriptor for input file */ ++static int32 Ucontrol; /* UART status register */ ++static unsigned char aq[UARTBUF], bq[UARTBUF]; ++static int32 anum, aind = 0; ++static int32 bnum, bind = 0; ++static char wbufa[UARTBUF], wbufb[UARTBUF]; ++static unsigned wnuma; ++static unsigned wnumb; ++static FILE *f1in, *f1out; ++static struct termios ioc1, ioc2, iocold1, iocold2; ++static int f1open = 0; ++ ++static char uarta_sreg, uarta_hreg; ++static uint32 uart_stat_reg; ++static uint32 uarta_data; ++ ++/* Forward declarations */ ++ ++static void mem_init (void); ++static void close_port (void); ++static void leon3_reset (void); ++static void irqmp_intack (int32 level); ++static void chk_irq (void); ++static void set_irq (int32 level); ++static int32 apb_read (uint32 addr, uint32 *data); ++static int apb_write (uint32 addr, uint32 data); ++static void port_init (void); ++static uint32 grlib_read_uart (uint32 addr); ++static void grlib_write_uart (uint32 addr, uint32 data); ++static void flush_uart (void); ++static void uarta_tx (void); ++static void uart_rx (caddr_t arg); ++static void uart_intr (caddr_t arg); ++static void uart_irq_start (void); ++static void gpt_intr (caddr_t arg); ++static void gpt_init (void); ++static void gpt_reset (void); ++static void gpt_scaler_set (uint32 val); ++static void timer_ctrl (uint32 val, int i); ++static unsigned char * ++ get_mem_ptr (uint32 addr, uint32 size); ++static void store_bytes (unsigned char *mem, uint32 waddr, ++ uint32 *data, int sz, int32 *ws); ++ ++static host_callback *callback; ++ ++ ++/* One-time init */ ++ ++static void ++init_sim() ++{ ++ callback = sim_callback; ++ grlib_init(); ++ mem_init(); ++ port_init(); ++ gpt_init(); ++} ++ ++/* Power-on reset init */ ++ ++static void ++reset() ++{ ++ leon3_reset(); ++ uart_irq_start(); ++ gpt_reset(); ++} ++ ++/* IU error mode manager */ ++ ++static void ++error_mode(pc) ++ uint32 pc; ++{ ++ ++} ++ ++ ++/* Memory init */ ++ ++static void ++mem_init() ++{ ++ ++/* Add AMBA P&P record for SRCTRL memory controller */ ++ ++ grlib_ahbspp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_SRCTRL, 0, 0), ++ GRLIB_PP_AHBADDR(0x00000000, 0xE00, 1, 1, 2), ++ GRLIB_PP_AHBADDR(0x40000000, 0xC00, 1, 1, 2), ++ GRLIB_PP_AHBADDR(0x20000000, 0xE00, 0, 0, 2), ++ 0); ++ if (sis_verbose) ++ printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n", ++ RAM_START, (RAM_MASK+1)/1024, (ROM_MASK+1)/1024); ++} ++ ++/* Flush ports when simulator stops */ ++ ++static void ++sim_halt() ++{ ++#ifdef FAST_UART ++ flush_uart(); ++#endif ++} ++ ++static void ++close_port() ++{ ++ if (f1open && f1in != stdin) ++ fclose(f1in); ++} ++ ++static void ++exit_sim() ++{ ++ close_port(); ++} ++ ++static void ++leon3_reset() ++{ ++ int i; ++ ++ irqmp_ipr = 0; ++ irqmp_imr = 0; ++ irqmp_ifr = 0; ++ ++ wnuma = wnumb = 0; ++ anum = aind = bnum = bind = 0; ++ ++ uart_stat_reg = UARTA_SRE | UARTA_HRE; ++ ++ gpt_counter[0] = 0xffffffff; ++ gpt_reload[0] = 0xffffffff; ++ gpt_scaler = 0xffff; ++ gpt_ctrl[0] = 0; ++ gpt_ctrl[1] = 0; ++ ++} ++ ++ ++ ++static void ++irqmp_intack(level) ++ int32 level; ++{ ++ int irq_test; ++ ++ if (sis_verbose > 2) ++ printf("interrupt %d acknowledged\n", level); ++ if (irqmp_ifr & (1 << level)) ++ irqmp_ifr &= ~(1 << level); ++ else ++ irqmp_ipr &= ~(1 << level); ++ chk_irq(); ++} ++ ++static void ++chk_irq() ++{ ++ int32 i; ++ uint32 itmp; ++ int old_irl; ++ ++ old_irl = ext_irl; ++ itmp = ((irqmp_ipr | irqmp_ifr) & irqmp_imr) & 0x0fffe; ++ ext_irl = 0; ++ if (itmp != 0) { ++ for (i = 15; i > 0; i--) { ++ if (((itmp >> i) & 1) != 0) { ++ if ((sis_verbose > 2) && (i > old_irl)) ++ printf("IU irl: %d\n", i); ++ ext_irl = i; ++ set_int(i, irqmp_intack, i); ++ break; ++ } ++ } ++ } ++} ++ ++static void ++set_irq(level) ++ int32 level; ++{ ++ irqmp_ipr |= (1 << level); ++ chk_irq(); ++} ++ ++static int32 ++apb_read(addr, data) ++ uint32 addr; ++ uint32 *data; ++{ ++ ++ switch (addr & 0xfff) { ++ ++ case APBUART_RXTX: /* 0x100 */ ++ case APBUART_STATUS: /* 0x104 */ ++ *data = grlib_read_uart(addr); ++ break; ++ ++ case IRQMP_IPR: /* 0x204 */ ++ *data = irqmp_ipr; ++ break; ++ ++ case IRQMP_IFR: /* 0x208 */ ++ *data = irqmp_ifr; ++ break; ++ ++ case IRQMP_IMR: /* 0x240 */ ++ *data = irqmp_imr; ++ break; ++ ++ case GPTIMER_SCALER: /* 0x300 */ ++ *data = gpt_scaler - (now() - gpt_scaler_start); ++ break; ++ ++ case GPTIMER_SCLOAD: /* 0x304 */ ++ *data = gpt_scaler; ++ break; ++ ++ case GPTIMER_CONFIG: /* 0x308 */ ++ *data = 0x100 | (GPTIMER_IRQ << 3) | NGPTIMERS; ++ break; ++ ++ case GPTIMER_TIMER1: /* 0x310 */ ++ *data = gpt_counter[0]; ++ break; ++ ++ case GPTIMER_RELOAD1: /* 0x314 */ ++ *data = gpt_reload[0]; ++ break; ++ ++ case GPTIMER_CTRL1: /* 0x318 */ ++ *data = gpt_ctrl[0]; ++ break; ++ ++ case GPTIMER_TIMER2: /* 0x320 */ ++ *data = gpt_counter[1]; ++ break; ++ ++ case GPTIMER_RELOAD2: /* 0x324 */ ++ *data = gpt_reload[1]; ++ break; ++ ++ case GPTIMER_CTRL2: /* 0x328 */ ++ *data = gpt_ctrl[1]; ++ break; ++ ++ default: ++ *data = 0; ++ break; ++ } ++ ++ if (sis_verbose > 1) ++ printf("APB read a: %08x, d: %08x\n", addr, *data); ++ ++ return (MOK); ++} ++ ++static int ++apb_write(addr, data) ++ uint32 addr; ++ uint32 data; ++{ ++ if (sis_verbose > 1) ++ printf("APB write a: %08x, d: %08x\n",addr,data); ++ switch (addr & 0xfff) { ++ ++ case APBUART_RXTX: /* 0x100 */ ++ case APBUART_STATUS: /* 0x104 */ ++ grlib_write_uart(addr, data); ++ break; ++ ++ case IRQMP_IFR: /* 0x208 */ ++ irqmp_ifr = data & 0xfffe; ++ chk_irq(); ++ break; ++ ++ case IRQMP_ICR: /* 0x20C */ ++ irqmp_ipr &= ~data & 0x0fffe; ++ chk_irq(); ++ break; ++ ++ case IRQMP_IMR: /* 0x240 */ ++ irqmp_imr = data & 0x7ffe; ++ chk_irq(); ++ break; ++ ++ case GPTIMER_SCLOAD: /* 0x304 */ ++ gpt_scaler_set(data); ++ break; ++ ++ case GPTIMER_TIMER1: /* 0x310 */ ++ gpt_counter[0] = data; ++ break; ++ ++ case GPTIMER_RELOAD1: /* 0x314 */ ++ gpt_reload[0] = data; ++ break; ++ ++ case GPTIMER_CTRL1: /* 0x318 */ ++ timer_ctrl(data, 0); ++ break; ++ ++ case GPTIMER_TIMER2: /* 0x320 */ ++ gpt_counter[1] = data; ++ break; ++ ++ case GPTIMER_RELOAD2: /* 0x324 */ ++ gpt_reload[1] = data; ++ break; ++ ++ case GPTIMER_CTRL2: /* 0x328 */ ++ timer_ctrl(data, 1); ++ break; ++ ++ default: ++ break; ++ } ++ return (MOK); ++} ++ ++ ++/* APBUART */ ++ ++static int ifd1 = -1, ofd1 = -1; ++ ++static void ++init_stdio() ++{ ++ if (dumbio) ++ return; /* do nothing */ ++ if (ifd1 == 0 && f1open) { ++ tcsetattr(0, TCSANOW, &ioc1); ++ tcflush(ifd1, TCIFLUSH); ++ } ++} ++ ++static void ++restore_stdio() ++{ ++ if (dumbio) ++ return; /* do nothing */ ++ if (ifd1 == 0 && f1open && tty_setup) ++ tcsetattr(0, TCSANOW, &iocold1); ++} ++ ++#define DO_STDIO_READ( _fd_, _buf_, _len_ ) \ ++ ( dumbio || nouartrx \ ++ ? (0) /* no bytes read, no delay */ \ ++ : (_fd_) == 1 && callback ? \ ++ callback->read_stdin (callback, _buf_, _len_) : \ ++ read( _fd_, _buf_, _len_ ) ) ++ ++ ++static void ++port_init() ++{ ++ ++ f1in = stdin; ++ f1out = stdout; ++ if (uart_dev1[0] != 0) ++ if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) { ++ printf("Warning, couldn't open output device %s\n", uart_dev1); ++ } else { ++ if (sis_verbose) ++ printf("serial port A on %s\n", uart_dev1); ++ f1in = f1out = fdopen(fd1, "r+"); ++ setbuf(f1out, NULL); ++ f1open = 1; ++ } ++ if (f1in) ifd1 = fileno(f1in); ++ if (ifd1 == 0) { ++ if (callback && !callback->isatty(callback, ifd1)) { ++ tty_setup = 0; ++ } ++ if (sis_verbose) ++ printf("serial port A on stdin/stdout\n"); ++ if (!dumbio) { ++ tcgetattr(ifd1, &ioc1); ++ if (tty_setup) { ++ iocold1 = ioc1; ++ ioc1.c_lflag &= ~(ICANON | ECHO); ++ ioc1.c_cc[VMIN] = 0; ++ ioc1.c_cc[VTIME] = 0; ++ } ++ } ++ f1open = 1; ++ } ++ ++ if (f1out) { ++ ofd1 = fileno(f1out); ++ if (!dumbio && tty_setup && ofd1 == 1) setbuf(f1out, NULL); ++ } ++ ++ wnuma = 0; ++ ++ ++ grlib_apbpp_add(GRLIB_PP_ID(VENDOR_GAISLER, GAISLER_APBUART, 1, 3), ++ GRLIB_PP_APBADDR(0x80000100, 0xFFF)); ++} ++ ++static uint32 ++grlib_read_uart(addr) ++ uint32 addr; ++{ ++ ++ unsigned tmp; ++ ++ tmp = 0; ++ switch (addr & 0xff) { ++ ++ case 0x00: /* UART 1 RX/TX */ ++#ifndef _WIN32 ++#ifdef FAST_UART ++ ++ if (aind < anum) { ++ if ((aind + 1) < anum) ++ set_irq(3); ++ return ((uint32) aq[aind++]); ++ } else { ++ if (f1open) { ++ anum = DO_STDIO_READ(ifd1, aq, UARTBUF); ++ } ++ else { ++ anum = 0; ++ } ++ if (anum > 0) { ++ aind = 0; ++ if ((aind + 1) < anum) ++ set_irq(3); ++ return ((uint32) aq[aind++]); ++ } else { ++ return ((uint32) aq[aind]); ++ } ++ ++ } ++#else ++ tmp = uarta_data; ++ uarta_data &= ~UART_DR; ++ uart_stat_reg &= ~UARTA_DR; ++ return tmp; ++#endif ++#else ++ return(0); ++#endif ++ break; ++ ++ case 0x04: /* UART status register */ ++#ifndef _WIN32 ++#ifdef FAST_UART ++ ++ Ucontrol = 0; ++ if (aind < anum) { ++ Ucontrol |= 0x00000001; ++ } else { ++ if (f1open) { ++ anum = DO_STDIO_READ(ifd1, aq, UARTBUF); ++ } ++ else { ++ anum = 0; ++ } ++ if (anum > 0) { ++ Ucontrol |= 0x00000001; ++ aind = 0; ++ set_irq(3); ++ } ++ } ++ Ucontrol |= 0x00000006; ++ return (Ucontrol); ++#else ++ return (uart_stat_reg); ++#endif ++#else ++ return(0x00060006); ++#endif ++ break; ++ default: ++ if (sis_verbose) ++ printf("Read from unimplemented MEC register (%x)\n", addr); ++ ++ } ++ return (0); ++} ++ ++static void ++grlib_write_uart(addr, data) ++ uint32 addr; ++ uint32 data; ++{ ++ unsigned char c; ++ ++ c = (unsigned char) data; ++ switch (addr & 0xff) { ++ ++ case 0x00: /* UART A */ ++#ifdef FAST_UART ++ if (f1open) { ++ if (wnuma < UARTBUF) ++ wbufa[wnuma++] = c; ++ else { ++ while (wnuma) { ++ if (ofd1 == 1 && callback) ++ wnuma -= callback->write_stdout(callback, wbufa, wnuma); ++ else ++ wnuma -= fwrite(wbufa, 1, wnuma, f1out); ++ } ++ wbufa[wnuma++] = c; ++ } ++ } ++ set_irq(3); ++#else ++ if (uart_stat_reg & UARTA_SRE) { ++ uarta_sreg = c; ++ uart_stat_reg &= ~UARTA_SRE; ++ event(uarta_tx, 0, UART_TX_TIME); ++ } else { ++ uarta_hreg = c; ++ uart_stat_reg &= ~UARTA_HRE; ++ } ++#endif ++ break; ++ ++ case 0x04: /* UART status register */ ++#ifndef FAST_UART ++ uart_stat_reg &= 1; ++#endif ++ break; ++ default: ++ if (sis_verbose) ++ printf("Write to unimplemented APB register (%x)\n", addr); ++ ++ } ++} ++ ++static void ++flush_uart() ++{ ++ while (wnuma && f1open) { ++ if (ofd1 == 1 && callback) { ++ wnuma -= callback->write_stdout(callback, wbufa, wnuma); ++ callback->flush_stdout(callback); ++ } ++ else ++ wnuma -= fwrite(wbufa, 1, wnuma, f1out); ++ } ++} ++ ++ ++ ++static void ++uarta_tx() ++{ ++ while (f1open) { ++ if (ofd1 == 1 && callback) { ++ while (callback->write_stdout(callback, &uarta_sreg, 1) != 1); ++ } ++ else { ++ while (fwrite(&uarta_sreg, 1, 1, f1out) != 1); ++ } ++ } ++ if (uart_stat_reg & UARTA_HRE) { ++ uart_stat_reg |= UARTA_SRE; ++ } else { ++ uarta_sreg = uarta_hreg; ++ uart_stat_reg |= UARTA_HRE; ++ event(uarta_tx, 0, UART_TX_TIME); ++ } ++ set_irq(3); ++} ++ ++static void ++uart_rx(arg) ++ caddr_t arg; ++{ ++ int32 rsize; ++ char rxd; ++ ++ ++ rsize = 0; ++ if (f1open) ++ rsize = DO_STDIO_READ(ifd1, &rxd, 1); ++ else ++ rsize = 0; ++ if (rsize > 0) { ++ uarta_data = rxd; ++ if (uart_stat_reg & UARTA_DR) { ++ uart_stat_reg |= UARTA_OR; ++ } ++ uart_stat_reg |= UARTA_DR; ++ set_irq(3); ++ } ++ event(uart_rx, 0, UART_RX_TIME); ++} ++ ++static void ++uart_intr(arg) ++ caddr_t arg; ++{ ++ grlib_read_uart(APBUART_STATUS); /* Check for UART interrupts every 1000 clk */ ++ flush_uart(); /* Flush UART ports */ ++ event(uart_intr, 0, UART_FLUSH_TIME); ++} ++ ++ ++static void ++uart_irq_start() ++{ ++#ifdef FAST_UART ++ event(uart_intr, 0, UART_FLUSH_TIME); ++#else ++#ifndef _WIN32 ++ event(uart_rx, 0, UART_RX_TIME); ++#endif ++#endif ++} ++ ++/* GPTIMER */ ++ ++static void ++gpt_intr(arg) ++ caddr_t arg; ++{ ++ int i; ++ ++ for (i=0; i= RAM_START) && (addr < RAM_END)) { ++ *data = *((uint32 *) & (ramb[addr & RAM_MASK])); ++ *ws = 0; ++ return (0); ++ } else if (addr < ROM_END) { ++ *data = *((uint32 *) & (romb[addr])); ++ *ws = 0; ++ return (0); ++ } ++ ++ printf("Memory exception at %x (illegal address)\n", addr); ++ *ws = MEM_EX_WS; ++ return (1); ++} ++ ++static int ++memory_read(addr, data, sz, ws) ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ int32 mexc; ++ ++ if ((addr >= RAM_START) && (addr < RAM_END)) { ++ *data = *((uint32 *) & (ramb[addr & RAM_MASK & ~3])); ++ *ws = 0; ++ return (0); ++ } else if ((addr >= APBPP_START) && (addr <= APBPP_END)) { ++ *data = grlib_apbpnp_read(addr); ++ if (sis_verbose > 1) ++ printf("APB PP read a: %08x, d: %08x\n",addr, *data); ++ *ws = 4; ++ return (0); ++ } else if ((addr >= APBSTART) && (addr < APBEND)) { ++ mexc = apb_read(addr, data); ++ if (mexc) { ++ *ws = MEM_EX_WS; ++ } else { ++ *ws = 0; ++ } ++ return (mexc); ++ } else if ((addr >= AHBPP_START) && (addr <= AHBPP_END)) { ++ if (sis_verbose > 1) ++ printf("AHB PP read a: %08x, d: %08x\n",addr, *data); ++ *data = grlib_ahbpnp_read(addr); ++ *ws = 4; ++ return (0); ++ } else if (addr < ROM_END) { ++ *data = *((uint32 *) & (romb[addr & ~3])); ++ *ws = 0; ++ return (0); ++ } ++ ++ printf("Memory exception at %x (illegal address)\n", addr); ++ *ws = MEM_EX_WS; ++ return (1); ++} ++ ++static int ++memory_read_asi(asi, addr, data, sz, ws) ++ int32 asi; ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ if (asi == 2) { ++ if (addr == 0) ++ *data = cache_ctrl; ++ else ++ *data = 0; ++ return MOK; ++ } else ++ return(memory_read(addr, data, sz, ws)); ++} ++ ++static int ++memory_write(addr, data, sz, ws) ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ uint32 byte_addr; ++ uint32 byte_mask; ++ uint32 waddr; ++ uint32 *ram; ++ int32 mexc; ++ int i; ++ int wphit[2]; ++ ++ if ((addr >= RAM_START) && (addr < RAM_END)) { ++ waddr = addr & RAM_MASK; ++ store_bytes (ramb, waddr, data, sz, ws); ++ return (0); ++ ++ } else if ((addr >= APBSTART) && (addr < APBEND)) { ++ if (sz != 2) { ++ *ws = MEM_EX_WS; ++ return (1); ++ } ++ apb_write(addr, *data); ++ *ws = 0; ++ return (0); ++ ++ } else if (addr < ROM_END) { ++// return (1); ++ *ws = 0; ++ store_bytes (romb, addr, data, sz, ws); ++ return (0); ++ } ++ ++ *ws = MEM_EX_WS; ++ return (1); ++} ++ ++static int ++memory_write_asi(asi, addr, data, sz, ws) ++ int32 asi; ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ if (asi == 2) { ++ cache_ctrl = *data & 0x81000f; ++ if (sis_verbose) ++ printf("cache ctrl reg : 0x%08x\n", cache_ctrl); ++ return MOK; ++ } else ++ return(memory_write(addr, data, sz, ws)); ++} ++ ++static unsigned char * ++get_mem_ptr(addr, size) ++ uint32 addr; ++ uint32 size; ++{ ++ if ((addr + size) < ROM_END) { ++ return (&romb[addr]); ++ } else if ((addr >= RAM_START) && ((addr + size) < RAM_END)) { ++ return (&ramb[addr & RAM_MASK]); ++ } ++ ++ return ((char *) -1); ++} ++ ++static int ++sis_memory_write(addr, data, length) ++ uint32 addr; ++ const unsigned char *data; ++ uint32 length; ++{ ++ char *mem; ++ ++ if ((mem = get_mem_ptr(addr, length)) == ((char *) -1)) ++ return (0); ++ ++ memcpy(mem, data, length); ++ return (length); ++} ++ ++static int ++sis_memory_read(addr, data, length) ++ uint32 addr; ++ char *data; ++ uint32 length; ++{ ++ char *mem; ++ int ws; ++ ++ if (length == 4) { ++ memory_read(addr, data, length, &ws); ++ return(4); ++ } ++ ++ if ((mem = get_mem_ptr(addr, length)) == ((char *) -1)) ++ return (0); ++ ++ memcpy(data, mem, length); ++ return (length); ++} ++ ++static void ++boot_init () ++{ ++// mec_write(MEC_WCR, 0); /* zero waitstates */ ++// mec_write(MEC_TRAPD, 0); /* turn off watch-dog */ ++ apb_write(GPTIMER_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */ ++ apb_write(GPTIMER_SCLOAD, sregs.freq-1); ++ apb_write(GPTIMER_TIMER1, -1); ++ apb_write(GPTIMER_RELOAD1, -1); ++ apb_write(GPTIMER_CTRL1, 0x7); ++// mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */ ++ sregs.wim = 2; ++ sregs.psr = 0xF30010e0; ++ sregs.r[30] = RAM_END; ++ sregs.r[14] = sregs.r[30] - 96*4; ++ cache_ctrl = 0x81000f; ++} ++ ++struct memsys leon3 = { ++ init_sim, ++ reset, ++ error_mode, ++ sim_halt, ++ exit_sim, ++ init_stdio, ++ restore_stdio, ++ memory_iread, ++ memory_read, ++ memory_read_asi, ++ memory_write, ++ memory_write_asi, ++ sis_memory_write, ++ sis_memory_read, ++ boot_init ++}; +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index d833da3..0e19270 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -142,7 +142,7 @@ main(argc, argv) + for (i = 0; i < 64; i++) + cmdq[i] = 0; + printf("\n SIS - SPARC instruction simulator %s, copyright Jiri Gaisler 1995\n", sis_version); +- printf(" Bug-reports to jgais@wd.estec.esa.nl\n\n"); ++ printf(" Bug-reports to jiri@gaisler.se\n\n"); + while (stat < argc) { + if (argv[stat][0] == '-') { + if (strcmp(argv[stat], "-v") == 0) { +@@ -181,6 +181,10 @@ main(argc, argv) + dumbio = 1; + } else if (strcmp(argv[stat], "-nouartrx") == 0) { + nouartrx = 1; ++ } else if (strcmp(argv[stat], "-leon3") == 0) { ++ ms = &leon3; ++ if (freq == 14) freq = 50; ++ cputype = CPU_LEON3; + } else if (strcmp(argv[stat], "-v") == 0) { + sis_verbose += 1; + } else { +@@ -193,13 +197,19 @@ main(argc, argv) + } + stat++; + } ++ ++ switch (cputype) { ++ case CPU_LEON3: ++ printf(" LEON3 emulation enabled\n"); ++ break; ++ default: ++ printf(" ERC32 emulation enabled\n"); ++ } ++ + if (nfp) +- printf("FPU disabled\n"); +-#ifdef ERA +- if (era) +- printf("ERA ECC emulation enabled\n"); +-#endif ++ printf(" FPU disabled\n"); + sregs.freq = freq; ++ printf("\n"); + + INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf); + #ifdef HOST_LITTLE_ENDIAN +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index 8a48f29..a551b4a 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -159,6 +159,30 @@ struct irqcell { + int32 arg; + }; + ++struct memsys { ++ void (*init_sim) (); ++ void (*reset) (void); ++ void (*error_mode) (uint32 pc); ++ void (*sim_halt) (void); ++ void (*exit_sim) (void); ++ void (*init_stdio) (void); ++ void (*restore_stdio) (void); ++ int (*memory_iread) (uint32 addr, uint32 *data, int32 *ws); ++ int (*memory_read) (uint32 addr, uint32 *data, ++ int32 sz, int32 *ws); ++ int (*memory_read_asi) (int32 asi, uint32 addr, uint32 *data, ++ int32 sz, int32 *ws); ++ int (*memory_write) (uint32 addr, uint32 *data, ++ int32 sz, int32 *ws); ++ int (*memory_write_asi) (int32 asi, uint32 addr, uint32 *data, ++ int32 sz, int32 *ws); ++ int (*sis_memory_write) (uint32 addr, ++ const unsigned char *data, uint32 length); ++ int (*sis_memory_read) (uint32 addr, char *data, ++ uint32 length); ++ void (*boot_init) (void); ++}; ++ + + #define OK 0 + #define TIME_OUT 1 +@@ -166,6 +190,8 @@ struct irqcell { + #define ERROR 3 + #define CTRL_C 4 + ++#define CPU_LEON3 3 ++ + /* Prototypes */ + + /* erc32.c */ +@@ -221,6 +247,7 @@ extern int nouartrx; + extern host_callback *sim_callback; + extern int current_target_byte_order; + extern int dumbio; ++extern int cputype; + + /* exec.c */ + extern int dispatch_instruction (struct pstate *sregs); +@@ -241,23 +268,7 @@ extern void set_fsr (uint32 fsr); + extern void usage (void); + extern void gen_help (void); + +-struct memsys { +- void (*init_sim) (); +- void (*reset) (void); +- void (*error_mode) (uint32 pc); +- void (*sim_halt) (void); +- void (*exit_sim) (void); +- void (*init_stdio) (void); +- void (*restore_stdio) (void); +- int (*memory_iread) (uint32 addr, uint32 *data, int32 *ws); +- int (*memory_read) (int32 asi, uint32 addr, uint32 *data, +- int32 sz, int32 *ws); +- int (*memory_write) (int32 asi, uint32 addr, uint32 *data, +- int32 sz, int32 *ws); +- int (*sis_memory_write) (uint32 addr, +- const unsigned char *data, uint32 length); +- int (*sis_memory_read) (uint32 addr, char *data, +- uint32 length); +-}; +- + extern struct memsys *ms; ++ ++/* leon3.c */ ++extern struct memsys leon3; +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0019-sim-erc32-Add-support-for-LEON2-processor-emulation.patch b/tools/4.11/gdb/sparc/7.9/0019-sim-erc32-Add-support-for-LEON2-processor-emulation.patch new file mode 100644 index 0000000..7076933 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0019-sim-erc32-Add-support-for-LEON2-processor-emulation.patch @@ -0,0 +1,1188 @@ +From 2c2afb029df432bd32f72789944cec2717861f7e Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Wed, 18 Feb 2015 22:54:34 +0100 +Subject: [PATCH 19/23] sim/erc32: Add support for LEON2 processor emulation. + + Added memory and I/O sub-system to emulate a LEON2 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 leon3.c and modified to emulate the + LEON2 address space and peripheral operations. +--- + sim/erc32/Makefile.in | 4 +- + sim/erc32/exec.c | 3 + + sim/erc32/interf.c | 11 +- + sim/erc32/leon2.c | 1041 +++++++++++++++++++++++++++++++++++++++++++++++++ + sim/erc32/sis.c | 7 + + sim/erc32/sis.h | 4 + + 6 files changed, 1066 insertions(+), 4 deletions(-) + create mode 100644 sim/erc32/leon2.c + +diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in +index e40eb79..bee357b 100644 +--- a/sim/erc32/Makefile.in ++++ b/sim/erc32/Makefile.in +@@ -21,7 +21,7 @@ + TERMCAP_LIB = @TERMCAP@ + READLINE_LIB = @READLINE@ + +-SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o leon3.o grlib.o ++SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o leon2.o leon3.o grlib.o + SIM_EXTRA_LIBS = $(READLINE_LIB) $(TERMCAP_LIB) -lm + SIM_EXTRA_ALL = sis + SIM_EXTRA_INSTALL = install-sis +@@ -35,7 +35,7 @@ SIM_EXTRA_CFLAGS = -DFAST_UART -I$(srcroot) + ## COMMON_POST_CONFIG_FRAG + + # `sis' doesn't need interf.o. +-SIS_OFILES = exec.o erc32.o func.o help.o float.o grlib.o leon3.o ++SIS_OFILES = exec.o erc32.o func.o help.o float.o grlib.o leon2.o leon3.o + + sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) -o sis \ +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index 6292998..f4a0124 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -2207,6 +2207,9 @@ init_regs(sregs) + if (cputype == CPU_LEON3) + sregs->psr |= 0xF3000080; /* Set supervisor bit */ + else ++ if (cputype == CPU_LEON2) ++ sregs->psr |= 0x00000080; /* Set supervisor bit */ ++ else + sregs->psr |= 0x11000080; /* Set supervisor bit */ + sregs->breakpoint = 0; + sregs->annul = 0; +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index 8f3b27d..8988f23 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -187,6 +187,10 @@ sim_open (kind, callback, abfd, argv) + if (strcmp(argv[stat], "-nouartrx") == 0) { + nouartrx = 1; + } else ++ if (strcmp(argv[stat], "-leon2") == 0) { ++ ms = &leon2; ++ cputype = CPU_LEON2; ++ } else + if (strcmp(argv[stat], "-leon3") == 0) { + ms = &leon3; + cputype = CPU_LEON3; +@@ -228,15 +232,18 @@ sim_open (kind, callback, abfd, argv) + stat++; + } + +- if (cputype == CPU_LEON3) ++ if ((cputype == CPU_LEON3) || (cputype == CPU_LEON2)) + sregs.freq = freq ? freq : 50; + else + sregs.freq = freq ? freq : 14; + + if (sis_verbose) { + (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version); +- (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jiri@gaisler.se)\n\n"); ++ (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler (jiri@gaisler.se)\n\n"); + switch (cputype) { ++ case CPU_LEON2: ++ (*sim_callback->printf_filtered) (sim_callback, "LEON2 emulation enabled\n"); ++ break; + case CPU_LEON3: + (*sim_callback->printf_filtered) (sim_callback, "LEON3 emulation enabled\n"); + break; +diff --git a/sim/erc32/leon2.c b/sim/erc32/leon2.c +new file mode 100644 +index 0000000..cf86167 +--- /dev/null ++++ b/sim/erc32/leon2.c +@@ -0,0 +1,1041 @@ ++/* ++ * This file is part of SIS. ++ * ++ * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler, ++ * European Space Agency ++ * ++ * This program is free software; you can redistribute it and/or modify it under ++ * the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 3 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, see . ++ * ++ * Leon2 emulation, based on leon3.c . ++ */ ++ ++/* The control space devices */ ++ ++#include "config.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sis.h" ++#include "sim-config.h" ++ ++static int tty_setup = 1; /* default setup if not a tty */ ++ ++/* APB registers */ ++#define APBSTART 0x80000000 ++#define APBEND 0x80000100 ++ ++/* Memory exception waitstates */ ++#define MEM_EX_WS 1 ++ ++#define MOK 0 ++ ++/* LEON2 APB register addresses */ ++ ++#define IRQCTRL_IPR 0x094 ++#define IRQCTRL_IMR 0x090 ++#define IRQCTRL_ICR 0x09C ++#define IRQCTRL_IFR 0x098 ++#define TIMER_SCALER 0x060 ++#define TIMER_SCLOAD 0x064 ++#define LEON2_CONFIG 0x024 ++#define TIMER_TIMER1 0x040 ++#define TIMER_RELOAD1 0x044 ++#define TIMER_CTRL1 0x048 ++#define TIMER_TIMER2 0x050 ++#define TIMER_RELOAD2 0x054 ++#define TIMER_CTRL2 0x058 ++#define CACHE_CTRL 0x014 ++#define POWER_DOWN 0x018 ++ ++#define APBUART_RXTX 0x070 ++#define APBUART_STATUS 0x074 ++ ++/* Size of UART buffers (bytes) */ ++#define UARTBUF 1024 ++ ++/* Number of simulator ticks between flushing the UARTS. */ ++/* For good performance, keep above 1000 */ ++#define UART_FLUSH_TIME 3000 ++ ++ ++/* New uart defines */ ++#define UART_TX_TIME 1000 ++#define UART_RX_TIME 1000 ++#define UARTA_DR 0x1 ++#define UARTA_SRE 0x2 ++#define UARTA_HRE 0x4 ++#define UARTA_OR 0x10 ++ ++/* IRQCTRL registers */ ++ ++static uint32 irqctrl_ipr; ++static uint32 irqctrl_imr; ++static uint32 irqctrl_ifr; ++ ++/* TIMER registers */ ++ ++#define NTIMERS 2 ++#define TIMER_IRQ 8 ++ ++static uint32 gpt_scaler; ++static uint32 gpt_scaler_start; ++static uint32 gpt_counter[NTIMERS]; ++static uint32 gpt_reload[NTIMERS]; ++static uint32 gpt_ctrl[NTIMERS]; ++ ++/* ROM size 16 Mbyte */ ++#define ROM_START 0x00000000 ++#define ROM_MASK 0x00ffffff ++#define ROM_END (ROM_START + ROM_MASK + 1) ++ ++/* RAM size 16 Mbyte */ ++#define RAM_START 0x40000000 ++#define RAM_MASK 0x00ffffff ++#define RAM_END (RAM_START + RAM_MASK + 1) ++ ++/* Memory */ ++ ++static unsigned char romb[ROM_END - ROM_START]; ++static unsigned char ramb[RAM_END - RAM_START]; ++static uint32 cache_ctrl; ++ ++ ++/* UART support variables */ ++ ++static int32 fd1, fd2; /* file descriptor for input file */ ++static int32 Ucontrol; /* UART status register */ ++static unsigned char aq[UARTBUF], bq[UARTBUF]; ++static int32 anum, aind = 0; ++static int32 bnum, bind = 0; ++static char wbufa[UARTBUF], wbufb[UARTBUF]; ++static unsigned wnuma; ++static unsigned wnumb; ++static FILE *f1in, *f1out; ++static struct termios ioc1, ioc2, iocold1, iocold2; ++static int f1open = 0; ++ ++static char uarta_sreg, uarta_hreg; ++static uint32 uart_stat_reg; ++static uint32 uarta_data; ++ ++/* Forward declarations */ ++ ++static void mem_init (void); ++static void close_port (void); ++static void leon2_reset (void); ++static void irqctrl_intack (int32 level); ++static void chk_irq (void); ++static void set_irq (int32 level); ++static int32 apb_read (uint32 addr, uint32 *data); ++static int apb_write (uint32 addr, uint32 data); ++static void port_init (void); ++static uint32 grlib_read_uart (uint32 addr); ++static void grlib_write_uart (uint32 addr, uint32 data); ++static void flush_uart (void); ++static void uarta_tx (void); ++static void uart_rx (caddr_t arg); ++static void uart_intr (caddr_t arg); ++static void uart_irq_start (void); ++static void gpt_intr (caddr_t arg); ++static void gpt_init (void); ++static void gpt_reset (void); ++static void gpt_scaler_set (uint32 val); ++static void timer_ctrl (uint32 val, int i); ++static unsigned char * ++ get_mem_ptr (uint32 addr, uint32 size); ++static void store_bytes (unsigned char *mem, uint32 waddr, ++ uint32 *data, int sz, int32 *ws); ++ ++static host_callback *callback; ++ ++ ++/* One-time init */ ++ ++static void ++init_sim() ++{ ++ callback = sim_callback; ++ grlib_init(); ++ mem_init(); ++ port_init(); ++ gpt_init(); ++} ++ ++/* Power-on reset init */ ++ ++static void ++reset() ++{ ++ leon2_reset(); ++ uart_irq_start(); ++ gpt_reset(); ++} ++ ++/* IU error mode manager */ ++ ++static void ++error_mode(pc) ++ uint32 pc; ++{ ++ ++} ++ ++ ++/* Memory init */ ++ ++static void ++mem_init() ++{ ++ ++ if (sis_verbose) ++ printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n", ++ RAM_START, (RAM_MASK+1)/1024, (ROM_MASK+1)/1024); ++} ++ ++/* Flush ports when simulator stops */ ++ ++static void ++sim_halt() ++{ ++#ifdef FAST_UART ++ flush_uart(); ++#endif ++} ++ ++static void ++close_port() ++{ ++ if (f1open && f1in != stdin) ++ fclose(f1in); ++} ++ ++static void ++exit_sim() ++{ ++ close_port(); ++} ++ ++static void ++leon2_reset() ++{ ++ int i; ++ ++ irqctrl_ipr = 0; ++ irqctrl_imr = 0; ++ irqctrl_ifr = 0; ++ ++ wnuma = wnumb = 0; ++ anum = aind = bnum = bind = 0; ++ ++ uart_stat_reg = UARTA_SRE | UARTA_HRE; ++ ++ gpt_counter[0] = 0xffffffff; ++ gpt_reload[0] = 0xffffffff; ++ gpt_scaler = 0xffff; ++ gpt_ctrl[0] = 0; ++ gpt_ctrl[1] = 0; ++ ++} ++ ++ ++ ++static void ++irqctrl_intack(level) ++ int32 level; ++{ ++ int irq_test; ++ ++ if (sis_verbose > 2) ++ printf("interrupt %d acknowledged\n", level); ++ if (irqctrl_ifr & (1 << level)) ++ irqctrl_ifr &= ~(1 << level); ++ else ++ irqctrl_ipr &= ~(1 << level); ++ chk_irq(); ++} ++ ++static void ++chk_irq() ++{ ++ int32 i; ++ uint32 itmp; ++ int old_irl; ++ ++ old_irl = ext_irl; ++ itmp = ((irqctrl_ipr | irqctrl_ifr) & irqctrl_imr) & 0x0fffe; ++ ext_irl = 0; ++ if (itmp != 0) { ++ for (i = 15; i > 0; i--) { ++ if (((itmp >> i) & 1) != 0) { ++ if ((sis_verbose > 2) && (i > old_irl)) ++ printf("IU irl: %d\n", i); ++ ext_irl = i; ++ set_int(i, irqctrl_intack, i); ++ break; ++ } ++ } ++ } ++} ++ ++static void ++set_irq(level) ++ int32 level; ++{ ++ irqctrl_ipr |= (1 << level); ++ chk_irq(); ++} ++ ++static int32 ++apb_read(addr, data) ++ uint32 addr; ++ uint32 *data; ++{ ++ ++ switch (addr & 0xfff) { ++ ++ case APBUART_RXTX: /* 0x100 */ ++ case APBUART_STATUS: /* 0x104 */ ++ *data = grlib_read_uart(addr); ++ break; ++ ++ case IRQCTRL_IPR: /* 0x204 */ ++ *data = irqctrl_ipr; ++ break; ++ ++ case IRQCTRL_IFR: /* 0x208 */ ++ *data = irqctrl_ifr; ++ break; ++ ++ case IRQCTRL_IMR: /* 0x240 */ ++ *data = irqctrl_imr; ++ break; ++ ++ case TIMER_SCALER: /* 0x300 */ ++ *data = gpt_scaler - (now() - gpt_scaler_start); ++ break; ++ ++ case TIMER_SCLOAD: /* 0x304 */ ++ *data = gpt_scaler; ++ break; ++ ++ case LEON2_CONFIG: /* 0x308 */ ++ *data = 0x700310; ++ break; ++ ++ case TIMER_TIMER1: /* 0x310 */ ++ *data = gpt_counter[0]; ++ break; ++ ++ case TIMER_RELOAD1: /* 0x314 */ ++ *data = gpt_reload[0]; ++ break; ++ ++ case TIMER_CTRL1: /* 0x318 */ ++ *data = gpt_ctrl[0]; ++ break; ++ ++ case TIMER_TIMER2: /* 0x320 */ ++ *data = gpt_counter[1]; ++ break; ++ ++ case TIMER_RELOAD2: /* 0x324 */ ++ *data = gpt_reload[1]; ++ break; ++ ++ case TIMER_CTRL2: /* 0x328 */ ++ *data = gpt_ctrl[1]; ++ break; ++ ++ case CACHE_CTRL: /* 0x328 */ ++ *data = cache_ctrl; ++ break; ++ ++ default: ++ *data = 0; ++ break; ++ } ++ ++ if (sis_verbose > 1) ++ printf("APB read a: %08x, d: %08x\n", addr, *data); ++ ++ return (MOK); ++} ++ ++static int ++apb_write(addr, data) ++ uint32 addr; ++ uint32 data; ++{ ++ if (sis_verbose > 1) ++ printf("APB write a: %08x, d: %08x\n",addr,data); ++ switch (addr & 0xff) { ++ ++ case APBUART_RXTX: /* 0x100 */ ++ case APBUART_STATUS: /* 0x104 */ ++ grlib_write_uart(addr, data); ++ break; ++ ++ case IRQCTRL_IFR: /* 0x208 */ ++ irqctrl_ifr = data & 0xfffe; ++ chk_irq(); ++ break; ++ ++ case IRQCTRL_ICR: /* 0x20C */ ++ irqctrl_ipr &= ~data & 0x0fffe; ++ chk_irq(); ++ break; ++ ++ case IRQCTRL_IMR: /* 0x240 */ ++ irqctrl_imr = data & 0x7ffe; ++ chk_irq(); ++ break; ++ ++ case TIMER_SCLOAD: /* 0x304 */ ++ gpt_scaler_set(data); ++ break; ++ ++ case TIMER_TIMER1: /* 0x310 */ ++ gpt_counter[0] = data; ++ break; ++ ++ case TIMER_RELOAD1: /* 0x314 */ ++ gpt_reload[0] = data; ++ break; ++ ++ case TIMER_CTRL1: /* 0x318 */ ++ timer_ctrl(data, 0); ++ break; ++ ++ case TIMER_TIMER2: /* 0x320 */ ++ gpt_counter[1] = data; ++ break; ++ ++ case TIMER_RELOAD2: /* 0x324 */ ++ gpt_reload[1] = data; ++ break; ++ ++ case TIMER_CTRL2: /* 0x328 */ ++ timer_ctrl(data, 1); ++ break; ++ ++ case POWER_DOWN: /* 0x328 */ ++ wait_for_irq(); ++ break; ++ ++ case CACHE_CTRL: /* 0x328 */ ++ cache_ctrl = data & 0x1000f; ++ break; ++ ++ default: ++ break; ++ } ++ return (MOK); ++} ++ ++ ++/* APBUART */ ++ ++static int ifd1 = -1, ofd1 = -1; ++ ++static void ++init_stdio() ++{ ++ if (dumbio) ++ return; /* do nothing */ ++ if (ifd1 == 0 && f1open) { ++ tcsetattr(0, TCSANOW, &ioc1); ++ tcflush(ifd1, TCIFLUSH); ++ } ++} ++ ++static void ++restore_stdio() ++{ ++ if (dumbio) ++ return; /* do nothing */ ++ if (ifd1 == 0 && f1open && tty_setup) ++ tcsetattr(0, TCSANOW, &iocold1); ++} ++ ++#define DO_STDIO_READ( _fd_, _buf_, _len_ ) \ ++ ( dumbio || nouartrx \ ++ ? (0) /* no bytes read, no delay */ \ ++ : (_fd_) == 1 && callback ? \ ++ callback->read_stdin (callback, _buf_, _len_) : \ ++ read( _fd_, _buf_, _len_ ) ) ++ ++ ++static void ++port_init() ++{ ++ ++ f1in = stdin; ++ f1out = stdout; ++ if (uart_dev1[0] != 0) ++ if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) { ++ printf("Warning, couldn't open output device %s\n", uart_dev1); ++ } else { ++ if (sis_verbose) ++ printf("serial port A on %s\n", uart_dev1); ++ f1in = f1out = fdopen(fd1, "r+"); ++ setbuf(f1out, NULL); ++ f1open = 1; ++ } ++ if (f1in) ifd1 = fileno(f1in); ++ if (ifd1 == 0) { ++ if (callback && !callback->isatty(callback, ifd1)) { ++ tty_setup = 0; ++ } ++ if (sis_verbose) ++ printf("serial port A on stdin/stdout\n"); ++ if (!dumbio) { ++ tcgetattr(ifd1, &ioc1); ++ if (tty_setup) { ++ iocold1 = ioc1; ++ ioc1.c_lflag &= ~(ICANON | ECHO); ++ ioc1.c_cc[VMIN] = 0; ++ ioc1.c_cc[VTIME] = 0; ++ } ++ } ++ f1open = 1; ++ } ++ ++ if (f1out) { ++ ofd1 = fileno(f1out); ++ if (!dumbio && tty_setup && ofd1 == 1) setbuf(f1out, NULL); ++ } ++ ++ wnuma = 0; ++ ++} ++ ++static uint32 ++grlib_read_uart(addr) ++ uint32 addr; ++{ ++ ++ unsigned tmp; ++ ++ tmp = 0; ++ switch (addr & 0xfff) { ++ ++ case 0x070: /* UART 1 RX/TX */ ++#ifndef _WIN32 ++#ifdef FAST_UART ++ ++ if (aind < anum) { ++ if ((aind + 1) < anum) ++ set_irq(3); ++ return ((uint32) aq[aind++]); ++ } else { ++ if (f1open) { ++ anum = DO_STDIO_READ(ifd1, aq, UARTBUF); ++ } ++ else { ++ anum = 0; ++ } ++ if (anum > 0) { ++ aind = 0; ++ if ((aind + 1) < anum) ++ set_irq(3); ++ return ((uint32) aq[aind++]); ++ } else { ++ return ((uint32) aq[aind]); ++ } ++ ++ } ++#else ++ tmp = uarta_data; ++ uarta_data &= ~UART_DR; ++ uart_stat_reg &= ~UARTA_DR; ++ return tmp; ++#endif ++#else ++ return(0); ++#endif ++ break; ++ ++ case 0x074: /* UART status register */ ++#ifndef _WIN32 ++#ifdef FAST_UART ++ ++ Ucontrol = 0; ++ if (aind < anum) { ++ Ucontrol |= 0x00000001; ++ } else { ++ if (f1open) { ++ anum = DO_STDIO_READ(ifd1, aq, UARTBUF); ++ } ++ else { ++ anum = 0; ++ } ++ if (anum > 0) { ++ Ucontrol |= 0x00000001; ++ aind = 0; ++ set_irq(3); ++ } ++ } ++ Ucontrol |= 0x00000006; ++ return (Ucontrol); ++#else ++ return (uart_stat_reg); ++#endif ++#else ++ return(0x00060006); ++#endif ++ break; ++ default: ++ if (sis_verbose) ++ printf("Read from unimplemented LEON2 register (%x)\n", addr); ++ ++ } ++ return (0); ++} ++ ++static void ++grlib_write_uart(addr, data) ++ uint32 addr; ++ uint32 data; ++{ ++ unsigned char c; ++ ++ c = (unsigned char) data; ++ switch (addr & 0xfff) { ++ ++ case 0x070: /* UART A */ ++#ifdef FAST_UART ++ if (f1open) { ++ if (wnuma < UARTBUF) ++ wbufa[wnuma++] = c; ++ else { ++ while (wnuma) { ++ if (ofd1 == 1 && callback) ++ wnuma -= callback->write_stdout(callback, wbufa, wnuma); ++ else ++ wnuma -= fwrite(wbufa, 1, wnuma, f1out); ++ } ++ wbufa[wnuma++] = c; ++ } ++ } ++ set_irq(3); ++#else ++ if (uart_stat_reg & UARTA_SRE) { ++ uarta_sreg = c; ++ uart_stat_reg &= ~UARTA_SRE; ++ event(uarta_tx, 0, UART_TX_TIME); ++ } else { ++ uarta_hreg = c; ++ uart_stat_reg &= ~UARTA_HRE; ++ } ++#endif ++ break; ++ ++ case 0x074: /* UART status register */ ++#ifndef FAST_UART ++ uart_stat_reg &= 1; ++#endif ++ break; ++ default: ++ if (sis_verbose) ++ printf("Write to unimplemented APB register (%x)\n", addr); ++ ++ } ++} ++ ++static void ++flush_uart() ++{ ++ while (wnuma && f1open) { ++ if (ofd1 == 1 && callback) { ++ wnuma -= callback->write_stdout(callback, wbufa, wnuma); ++ callback->flush_stdout(callback); ++ } ++ else ++ wnuma -= fwrite(wbufa, 1, wnuma, f1out); ++ } ++} ++ ++ ++ ++static void ++uarta_tx() ++{ ++ while (f1open) { ++ if (ofd1 == 1 && callback) { ++ while (callback->write_stdout(callback, &uarta_sreg, 1) != 1); ++ } ++ else { ++ while (fwrite(&uarta_sreg, 1, 1, f1out) != 1); ++ } ++ } ++ if (uart_stat_reg & UARTA_HRE) { ++ uart_stat_reg |= UARTA_SRE; ++ } else { ++ uarta_sreg = uarta_hreg; ++ uart_stat_reg |= UARTA_HRE; ++ event(uarta_tx, 0, UART_TX_TIME); ++ } ++ set_irq(3); ++} ++ ++static void ++uart_rx(arg) ++ caddr_t arg; ++{ ++ int32 rsize; ++ char rxd; ++ ++ ++ rsize = 0; ++ if (f1open) ++ rsize = DO_STDIO_READ(ifd1, &rxd, 1); ++ else ++ rsize = 0; ++ if (rsize > 0) { ++ uarta_data = rxd; ++ if (uart_stat_reg & UARTA_DR) { ++ uart_stat_reg |= UARTA_OR; ++ } ++ uart_stat_reg |= UARTA_DR; ++ set_irq(3); ++ } ++ event(uart_rx, 0, UART_RX_TIME); ++} ++ ++static void ++uart_intr(arg) ++ caddr_t arg; ++{ ++ grlib_read_uart(APBUART_STATUS); /* Check for UART interrupts every 1000 clk */ ++ flush_uart(); /* Flush UART ports */ ++ event(uart_intr, 0, UART_FLUSH_TIME); ++} ++ ++ ++static void ++uart_irq_start() ++{ ++#ifdef FAST_UART ++ event(uart_intr, 0, UART_FLUSH_TIME); ++#else ++#ifndef _WIN32 ++ event(uart_rx, 0, UART_RX_TIME); ++#endif ++#endif ++} ++ ++/* TIMER */ ++ ++static void ++gpt_intr(arg) ++ caddr_t arg; ++{ ++ int i; ++ ++ for (i=0; i= RAM_START) && (addr < RAM_END)) { ++ *data = *((uint32 *) & (ramb[addr & RAM_MASK])); ++ *ws = 0; ++ return (0); ++ } else if (addr < ROM_END) { ++ *data = *((uint32 *) & (romb[addr])); ++ *ws = 0; ++ return (0); ++ } ++ ++ printf("Memory exception at %x (illegal address)\n", addr); ++ *ws = MEM_EX_WS; ++ return (1); ++} ++ ++static int ++memory_read(addr, data, sz, ws) ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ int32 mexc; ++ ++ if ((addr >= RAM_START) && (addr < RAM_END)) { ++ *data = *((uint32 *) & (ramb[addr & RAM_MASK & ~3])); ++ *ws = 0; ++ return (0); ++ } else if ((addr >= APBSTART) && (addr < APBEND)) { ++ mexc = apb_read(addr, data); ++ if (mexc) { ++ *ws = MEM_EX_WS; ++ } else { ++ *ws = 0; ++ } ++ return (mexc); ++ } else if (addr < ROM_END) { ++ *data = *((uint32 *) & (romb[addr & ~3])); ++ *ws = 0; ++ return (0); ++ } ++ ++ printf("Memory exception at %x (illegal address)\n", addr); ++ *ws = MEM_EX_WS; ++ return (1); ++} ++ ++static int ++memory_read_asi(asi, addr, data, sz, ws) ++ int32 asi; ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ return(memory_read(addr, data, sz, ws)); ++} ++ ++static int ++memory_write(addr, data, sz, ws) ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ uint32 byte_addr; ++ uint32 byte_mask; ++ uint32 waddr; ++ uint32 *ram; ++ int32 mexc; ++ int i; ++ int wphit[2]; ++ ++ if ((addr >= RAM_START) && (addr < RAM_END)) { ++ waddr = addr & RAM_MASK; ++ store_bytes (ramb, waddr, data, sz, ws); ++ return (0); ++ ++ } else if ((addr >= APBSTART) && (addr < APBEND)) { ++ if (sz != 2) { ++ *ws = MEM_EX_WS; ++ return (1); ++ } ++ apb_write(addr, *data); ++ *ws = 0; ++ return (0); ++ ++ } else if (addr < ROM_END) { ++// return (1); ++ *ws = 0; ++ store_bytes (romb, addr, data, sz, ws); ++ return (0); ++ } ++ ++ *ws = MEM_EX_WS; ++ return (1); ++} ++ ++static int ++memory_write_asi(asi, addr, data, sz, ws) ++ int32 asi; ++ uint32 addr; ++ uint32 *data; ++ int32 sz; ++ int32 *ws; ++{ ++ return(memory_write(addr, data, sz, ws)); ++} ++ ++static unsigned char * ++get_mem_ptr(addr, size) ++ uint32 addr; ++ uint32 size; ++{ ++ if ((addr + size) < ROM_END) { ++ return (&romb[addr]); ++ } else if ((addr >= RAM_START) && ((addr + size) < RAM_END)) { ++ return (&ramb[addr & RAM_MASK]); ++ } ++ ++ return ((char *) -1); ++} ++ ++static int ++sis_memory_write(addr, data, length) ++ uint32 addr; ++ const unsigned char *data; ++ uint32 length; ++{ ++ char *mem; ++ ++ if ((mem = get_mem_ptr(addr, length)) == ((char *) -1)) ++ return (0); ++ ++ memcpy(mem, data, length); ++ return (length); ++} ++ ++static int ++sis_memory_read(addr, data, length) ++ uint32 addr; ++ char *data; ++ uint32 length; ++{ ++ char *mem; ++ int ws; ++ ++ if (length == 4) { ++ memory_read(addr, data, length, &ws); ++ return(4); ++ } ++ ++ if ((mem = get_mem_ptr(addr, length)) == ((char *) -1)) ++ return (0); ++ ++ memcpy(data, mem, length); ++ return (length); ++} ++ ++static void ++boot_init () ++{ ++// mec_write(MEC_WCR, 0); /* zero waitstates */ ++// mec_write(MEC_TRAPD, 0); /* turn off watch-dog */ ++ apb_write(TIMER_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */ ++ apb_write(TIMER_SCLOAD, sregs.freq-1); ++ apb_write(TIMER_TIMER1, -1); ++ apb_write(TIMER_RELOAD1, -1); ++ apb_write(TIMER_CTRL1, 0x7); ++// mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */ ++ sregs.wim = 2; ++ sregs.psr = 0x000010e0; ++ sregs.r[30] = RAM_END; ++ sregs.r[14] = sregs.r[30] - 96*4; ++ cache_ctrl = 0x01000f; ++ ++} ++ ++struct memsys leon2 = { ++ init_sim, ++ reset, ++ error_mode, ++ sim_halt, ++ exit_sim, ++ init_stdio, ++ restore_stdio, ++ memory_iread, ++ memory_read, ++ memory_read_asi, ++ memory_write, ++ memory_write_asi, ++ sis_memory_write, ++ sis_memory_read, ++ boot_init ++}; +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index 0e19270..99d5286 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -181,6 +181,10 @@ main(argc, argv) + dumbio = 1; + } else if (strcmp(argv[stat], "-nouartrx") == 0) { + nouartrx = 1; ++ } else if (strcmp(argv[stat], "-leon2") == 0) { ++ ms = &leon2; ++ if (freq == 14) freq = 50; ++ cputype = CPU_LEON2; + } else if (strcmp(argv[stat], "-leon3") == 0) { + ms = &leon3; + if (freq == 14) freq = 50; +@@ -199,6 +203,9 @@ main(argc, argv) + } + + switch (cputype) { ++ case CPU_LEON2: ++ printf(" LEON2 emulation enabled\n"); ++ break; + case CPU_LEON3: + printf(" LEON3 emulation enabled\n"); + break; +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index a551b4a..c043504 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -190,6 +190,7 @@ struct memsys { + #define ERROR 3 + #define CTRL_C 4 + ++#define CPU_LEON2 2 + #define CPU_LEON3 3 + + /* Prototypes */ +@@ -270,5 +271,8 @@ extern void gen_help (void); + + extern struct memsys *ms; + ++/* leon2.c */ ++extern struct memsys leon2; ++ + /* leon3.c */ + extern struct memsys leon3; +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0020-sim-erc32-Updated-documentation.patch b/tools/4.11/gdb/sparc/7.9/0020-sim-erc32-Updated-documentation.patch new file mode 100644 index 0000000..3676f6b --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0020-sim-erc32-Updated-documentation.patch @@ -0,0 +1,516 @@ +From f2694ee29b6f598d1361d59a3858f46b0a495450 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Wed, 18 Feb 2015 23:10:51 +0100 +Subject: [PATCH 20/23] sim/erc32: Updated documentation. + + Cleaned up documentation. Obsolote README files were removed, + main documentation on operation is now in READMEM.sis. +--- + sim/erc32/NEWS | 108 --------------------------- + sim/erc32/README.gdb | 67 ----------------- + sim/erc32/README.leon2 | 53 ++++++++++++++ + sim/erc32/README.sis | 193 ++++++++++++++++--------------------------------- + sim/erc32/startsim | 4 - + 5 files changed, 117 insertions(+), 308 deletions(-) + delete mode 100644 sim/erc32/NEWS + delete mode 100644 sim/erc32/README.gdb + create mode 100644 sim/erc32/README.leon2 + delete mode 100644 sim/erc32/startsim + +diff --git a/sim/erc32/NEWS b/sim/erc32/NEWS +deleted file mode 100644 +index dd24b7b..0000000 +--- a/sim/erc32/NEWS ++++ /dev/null +@@ -1,108 +0,0 @@ +- +-version 2.0 05-02-96 +--------------------- +- +-* Switched to bfd library. Any supported format (elf, coff, ...) can be used. +-* The UART devices can be set through -uart1 and -uart2 switches. +-* Switched to GNU readline. +-* Added -c option to run batch files at startup +-* 'reg' command can show different register windows (eg 'reg w3'). +-* Use 'help' for online help on simulator commands +- +-version 1.8.1 20-01-96 +--------------------- +- +-* added -mevrev0 switch to simulate MEC rev.0 bugs in timer and uart +- +-* added -iurev0 switch to simulate IU rev.0 jmpl/restore bug +- +-* Added sis command 'batch' to run batch files +- +- +-version 1.8 30-10-95 +--------------------- +- +-* Added s-record support. Use the '-s' switch with sis or the 'load' command. +- +-* IU load dependencies are now modelled +- +-version 1.7 30-10-95 +--------------------- +- +-* Power-down mode implemented in erc32.c. +- +-* Performance display shows the ratio between simulator-time and real-time. +- +- +-version 1.6.2 25-10-95 +--------------------- +- +-* The UARTs can now be run at a given speed (simulator time) to better +- simulate the behaviour of interrupt routines. The "true mode" is +- selected through a compile switch in the makefile. +- +- +-version 1.6 28-09-95 +--------------------- +- +-* Major reorganisation of the code. mec.c and mem.c merged into erc32.c. +- +-* The load command does NOT longer load the initialised data at an address +- defined by .bdata. This is done in srt0.s using _environ. +- +-* Additional MEC functionallity added - software reset, memory access +- protection and waitstate configuration register. +- +-* interf.c - a GDB interface added +- +-* -v switch (verbose) added +- +-version 1.5 14-09-95 +--------------------- +- +-* Added a instruction trace buffer, enabled through the 'hist' command. +- +-* Added a 'perf' command to display statistics such as instruction mix, +- CPI, FPU holds etc. +- +-* Added -nfp switch to disable FPU. +- +-* Added -freq switch to set simulated frequency. +- +-version 1.4 22-08-95 +--------------------- +- +-* A -g is provided for those who have problems with GNU readline(). +- +-version 1.3 26-07-95 +--------------------- +- +-* No major news, just a bug fix release ... +- +- +-version 1.2 13-07-95 +--------------------- +- +-* Added setting of IU registers through the 'reg' command. See README. +- +-* The GNU readline() function is used for command input. However, a +-ctrl-D still kills the simulator ... +- +- +-version 1.1 07-07-95 +--------------------- +- +- +-* Added a 'go' command +- +-* Added cycle counting for interrupt overhead. +- +-* Function 'get_mem_ptr' takes one more parameter to avoid segmentation +- faults if a.out files are loaded outside the simulated memory. See README. +- +-* Added user-defined function sim_stop(). +- +-* Added a reset command. See README. +- +-* Implemented buffered output for MEC uarts to improve output speed. +- +diff --git a/sim/erc32/README.gdb b/sim/erc32/README.gdb +deleted file mode 100644 +index 619fcb3..0000000 +--- a/sim/erc32/README.gdb ++++ /dev/null +@@ -1,67 +0,0 @@ +-How to use SIS with GDB +------------------------ +- +-1. Building GDB with SIS +- +-To build GDB with the SIS/ERC32 simulator, configure with option +-'--target sparc-erc32-aout' and build as usual. +- +-2. Attaching the simulator +- +-To attach GDB to the simulator, use: +- +-target sim [options] [files] +- +-The following options are supported: +- +- -nfp Disable FPU. FPops will cause an FPU disabled trap. +- +- -freq Set the simulated "system clock" to MHz. +- +- -v Verbose mode. +- +- -nogdb Disable GDB breakpoint handling (see below) +- +-The listed [files] are expected to be in aout format and will be +-loaded in the simulator memory prior. This could be used to load +-a boot block at address 0x0 if the application is linked to run +-from RAM (0x2000000). +- +-To start debugging a program type 'load ' and debug as +-usual. +- +-The native simulator commands can be reached using the GDB 'sim' +-command: +- +-sim +- +-Direct simulator commands during a GDB session must be issued +-with care not to disturb GDB's operation ... +- +-For info on supported ERC32 functionality, see README.sis. +- +- +-3. Loading aout files +- +-The GDB load command loads an aout file into the simulator +-memory with the data section starting directly after the text +-section regardless of wich start address was specified for the data +-at link time! This means that your applications either has to include +-a routine that initialise the data segment at the proper address or +-link with the data placed directly after the text section. +- +-A copying routine is fairly simple, just copy all data between +-_etext and _data to a memory loaction starting at _environ. This +-should be done at the same time as the bss is cleared (in srt0.s). +- +- +-4. GDB breakpoint handling +- +-GDB inserts breakpoint in the form of the 'ta 1' instruction. The +-GDB-integrated simulator will therefore recognize the breakpoint +-instruction and return control to GDB. If the application uses +-'ta 1', the breakpoint detection can be disabled with the -nogdb +-switch. In this case however, GDB breakpoints will not work. +- +- +-Report problems to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl) +diff --git a/sim/erc32/README.leon2 b/sim/erc32/README.leon2 +new file mode 100644 +index 0000000..19f2fbb +--- /dev/null ++++ b/sim/erc32/README.leon2 +@@ -0,0 +1,53 @@ ++ ++1. LEON2 emulation ++ ++The file 'leon2.c' contains a model of simple LEON2 sub-system. It ++contains 16 Mbyte ROM and 16 Mbyte RAM. Standard peripherals ++such as interrupt controller, UART and timer are provided. ++The model can execute leon2 binaries that do not require an ++MMU. ++ ++To start sis in Leon2 mode, add the -leon2 switch. In gdb, ++use 'target sim -leon2' . ++ ++1.1 UART ++ ++One LEON2 UART is emaulted, and is located at address 0x80000070. ++The following registers are implemeted: ++ ++- UART RX and TX register (0x80000070) ++- UART status register (0x80000074) ++ ++The UART generates interrupt 3. ++ ++1.2 Timer unit ++ ++The LEON2 timer unit is emulated and located at address 0x80000040. ++It is configured with two timers and separate interrupts (8 and 9). ++The scaler is configured to 16 bits, while the counters are 32 bits. ++ ++1.3 Interrupt controller ++ ++The interrupt controller is implemented as described in the ++LEON2 IP manual, with the exception of the interrupt level register. ++Secondary interrupts are not supported. The registers are located ++at address 0x80000090. ++ ++1.5 Memory interface ++ ++The following memory areas are valid for the Leon3 simulator: ++ ++0x00000000 - 0x01000000 ROM (16 Mbyte, loaded at start-up) ++0x40000000 - 0x41000000 RAM (16 Mbyte, loaded at start-up) ++0x80000000 - 0x81000000 APB bus, including plug&play ++0xFFFFF000 - 0xFFFFFFFF AHB plug&play area ++ ++Access to non-existing memory will result in a memory exception trap. ++ ++1.8 Power-down mode ++ ++The Leon2 power-down register (0x80000018) is supported. When power-down is ++entered, time is skipped forward until the next event in the event queue. ++However, if the simulator event queue is empty, power-down mode is not ++entered since no interrupt would be generated to exit from the mode. A ++Ctrl-C in the simulator window will exit the power-down mode. +diff --git a/sim/erc32/README.sis b/sim/erc32/README.sis +index 124e577..27e6ede 100644 +--- a/sim/erc32/README.sis ++++ b/sim/erc32/README.sis +@@ -11,13 +11,14 @@ and peripherals. + + 2. Usage + +-The simulator is started as follows: ++The simulator is started as follows: + +-sis [-leon3] [-uart1 uart_device1] [-uart2 uart_device2] +- [-nfp] [-freq frequency] [-c batch_file] [files] ++sis [-leon2] [-leon3] [-uart1 uart_device1] [-uart2 uart_device2] ++ [-nfp] [-freq frequency] [-c batch_file] [-v] [files] + +-By default, SIS emulates an ERC32 system. The -leon3 switch +-enables emulation of a LEON3 SOC system. ++By default, SIS emulates an ERC32 system. The -leon2 switch enables ++LEON2 emulation, while the -leon3 switch enables emulation of a ++LEON3 SOC system. + + The emulated console uart is connected to stdin/stdout. The -uart[1,2] + switch can be used to connect the uarts to other devices. +@@ -143,8 +144,50 @@ Typing a 'Ctrl-C' will interrupt a running simulator. + Short forms of the commands are allowed, e.g 'c' 'co' or 'con' are all + interpreted as 'cont'. + ++2. Using SIS with GDB + +-3. Simulator core ++To attach GDB to the simulator, use: ++ ++target sim [options] ++ ++The following options are supported: ++ ++ -leon2 Emulate a LEON2 system ++ ++ -leon3 Emulate a LEON3 system ++ ++ -nfp Disable FPU. FPops will cause an FPU disabled trap. ++ ++ -freq Set the simulated "system clock" to MHz. ++ ++ -v Verbose mode. ++ ++ -nogdb Disable GDB breakpoint handling (see below) ++ ++To start debugging a program type 'load ' and debug as ++usual. ++ ++The native simulator commands can be reached using the GDB 'sim' ++command: ++ ++sim ++ ++Direct simulator commands during a GDB session must be issued ++with care not to disturb GDB's operation ... ++ ++A program can be restarted in GDB by first issuing the load command, ++followed by run. ++ ++3. GDB breakpoint handling ++ ++GDB inserts breakpoint in the form of the 'ta 1' instruction. The ++GDB-integrated simulator will therefore recognize the breakpoint ++instruction and return control to GDB. If the application uses ++'ta 1', the breakpoint detection can be disabled with the -nogdb ++switch. In this case however, GDB breakpoints will not work. ++ ++ ++4. Simulator core + + In ERC32 mode, SIS emulates the behavior of the 90C601E and 90C602E + sparc IU and FPU from Matra MHS. These are roughly equivalent to the +@@ -153,129 +196,10 @@ maintained and incremented according the IU and FPU instruction timing. + The parallel execution between the IU and FPU is modelled, as well as + stalls due to operand dependencies (FPU). + +-In Leon3 mode, the core emulates the Leon3 SPARC V8 core from ++In Leon2/3 mode, the core emulates the Leon2/3 SPARC V8 core from + Gaisler Research. All SPARC V8 instructions are supported but + emulation is not fully cycle-true as the cache is not emulated. + +-The core interacts with the user-defined memory modules through +-a number of functions. The memory module must provide the following +-functions: +- +-int memory_read(asi,addr,data,ws) +-int asi; +-unsigned int addr; +-unsigned int *data; +-int *ws; +- +-int memory_write(asi,addr,data,sz,ws) +-int asi; +-unsigned int addr; +-unsigned int *data; +-int sz; +-int *ws; +- +-int sis_memory_read(addr, data, length) +-unsigned int addr; +-char *data; +-unsigned int length; +- +-int sis_memory_write(addr, data, length) +-unsigned int addr; +-char *data; +-unsigned int length; +- +-int init_sim() +- +-int reset() +- +-int error_mode(pc) +-unsigned int pc; +- +-memory_read() is used by the simulator to fetch instructions and +-operands. The address space identifier (asi) and address is passed as +-parameters. The read data should be assigned to the data pointer +-(*data) and the number of waitstate to *ws. 'memory_read' should return +-0 on success and 1 on failure. A failure will cause a data or +-instruction fetch trap. memory_read() always reads one 32-bit word. +- +-sis_memory_read() is used by the simulator to display and disassemble +-memory contants. The function should copy 'length' bytes of the simulated +-memory starting at 'addr' to '*data'. +-The sis_memory_read() should return 1 on success and 0 on failure. +-Failure should only be indicated if access to unimplemented memory is attempted. +- +-memory_write() is used to write to memory. In addition to the asi +-and address parameters, the size of the written data is given by 'sz'. +-The pointer *data points to the data to be written. The 'sz' is coded +-as follows: +- +- sz access type +- 0 byte +- 1 halfword +- 2 word +- 3 double-word +- +-If a double word is written, the most significant word is in data[0] and +-the least significant in data[1]. +- +-sis_memory_write() is used by the simulator during loading of programs. +-The function should copy 'length' bytes from *data to the simulated +-memory starting at 'addr'. sis_memory_write() should return 1 on +-success and 0 on failure. Failure should only be indicated if access +-to unimplemented memory is attempted. See erc32.c for more details +-on how to define the memory emulation functions. +- +-The 'init_sim' is called once when the simulator is started. This function +-should be used to perform initialisations of user defined memory or +-peripherals that only have to be done once, such as opening files etc. +- +-The 'reset' is called every time the simulator is reset, i.e. when a +-'run' command is given. This function should be used to simulate a power +-on reset of memory and peripherals. +- +-error_mode() is called by the simulator when the IU goes into error mode, +-typically if a trap is caused when traps are disabled. The memory module +-can then take actions, such as issue a reset. +- +-sys_reset() can be called by the memory module to reset the simulator. A +-reset will empty the event queue and perform a power-on reset. +- +-4. Events and interrupts +- +-The simulator supports an event queue and the generation of processor +-interrupts. The following functions are available to the user-defined +-memory module: +- +-event(cfunc,arg,delta) +-void (*cfunc)(); +-int arg; +-unsigned int delta; +- +-set_int(level,callback,arg) +-int level; +-void (*callback)(); +-int arg; +- +-clear_int(level) +-int level; +- +-sim_stop() +- +-The 'event' functions will schedule the execution of the function 'cfunc' +-at time 'now + delta' clock cycles. The parameter 'arg' is passed as a +-parameter to 'cfunc'. +- +-The 'set_int' function set the processor interrupt 'level'. When the interrupt +-is taken, the function 'callback' is called with the argument 'arg'. This +-will also clear the interrupt. An interrupt can be cleared before it is +-taken by calling 'clear_int' with the appropriate interrupt level. +- +-The sim_stop function is called each time the simulator stops execution. +-It can be used to flush buffered devices to get a clean state during +-single stepping etc. +- +-See 'erc32.c' for examples on how to use events and interrupts. +- + 5. Memory module + + The ERC32 memory module (erc32.c) emulates the functions of memory and +@@ -292,6 +216,19 @@ the MEC asic developed for the 90C601/2. It includes the following functions: + + See README.erc32 on how the MEC functions are emulated. + ++The Leon2 memory module (leon2.c) emulates on-chip peripherals and ++external memory for a simple Leon2 system. The modules includes the ++following functions: ++ ++* AHB and APB buses ++* One UART ++* Interrupt controller ++* Timer unit with two timers ++* PROM/SRAM memory controller ++* 16 Mbyte PROM, 16 Mbyte SRAM ++ ++See README.leon2 for further details on Leon2 emulation. ++ + The Leon3 memory module (leon3.c) emulates on-chip peripherals and + external memory for a simple Leon3 system. The modules includes the + following functions: +@@ -305,9 +242,7 @@ following functions: + + See README.leon3 for further details on Leon3 emulation. + +-6. Compile and linking programs +- +-7. IU and FPU instruction timing. ++6. IU and FPU instruction timing. + + The simulator provides cycle true simulation for ERC32. The following table + shows the emulated instruction timing for 90C601E & 90C602E: +diff --git a/sim/erc32/startsim b/sim/erc32/startsim +deleted file mode 100644 +index 1b9b41c..0000000 +--- a/sim/erc32/startsim ++++ /dev/null +@@ -1,4 +0,0 @@ +-# +-xterm -e sis $* & +-xterm -e tip /dev/ttypc & +- +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch b/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch new file mode 100644 index 0000000..7078cc3 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0021-sim-erc32-Add-data-watchpoint-support.patch @@ -0,0 +1,377 @@ +From 933b0b5f256713f50959cd1f1c6ad565f40b12ab Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Thu, 19 Feb 2015 23:21:02 +0100 +Subject: [PATCH 21/23] sim/erc32: Add data watchpoint support + + Add watchpoint to all processor targets (erc32, leon2, leon3). +--- + sim/erc32/exec.c | 54 +++++++++++++++++++++++++++------- + sim/erc32/func.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- + sim/erc32/sis.c | 32 +++++++++++++++----- + sim/erc32/sis.h | 23 ++++++++++++++- + 4 files changed, 179 insertions(+), 20 deletions(-) + +diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c +index f4a0124..134e789 100644 +--- a/sim/erc32/exec.c ++++ b/sim/erc32/exec.c +@@ -395,6 +395,20 @@ extract_byte_signed(uint32 data, uint32 address) + return(tmp); + } + ++/* Decode watchpoint address mask from opcode. Not correct for LDST, ++ SWAP and STFSR but watchpoints will work anyway. */ ++ ++static unsigned char ++wpmask(uint32 op3) ++{ ++ switch (op3 & 3) { ++ case 0: return(3); /* word */ ++ case 1: return(0); /* byte */ ++ case 2: return(1); /* half-word */ ++ case 3: return(7); /* double word */ ++ } ++} ++ + int + dispatch_instruction(sregs) + struct pstate *sregs; +@@ -698,6 +712,12 @@ dispatch_instruction(sregs) + } + if (eicc & 1) { + sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f)); ++ if ((sregs->trap == 129) && (sis_gdb_break) && ++ (sregs->inst == 0x91d02001)) ++ { ++ sregs->trap = WPT_TRAP; ++ sregs->bphit = 1; ++ } + } + break; + +@@ -1211,18 +1231,25 @@ dispatch_instruction(sregs) + + address = rs1 + operand2; + +- if (sregs->psr & PSR_S) +- asi = 11; +- else +- asi = 10; +- + if (op3 & 4) { + sregs->icnt = T_ST; /* Set store instruction count */ ++ if (sregs->wpwnum) { ++ if (sregs->wphit = check_wpw(sregs, address, wpmask(op3))) { ++ sregs->trap = WPT_TRAP; ++ break; ++ } ++ } + #ifdef STAT + sregs->nstore++; + #endif + } else { + sregs->icnt = T_LD; /* Set load instruction count */ ++ if (sregs->wprnum) { ++ if (sregs->wphit = check_wpr(sregs, address, wpmask(op3))) { ++ sregs->trap = WPT_TRAP; ++ break; ++ } ++ } + #ifdef STAT + sregs->nload++; + #endif +@@ -2133,12 +2160,18 @@ execute_trap(sregs) + { + int32 cwp; + +- if (sregs->trap == 256) { +- sregs->pc = 0; +- sregs->npc = 4; +- sregs->trap = 0; +- } else if (sregs->trap == 257) { ++ if (sregs->trap >= 256) { ++ switch (sregs->trap) { ++ case 256: ++ sregs->pc = 0; ++ sregs->npc = 4; ++ sregs->trap = 0; ++ break; ++ case ERROR_TRAP: + return (ERROR); ++ case WPT_TRAP: ++ return (WPT_HIT); ++ } + } else { + + if ((sregs->psr & PSR_ET) == 0) +@@ -2231,6 +2264,7 @@ init_regs(sregs) + sregs->fpu_pres = !nfp; + set_fsr(sregs->fsr); + sregs->bphit = 0; ++ sregs->wphit = 0; + sregs->ildreg = 0; + sregs->ildtime = 0; + +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index a22e800..7a8a4e4 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -61,7 +61,8 @@ uint32 last_load_addr = 0; + int nouartrx = 0; + host_callback *sim_callback; + struct memsys *ms = &erc32sys; +-int cputype = 0; /* 0 = erc32, 3 = leon3 */ ++int cputype = 0; /* 0 = erc32, 2 = leon2,3 = leon3 */ ++int sis_gdb_break; + + #ifdef ERRINJ + uint32 errcnt = 0; +@@ -624,6 +625,53 @@ exec_cmd(sregs, cmd) + stat = run_sim(sregs, UINT64_MAX, 0); + daddr = sregs->pc; + ms->sim_halt(); ++ } else if (strncmp(cmd1, "wp", clen) == 0) { ++ for (i = 0; i < sregs->wprnum; i++) { ++ printf(" %d : 0x%08x (read)\n", i + 1, sregs->wprs[i]); ++ } ++ for (i = 0; i < sregs->wpwnum; i++) { ++ printf(" %d : 0x%08x (write)\n", i + 1, sregs->wpws[i]); ++ } ++ } else if (strncmp(cmd1, "+wpr", clen) == 0) { ++ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { ++ sregs->wprs[sregs->wprnum] = VAL(cmd1) & ~0x3; ++ sregs->wprm[sregs->wprnum] = 3; ++ printf("added read watchpoint %d at 0x%08x\n", ++ sregs->wprnum + 1, sregs->wprs[sregs->wprnum]); ++ sregs->wprnum += 1; ++ } ++ } else if (strncmp(cmd1, "-wpr", clen) == 0) { ++ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { ++ i = VAL(cmd1) - 1; ++ if ((i >= 0) && (i < sregs->wprnum)) { ++ printf("deleted read watchpoint %d at 0x%08x\n", i + 1, ++ sregs->wprs[i]); ++ for (; i < sregs->wprnum - 1; i++) { ++ sregs->wprs[i] = sregs->wprs[i + 1]; ++ } ++ sregs->wprnum -= 1; ++ } ++ } ++ } else if (strncmp(cmd1, "+wpw", clen) == 0) { ++ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { ++ sregs->wpws[sregs->wpwnum] = VAL(cmd1) & ~0x3; ++ sregs->wpwm[sregs->wpwnum] = 3; ++ printf("added write watchpoint %d at 0x%08x\n", ++ sregs->wpwnum + 1, sregs->wpws[sregs->wpwnum]); ++ sregs->wpwnum += 1; ++ } ++ } else if (strncmp(cmd1, "-wpw", clen) == 0) { ++ if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { ++ i = VAL(cmd1) - 1; ++ if ((i >= 0) && (i < sregs->wpwnum)) { ++ printf("deleted write watchpoint %d at 0x%08x\n", i + 1, ++ sregs->wpws[i]); ++ for (; i < sregs->wpwnum - 1; i++) { ++ sregs->wpws[i] = sregs->wpws[i + 1]; ++ } ++ sregs->wpwnum -= 1; ++ } ++ } + } else + printf("syntax error\n"); + } +@@ -714,6 +762,8 @@ init_bpt(sregs) + struct pstate *sregs; + { + sregs->bptnum = 0; ++ sregs->wprnum = 0; ++ sregs->wpwnum = 0; + sregs->histlen = 0; + sregs->histind = 0; + sregs->histbuf = NULL; +@@ -1023,6 +1073,44 @@ check_bpt(sregs) + return (0); + } + ++int ++check_wpr(sregs, address, mask) ++ struct pstate *sregs; ++ int32 address; ++ unsigned char mask; ++{ ++ int32 i, msk; ++ ++ for (i = 0; i < sregs->wprnum; i++) { ++ msk = ~(mask | sregs->wprm[i]); ++ if (((address ^ sregs->wprs[i]) & msk) == 0) { ++ sregs->wpaddress = address; ++ if (sregs->wphit) return (0); ++ return (WPT_HIT); ++ } ++ } ++ return (0); ++} ++ ++int ++check_wpw(sregs, address, mask) ++ struct pstate *sregs; ++ int32 address; ++ unsigned char mask; ++{ ++ int32 i, msk; ++ ++ for (i = 0; i < sregs->wpwnum; i++) { ++ msk = ~(mask | sregs->wpwm[i]); ++ if (((address ^ sregs->wpws[i]) & msk) == 0) { ++ sregs->wpaddress = address; ++ if (sregs->wphit) return (0); ++ return (WPT_HIT); ++ } ++ } ++ return (0); ++} ++ + void + reset_all() + { +diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c +index 99d5286..7c984bc 100644 +--- a/sim/erc32/sis.c ++++ b/sim/erc32/sis.c +@@ -75,11 +75,7 @@ run_sim(sregs, icount, dis) + sregs->trap = I_ACC_EXC; + } else { + if (deb) { +- if ((sregs->bphit = check_bpt(sregs)) != 0) { +- ms->restore_stdio(); +- return (BPT_HIT); +- } +- if (sregs->histlen) { ++ if (sregs->histlen) { + sregs->histbuf[sregs->histind].addr = sregs->pc; + sregs->histbuf[sregs->histind].time = ebase.simtime; + sregs->histind++; +@@ -90,14 +86,25 @@ run_sim(sregs, icount, dis) + printf(" %8" PRIu64 " ", ebase.simtime); + dis_mem(sregs->pc, 1, &dinfo); + } ++ if ((sregs->bptnum) && (sregs->bphit = check_bpt(sregs))) ++ icount = 0; ++ else { ++ dispatch_instruction(sregs); ++ icount--; ++ } ++ } else { ++ dispatch_instruction(sregs); ++ icount--; + } +- dispatch_instruction(sregs); +- icount--; + } + } + if (sregs->trap) { + irq = 0; +- sregs->err_mode = execute_trap(sregs); ++ if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) { ++ sregs->err_mode = 0; ++ sregs->trap = 0; ++ icount = 0; ++ } + if (sregs->err_mode) { + ms->error_mode(sregs->pc); + icount = 0; +@@ -118,6 +125,10 @@ run_sim(sregs, icount, dis) + ctrl_c = 0; + return (CTRL_C); + } ++ if (sregs->bphit) ++ return (BPT_HIT); ++ if (sregs->wphit) ++ return (WPT_HIT); + return (TIME_OUT); + } + +@@ -283,6 +294,11 @@ main(argc, argv) + printf(" %8" PRIu64 " ", ebase.simtime); + dis_mem(sregs.pc, 1, &dinfo); + break; ++ case WPT_HIT: ++ printf("watchpoint at 0x%08x reached, pc = 0x%08x\n", ++ sregs.wpaddress, sregs.pc); ++ sregs.wphit = 1; ++ break; + default: + break; + } +diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h +index c043504..fda5f01 100644 +--- a/sim/erc32/sis.h ++++ b/sim/erc32/sis.h +@@ -39,8 +39,10 @@ + /* Maximum # of floating point queue */ + #define FPUQN 1 + +-/* Maximum # of breakpoints */ ++/* Maximum # of breakpoints and watchpoints */ + #define BPT_MAX 256 ++#define WPR_MAX 256 ++#define WPW_MAX 256 + + struct histype { + unsigned addr; +@@ -108,6 +110,14 @@ struct pstate { + uint32 bptnum; + uint32 bphit; + uint32 bpts[BPT_MAX]; /* Breakpoints */ ++ uint32 wprnum; ++ uint32 wphit; ++ uint32 wprs[WPR_MAX]; /* Read Watchpoints */ ++ unsigned char wprm[WPR_MAX]; /* Read Watchpoint masks*/ ++ uint32 wpwnum; ++ uint32 wpws[WPW_MAX]; /* Write Watchpoints */ ++ unsigned char wpwm[WPW_MAX]; /* Write Watchpoint masks */ ++ uint32 wpaddress; + + uint32 ltime; /* Load interlock time */ + uint32 hold; /* IU hold cycles in current inst */ +@@ -184,12 +194,19 @@ struct memsys { + }; + + ++/* return values for run_sim */ + #define OK 0 + #define TIME_OUT 1 + #define BPT_HIT 2 + #define ERROR 3 + #define CTRL_C 4 ++#define WPT_HIT 5 + ++/* special simulator trap types */ ++#define ERROR_TRAP 257 ++#define WPT_TRAP 258 ++ ++/* cpu type defines */ + #define CPU_LEON2 2 + #define CPU_LEON3 3 + +@@ -240,6 +257,9 @@ extern void advance_time (struct pstate *sregs); + extern uint32 now (void); + extern int wait_for_irq (void); + extern int check_bpt (struct pstate *sregs); ++extern int check_wpr(struct pstate *sregs, int32 address, unsigned char mask); ++extern int check_wpw(struct pstate *sregs, int32 address, unsigned char mask); ++ + extern void reset_all (void); + extern void sys_reset (void); + extern void sys_halt (void); +@@ -249,6 +269,7 @@ extern host_callback *sim_callback; + extern int current_target_byte_order; + extern int dumbio; + extern int cputype; ++extern int sis_gdb_break; + + /* exec.c */ + extern int dispatch_instruction (struct pstate *sregs); +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0022-Add-watchpoint-support-to-gdb-simulator-interface.patch b/tools/4.11/gdb/sparc/7.9/0022-Add-watchpoint-support-to-gdb-simulator-interface.patch new file mode 100644 index 0000000..6a1e0ee --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0022-Add-watchpoint-support-to-gdb-simulator-interface.patch @@ -0,0 +1,1025 @@ +From b2a82dcd2f4779119cc1a87591a7ab9eebc3ea61 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Mon, 8 Dec 2014 23:06:17 +0100 +Subject: [PATCH 22/23] Add watchpoint support to gdb simulator interface. + + Currently, only the sparc sim supports watchpoints. Stubs for the + watchpoint functions were added to all other built-in sims + to avoid linking errors. +--- + gdb/remote-sim.c | 69 +++++++++++++ + include/gdb/remote-sim.h | 24 +++++ + sim/arm/wrapper.c | 25 +++++ + sim/avr/interp.c | 25 +++++ + sim/bfin/Makefile.in | 1 + + sim/common/sim-watch-remote.c | 27 +++++ + sim/cr16/interp.c | 25 +++++ + sim/cris/Makefile.in | 1 + + sim/erc32/interf.c | 235 ++++++++++++++++++++++++++++++++---------- + sim/frv/Makefile.in | 1 + + sim/h8300/Makefile.in | 1 + + sim/iq2000/Makefile.in | 1 + + sim/lm32/Makefile.in | 1 + + sim/m32c/gdb-if.c | 25 +++++ + sim/m32r/Makefile.in | 1 + + sim/m68hc11/Makefile.in | 1 + + sim/mcore/interp.c | 25 +++++ + sim/microblaze/Makefile.in | 2 +- + sim/mips/Makefile.in | 1 + + sim/mn10300/Makefile.in | 1 + + sim/moxie/interp.c | 25 +++++ + sim/msp430/Makefile.in | 1 + + sim/ppc/gdb-sim.c | 25 +++++ + sim/rl78/gdb-if.c | 25 +++++ + sim/rx/gdb-if.c | 25 +++++ + sim/sh/interp.c | 25 +++++ + sim/sh64/Makefile.in | 1 + + sim/v850/Makefile.in | 3 +- + 28 files changed, 568 insertions(+), 54 deletions(-) + create mode 100644 sim/common/sim-watch-remote.c + +diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c +index fd2fd58..af17e85 100644 +--- a/gdb/remote-sim.c ++++ b/gdb/remote-sim.c +@@ -1294,6 +1294,70 @@ gdbsim_has_memory (struct target_ops *ops) + return 1; + } + ++static int ++gdbsim_insert_watchpoint (struct target_ops *self, ++ CORE_ADDR addr, int len, int type, ++ struct expression *cond) ++{ ++ struct sim_inferior_data *sim_data ++ = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); ++ ++ if (remote_debug) ++ fprintf_unfiltered (gdb_stdlog, "gdbsim_insert_watchpoint: %d\n", type); ++ ++ if (sim_set_watchpoint (sim_data->gdbsim_desc, addr, len, type) != SIM_RC_OK) ++ return -1; ++ ++ return 0; ++} ++ ++static int ++gdbsim_remove_watchpoint (struct target_ops *self, ++ CORE_ADDR addr, int len, int type, ++ struct expression *cond) ++{ ++ struct sim_inferior_data *sim_data ++ = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); ++ ++ if (remote_debug) ++ fprintf_unfiltered (gdb_stdlog, "gdbsim_remove_watchpoint: %d\n", type); ++ ++ if (sim_clear_watchpoint (sim_data->gdbsim_desc, addr, len, type) != SIM_RC_OK) ++ return -1; ++ ++ return 0; ++} ++ ++ ++static int ++gdbsim_can_use_hw_breakpoint (struct target_ops *self, ++ int type, int cnt, int othertype) ++{ ++ struct sim_inferior_data *sim_data ++ = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); ++ ++ return (sim_can_use_hw_breakpoint(sim_data->gdbsim_desc, type, cnt, othertype)); ++} ++ ++static int ++gdbsim_stopped_by_watchpoint (struct target_ops *ops) ++{ ++ struct sim_inferior_data *sim_data ++ = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); ++ ++ return (sim_stopped_by_watchpoint(sim_data->gdbsim_desc));; ++} ++ ++static int ++gdbsim_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr) ++{ ++ struct sim_inferior_data *sim_data ++ = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); ++ ++ *addr = sim_watchpoint_address(sim_data->gdbsim_desc);; ++ return (1); ++} ++ + /* Define the target subroutine names. */ + + struct target_ops gdbsim_ops; +@@ -1316,6 +1380,11 @@ init_gdbsim_ops (void) + gdbsim_ops.to_files_info = gdbsim_files_info; + gdbsim_ops.to_insert_breakpoint = memory_insert_breakpoint; + gdbsim_ops.to_remove_breakpoint = memory_remove_breakpoint; ++ gdbsim_ops.to_insert_watchpoint = gdbsim_insert_watchpoint; ++ gdbsim_ops.to_remove_watchpoint = gdbsim_remove_watchpoint; ++ gdbsim_ops.to_stopped_by_watchpoint = gdbsim_stopped_by_watchpoint; ++ gdbsim_ops.to_can_use_hw_breakpoint = gdbsim_can_use_hw_breakpoint; ++ gdbsim_ops.to_stopped_data_address = gdbsim_stopped_data_address; + gdbsim_ops.to_kill = gdbsim_kill; + gdbsim_ops.to_load = gdbsim_load; + gdbsim_ops.to_create_inferior = gdbsim_create_inferior; +diff --git a/include/gdb/remote-sim.h b/include/gdb/remote-sim.h +index 3dca380..36fef3c 100644 +--- a/include/gdb/remote-sim.h ++++ b/include/gdb/remote-sim.h +@@ -280,6 +280,30 @@ void sim_do_command (SIM_DESC sd, const char *cmd); + + char **sim_complete_command (SIM_DESC sd, const char *text, const char *word); + ++/* Add hardware watchpoint. See to_insert_watchpoint() in target.h ++ for description of parameters. */ ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type); ++ ++/* Remove hardware watchpoint. See to_remove_watchpoint() in target.h ++ for description of parameters. */ ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type); ++ ++/* Returns data address when watchpoint has been hit. See ++ to_stopped_data_address() in target.h for description. */ ++ ++int sim_watchpoint_address (SIM_DESC sd); ++ ++/* Returns 1 if simulator was stopped by watchpoint hit. */ ++ ++int sim_stopped_by_watchpoint(SIM_DESC sd); ++ ++/* Returns non-zero if we can set a hardware watchpoint of type TYPE. ++ See to_can_use_hw_breakpoint() in target.h for details. */ ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype); ++ + #ifdef __cplusplus + } + #endif +diff --git a/sim/arm/wrapper.c b/sim/arm/wrapper.c +index 0ccc7fb..a6871ad 100644 +--- a/sim/arm/wrapper.c ++++ b/sim/arm/wrapper.c +@@ -1016,3 +1016,28 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word) + { + return NULL; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/avr/interp.c b/sim/avr/interp.c +index 8ae4887..c9f944c 100644 +--- a/sim/avr/interp.c ++++ b/sim/avr/interp.c +@@ -1859,3 +1859,28 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word) + { + return NULL; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/bfin/Makefile.in b/sim/bfin/Makefile.in +index b6cfeb5..d3fa401 100644 +--- a/sim/bfin/Makefile.in ++++ b/sim/bfin/Makefile.in +@@ -39,6 +39,7 @@ SIM_OBJS = \ + sim-reg.o \ + sim-resume.o \ + sim-stop.o \ ++ sim-watch-remote.o \ + @BFIN_SIM_EXTRA_OBJS@ \ + $(SIM_EXTRA_OBJS) + +diff --git a/sim/common/sim-watch-remote.c b/sim/common/sim-watch-remote.c +new file mode 100644 +index 0000000..279bb06 +--- /dev/null ++++ b/sim/common/sim-watch-remote.c +@@ -0,0 +1,27 @@ ++ ++#include "gdb/remote-sim.h" ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/cr16/interp.c b/sim/cr16/interp.c +index 9c85948..1c79258 100644 +--- a/sim/cr16/interp.c ++++ b/sim/cr16/interp.c +@@ -1584,3 +1584,28 @@ sim_load (SIM_DESC sd, const char *prog, struct bfd *abfd, int from_tty) + prog_bfd_was_opened_p = abfd == NULL; + return SIM_RC_OK; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/cris/Makefile.in b/sim/cris/Makefile.in +index a4332c8..6607c32 100644 +--- a/sim/cris/Makefile.in ++++ b/sim/cris/Makefile.in +@@ -30,6 +30,7 @@ SIM_OBJS = \ + sim-hrw.o \ + sim-model.o \ + sim-reg.o \ ++ sim-watch-remote.o \ + cgen-utils.o cgen-trace.o cgen-scache.o \ + cgen-run.o sim-reason.o sim-engine.o sim-stop.o \ + sim-if.o arch.o \ +diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c +index 8988f23..b2f81c5 100644 +--- a/sim/erc32/interf.c ++++ b/sim/erc32/interf.c +@@ -36,8 +36,6 @@ + + #define PSR_CWP 0x7 + +-int sis_gdb_break = 1; +- + int + run_sim(sregs, icount, dis) + struct pstate *sregs; +@@ -52,37 +50,14 @@ run_sim(sregs, icount, dis) + ms->init_stdio(); + sregs->starttime = get_time(); + irq = 0; ++ if (sregs->err_mode) icount = 0; + if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init(); +- while (!sregs->err_mode & (icount > 0)) { +- ++ while (icount > 0) { + sregs->fhold = 0; +- sregs->hold = 0; + sregs->icnt = 1; +- +- if (sregs->psr & 0x080) +- sregs->asi = 8; +- else +- sregs->asi = 9; +- +-#if 0 /* DELETE ME! for debugging purposes only */ +- if (sis_verbose > 1) +- if (sregs->pc == 0 || sregs->npc == 0) +- printf ("bogus pc or npc\n"); +-#endif + mexc = ms->memory_iread(sregs->pc, &sregs->inst, &sregs->hold); +-#if 0 /* DELETE ME! for debugging purposes only */ +- if (sis_verbose > 2) +- printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n", +- sregs->pc, sregs->npc, +- sregs->r[(((sregs->psr & 7) << 4) + 14) & 0x7f], +- sregs->r[(((sregs->psr & 7) << 4) + 30) & 0x7f], +- sregs->wim, +- sregs->psr & 7, +- sregs->inst); +-#endif + if (sregs->annul) { + sregs->annul = 0; +- sregs->icnt = 1; + sregs->pc = sregs->npc; + sregs->npc = sregs->npc + 4; + } else { +@@ -91,47 +66,40 @@ run_sim(sregs, icount, dis) + if (mexc) { + sregs->trap = I_ACC_EXC; + } else { +- if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) { +- if (sis_verbose) +- (*sim_callback->printf_filtered) (sim_callback, +- "SW BP hit at %x\n", sregs->pc); +- ms->sim_halt(); +- ms->restore_stdio(); +- clearerr(stdin); +- return (BPT_HIT); +- } else +- dispatch_instruction(sregs); ++ dispatch_instruction(sregs); ++ icount--; + } +- icount--; + } + if (sregs->trap) { + irq = 0; +- sregs->err_mode = execute_trap(sregs); ++ if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) { ++ sregs->err_mode = 0; ++ sregs->trap = 0; ++ icount = 0; ++ } ++ if (sregs->err_mode) icount = 0; ++ + } + } + advance_time(sregs); +- if (ctrl_c) { ++ if (ctrl_c) + icount = 0; +- } + } + ms->sim_halt(); + sregs->tottime += get_time() - sregs->starttime; + ms->restore_stdio(); + clearerr(stdin); +- if (sregs->err_mode) ++ if (sregs->err_mode) { + ms->error_mode(sregs->pc); +- if (sregs->err_mode) + return (ERROR); +- if (sregs->bphit) { +- if (sis_verbose) +- (*sim_callback->printf_filtered) (sim_callback, +- "HW BP hit at %x\n", sregs->pc); +- return (BPT_HIT); + } + if (ctrl_c) { + ctrl_c = 0; ++ sregs->wphit = sregs->bphit = 0; + return (CTRL_C); + } ++ if ((sregs->bphit) || (sregs->wphit)) ++ return (BPT_HIT); + return (TIME_OUT); + } + +@@ -161,6 +129,7 @@ sim_open (kind, callback, abfd, argv) + int freq = 0; + + sim_callback = callback; ++ sis_gdb_break = 1; + + while (argv[argc]) + argc++; +@@ -413,12 +382,15 @@ sim_stop_reason(sd, reason, sigrc) + { + + switch (simstat) { +- case CTRL_C: ++ case CTRL_C: + *reason = sim_stopped; + *sigrc = GDB_SIGNAL_INT; + break; + case OK: + case TIME_OUT: ++ *reason = sim_stopped; ++ *sigrc = 0; ++ break; + case BPT_HIT: + *reason = sim_stopped; + *sigrc = GDB_SIGNAL_TRAP; +@@ -427,8 +399,10 @@ sim_stop_reason(sd, reason, sigrc) + *sigrc = 0; + *reason = sim_exited; + } +- ctrl_c = 0; +- simstat = OK; ++ ++ if (sis_verbose) ++ (*sim_callback->printf_filtered) (sim_callback, ++ "sim_stop_reason %x : %x\n", *reason, *sigrc); + } + + /* Flush all register windows out to the stack. Starting after the invalid +@@ -489,7 +463,25 @@ flush_windows () + void + sim_resume(SIM_DESC sd, int step, int siggnal) + { +- simstat = run_sim(&sregs, UINT64_MAX, 0); ++ if (sis_verbose) ++ (*sim_callback->printf_filtered) (sim_callback, ++ "sim_resume %x : %x : %x : %x : 0x%08x\n", step, siggnal, sregs.bphit, sregs.wphit, sregs.pc); ++ if (step) { ++ sregs.bphit = 0; ++ sregs.wphit = 1; ++ simstat = run_sim(&sregs, 1, 0); ++ sregs.bphit = 0; ++ sregs.wphit = 0; ++ } else if (sregs.bphit || sregs.wphit) { ++ sregs.bphit = 0; ++ sregs.wphit = 1; ++ simstat = run_sim(&sregs, 1, 0); ++ sregs.bphit = sregs.wphit = 0; ++ simstat = run_sim(&sregs, UINT64_MAX, 0); ++ sregs.bphit = 0; ++ } ++ else ++ simstat = run_sim(&sregs, UINT64_MAX, 0); + + if (sis_gdb_break) flush_windows (); + } +@@ -524,6 +516,145 @@ sim_stop(SIM_DESC sd) + return 1; + } + ++static int ++sis_insert_watchpoint_read(int addr, unsigned char mask) ++{ ++ if (sregs.wprnum < WPR_MAX) { ++ sregs.wprs[sregs.wprnum] = addr; ++ sregs.wprm[sregs.wprnum] = mask; ++ sregs.wprnum++; ++ if (sis_verbose) ++ (*sim_callback->printf_filtered) (sim_callback, "inserted read watchpoint at %x\n", addr); ++ return SIM_RC_OK; ++ } else ++ return SIM_RC_FAIL; ++} ++ ++static int ++sis_remove_watchpoint_read(int addr) ++{ ++ int i = 0; ++ ++ while ((i < sregs.wprnum) && (sregs.wprs[i] != addr)) ++ i++; ++ if (addr == sregs.wprs[i]) { ++ for (; i < sregs.wprnum - 1; i++) ++ sregs.wprs[i] = sregs.wprs[i + 1]; ++ sregs.wprnum -= 1; ++ if (sis_verbose) ++ (*sim_callback->printf_filtered) (sim_callback, "removed read watchpoint at %x\n", addr); ++ return 0; ++ } ++ return 1; ++} ++ ++static int ++sis_insert_watchpoint_write(int32 addr, unsigned char mask) ++{ ++ if (sregs.wpwnum < WPR_MAX) { ++ sregs.wpws[sregs.wpwnum] = addr; ++ sregs.wpwm[sregs.wpwnum] = mask; ++ sregs.wpwnum++; ++ if (sis_verbose) ++ (*sim_callback->printf_filtered) (sim_callback, "sim_insert_watchpoint_write: 0x%08x : %x\n", addr, mask); ++ return SIM_RC_OK; ++ } else ++ return SIM_RC_FAIL; ++} ++ ++static int ++sis_remove_watchpoint_write(int addr) ++{ ++ int i = 0; ++ ++ while ((i < sregs.wpwnum) && (sregs.wpws[i] != addr)) ++ i++; ++ if (addr == sregs.wpws[i]) { ++ for (; i < sregs.wpwnum - 1; i++) ++ sregs.wpws[i] = sregs.wpws[i + 1]; ++ sregs.wpwnum -= 1; ++ if (sis_verbose) ++ (*sim_callback->printf_filtered) (sim_callback, "removed write watchpoint at %x\n", addr); ++ return SIM_RC_OK; ++ } ++ return SIM_RC_FAIL; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ if (type == 2) /* bp_hardware_breakpoint not supported */ ++ return 0; ++ else ++ return 1; ++} ++ ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ int res; ++ unsigned char mask; ++ ++ switch (length) { ++ case 1: mask = 0; break; ++ case 2: mask = 1; break; ++ case 4: mask = 3; break; ++ default: mask = 7; break; ++ } ++ ++ switch (type) { ++ case 0: ++ res = sis_insert_watchpoint_write (mem, mask); ++ break; ++ case 1: ++ res = sis_insert_watchpoint_read (mem, mask); ++ break; ++ case 2: ++ if ((res = sis_insert_watchpoint_write (mem, mask)) == SIM_RC_OK) ++ res = sis_insert_watchpoint_read (mem, mask); ++ if (res == SIM_RC_FAIL) ++ sis_remove_watchpoint_read (mem); ++ break; ++ default: ++ res = -1; ++ } ++ return (res); ++} ++ ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ int res; ++ switch (type) { ++ case 0: ++ res = sis_remove_watchpoint_write (mem); ++ break; ++ case 1: ++ res = sis_remove_watchpoint_read (mem); ++ break; ++ case 2: ++ if ((res = sis_remove_watchpoint_write (mem)) == SIM_RC_OK) ++ res = sis_remove_watchpoint_read (mem); ++ else ++ sis_remove_watchpoint_read (mem); ++ break; ++ default: ++ res = -1; ++ } ++ return (res); ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ if (sis_verbose) ++ (*sim_callback->printf_filtered) (sim_callback, "sim_stopped_by_watchpoint %x\n", sregs.wphit); ++ return((sregs.wphit != 0)); ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return(sregs.wpaddress); ++} ++ + #if 0 /* FIXME: These shouldn't exist. */ + + int +diff --git a/sim/frv/Makefile.in b/sim/frv/Makefile.in +index ea34bf2..1e1398d 100644 +--- a/sim/frv/Makefile.in ++++ b/sim/frv/Makefile.in +@@ -26,6 +26,7 @@ SIM_OBJS = \ + sim-hrw.o \ + sim-model.o \ + sim-reg.o \ ++ sim-watch-remote.o \ + cgen-utils.o cgen-trace.o cgen-scache.o cgen-fpu.o cgen-accfp.o \ + cgen-run.o sim-reason.o sim-engine.o sim-stop.o \ + sim-if.o arch.o \ +diff --git a/sim/h8300/Makefile.in b/sim/h8300/Makefile.in +index 7a569bd..3337b89 100644 +--- a/sim/h8300/Makefile.in ++++ b/sim/h8300/Makefile.in +@@ -25,6 +25,7 @@ SIM_OBJS = compile.o \ + sim-cpu.o \ + sim-engine.o \ + sim-load.o \ ++ sim-watch-remote.o \ + $(SIM_EXTRA_OBJS) + + ## COMMON_POST_CONFIG_FRAG +diff --git a/sim/iq2000/Makefile.in b/sim/iq2000/Makefile.in +index 7606b26..c079248 100644 +--- a/sim/iq2000/Makefile.in ++++ b/sim/iq2000/Makefile.in +@@ -32,6 +32,7 @@ SIM_OBJS = \ + cgen-utils.o cgen-trace.o cgen-scache.o \ + cgen-run.o sim-reason.o sim-engine.o sim-stop.o \ + sim-if.o arch.o \ ++ sim-watch-remote.o \ + $(IQ2000_OBJS) \ + $(CONFIG_DEVICES) + +diff --git a/sim/lm32/Makefile.in b/sim/lm32/Makefile.in +index 05cf53b..d8d5a2a 100644 +--- a/sim/lm32/Makefile.in ++++ b/sim/lm32/Makefile.in +@@ -15,6 +15,7 @@ SIM_OBJS = \ + cgen-utils.o cgen-trace.o cgen-scache.o \ + cgen-run.o sim-reason.o sim-engine.o sim-stop.o \ + sim-if.o arch.o \ ++ sim-watch-remote.o \ + cpu.o decode.o sem.o model.o mloop.o \ + lm32.o traps.o user.o + +diff --git a/sim/m32c/gdb-if.c b/sim/m32c/gdb-if.c +index 62ec28c..b8560d5 100644 +--- a/sim/m32c/gdb-if.c ++++ b/sim/m32c/gdb-if.c +@@ -710,3 +710,28 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word) + { + return NULL; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/m32r/Makefile.in b/sim/m32r/Makefile.in +index 12a6a8d..dfa7bd0 100644 +--- a/sim/m32r/Makefile.in ++++ b/sim/m32r/Makefile.in +@@ -34,6 +34,7 @@ SIM_OBJS = \ + cgen-utils.o cgen-trace.o cgen-scache.o \ + cgen-run.o sim-reason.o sim-engine.o sim-stop.o \ + sim-if.o arch.o \ ++ sim-watch-remote.o \ + $(M32R_OBJS) \ + $(M32RX_OBJS) \ + $(M32R2_OBJS) \ +diff --git a/sim/m68hc11/Makefile.in b/sim/m68hc11/Makefile.in +index fac0b24..62915d1 100644 +--- a/sim/m68hc11/Makefile.in ++++ b/sim/m68hc11/Makefile.in +@@ -31,6 +31,7 @@ SIM_OBJS = $(M68HC11_OBJS) \ + sim-stop.o \ + sim-hrw.o \ + sim-reason.o \ ++ sim-watch-remote.o \ + $(SIM_EXTRA_OBJS) + + SIM_PROFILE= -DPROFILE=1 -DWITH_PROFILE=-1 +diff --git a/sim/mcore/interp.c b/sim/mcore/interp.c +index d2edd12..003bb80 100644 +--- a/sim/mcore/interp.c ++++ b/sim/mcore/interp.c +@@ -2204,3 +2204,28 @@ sim_set_callbacks (ptr) + { + callback = ptr; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/microblaze/Makefile.in b/sim/microblaze/Makefile.in +index dda4650..49be635 100644 +--- a/sim/microblaze/Makefile.in ++++ b/sim/microblaze/Makefile.in +@@ -17,7 +17,7 @@ + + ## COMMON_PRE_CONFIG_FRAG + +-SIM_OBJS = interp.o sim-load.o ++SIM_OBJS = interp.o sim-load.o sim-watch-remote.o + SIM_EXTRA_LIBS = -lm + SIM_EXTRA_CLEAN = microblaze-clean + +diff --git a/sim/mips/Makefile.in b/sim/mips/Makefile.in +index 985f4e5..22b4714 100644 +--- a/sim/mips/Makefile.in ++++ b/sim/mips/Makefile.in +@@ -54,6 +54,7 @@ SIM_OBJS = \ + sim-stop.o \ + sim-resume.o \ + sim-reason.o \ ++ sim-watch-remote.o + + + # List of flags to always pass to $(CC). +diff --git a/sim/mn10300/Makefile.in b/sim/mn10300/Makefile.in +index c94e531..0a8cd86 100644 +--- a/sim/mn10300/Makefile.in ++++ b/sim/mn10300/Makefile.in +@@ -27,6 +27,7 @@ MN10300_OBJS = \ + sim-resume.o \ + sim-reason.o \ + sim-stop.o \ ++ sim-watch-remote.o \ + dv-sockser.o + + SIM_OBJS = $(MN10300_OBJS) interp.o +diff --git a/sim/moxie/interp.c b/sim/moxie/interp.c +index 5f449af..3e86b41 100644 +--- a/sim/moxie/interp.c ++++ b/sim/moxie/interp.c +@@ -1475,3 +1475,28 @@ sim_set_callbacks (ptr) + { + callback = ptr; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/msp430/Makefile.in b/sim/msp430/Makefile.in +index e398d0d..5982f4b 100644 +--- a/sim/msp430/Makefile.in ++++ b/sim/msp430/Makefile.in +@@ -36,6 +36,7 @@ SIM_OBJS = \ + sim-reg.o \ + sim-resume.o \ + sim-stop.o \ ++ sim-watch-remote.o \ + $(SIM_EXTRA_OBJS) + + # List of extra dependencies. +diff --git a/sim/ppc/gdb-sim.c b/sim/ppc/gdb-sim.c +index 0269458..3ce3016 100644 +--- a/sim/ppc/gdb-sim.c ++++ b/sim/ppc/gdb-sim.c +@@ -1296,3 +1296,28 @@ sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length) + return psim_write_register(simulator, MAX_NR_PROCESSORS, + buf, regname, raw_transfer); + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/rl78/gdb-if.c b/sim/rl78/gdb-if.c +index 6317a73..262e3e1 100644 +--- a/sim/rl78/gdb-if.c ++++ b/sim/rl78/gdb-if.c +@@ -571,3 +571,28 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word) + { + return NULL; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/rx/gdb-if.c b/sim/rx/gdb-if.c +index 762c3d2..8140a8b 100644 +--- a/sim/rx/gdb-if.c ++++ b/sim/rx/gdb-if.c +@@ -853,3 +853,28 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word) + { + return NULL; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/sh/interp.c b/sim/sh/interp.c +index c854174..24f03ed 100644 +--- a/sim/sh/interp.c ++++ b/sim/sh/interp.c +@@ -2780,3 +2780,28 @@ sim_complete_command (SIM_DESC sd, const char *text, const char *word) + { + return NULL; + } ++ ++int sim_set_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) ++{ ++ return -1; ++} ++ ++int sim_stopped_by_watchpoint (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_watchpoint_address (SIM_DESC sd) ++{ ++ return 0; ++} ++ ++int sim_can_use_hw_breakpoint (SIM_DESC sd, int type, int cnt, int othertype) ++{ ++ return 0; ++} +diff --git a/sim/sh64/Makefile.in b/sim/sh64/Makefile.in +index 0022d8e..a9cf62a 100644 +--- a/sim/sh64/Makefile.in ++++ b/sim/sh64/Makefile.in +@@ -34,6 +34,7 @@ SIM_OBJS = \ + cgen-utils.o cgen-trace.o cgen-scache.o \ + cgen-run.o sim-reason.o sim-engine.o sim-stop.o \ + sim-if.o arch.o \ ++ sim-watch-remote.o \ + $(SH64_OBJS) \ + $(CONFIG_DEVICES) + +diff --git a/sim/v850/Makefile.in b/sim/v850/Makefile.in +index 067158f..ad24cd8 100644 +--- a/sim/v850/Makefile.in ++++ b/sim/v850/Makefile.in +@@ -28,7 +28,8 @@ SIM_OBJS = \ + sim-hrw.o \ + sim-resume.o \ + sim-reason.o \ +- sim-stop.o ++ sim-stop.o \ ++ sim-watch-remote.o + + SIM_RUN_OBJS = nrun.o + +-- +1.9.1 + diff --git a/tools/4.11/gdb/sparc/7.9/0023-sim-erc32-ELF-loading-could-fail-on-unaligned-sectio.patch b/tools/4.11/gdb/sparc/7.9/0023-sim-erc32-ELF-loading-could-fail-on-unaligned-sectio.patch new file mode 100644 index 0000000..4a80399 --- /dev/null +++ b/tools/4.11/gdb/sparc/7.9/0023-sim-erc32-ELF-loading-could-fail-on-unaligned-sectio.patch @@ -0,0 +1,39 @@ +From 7cecef8c4569896ec7c16c6fc51ef0c5ce7aa7f1 Mon Sep 17 00:00:00 2001 +From: Jiri Gaisler +Date: Sat, 21 Mar 2015 18:31:15 +0100 +Subject: [PATCH 23/23] sim/erc32: ELF loading could fail on unaligned + sections. + +Endian swapping on little-endian hosts could fail if ELF section +length not a multiple of 4. + + func.c (bfd_load): Pad section buffers with zeros and round + section size upwards towards nearest 4-multiple. +--- + sim/erc32/func.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sim/erc32/func.c b/sim/erc32/func.c +index 7a8a4e4..31948a6 100644 +--- a/sim/erc32/func.c ++++ b/sim/erc32/func.c +@@ -1231,13 +1231,13 @@ bfd_load(fname) + uint32 *wbuffer = (uint32 *) buffer; + + count = min(section_size, 1024); +- ++ wbuffer[(count - 1) / 4] = 0; /* clear last word in buffer */ + bfd_get_section_contents(pbfd, section, buffer, fptr, count); + + #ifdef HOST_LITTLE_ENDIAN +- for (i=0;isis_memory_write(section_address, buffer, count); ++ ms->sis_memory_write(section_address, buffer, (count + 3) & ~3); + + section_address += count; + fptr += count; +-- +1.9.1 + -- cgit v1.2.3