xref: /netbsd-src/external/gpl3/gdb/dist/sim/erc32/interf.c (revision 1f4e7eb9e5e045e008f1894823a8e4e6c9f46890)
1212397c6Schristos /* This file is part of SIS (SPARC instruction simulator)
2212397c6Schristos 
3*1f4e7eb9Schristos    Copyright (C) 1995-2024 Free Software Foundation, Inc.
4212397c6Schristos    Contributed by Jiri Gaisler, European Space Agency
5212397c6Schristos 
6212397c6Schristos    This program is free software; you can redistribute it and/or modify
7212397c6Schristos    it under the terms of the GNU General Public License as published by
8212397c6Schristos    the Free Software Foundation; either version 3 of the License, or
9212397c6Schristos    (at your option) any later version.
10212397c6Schristos 
11212397c6Schristos    This program is distributed in the hope that it will be useful,
12212397c6Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
13212397c6Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14212397c6Schristos    GNU General Public License for more details.
15212397c6Schristos 
16212397c6Schristos    You should have received a copy of the GNU General Public License
17212397c6Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
184e98e3e1Schristos 
194b169a6bSchristos /* This must come before any other includes.  */
204b169a6bSchristos #include "defs.h"
214b169a6bSchristos 
224e98e3e1Schristos #include <signal.h>
234e98e3e1Schristos #include <string.h>
244e98e3e1Schristos #include <stdio.h>
254e98e3e1Schristos #include <stdlib.h>
264e98e3e1Schristos #include <sys/fcntl.h>
274e98e3e1Schristos #include "sis.h"
284e98e3e1Schristos #include "libiberty.h"
294e98e3e1Schristos #include "bfd.h"
304e98e3e1Schristos #include <dis-asm.h>
314e98e3e1Schristos #include "sim-config.h"
324e98e3e1Schristos 
334b169a6bSchristos #include "sim/sim.h"
344e98e3e1Schristos #include "gdb/signals.h"
354e98e3e1Schristos 
364e98e3e1Schristos #define PSR_CWP 0x7
374e98e3e1Schristos 
384e98e3e1Schristos extern struct disassemble_info dinfo;
394e98e3e1Schristos extern struct pstate sregs;
404e98e3e1Schristos extern struct estate ebase;
414e98e3e1Schristos 
424e98e3e1Schristos extern int      ctrl_c;
434e98e3e1Schristos extern int      nfp;
444e98e3e1Schristos extern int      ift;
454e98e3e1Schristos extern int      rom8;
464e98e3e1Schristos extern int      wrp;
474e98e3e1Schristos extern int      uben;
484e98e3e1Schristos extern int      sis_verbose;
494e98e3e1Schristos extern char    *sis_version;
504e98e3e1Schristos extern struct estate ebase;
514e98e3e1Schristos extern struct evcell evbuf[];
524e98e3e1Schristos extern struct irqcell irqarr[];
534e98e3e1Schristos extern int      irqpend, ext_irl;
544e98e3e1Schristos extern int      sparclite;
554e98e3e1Schristos extern int      dumbio;
564e98e3e1Schristos extern int      sparclite_board;
574e98e3e1Schristos extern int      termsave;
584e98e3e1Schristos extern char     uart_dev1[], uart_dev2[];
594e98e3e1Schristos 
604e98e3e1Schristos int             sis_gdb_break = 1;
614e98e3e1Schristos 
624e98e3e1Schristos host_callback *sim_callback;
634e98e3e1Schristos 
644e98e3e1Schristos int
654b169a6bSchristos run_sim(struct pstate *sregs, uint64_t icount, int dis)
664e98e3e1Schristos {
674e98e3e1Schristos     int             mexc, irq;
684e98e3e1Schristos 
694e98e3e1Schristos     if (sis_verbose)
704e98e3e1Schristos 	(*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n",
714e98e3e1Schristos 					  sregs->pc);
724e98e3e1Schristos    init_stdio();
73212397c6Schristos    sregs->starttime = get_time();
744e98e3e1Schristos    irq = 0;
75212397c6Schristos    if ((sregs->pc != 0) && (ebase.simtime == 0))
76212397c6Schristos 	boot_init();
774e98e3e1Schristos    while (!sregs->err_mode & (icount > 0)) {
784e98e3e1Schristos 
794e98e3e1Schristos 	sregs->fhold = 0;
804e98e3e1Schristos 	sregs->hold = 0;
814e98e3e1Schristos 	sregs->icnt = 1;
824e98e3e1Schristos 
834e98e3e1Schristos         if (sregs->psr & 0x080)
844e98e3e1Schristos             sregs->asi = 8;
854e98e3e1Schristos         else
864e98e3e1Schristos             sregs->asi = 9;
874e98e3e1Schristos 
884e98e3e1Schristos #if 0	/* DELETE ME! for debugging purposes only */
894e98e3e1Schristos         if (sis_verbose > 1)
904e98e3e1Schristos             if (sregs->pc == 0 || sregs->npc == 0)
914e98e3e1Schristos                 printf ("bogus pc or npc\n");
924e98e3e1Schristos #endif
93212397c6Schristos         mexc = memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
94212397c6Schristos #if 0	/* DELETE ME! for debugging purposes only */
954e98e3e1Schristos         if (sis_verbose > 2)
964e98e3e1Schristos             printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n",
974e98e3e1Schristos                    sregs->pc, sregs->npc,
984e98e3e1Schristos                    sregs->r[(((sregs->psr & 7) << 4) + 14) & 0x7f],
994e98e3e1Schristos                    sregs->r[(((sregs->psr & 7) << 4) + 30) & 0x7f],
1004e98e3e1Schristos                    sregs->wim,
1014e98e3e1Schristos                    sregs->psr & 7,
1024e98e3e1Schristos                    sregs->inst);
1034e98e3e1Schristos #endif
1044e98e3e1Schristos         if (sregs->annul) {
1054e98e3e1Schristos             sregs->annul = 0;
1064e98e3e1Schristos             sregs->icnt = 1;
1074e98e3e1Schristos             sregs->pc = sregs->npc;
1084e98e3e1Schristos             sregs->npc = sregs->npc + 4;
1094e98e3e1Schristos         } else {
1104e98e3e1Schristos 	    if (ext_irl) irq = check_interrupts(sregs);
1114e98e3e1Schristos 	    if (!irq) {
1124e98e3e1Schristos 		if (mexc) {
1134e98e3e1Schristos 		    sregs->trap = I_ACC_EXC;
1144e98e3e1Schristos 		} else {
1154e98e3e1Schristos 		    if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) {
1164e98e3e1Schristos 			if (sis_verbose)
1174e98e3e1Schristos 			    (*sim_callback->printf_filtered) (sim_callback,
1184e98e3e1Schristos 							      "SW BP hit at %x\n", sregs->pc);
1194e98e3e1Schristos                         sim_halt();
1204e98e3e1Schristos 			restore_stdio();
1214e98e3e1Schristos 			clearerr(stdin);
122212397c6Schristos 			return BPT_HIT;
1234e98e3e1Schristos 		    } else
1244e98e3e1Schristos 			dispatch_instruction(sregs);
1254e98e3e1Schristos 		}
1264e98e3e1Schristos 		icount--;
1274e98e3e1Schristos 	    }
1284e98e3e1Schristos 	    if (sregs->trap) {
1294e98e3e1Schristos                 irq = 0;
1304e98e3e1Schristos 		sregs->err_mode = execute_trap(sregs);
1314e98e3e1Schristos 	    }
1324e98e3e1Schristos 	}
1334e98e3e1Schristos 	advance_time(sregs);
1344e98e3e1Schristos 	if (ctrl_c) {
1354e98e3e1Schristos 	    icount = 0;
1364e98e3e1Schristos 	}
1374e98e3e1Schristos     }
1384e98e3e1Schristos     sim_halt();
139212397c6Schristos     sregs->tottime += get_time() - sregs->starttime;
1404e98e3e1Schristos     restore_stdio();
1414e98e3e1Schristos     clearerr(stdin);
1424e98e3e1Schristos     if (sregs->err_mode)
1434e98e3e1Schristos 	error_mode(sregs->pc);
1444e98e3e1Schristos     if (sregs->err_mode)
145212397c6Schristos 	return ERROR;
1464e98e3e1Schristos     if (sregs->bphit) {
1474e98e3e1Schristos 	if (sis_verbose)
1484e98e3e1Schristos 	    (*sim_callback->printf_filtered) (sim_callback,
1494e98e3e1Schristos 					      "HW BP hit at %x\n", sregs->pc);
150212397c6Schristos 	return BPT_HIT;
1514e98e3e1Schristos     }
1524e98e3e1Schristos     if (ctrl_c) {
1534e98e3e1Schristos 	ctrl_c = 0;
154212397c6Schristos 	return CTRL_C;
1554e98e3e1Schristos     }
156212397c6Schristos     return TIME_OUT;
1574e98e3e1Schristos }
1584e98e3e1Schristos 
1594b169a6bSchristos static int ATTRIBUTE_PRINTF (3, 4)
1604b169a6bSchristos fprintf_styled (void *stream, enum disassembler_style style,
1614b169a6bSchristos 		const char *fmt, ...)
1624b169a6bSchristos {
1634b169a6bSchristos   int ret;
1644b169a6bSchristos   FILE *out = (FILE *) stream;
1654b169a6bSchristos   va_list args;
1664b169a6bSchristos 
1674b169a6bSchristos   va_start (args, fmt);
1684b169a6bSchristos   ret = vfprintf (out, fmt, args);
1694b169a6bSchristos   va_end (args);
1704b169a6bSchristos 
1714b169a6bSchristos   return ret;
1724b169a6bSchristos }
1734b169a6bSchristos 
1744e98e3e1Schristos SIM_DESC
1754b169a6bSchristos sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *callback,
1764b169a6bSchristos 	  struct bfd *abfd, char * const *argv)
1774e98e3e1Schristos {
1784e98e3e1Schristos 
1794e98e3e1Schristos     int             argc = 0;
1804e98e3e1Schristos     int             stat = 1;
1814e98e3e1Schristos     int             freq = 0;
1824e98e3e1Schristos 
1834e98e3e1Schristos     sim_callback = callback;
1844e98e3e1Schristos 
185ba340e45Schristos     argc = countargv (argv);
1864e98e3e1Schristos     while (stat < argc) {
1874e98e3e1Schristos 	if (argv[stat][0] == '-') {
1884e98e3e1Schristos 	    if (strcmp(argv[stat], "-v") == 0) {
1894e98e3e1Schristos 		sis_verbose++;
1904e98e3e1Schristos 	    } else
1914e98e3e1Schristos 	    if (strcmp(argv[stat], "-nfp") == 0) {
1924e98e3e1Schristos 		nfp = 1;
1934e98e3e1Schristos 	    } else
1944e98e3e1Schristos             if (strcmp(argv[stat], "-ift") == 0) {
1954e98e3e1Schristos                 ift = 1;
1964e98e3e1Schristos 	    } else
1974e98e3e1Schristos 	    if (strcmp(argv[stat], "-sparclite") == 0) {
1984e98e3e1Schristos 		sparclite = 1;
1994e98e3e1Schristos 	    } else
2004e98e3e1Schristos 	    if (strcmp(argv[stat], "-sparclite-board") == 0) {
2014e98e3e1Schristos 		sparclite_board = 1;
2024e98e3e1Schristos             } else
2034e98e3e1Schristos             if (strcmp(argv[stat], "-dumbio") == 0) {
2044e98e3e1Schristos 		dumbio = 1;
2054e98e3e1Schristos 	    } else
2064e98e3e1Schristos             if (strcmp(argv[stat], "-wrp") == 0) {
2074e98e3e1Schristos                 wrp = 1;
2084e98e3e1Schristos 	    } else
2094e98e3e1Schristos             if (strcmp(argv[stat], "-rom8") == 0) {
2104e98e3e1Schristos                 rom8 = 1;
2114e98e3e1Schristos 	    } else
2124e98e3e1Schristos             if (strcmp(argv[stat], "-uben") == 0) {
2134e98e3e1Schristos                 uben = 1;
2144e98e3e1Schristos 	    } else
2154e98e3e1Schristos 	    if (strcmp(argv[stat], "-uart1") == 0) {
2164e98e3e1Schristos 		if ((stat + 1) < argc)
2174e98e3e1Schristos 		    strcpy(uart_dev1, argv[++stat]);
2184e98e3e1Schristos 	    } else
2194e98e3e1Schristos 	    if (strcmp(argv[stat], "-uart2") == 0) {
2204e98e3e1Schristos 		if ((stat + 1) < argc)
2214e98e3e1Schristos 		    strcpy(uart_dev2, argv[++stat]);
2224e98e3e1Schristos 	    } else
2234e98e3e1Schristos 	    if (strcmp(argv[stat], "-nogdb") == 0) {
2244e98e3e1Schristos 		sis_gdb_break = 0;
2254e98e3e1Schristos 	    } else
2264e98e3e1Schristos 	    if (strcmp(argv[stat], "-freq") == 0) {
2274e98e3e1Schristos 		if ((stat + 1) < argc) {
2284e98e3e1Schristos 		    freq = strtol(argv[++stat], (char **)NULL, 0);
2294e98e3e1Schristos 		}
230a2e2270fSchristos 	    } else
231a2e2270fSchristos 	    if (strncmp(argv[stat], "--sysroot=", sizeof("--sysroot=") - 1) == 0) {
232a2e2270fSchristos 		/* Ignore until we start to support this.  */
2334e98e3e1Schristos 	    } else {
2344e98e3e1Schristos 		(*sim_callback->printf_filtered) (sim_callback,
2354e98e3e1Schristos 						  "unknown option %s\n",
2364e98e3e1Schristos 						  argv[stat]);
2374e98e3e1Schristos 	    }
2384e98e3e1Schristos 	} else
2394e98e3e1Schristos 	    bfd_load(argv[stat]);
2404e98e3e1Schristos 	stat++;
2414e98e3e1Schristos     }
2424e98e3e1Schristos 
2434e98e3e1Schristos     if (sis_verbose) {
2444e98e3e1Schristos 	(*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
2454e98e3e1Schristos 	(*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
2464e98e3e1Schristos 	if (nfp)
2474e98e3e1Schristos 	  (*sim_callback->printf_filtered) (sim_callback, "no FPU\n");
2484e98e3e1Schristos 	if (sparclite)
2494e98e3e1Schristos 	  (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n");
2504e98e3e1Schristos 	if (dumbio)
2514e98e3e1Schristos 	  (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n");
2524e98e3e1Schristos 	if (sis_gdb_break == 0)
2534e98e3e1Schristos 	  (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
2544e98e3e1Schristos 	if (freq)
2554e98e3e1Schristos 	  (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq);
2564e98e3e1Schristos     }
2574e98e3e1Schristos 
2584e98e3e1Schristos     sregs.freq = freq ? freq : 15;
2594b169a6bSchristos #ifdef F_GETFL
2604e98e3e1Schristos     termsave = fcntl(0, F_GETFL, 0);
2614b169a6bSchristos #endif
2624b169a6bSchristos     INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf,
2634b169a6bSchristos 			  fprintf_styled);
264212397c6Schristos #ifdef HOST_LITTLE_ENDIAN
265212397c6Schristos     dinfo.endian = BFD_ENDIAN_LITTLE;
266212397c6Schristos #else
2674e98e3e1Schristos     dinfo.endian = BFD_ENDIAN_BIG;
268212397c6Schristos #endif
2694e98e3e1Schristos     reset_all();
2704e98e3e1Schristos     ebase.simtime = 0;
2714e98e3e1Schristos     init_sim();
2724e98e3e1Schristos     init_bpt(&sregs);
2734e98e3e1Schristos     reset_stat(&sregs);
2744e98e3e1Schristos 
2754e98e3e1Schristos     /* Fudge our descriptor for now.  */
2764e98e3e1Schristos     return (SIM_DESC) 1;
2774e98e3e1Schristos }
2784e98e3e1Schristos 
2794e98e3e1Schristos void
2804b169a6bSchristos sim_close(SIM_DESC sd, int quitting)
2814e98e3e1Schristos {
2824e98e3e1Schristos 
2834e98e3e1Schristos     exit_sim();
2844b169a6bSchristos #ifdef F_SETFL
2854e98e3e1Schristos     fcntl(0, F_SETFL, termsave);
2864b169a6bSchristos #endif
2874b169a6bSchristos }
2884e98e3e1Schristos 
2894e98e3e1Schristos SIM_RC
2904b169a6bSchristos sim_load(SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
2914e98e3e1Schristos {
2924e98e3e1Schristos     bfd_load (prog);
2934e98e3e1Schristos     return SIM_RC_OK;
2944e98e3e1Schristos }
2954e98e3e1Schristos 
2964e98e3e1Schristos SIM_RC
2974b169a6bSchristos sim_create_inferior(SIM_DESC sd, bfd *abfd, char * const *argv,
2984b169a6bSchristos 		    char * const *env)
2994e98e3e1Schristos {
3004e98e3e1Schristos     bfd_vma start_address = 0;
3014e98e3e1Schristos     if (abfd != NULL)
3024e98e3e1Schristos       start_address = bfd_get_start_address (abfd);
3034e98e3e1Schristos 
3044e98e3e1Schristos     ebase.simtime = 0;
3054e98e3e1Schristos     reset_all();
3064e98e3e1Schristos     reset_stat(&sregs);
3074e98e3e1Schristos     sregs.pc = start_address & ~3;
3084e98e3e1Schristos     sregs.npc = sregs.pc + 4;
3094e98e3e1Schristos     return SIM_RC_OK;
3104e98e3e1Schristos }
3114e98e3e1Schristos 
3124e98e3e1Schristos int
3134b169a6bSchristos sim_store_register(SIM_DESC sd, int regno, const void *buf, int length)
3144e98e3e1Schristos {
3154b169a6bSchristos     const unsigned char *value = buf;
3164e98e3e1Schristos     int regval;
317212397c6Schristos 
3184e98e3e1Schristos     regval = (value[0] << 24) | (value[1] << 16)
3194e98e3e1Schristos 		 | (value[2] << 8) | value[3];
3204e98e3e1Schristos     set_regi(&sregs, regno, regval);
3214e98e3e1Schristos     return length;
3224e98e3e1Schristos }
3234e98e3e1Schristos 
3244e98e3e1Schristos 
3254e98e3e1Schristos int
3264b169a6bSchristos sim_fetch_register(SIM_DESC sd, int regno, void *buf, int length)
3274e98e3e1Schristos {
3284e98e3e1Schristos     get_regi(&sregs, regno, buf);
3294e98e3e1Schristos     return -1;
3304e98e3e1Schristos }
3314e98e3e1Schristos 
332*1f4e7eb9Schristos uint64_t
333*1f4e7eb9Schristos sim_write (SIM_DESC sd, uint64_t addr, const void *buffer, uint64_t length)
3344e98e3e1Schristos {
335*1f4e7eb9Schristos     int i;
3364b169a6bSchristos     const unsigned char *data = buffer;
337212397c6Schristos 
338212397c6Schristos     for (i = 0; i < length; i++) {
339*1f4e7eb9Schristos 	sis_memory_write ((addr + i) ^ EBT, &data[i], 1);
340212397c6Schristos     }
341212397c6Schristos     return length;
3424e98e3e1Schristos }
3434e98e3e1Schristos 
344*1f4e7eb9Schristos uint64_t
345*1f4e7eb9Schristos sim_read (SIM_DESC sd, uint64_t addr, void *buffer, uint64_t length)
3464e98e3e1Schristos {
347*1f4e7eb9Schristos     int i;
3484b169a6bSchristos     unsigned char *data = buffer;
349212397c6Schristos 
350212397c6Schristos     for (i = 0; i < length; i++) {
351*1f4e7eb9Schristos 	sis_memory_read ((addr + i) ^ EBT, &data[i], 1);
352212397c6Schristos     }
353212397c6Schristos     return length;
3544e98e3e1Schristos }
3554e98e3e1Schristos 
3564e98e3e1Schristos void
357*1f4e7eb9Schristos sim_info(SIM_DESC sd, bool verbose)
3584e98e3e1Schristos {
3594e98e3e1Schristos     show_stat(&sregs);
3604e98e3e1Schristos }
3614e98e3e1Schristos 
3624e98e3e1Schristos int             simstat = OK;
3634e98e3e1Schristos 
3644e98e3e1Schristos void
3654b169a6bSchristos sim_stop_reason(SIM_DESC sd, enum sim_stop *reason, int *sigrc)
3664e98e3e1Schristos {
3674e98e3e1Schristos 
3684e98e3e1Schristos     switch (simstat) {
3694e98e3e1Schristos 	case CTRL_C:
3704e98e3e1Schristos 	*reason = sim_stopped;
371a2e2270fSchristos 	*sigrc = GDB_SIGNAL_INT;
3724e98e3e1Schristos 	break;
3734e98e3e1Schristos     case OK:
3744e98e3e1Schristos     case TIME_OUT:
3754e98e3e1Schristos     case BPT_HIT:
3764e98e3e1Schristos 	*reason = sim_stopped;
377a2e2270fSchristos 	*sigrc = GDB_SIGNAL_TRAP;
3784e98e3e1Schristos 	break;
3794e98e3e1Schristos     case ERROR:
3804e98e3e1Schristos 	*sigrc = 0;
3814e98e3e1Schristos 	*reason = sim_exited;
3824e98e3e1Schristos     }
3834e98e3e1Schristos     ctrl_c = 0;
3844e98e3e1Schristos     simstat = OK;
3854e98e3e1Schristos }
3864e98e3e1Schristos 
3874e98e3e1Schristos /* Flush all register windows out to the stack.  Starting after the invalid
3884e98e3e1Schristos    window, flush all windows up to, and including the current window.  This
3894e98e3e1Schristos    allows GDB to do backtraces and look at local variables for frames that
3904e98e3e1Schristos    are still in the register windows.  Note that strictly speaking, this
3914e98e3e1Schristos    behavior is *wrong* for several reasons.  First, it doesn't use the window
3924e98e3e1Schristos    overflow handlers.  It therefore assumes standard frame layouts and window
3934e98e3e1Schristos    handling policies.  Second, it changes system state behind the back of the
3944e98e3e1Schristos    target program.  I expect this to mainly pose problems when debugging trap
3954e98e3e1Schristos    handlers.
3964e98e3e1Schristos */
3974e98e3e1Schristos 
3984e98e3e1Schristos static void
3994b169a6bSchristos flush_windows (void)
4004e98e3e1Schristos {
4014e98e3e1Schristos   int invwin;
4024e98e3e1Schristos   int cwp;
4034e98e3e1Schristos   int win;
4044e98e3e1Schristos   int ws;
4054e98e3e1Schristos 
4064e98e3e1Schristos   /* Keep current window handy */
4074e98e3e1Schristos 
4084e98e3e1Schristos   cwp = sregs.psr & PSR_CWP;
4094e98e3e1Schristos 
4104e98e3e1Schristos   /* Calculate the invalid window from the wim. */
4114e98e3e1Schristos 
4124e98e3e1Schristos   for (invwin = 0; invwin <= PSR_CWP; invwin++)
4134e98e3e1Schristos     if ((sregs.wim >> invwin) & 1)
4144e98e3e1Schristos       break;
4154e98e3e1Schristos 
4164e98e3e1Schristos   /* Start saving with the window after the invalid window. */
4174e98e3e1Schristos 
4184e98e3e1Schristos   invwin = (invwin - 1) & PSR_CWP;
4194e98e3e1Schristos 
4204e98e3e1Schristos   for (win = invwin; ; win = (win - 1) & PSR_CWP)
4214e98e3e1Schristos     {
4224b169a6bSchristos       uint32_t sp;
4234e98e3e1Schristos       int i;
4244e98e3e1Schristos 
4254e98e3e1Schristos       sp = sregs.r[(win * 16 + 14) & 0x7f];
4264e98e3e1Schristos #if 1
4274e98e3e1Schristos       if (sis_verbose > 2) {
4284b169a6bSchristos 	uint32_t fp = sregs.r[(win * 16 + 30) & 0x7f];
4294e98e3e1Schristos 	printf("flush_window: win %d, sp %x, fp %x\n", win, sp, fp);
4304e98e3e1Schristos       }
4314e98e3e1Schristos #endif
4324e98e3e1Schristos 
4334e98e3e1Schristos       for (i = 0; i < 16; i++)
4344e98e3e1Schristos 	memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
4354e98e3e1Schristos 		      &ws);
4364e98e3e1Schristos 
4374e98e3e1Schristos       if (win == cwp)
4384e98e3e1Schristos 	break;
4394e98e3e1Schristos     }
4404e98e3e1Schristos }
4414e98e3e1Schristos 
4424e98e3e1Schristos void
4434e98e3e1Schristos sim_resume(SIM_DESC sd, int step, int siggnal)
4444e98e3e1Schristos {
4454e98e3e1Schristos     simstat = run_sim(&sregs, UINT64_MAX, 0);
4464e98e3e1Schristos 
4474e98e3e1Schristos     if (sis_gdb_break) flush_windows ();
4484e98e3e1Schristos }
4494e98e3e1Schristos 
4504e98e3e1Schristos void
4514b169a6bSchristos sim_do_command(SIM_DESC sd, const char *cmd)
4524e98e3e1Schristos {
4534e98e3e1Schristos     exec_cmd(&sregs, cmd);
4544e98e3e1Schristos }
4554e98e3e1Schristos 
456a2e2270fSchristos char **
45703467a24Schristos sim_complete_command (SIM_DESC sd, const char *text, const char *word)
458a2e2270fSchristos {
459a2e2270fSchristos   return NULL;
460a2e2270fSchristos }
461a2e2270fSchristos 
4624b169a6bSchristos char *
4634b169a6bSchristos sim_memory_map (SIM_DESC sd)
4644b169a6bSchristos {
4654b169a6bSchristos   return NULL;
4664b169a6bSchristos }
4674b169a6bSchristos 
4684e98e3e1Schristos #if 0 /* FIXME: These shouldn't exist.  */
4694e98e3e1Schristos 
4704e98e3e1Schristos int
4714e98e3e1Schristos sim_insert_breakpoint(int addr)
4724e98e3e1Schristos {
4734e98e3e1Schristos     if (sregs.bptnum < BPT_MAX) {
4744e98e3e1Schristos 	sregs.bpts[sregs.bptnum] = addr & ~0x3;
4754e98e3e1Schristos 	sregs.bptnum++;
4764e98e3e1Schristos 	if (sis_verbose)
4774e98e3e1Schristos 	    (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr);
4784e98e3e1Schristos 	return 0;
4794e98e3e1Schristos     } else
4804e98e3e1Schristos 	return 1;
4814e98e3e1Schristos }
4824e98e3e1Schristos 
4834e98e3e1Schristos int
4844e98e3e1Schristos sim_remove_breakpoint(int addr)
4854e98e3e1Schristos {
4864e98e3e1Schristos     int             i = 0;
4874e98e3e1Schristos 
4884e98e3e1Schristos     while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
4894e98e3e1Schristos 	i++;
4904e98e3e1Schristos     if (addr == sregs.bpts[i]) {
4914e98e3e1Schristos 	for (; i < sregs.bptnum - 1; i++)
4924e98e3e1Schristos 	    sregs.bpts[i] = sregs.bpts[i + 1];
4934e98e3e1Schristos 	sregs.bptnum -= 1;
4944e98e3e1Schristos 	if (sis_verbose)
4954e98e3e1Schristos 	    (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr);
4964e98e3e1Schristos 	return 0;
4974e98e3e1Schristos     }
4984e98e3e1Schristos     return 1;
4994e98e3e1Schristos }
5004e98e3e1Schristos 
5014e98e3e1Schristos #endif
502