Home | History | Annotate | Line # | Download | only in erc32
erc32.c revision 1.1.1.1
      1  1.1  christos /*
      2  1.1  christos  * This file is part of SIS.
      3  1.1  christos  *
      4  1.1  christos  * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler,
      5  1.1  christos  * European Space Agency
      6  1.1  christos  *
      7  1.1  christos  * This program is free software; you can redistribute it and/or modify it under
      8  1.1  christos  * the terms of the GNU General Public License as published by the Free
      9  1.1  christos  * Software Foundation; either version 3 of the License, or (at your option)
     10  1.1  christos  * any later version.
     11  1.1  christos  *
     12  1.1  christos  * This program is distributed in the hope that it will be useful, but WITHOUT
     13  1.1  christos  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  1.1  christos  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     15  1.1  christos  * more details.
     16  1.1  christos  *
     17  1.1  christos  * You should have received a copy of the GNU General Public License along with
     18  1.1  christos  * this program; if not, see <http://www.gnu.org/licenses/>.
     19  1.1  christos  *
     20  1.1  christos  */
     21  1.1  christos 
     22  1.1  christos /* The control space devices */
     23  1.1  christos 
     24  1.1  christos #include "config.h"
     25  1.1  christos #include <sys/types.h>
     26  1.1  christos #include <stdio.h>
     27  1.1  christos #include <string.h>
     28  1.1  christos #include <termios.h>
     29  1.1  christos #include <sys/fcntl.h>
     30  1.1  christos #include <sys/file.h>
     31  1.1  christos #include <unistd.h>
     32  1.1  christos #include "sis.h"
     33  1.1  christos #include "end.h"
     34  1.1  christos #include "sim-config.h"
     35  1.1  christos 
     36  1.1  christos extern int      ctrl_c;
     37  1.1  christos extern int32    sis_verbose;
     38  1.1  christos extern int32    sparclite, sparclite_board;
     39  1.1  christos extern int      rom8,wrp,uben;
     40  1.1  christos extern char     uart_dev1[], uart_dev2[];
     41  1.1  christos 
     42  1.1  christos int dumbio = 0; /* normal, smart, terminal oriented IO by default */
     43  1.1  christos 
     44  1.1  christos /* MEC registers */
     45  1.1  christos #define MEC_START 	0x01f80000
     46  1.1  christos #define MEC_END 	0x01f80100
     47  1.1  christos 
     48  1.1  christos /* Memory exception waitstates */
     49  1.1  christos #define MEM_EX_WS 	1
     50  1.1  christos 
     51  1.1  christos /* ERC32 always adds one waitstate during RAM std */
     52  1.1  christos #define STD_WS 1
     53  1.1  christos 
     54  1.1  christos #ifdef ERRINJ
     55  1.1  christos extern int errmec;
     56  1.1  christos #endif
     57  1.1  christos 
     58  1.1  christos /* The target's byte order is big-endian by default until we load a
     59  1.1  christos    little-endian program.  */
     60  1.1  christos 
     61  1.1  christos int	current_target_byte_order = BIG_ENDIAN;
     62  1.1  christos 
     63  1.1  christos #define MEC_WS	0		/* Waitstates per MEC access (0 ws) */
     64  1.1  christos #define MOK	0
     65  1.1  christos 
     66  1.1  christos /* MEC register addresses */
     67  1.1  christos 
     68  1.1  christos #define MEC_MCR		0x000
     69  1.1  christos #define MEC_SFR  	0x004
     70  1.1  christos #define MEC_PWDR  	0x008
     71  1.1  christos #define MEC_MEMCFG	0x010
     72  1.1  christos #define MEC_IOCR	0x014
     73  1.1  christos #define MEC_WCR		0x018
     74  1.1  christos 
     75  1.1  christos #define MEC_MAR0  	0x020
     76  1.1  christos #define MEC_MAR1  	0x024
     77  1.1  christos 
     78  1.1  christos #define MEC_SSA1 	0x020
     79  1.1  christos #define MEC_SEA1 	0x024
     80  1.1  christos #define MEC_SSA2 	0x028
     81  1.1  christos #define MEC_SEA2 	0x02C
     82  1.1  christos #define MEC_ISR		0x044
     83  1.1  christos #define MEC_IPR		0x048
     84  1.1  christos #define MEC_IMR 	0x04C
     85  1.1  christos #define MEC_ICR 	0x050
     86  1.1  christos #define MEC_IFR 	0x054
     87  1.1  christos #define MEC_WDOG  	0x060
     88  1.1  christos #define MEC_TRAPD  	0x064
     89  1.1  christos #define MEC_RTC_COUNTER	0x080
     90  1.1  christos #define MEC_RTC_RELOAD	0x080
     91  1.1  christos #define MEC_RTC_SCALER	0x084
     92  1.1  christos #define MEC_GPT_COUNTER	0x088
     93  1.1  christos #define MEC_GPT_RELOAD	0x088
     94  1.1  christos #define MEC_GPT_SCALER	0x08C
     95  1.1  christos #define MEC_TIMER_CTRL	0x098
     96  1.1  christos #define MEC_SFSR	0x0A0
     97  1.1  christos #define MEC_FFAR	0x0A4
     98  1.1  christos #define MEC_ERSR	0x0B0
     99  1.1  christos #define MEC_DBG		0x0C0
    100  1.1  christos #define MEC_TCR		0x0D0
    101  1.1  christos 
    102  1.1  christos #define MEC_BRK		0x0C4
    103  1.1  christos #define MEC_WPR		0x0C8
    104  1.1  christos 
    105  1.1  christos #define MEC_UARTA	0x0E0
    106  1.1  christos #define MEC_UARTB	0x0E4
    107  1.1  christos #define MEC_UART_CTRL	0x0E8
    108  1.1  christos #define SIM_LOAD	0x0F0
    109  1.1  christos 
    110  1.1  christos /* Memory exception causes */
    111  1.1  christos #define PROT_EXC	0x3
    112  1.1  christos #define UIMP_ACC	0x4
    113  1.1  christos #define MEC_ACC		0x6
    114  1.1  christos #define WATCH_EXC	0xa
    115  1.1  christos #define BREAK_EXC	0xb
    116  1.1  christos 
    117  1.1  christos /* Size of UART buffers (bytes) */
    118  1.1  christos #define UARTBUF	1024
    119  1.1  christos 
    120  1.1  christos /* Number of simulator ticks between flushing the UARTS. 	 */
    121  1.1  christos /* For good performance, keep above 1000			 */
    122  1.1  christos #define UART_FLUSH_TIME	  3000
    123  1.1  christos 
    124  1.1  christos /* MEC timer control register bits */
    125  1.1  christos #define TCR_GACR 1
    126  1.1  christos #define TCR_GACL 2
    127  1.1  christos #define TCR_GASE 4
    128  1.1  christos #define TCR_GASL 8
    129  1.1  christos #define TCR_TCRCR 0x100
    130  1.1  christos #define TCR_TCRCL 0x200
    131  1.1  christos #define TCR_TCRSE 0x400
    132  1.1  christos #define TCR_TCRSL 0x800
    133  1.1  christos 
    134  1.1  christos /* New uart defines */
    135  1.1  christos #define UART_TX_TIME	1000
    136  1.1  christos #define UART_RX_TIME	1000
    137  1.1  christos #define UARTA_DR	0x1
    138  1.1  christos #define UARTA_SRE	0x2
    139  1.1  christos #define UARTA_HRE	0x4
    140  1.1  christos #define UARTA_OR	0x40
    141  1.1  christos #define UARTA_CLR	0x80
    142  1.1  christos #define UARTB_DR	0x10000
    143  1.1  christos #define UARTB_SRE	0x20000
    144  1.1  christos #define UARTB_HRE	0x40000
    145  1.1  christos #define UARTB_OR	0x400000
    146  1.1  christos #define UARTB_CLR	0x800000
    147  1.1  christos 
    148  1.1  christos #define UART_DR		0x100
    149  1.1  christos #define UART_TSE	0x200
    150  1.1  christos #define UART_THE	0x400
    151  1.1  christos 
    152  1.1  christos /* MEC registers */
    153  1.1  christos 
    154  1.1  christos static char     fname[256];
    155  1.1  christos static int32    find = 0;
    156  1.1  christos static uint32   mec_ssa[2];	/* Write protection start address */
    157  1.1  christos static uint32   mec_sea[2];	/* Write protection end address */
    158  1.1  christos static uint32   mec_wpr[2];	/* Write protection control fields */
    159  1.1  christos static uint32   mec_sfsr;
    160  1.1  christos static uint32   mec_ffar;
    161  1.1  christos static uint32   mec_ipr;
    162  1.1  christos static uint32   mec_imr;
    163  1.1  christos static uint32   mec_isr;
    164  1.1  christos static uint32   mec_icr;
    165  1.1  christos static uint32   mec_ifr;
    166  1.1  christos static uint32   mec_mcr;	/* MEC control register */
    167  1.1  christos static uint32   mec_memcfg;	/* Memory control register */
    168  1.1  christos static uint32   mec_wcr;	/* MEC waitstate register */
    169  1.1  christos static uint32   mec_iocr;	/* MEC IO control register */
    170  1.1  christos static uint32   posted_irq;
    171  1.1  christos static uint32   mec_ersr;	/* MEC error and status register */
    172  1.1  christos static uint32   mec_tcr;	/* MEC test comtrol register */
    173  1.1  christos 
    174  1.1  christos static uint32   rtc_counter;
    175  1.1  christos static uint32   rtc_reload;
    176  1.1  christos static uint32   rtc_scaler;
    177  1.1  christos static uint32   rtc_scaler_start;
    178  1.1  christos static uint32   rtc_enabled;
    179  1.1  christos static uint32   rtc_cr;
    180  1.1  christos static uint32   rtc_se;
    181  1.1  christos 
    182  1.1  christos static uint32   gpt_counter;
    183  1.1  christos static uint32   gpt_reload;
    184  1.1  christos static uint32   gpt_scaler;
    185  1.1  christos static uint32   gpt_scaler_start;
    186  1.1  christos static uint32   gpt_enabled;
    187  1.1  christos static uint32   gpt_cr;
    188  1.1  christos static uint32   gpt_se;
    189  1.1  christos 
    190  1.1  christos static uint32   wdog_scaler;
    191  1.1  christos static uint32   wdog_counter;
    192  1.1  christos static uint32   wdog_rst_delay;
    193  1.1  christos static uint32   wdog_rston;
    194  1.1  christos 
    195  1.1  christos enum wdog_type {
    196  1.1  christos     init, disabled, enabled, stopped
    197  1.1  christos };
    198  1.1  christos 
    199  1.1  christos static enum wdog_type wdog_status;
    200  1.1  christos 
    201  1.1  christos 
    202  1.1  christos /* ROM size 1024 Kbyte */
    203  1.1  christos #define ROM_SZ	 	0x100000
    204  1.1  christos #define ROM_MASK 	0x0fffff
    205  1.1  christos 
    206  1.1  christos /* RAM size 4 Mbyte */
    207  1.1  christos #define RAM_START 	0x02000000
    208  1.1  christos #define RAM_END 	0x02400000
    209  1.1  christos #define RAM_MASK 	0x003fffff
    210  1.1  christos 
    211  1.1  christos /* SPARClite boards all seem to have RAM at the same place. */
    212  1.1  christos #define RAM_START_SLITE	0x40000000
    213  1.1  christos #define RAM_END_SLITE 	0x40400000
    214  1.1  christos #define RAM_MASK_SLITE 	0x003fffff
    215  1.1  christos 
    216  1.1  christos /* Memory support variables */
    217  1.1  christos 
    218  1.1  christos static uint32   mem_ramr_ws;	/* RAM read waitstates */
    219  1.1  christos static uint32   mem_ramw_ws;	/* RAM write waitstates */
    220  1.1  christos static uint32   mem_romr_ws;	/* ROM read waitstates */
    221  1.1  christos static uint32   mem_romw_ws;	/* ROM write waitstates */
    222  1.1  christos static uint32	mem_ramstart;	/* RAM start */
    223  1.1  christos static uint32	mem_ramend;	/* RAM end */
    224  1.1  christos static uint32	mem_rammask;	/* RAM address mask */
    225  1.1  christos static uint32   mem_ramsz;	/* RAM size */
    226  1.1  christos static uint32   mem_romsz;	/* ROM size */
    227  1.1  christos static uint32   mem_accprot;	/* RAM write protection enabled */
    228  1.1  christos static uint32   mem_blockprot;	/* RAM block write protection enabled */
    229  1.1  christos 
    230  1.1  christos static unsigned char	romb[ROM_SZ];
    231  1.1  christos static unsigned char	ramb[RAM_END - RAM_START];
    232  1.1  christos 
    233  1.1  christos 
    234  1.1  christos /* UART support variables */
    235  1.1  christos 
    236  1.1  christos static int32    fd1, fd2;	/* file descriptor for input file */
    237  1.1  christos static int32    Ucontrol;	/* UART status register */
    238  1.1  christos static unsigned char aq[UARTBUF], bq[UARTBUF];
    239  1.1  christos static int32    anum, aind = 0;
    240  1.1  christos static int32    bnum, bind = 0;
    241  1.1  christos static char     wbufa[UARTBUF], wbufb[UARTBUF];
    242  1.1  christos static unsigned wnuma;
    243  1.1  christos static unsigned wnumb;
    244  1.1  christos static FILE    *f1in, *f1out, *f2in, *f2out;
    245  1.1  christos static struct termios ioc1, ioc2, iocold1, iocold2;
    246  1.1  christos static int      f1open = 0, f2open = 0;
    247  1.1  christos 
    248  1.1  christos static char     uarta_sreg, uarta_hreg, uartb_sreg, uartb_hreg;
    249  1.1  christos static uint32   uart_stat_reg;
    250  1.1  christos static uint32   uarta_data, uartb_data;
    251  1.1  christos 
    252  1.1  christos #ifdef ERA
    253  1.1  christos int era = 0;
    254  1.1  christos int erareg;
    255  1.1  christos #endif
    256  1.1  christos 
    257  1.1  christos /* Forward declarations */
    258  1.1  christos 
    259  1.1  christos static void	decode_ersr (void);
    260  1.1  christos #ifdef ERRINJ
    261  1.1  christos static void	iucomperr (void);
    262  1.1  christos #endif
    263  1.1  christos static void	mecparerror (void);
    264  1.1  christos static void	decode_memcfg (void);
    265  1.1  christos static void	decode_wcr (void);
    266  1.1  christos static void	decode_mcr (void);
    267  1.1  christos static void	close_port (void);
    268  1.1  christos static void	mec_reset (void);
    269  1.1  christos static void	mec_intack (int32 level);
    270  1.1  christos static void	chk_irq (void);
    271  1.1  christos static void	mec_irq (int32 level);
    272  1.1  christos static void	set_sfsr (uint32 fault, uint32 addr,
    273  1.1  christos 			  uint32 asi, uint32 read);
    274  1.1  christos static int32	mec_read (uint32 addr, uint32 asi, uint32 *data);
    275  1.1  christos static int	mec_write (uint32 addr, uint32 data);
    276  1.1  christos static void	port_init (void);
    277  1.1  christos static uint32	read_uart (uint32 addr);
    278  1.1  christos static void	write_uart (uint32 addr, uint32 data);
    279  1.1  christos static void	flush_uart (void);
    280  1.1  christos static void	uarta_tx (void);
    281  1.1  christos static void	uartb_tx (void);
    282  1.1  christos static void	uart_rx (caddr_t arg);
    283  1.1  christos static void	uart_intr (caddr_t arg);
    284  1.1  christos static void	uart_irq_start (void);
    285  1.1  christos static void	wdog_intr (caddr_t arg);
    286  1.1  christos static void	wdog_start (void);
    287  1.1  christos static void	rtc_intr (caddr_t arg);
    288  1.1  christos static void	rtc_start (void);
    289  1.1  christos static uint32	rtc_counter_read (void);
    290  1.1  christos static void	rtc_scaler_set (uint32 val);
    291  1.1  christos static void	rtc_reload_set (uint32 val);
    292  1.1  christos static void	gpt_intr (caddr_t arg);
    293  1.1  christos static void	gpt_start (void);
    294  1.1  christos static uint32	gpt_counter_read (void);
    295  1.1  christos static void	gpt_scaler_set (uint32 val);
    296  1.1  christos static void	gpt_reload_set (uint32 val);
    297  1.1  christos static void	timer_ctrl (uint32 val);
    298  1.1  christos static unsigned char *
    299  1.1  christos 		get_mem_ptr (uint32 addr, uint32 size);
    300  1.1  christos 
    301  1.1  christos static void	fetch_bytes (int asi, unsigned char *mem,
    302  1.1  christos 			     uint32 *data, int sz);
    303  1.1  christos 
    304  1.1  christos static void	store_bytes (unsigned char *mem, uint32 *data, int sz);
    305  1.1  christos 
    306  1.1  christos extern int	ext_irl;
    307  1.1  christos 
    308  1.1  christos 
    309  1.1  christos /* One-time init */
    310  1.1  christos 
    311  1.1  christos void
    312  1.1  christos init_sim()
    313  1.1  christos {
    314  1.1  christos     port_init();
    315  1.1  christos }
    316  1.1  christos 
    317  1.1  christos /* Power-on reset init */
    318  1.1  christos 
    319  1.1  christos void
    320  1.1  christos reset()
    321  1.1  christos {
    322  1.1  christos     mec_reset();
    323  1.1  christos     uart_irq_start();
    324  1.1  christos     wdog_start();
    325  1.1  christos }
    326  1.1  christos 
    327  1.1  christos static void
    328  1.1  christos decode_ersr()
    329  1.1  christos {
    330  1.1  christos     if (mec_ersr & 0x01) {
    331  1.1  christos 	if (!(mec_mcr & 0x20)) {
    332  1.1  christos 	    if (mec_mcr & 0x40) {
    333  1.1  christos 	        sys_reset();
    334  1.1  christos 	        mec_ersr = 0x8000;
    335  1.1  christos 	        if (sis_verbose)
    336  1.1  christos 	            printf("Error manager reset - IU in error mode\n");
    337  1.1  christos 	    } else {
    338  1.1  christos 	        sys_halt();
    339  1.1  christos 	        mec_ersr |= 0x2000;
    340  1.1  christos 	        if (sis_verbose)
    341  1.1  christos 	            printf("Error manager halt - IU in error mode\n");
    342  1.1  christos 	    }
    343  1.1  christos 	} else
    344  1.1  christos 	    mec_irq(1);
    345  1.1  christos     }
    346  1.1  christos     if (mec_ersr & 0x04) {
    347  1.1  christos 	if (!(mec_mcr & 0x200)) {
    348  1.1  christos 	    if (mec_mcr & 0x400) {
    349  1.1  christos 	        sys_reset();
    350  1.1  christos 	        mec_ersr = 0x8000;
    351  1.1  christos 	        if (sis_verbose)
    352  1.1  christos 	            printf("Error manager reset - IU comparison error\n");
    353  1.1  christos 	    } else {
    354  1.1  christos 	        sys_halt();
    355  1.1  christos 	        mec_ersr |= 0x2000;
    356  1.1  christos 	        if (sis_verbose)
    357  1.1  christos 	            printf("Error manager halt - IU comparison error\n");
    358  1.1  christos 	    }
    359  1.1  christos 	} else
    360  1.1  christos 	    mec_irq(1);
    361  1.1  christos     }
    362  1.1  christos     if (mec_ersr & 0x20) {
    363  1.1  christos 	if (!(mec_mcr & 0x2000)) {
    364  1.1  christos 	    if (mec_mcr & 0x4000) {
    365  1.1  christos 	        sys_reset();
    366  1.1  christos 	        mec_ersr = 0x8000;
    367  1.1  christos 	        if (sis_verbose)
    368  1.1  christos 	            printf("Error manager reset - MEC hardware error\n");
    369  1.1  christos 	    } else {
    370  1.1  christos 	        sys_halt();
    371  1.1  christos 	        mec_ersr |= 0x2000;
    372  1.1  christos 	        if (sis_verbose)
    373  1.1  christos 	            printf("Error manager halt - MEC hardware error\n");
    374  1.1  christos 	    }
    375  1.1  christos 	} else
    376  1.1  christos 	    mec_irq(1);
    377  1.1  christos     }
    378  1.1  christos }
    379  1.1  christos 
    380  1.1  christos #ifdef ERRINJ
    381  1.1  christos static void
    382  1.1  christos iucomperr()
    383  1.1  christos {
    384  1.1  christos     mec_ersr |= 0x04;
    385  1.1  christos     decode_ersr();
    386  1.1  christos }
    387  1.1  christos #endif
    388  1.1  christos 
    389  1.1  christos static void
    390  1.1  christos mecparerror()
    391  1.1  christos {
    392  1.1  christos     mec_ersr |= 0x20;
    393  1.1  christos     decode_ersr();
    394  1.1  christos }
    395  1.1  christos 
    396  1.1  christos 
    397  1.1  christos /* IU error mode manager */
    398  1.1  christos 
    399  1.1  christos void
    400  1.1  christos error_mode(pc)
    401  1.1  christos     uint32          pc;
    402  1.1  christos {
    403  1.1  christos 
    404  1.1  christos     mec_ersr |= 0x1;
    405  1.1  christos     decode_ersr();
    406  1.1  christos }
    407  1.1  christos 
    408  1.1  christos 
    409  1.1  christos /* Check memory settings */
    410  1.1  christos 
    411  1.1  christos static void
    412  1.1  christos decode_memcfg()
    413  1.1  christos {
    414  1.1  christos     if (rom8) mec_memcfg &= ~0x20000;
    415  1.1  christos     else mec_memcfg |= 0x20000;
    416  1.1  christos 
    417  1.1  christos     mem_ramsz = (256 * 1024) << ((mec_memcfg >> 10) & 7);
    418  1.1  christos     mem_romsz = (128 * 1024) << ((mec_memcfg >> 18) & 7);
    419  1.1  christos 
    420  1.1  christos     if (sparclite_board) {
    421  1.1  christos 	mem_ramstart = RAM_START_SLITE;
    422  1.1  christos 	mem_ramend = RAM_END_SLITE;
    423  1.1  christos 	mem_rammask = RAM_MASK_SLITE;
    424  1.1  christos     }
    425  1.1  christos     else {
    426  1.1  christos 	mem_ramstart = RAM_START;
    427  1.1  christos 	mem_ramend = RAM_END;
    428  1.1  christos 	mem_rammask = RAM_MASK;
    429  1.1  christos     }
    430  1.1  christos     if (sis_verbose)
    431  1.1  christos 	printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
    432  1.1  christos 	       mem_ramstart, mem_ramsz >> 10, mem_romsz >> 10);
    433  1.1  christos }
    434  1.1  christos 
    435  1.1  christos static void
    436  1.1  christos decode_wcr()
    437  1.1  christos {
    438  1.1  christos     mem_ramr_ws = mec_wcr & 3;
    439  1.1  christos     mem_ramw_ws = (mec_wcr >> 2) & 3;
    440  1.1  christos     mem_romr_ws = (mec_wcr >> 4) & 0x0f;
    441  1.1  christos     if (rom8) {
    442  1.1  christos     	if (mem_romr_ws > 0 )  mem_romr_ws--;
    443  1.1  christos 	mem_romr_ws = 5 + (4*mem_romr_ws);
    444  1.1  christos     }
    445  1.1  christos     mem_romw_ws = (mec_wcr >> 8) & 0x0f;
    446  1.1  christos     if (sis_verbose)
    447  1.1  christos 	printf("Waitstates = RAM read: %d, RAM write: %d, ROM read: %d, ROM write: %d\n",
    448  1.1  christos 	       mem_ramr_ws, mem_ramw_ws, mem_romr_ws, mem_romw_ws);
    449  1.1  christos }
    450  1.1  christos 
    451  1.1  christos static void
    452  1.1  christos decode_mcr()
    453  1.1  christos {
    454  1.1  christos     mem_accprot = (mec_wpr[0] | mec_wpr[1]);
    455  1.1  christos     mem_blockprot = (mec_mcr >> 3) & 1;
    456  1.1  christos     if (sis_verbose && mem_accprot)
    457  1.1  christos 	printf("Memory block write protection enabled\n");
    458  1.1  christos     if (mec_mcr & 0x08000) {
    459  1.1  christos 	mec_ersr |= 0x20;
    460  1.1  christos 	decode_ersr();
    461  1.1  christos     }
    462  1.1  christos     if (sis_verbose && (mec_mcr & 2))
    463  1.1  christos 	printf("Software reset enabled\n");
    464  1.1  christos     if (sis_verbose && (mec_mcr & 1))
    465  1.1  christos 	printf("Power-down mode enabled\n");
    466  1.1  christos }
    467  1.1  christos 
    468  1.1  christos /* Flush ports when simulator stops */
    469  1.1  christos 
    470  1.1  christos void
    471  1.1  christos sim_halt()
    472  1.1  christos {
    473  1.1  christos #ifdef FAST_UART
    474  1.1  christos     flush_uart();
    475  1.1  christos #endif
    476  1.1  christos }
    477  1.1  christos 
    478  1.1  christos int
    479  1.1  christos sim_stop(SIM_DESC sd)
    480  1.1  christos {
    481  1.1  christos   ctrl_c = 1;
    482  1.1  christos   return 1;
    483  1.1  christos }
    484  1.1  christos 
    485  1.1  christos static void
    486  1.1  christos close_port()
    487  1.1  christos {
    488  1.1  christos     if (f1open && f1in != stdin)
    489  1.1  christos 	fclose(f1in);
    490  1.1  christos     if (f2open && f2in != stdin)
    491  1.1  christos 	fclose(f2in);
    492  1.1  christos }
    493  1.1  christos 
    494  1.1  christos void
    495  1.1  christos exit_sim()
    496  1.1  christos {
    497  1.1  christos     close_port();
    498  1.1  christos }
    499  1.1  christos 
    500  1.1  christos static void
    501  1.1  christos mec_reset()
    502  1.1  christos {
    503  1.1  christos     int             i;
    504  1.1  christos 
    505  1.1  christos     find = 0;
    506  1.1  christos     for (i = 0; i < 2; i++)
    507  1.1  christos 	mec_ssa[i] = mec_sea[i] = mec_wpr[i] = 0;
    508  1.1  christos     mec_mcr = 0x01350014;
    509  1.1  christos     mec_iocr = 0;
    510  1.1  christos     mec_sfsr = 0x078;
    511  1.1  christos     mec_ffar = 0;
    512  1.1  christos     mec_ipr = 0;
    513  1.1  christos     mec_imr = 0x7ffe;
    514  1.1  christos     mec_isr = 0;
    515  1.1  christos     mec_icr = 0;
    516  1.1  christos     mec_ifr = 0;
    517  1.1  christos     mec_memcfg = 0x10000;
    518  1.1  christos     mec_wcr = -1;
    519  1.1  christos     mec_ersr = 0;		/* MEC error and status register */
    520  1.1  christos     mec_tcr = 0;		/* MEC test comtrol register */
    521  1.1  christos 
    522  1.1  christos     decode_memcfg();
    523  1.1  christos     decode_wcr();
    524  1.1  christos     decode_mcr();
    525  1.1  christos 
    526  1.1  christos     posted_irq = 0;
    527  1.1  christos     wnuma = wnumb = 0;
    528  1.1  christos     anum = aind = bnum = bind = 0;
    529  1.1  christos 
    530  1.1  christos     uart_stat_reg = UARTA_SRE | UARTA_HRE | UARTB_SRE | UARTB_HRE;
    531  1.1  christos     uarta_data = uartb_data = UART_THE | UART_TSE;
    532  1.1  christos 
    533  1.1  christos     rtc_counter = 0xffffffff;
    534  1.1  christos     rtc_reload = 0xffffffff;
    535  1.1  christos     rtc_scaler = 0xff;
    536  1.1  christos     rtc_enabled = 0;
    537  1.1  christos     rtc_cr = 0;
    538  1.1  christos     rtc_se = 0;
    539  1.1  christos 
    540  1.1  christos     gpt_counter = 0xffffffff;
    541  1.1  christos     gpt_reload = 0xffffffff;
    542  1.1  christos     gpt_scaler = 0xffff;
    543  1.1  christos     gpt_enabled = 0;
    544  1.1  christos     gpt_cr = 0;
    545  1.1  christos     gpt_se = 0;
    546  1.1  christos 
    547  1.1  christos     wdog_scaler = 255;
    548  1.1  christos     wdog_rst_delay = 255;
    549  1.1  christos     wdog_counter = 0xffff;
    550  1.1  christos     wdog_rston = 0;
    551  1.1  christos     wdog_status = init;
    552  1.1  christos 
    553  1.1  christos #ifdef ERA
    554  1.1  christos     erareg = 0;
    555  1.1  christos #endif
    556  1.1  christos 
    557  1.1  christos }
    558  1.1  christos 
    559  1.1  christos 
    560  1.1  christos 
    561  1.1  christos static void
    562  1.1  christos mec_intack(level)
    563  1.1  christos     int32           level;
    564  1.1  christos {
    565  1.1  christos     int             irq_test;
    566  1.1  christos 
    567  1.1  christos     if (sis_verbose)
    568  1.1  christos 	printf("interrupt %d acknowledged\n", level);
    569  1.1  christos     irq_test = mec_tcr & 0x80000;
    570  1.1  christos     if ((irq_test) && (mec_ifr & (1 << level)))
    571  1.1  christos 	mec_ifr &= ~(1 << level);
    572  1.1  christos     else
    573  1.1  christos 	mec_ipr &= ~(1 << level);
    574  1.1  christos    chk_irq();
    575  1.1  christos }
    576  1.1  christos 
    577  1.1  christos static void
    578  1.1  christos chk_irq()
    579  1.1  christos {
    580  1.1  christos     int32           i;
    581  1.1  christos     uint32          itmp;
    582  1.1  christos     int		    old_irl;
    583  1.1  christos 
    584  1.1  christos     old_irl = ext_irl;
    585  1.1  christos     if (mec_tcr & 0x80000) itmp = mec_ifr;
    586  1.1  christos     else itmp  = 0;
    587  1.1  christos     itmp = ((mec_ipr | itmp) & ~mec_imr) & 0x0fffe;
    588  1.1  christos     ext_irl = 0;
    589  1.1  christos     if (itmp != 0) {
    590  1.1  christos 	for (i = 15; i > 0; i--) {
    591  1.1  christos 	    if (((itmp >> i) & 1) != 0) {
    592  1.1  christos 		if ((sis_verbose) && (i > old_irl))
    593  1.1  christos 		    printf("IU irl: %d\n", i);
    594  1.1  christos 		ext_irl = i;
    595  1.1  christos 	        set_int(i, mec_intack, i);
    596  1.1  christos 		break;
    597  1.1  christos 	    }
    598  1.1  christos 	}
    599  1.1  christos     }
    600  1.1  christos }
    601  1.1  christos 
    602  1.1  christos static void
    603  1.1  christos mec_irq(level)
    604  1.1  christos     int32           level;
    605  1.1  christos {
    606  1.1  christos     mec_ipr |= (1 << level);
    607  1.1  christos     chk_irq();
    608  1.1  christos }
    609  1.1  christos 
    610  1.1  christos static void
    611  1.1  christos set_sfsr(fault, addr, asi, read)
    612  1.1  christos     uint32          fault;
    613  1.1  christos     uint32          addr;
    614  1.1  christos     uint32          asi;
    615  1.1  christos     uint32          read;
    616  1.1  christos {
    617  1.1  christos     if ((asi == 0xa) || (asi == 0xb)) {
    618  1.1  christos 	mec_ffar = addr;
    619  1.1  christos 	mec_sfsr = (fault << 3) | (!read << 15);
    620  1.1  christos 	mec_sfsr |= ((mec_sfsr & 1) ^ 1) | (mec_sfsr & 1);
    621  1.1  christos 	switch (asi) {
    622  1.1  christos 	case 0xa:
    623  1.1  christos 	    mec_sfsr |= 0x0004;
    624  1.1  christos 	    break;
    625  1.1  christos 	case 0xb:
    626  1.1  christos 	    mec_sfsr |= 0x1004;
    627  1.1  christos 	    break;
    628  1.1  christos 	}
    629  1.1  christos     }
    630  1.1  christos }
    631  1.1  christos 
    632  1.1  christos static int32
    633  1.1  christos mec_read(addr, asi, data)
    634  1.1  christos     uint32          addr;
    635  1.1  christos     uint32          asi;
    636  1.1  christos     uint32         *data;
    637  1.1  christos {
    638  1.1  christos 
    639  1.1  christos     switch (addr & 0x0ff) {
    640  1.1  christos 
    641  1.1  christos     case MEC_MCR:		/* 0x00 */
    642  1.1  christos 	*data = mec_mcr;
    643  1.1  christos 	break;
    644  1.1  christos 
    645  1.1  christos     case MEC_MEMCFG:		/* 0x10 */
    646  1.1  christos 	*data = mec_memcfg;
    647  1.1  christos 	break;
    648  1.1  christos 
    649  1.1  christos     case MEC_IOCR:
    650  1.1  christos 	*data = mec_iocr;	/* 0x14 */
    651  1.1  christos 	break;
    652  1.1  christos 
    653  1.1  christos     case MEC_SSA1:		/* 0x20 */
    654  1.1  christos 	*data = mec_ssa[0] | (mec_wpr[0] << 23);
    655  1.1  christos 	break;
    656  1.1  christos     case MEC_SEA1:		/* 0x24 */
    657  1.1  christos 	*data = mec_sea[0];
    658  1.1  christos 	break;
    659  1.1  christos     case MEC_SSA2:		/* 0x28 */
    660  1.1  christos 	*data = mec_ssa[1] | (mec_wpr[1] << 23);
    661  1.1  christos 	break;
    662  1.1  christos     case MEC_SEA2:		/* 0x2c */
    663  1.1  christos 	*data = mec_sea[1];
    664  1.1  christos 	break;
    665  1.1  christos 
    666  1.1  christos     case MEC_ISR:		/* 0x44 */
    667  1.1  christos 	*data = mec_isr;
    668  1.1  christos 	break;
    669  1.1  christos 
    670  1.1  christos     case MEC_IPR:		/* 0x48 */
    671  1.1  christos 	*data = mec_ipr;
    672  1.1  christos 	break;
    673  1.1  christos 
    674  1.1  christos     case MEC_IMR:		/* 0x4c */
    675  1.1  christos 	*data = mec_imr;
    676  1.1  christos 	break;
    677  1.1  christos 
    678  1.1  christos     case MEC_IFR:		/* 0x54 */
    679  1.1  christos 	*data = mec_ifr;
    680  1.1  christos 	break;
    681  1.1  christos 
    682  1.1  christos     case MEC_RTC_COUNTER:	/* 0x80 */
    683  1.1  christos 	*data = rtc_counter_read();
    684  1.1  christos 	break;
    685  1.1  christos     case MEC_RTC_SCALER:	/* 0x84 */
    686  1.1  christos 	if (rtc_enabled)
    687  1.1  christos 	    *data = rtc_scaler - (now() - rtc_scaler_start);
    688  1.1  christos 	else
    689  1.1  christos 	    *data = rtc_scaler;
    690  1.1  christos 	break;
    691  1.1  christos 
    692  1.1  christos     case MEC_GPT_COUNTER:	/* 0x88 */
    693  1.1  christos 	*data = gpt_counter_read();
    694  1.1  christos 	break;
    695  1.1  christos 
    696  1.1  christos     case MEC_GPT_SCALER:	/* 0x8c */
    697  1.1  christos 	if (rtc_enabled)
    698  1.1  christos 	    *data = gpt_scaler - (now() - gpt_scaler_start);
    699  1.1  christos 	else
    700  1.1  christos 	    *data = gpt_scaler;
    701  1.1  christos 	break;
    702  1.1  christos 
    703  1.1  christos 
    704  1.1  christos     case MEC_SFSR:		/* 0xA0 */
    705  1.1  christos 	*data = mec_sfsr;
    706  1.1  christos 	break;
    707  1.1  christos 
    708  1.1  christos     case MEC_FFAR:		/* 0xA4 */
    709  1.1  christos 	*data = mec_ffar;
    710  1.1  christos 	break;
    711  1.1  christos 
    712  1.1  christos     case SIM_LOAD:
    713  1.1  christos 	fname[find] = 0;
    714  1.1  christos 	if (find == 0)
    715  1.1  christos 	    strcpy(fname, "simload");
    716  1.1  christos 	find = bfd_load(fname);
    717  1.1  christos  	if (find == -1)
    718  1.1  christos 	    *data = 0;
    719  1.1  christos 	else
    720  1.1  christos 	    *data = 1;
    721  1.1  christos 	find = 0;
    722  1.1  christos 	break;
    723  1.1  christos 
    724  1.1  christos     case MEC_ERSR:		/* 0xB0 */
    725  1.1  christos 	*data = mec_ersr;
    726  1.1  christos 	break;
    727  1.1  christos 
    728  1.1  christos     case MEC_TCR:		/* 0xD0 */
    729  1.1  christos 	*data = mec_tcr;
    730  1.1  christos 	break;
    731  1.1  christos 
    732  1.1  christos     case MEC_UARTA:		/* 0xE0 */
    733  1.1  christos     case MEC_UARTB:		/* 0xE4 */
    734  1.1  christos 	if (asi != 0xb) {
    735  1.1  christos 	    set_sfsr(MEC_ACC, addr, asi, 1);
    736  1.1  christos 	    return (1);
    737  1.1  christos 	}
    738  1.1  christos 	*data = read_uart(addr);
    739  1.1  christos 	break;
    740  1.1  christos 
    741  1.1  christos     case MEC_UART_CTRL:		/* 0xE8 */
    742  1.1  christos 
    743  1.1  christos 	*data = read_uart(addr);
    744  1.1  christos 	break;
    745  1.1  christos 
    746  1.1  christos     default:
    747  1.1  christos 	set_sfsr(MEC_ACC, addr, asi, 1);
    748  1.1  christos 	return (1);
    749  1.1  christos 	break;
    750  1.1  christos     }
    751  1.1  christos     return (MOK);
    752  1.1  christos }
    753  1.1  christos 
    754  1.1  christos static int
    755  1.1  christos mec_write(addr, data)
    756  1.1  christos     uint32          addr;
    757  1.1  christos     uint32          data;
    758  1.1  christos {
    759  1.1  christos     if (sis_verbose > 1)
    760  1.1  christos 	printf("MEC write a: %08x, d: %08x\n",addr,data);
    761  1.1  christos     switch (addr & 0x0ff) {
    762  1.1  christos 
    763  1.1  christos     case MEC_MCR:
    764  1.1  christos 	mec_mcr = data;
    765  1.1  christos 	decode_mcr();
    766  1.1  christos         if (mec_mcr & 0x08000) mecparerror();
    767  1.1  christos 	break;
    768  1.1  christos 
    769  1.1  christos     case MEC_SFR:
    770  1.1  christos 	if (mec_mcr & 0x2) {
    771  1.1  christos 	    sys_reset();
    772  1.1  christos 	    mec_ersr = 0x4000;
    773  1.1  christos     	    if (sis_verbose)
    774  1.1  christos 	    	printf(" Software reset issued\n");
    775  1.1  christos 	}
    776  1.1  christos 	break;
    777  1.1  christos 
    778  1.1  christos     case MEC_IOCR:
    779  1.1  christos 	mec_iocr = data;
    780  1.1  christos         if (mec_iocr & 0xC0C0C0C0) mecparerror();
    781  1.1  christos 	break;
    782  1.1  christos 
    783  1.1  christos     case MEC_SSA1:		/* 0x20 */
    784  1.1  christos         if (data & 0xFE000000) mecparerror();
    785  1.1  christos 	mec_ssa[0] = data & 0x7fffff;
    786  1.1  christos 	mec_wpr[0] = (data >> 23) & 0x03;
    787  1.1  christos 	mem_accprot = mec_wpr[0] || mec_wpr[1];
    788  1.1  christos 	if (sis_verbose && mec_wpr[0])
    789  1.1  christos 	    printf("Segment 1 memory protection enabled (0x02%06x - 0x02%06x)\n",
    790  1.1  christos 		   mec_ssa[0] << 2, mec_sea[0] << 2);
    791  1.1  christos 	break;
    792  1.1  christos     case MEC_SEA1:		/* 0x24 */
    793  1.1  christos         if (data & 0xFF800000) mecparerror();
    794  1.1  christos 	mec_sea[0] = data & 0x7fffff;
    795  1.1  christos 	break;
    796  1.1  christos     case MEC_SSA2:		/* 0x28 */
    797  1.1  christos         if (data & 0xFE000000) mecparerror();
    798  1.1  christos 	mec_ssa[1] = data & 0x7fffff;
    799  1.1  christos 	mec_wpr[1] = (data >> 23) & 0x03;
    800  1.1  christos 	mem_accprot = mec_wpr[0] || mec_wpr[1];
    801  1.1  christos 	if (sis_verbose && mec_wpr[1])
    802  1.1  christos 	    printf("Segment 2 memory protection enabled (0x02%06x - 0x02%06x)\n",
    803  1.1  christos 		   mec_ssa[1] << 2, mec_sea[1] << 2);
    804  1.1  christos 	break;
    805  1.1  christos     case MEC_SEA2:		/* 0x2c */
    806  1.1  christos         if (data & 0xFF800000) mecparerror();
    807  1.1  christos 	mec_sea[1] = data & 0x7fffff;
    808  1.1  christos 	break;
    809  1.1  christos 
    810  1.1  christos     case MEC_UARTA:
    811  1.1  christos     case MEC_UARTB:
    812  1.1  christos         if (data & 0xFFFFFF00) mecparerror();
    813  1.1  christos     case MEC_UART_CTRL:
    814  1.1  christos         if (data & 0xFF00FF00) mecparerror();
    815  1.1  christos 	write_uart(addr, data);
    816  1.1  christos 	break;
    817  1.1  christos 
    818  1.1  christos     case MEC_GPT_RELOAD:
    819  1.1  christos 	gpt_reload_set(data);
    820  1.1  christos 	break;
    821  1.1  christos 
    822  1.1  christos     case MEC_GPT_SCALER:
    823  1.1  christos         if (data & 0xFFFF0000) mecparerror();
    824  1.1  christos 	gpt_scaler_set(data);
    825  1.1  christos 	break;
    826  1.1  christos 
    827  1.1  christos     case MEC_TIMER_CTRL:
    828  1.1  christos         if (data & 0xFFFFF0F0) mecparerror();
    829  1.1  christos 	timer_ctrl(data);
    830  1.1  christos 	break;
    831  1.1  christos 
    832  1.1  christos     case MEC_RTC_RELOAD:
    833  1.1  christos 	rtc_reload_set(data);
    834  1.1  christos 	break;
    835  1.1  christos 
    836  1.1  christos     case MEC_RTC_SCALER:
    837  1.1  christos         if (data & 0xFFFFFF00) mecparerror();
    838  1.1  christos 	rtc_scaler_set(data);
    839  1.1  christos 	break;
    840  1.1  christos 
    841  1.1  christos     case MEC_SFSR:		/* 0xA0 */
    842  1.1  christos         if (data & 0xFFFF0880) mecparerror();
    843  1.1  christos 	mec_sfsr = 0x78;
    844  1.1  christos 	break;
    845  1.1  christos 
    846  1.1  christos     case MEC_ISR:
    847  1.1  christos         if (data & 0xFFFFE000) mecparerror();
    848  1.1  christos 	mec_isr = data;
    849  1.1  christos 	break;
    850  1.1  christos 
    851  1.1  christos     case MEC_IMR:		/* 0x4c */
    852  1.1  christos 
    853  1.1  christos         if (data & 0xFFFF8001) mecparerror();
    854  1.1  christos 	mec_imr = data & 0x7ffe;
    855  1.1  christos 	chk_irq();
    856  1.1  christos 	break;
    857  1.1  christos 
    858  1.1  christos     case MEC_ICR:		/* 0x50 */
    859  1.1  christos 
    860  1.1  christos         if (data & 0xFFFF0001) mecparerror();
    861  1.1  christos 	mec_ipr &= ~data & 0x0fffe;
    862  1.1  christos 	chk_irq();
    863  1.1  christos 	break;
    864  1.1  christos 
    865  1.1  christos     case MEC_IFR:		/* 0x54 */
    866  1.1  christos 
    867  1.1  christos         if (mec_tcr & 0x080000) {
    868  1.1  christos             if (data & 0xFFFF0001) mecparerror();
    869  1.1  christos 	    mec_ifr = data & 0xfffe;
    870  1.1  christos 	    chk_irq();
    871  1.1  christos 	}
    872  1.1  christos 	break;
    873  1.1  christos     case SIM_LOAD:
    874  1.1  christos 	fname[find++] = (char) data;
    875  1.1  christos 	break;
    876  1.1  christos 
    877  1.1  christos 
    878  1.1  christos     case MEC_MEMCFG:		/* 0x10 */
    879  1.1  christos         if (data & 0xC0E08000) mecparerror();
    880  1.1  christos 	mec_memcfg = data;
    881  1.1  christos 	decode_memcfg();
    882  1.1  christos 	if (mec_memcfg & 0xc0e08000)
    883  1.1  christos 	    mecparerror();
    884  1.1  christos 	break;
    885  1.1  christos 
    886  1.1  christos     case MEC_WCR:		/* 0x18 */
    887  1.1  christos 	mec_wcr = data;
    888  1.1  christos 	decode_wcr();
    889  1.1  christos 	break;
    890  1.1  christos 
    891  1.1  christos     case MEC_ERSR:		/* 0xB0 */
    892  1.1  christos 	if (mec_tcr & 0x100000)
    893  1.1  christos             if (data & 0xFFFFEFC0) mecparerror();
    894  1.1  christos 	    mec_ersr = data & 0x103f;
    895  1.1  christos 	break;
    896  1.1  christos 
    897  1.1  christos     case MEC_TCR:		/* 0xD0 */
    898  1.1  christos         if (data & 0xFFE1FFC0) mecparerror();
    899  1.1  christos 	mec_tcr = data & 0x1e003f;
    900  1.1  christos 	break;
    901  1.1  christos 
    902  1.1  christos     case MEC_WDOG:		/* 0x60 */
    903  1.1  christos 	wdog_scaler = (data >> 16) & 0x0ff;
    904  1.1  christos 	wdog_counter = data & 0x0ffff;
    905  1.1  christos 	wdog_rst_delay = data >> 24;
    906  1.1  christos 	wdog_rston = 0;
    907  1.1  christos 	if (wdog_status == stopped)
    908  1.1  christos 	    wdog_start();
    909  1.1  christos 	wdog_status = enabled;
    910  1.1  christos 	break;
    911  1.1  christos 
    912  1.1  christos     case MEC_TRAPD:		/* 0x64 */
    913  1.1  christos 	if (wdog_status == init) {
    914  1.1  christos 	    wdog_status = disabled;
    915  1.1  christos 	    if (sis_verbose)
    916  1.1  christos 		printf("Watchdog disabled\n");
    917  1.1  christos 	}
    918  1.1  christos 	break;
    919  1.1  christos 
    920  1.1  christos     case MEC_PWDR:
    921  1.1  christos 	if (mec_mcr & 1)
    922  1.1  christos 	    wait_for_irq();
    923  1.1  christos 	break;
    924  1.1  christos 
    925  1.1  christos     default:
    926  1.1  christos 	set_sfsr(MEC_ACC, addr, 0xb, 0);
    927  1.1  christos 	return (1);
    928  1.1  christos 	break;
    929  1.1  christos     }
    930  1.1  christos     return (MOK);
    931  1.1  christos }
    932  1.1  christos 
    933  1.1  christos 
    934  1.1  christos /* MEC UARTS */
    935  1.1  christos 
    936  1.1  christos static int      ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1;
    937  1.1  christos 
    938  1.1  christos void
    939  1.1  christos init_stdio()
    940  1.1  christos {
    941  1.1  christos     if (dumbio)
    942  1.1  christos         return; /* do nothing */
    943  1.1  christos     if (!ifd1)
    944  1.1  christos 	tcsetattr(0, TCSANOW, &ioc1);
    945  1.1  christos     if (!ifd2)
    946  1.1  christos 	tcsetattr(0, TCSANOW, &ioc2);
    947  1.1  christos }
    948  1.1  christos 
    949  1.1  christos void
    950  1.1  christos restore_stdio()
    951  1.1  christos {
    952  1.1  christos     if (dumbio)
    953  1.1  christos         return; /* do nothing */
    954  1.1  christos     if (!ifd1)
    955  1.1  christos 	tcsetattr(0, TCSANOW, &iocold1);
    956  1.1  christos     if (!ifd2)
    957  1.1  christos 	tcsetattr(0, TCSANOW, &iocold2);
    958  1.1  christos }
    959  1.1  christos 
    960  1.1  christos #define DO_STDIO_READ( _fd_, _buf_, _len_ )          \
    961  1.1  christos              ( dumbio                                \
    962  1.1  christos                ? (0) /* no bytes read, no delay */   \
    963  1.1  christos                : read( _fd_, _buf_, _len_ ) )
    964  1.1  christos 
    965  1.1  christos 
    966  1.1  christos static void
    967  1.1  christos port_init()
    968  1.1  christos {
    969  1.1  christos 
    970  1.1  christos     if (uben) {
    971  1.1  christos     f2in = stdin;
    972  1.1  christos     f1in = NULL;
    973  1.1  christos     f2out = stdout;
    974  1.1  christos     f1out = NULL;
    975  1.1  christos     } else {
    976  1.1  christos     f1in = stdin;
    977  1.1  christos     f2in = NULL;
    978  1.1  christos     f1out = stdout;
    979  1.1  christos     f2out = NULL;
    980  1.1  christos     }
    981  1.1  christos     if (uart_dev1[0] != 0)
    982  1.1  christos 	if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) {
    983  1.1  christos 	    printf("Warning, couldn't open output device %s\n", uart_dev1);
    984  1.1  christos 	} else {
    985  1.1  christos 	    if (sis_verbose)
    986  1.1  christos 		printf("serial port A on %s\n", uart_dev1);
    987  1.1  christos 	    f1in = f1out = fdopen(fd1, "r+");
    988  1.1  christos 	    setbuf(f1out, NULL);
    989  1.1  christos 	    f1open = 1;
    990  1.1  christos 	}
    991  1.1  christos     if (f1in) ifd1 = fileno(f1in);
    992  1.1  christos     if (ifd1 == 0) {
    993  1.1  christos 	if (sis_verbose)
    994  1.1  christos 	    printf("serial port A on stdin/stdout\n");
    995  1.1  christos         if (!dumbio) {
    996  1.1  christos             tcgetattr(ifd1, &ioc1);
    997  1.1  christos             iocold1 = ioc1;
    998  1.1  christos             ioc1.c_lflag &= ~(ICANON | ECHO);
    999  1.1  christos             ioc1.c_cc[VMIN] = 0;
   1000  1.1  christos             ioc1.c_cc[VTIME] = 0;
   1001  1.1  christos         }
   1002  1.1  christos 	f1open = 1;
   1003  1.1  christos     }
   1004  1.1  christos 
   1005  1.1  christos     if (f1out) {
   1006  1.1  christos 	ofd1 = fileno(f1out);
   1007  1.1  christos     	if (!dumbio && ofd1 == 1) setbuf(f1out, NULL);
   1008  1.1  christos     }
   1009  1.1  christos 
   1010  1.1  christos     if (uart_dev2[0] != 0)
   1011  1.1  christos 	if ((fd2 = open(uart_dev2, O_RDWR | O_NONBLOCK)) < 0) {
   1012  1.1  christos 	    printf("Warning, couldn't open output device %s\n", uart_dev2);
   1013  1.1  christos 	} else {
   1014  1.1  christos 	    if (sis_verbose)
   1015  1.1  christos 		printf("serial port B on %s\n", uart_dev2);
   1016  1.1  christos 	    f2in = f2out = fdopen(fd2, "r+");
   1017  1.1  christos 	    setbuf(f2out, NULL);
   1018  1.1  christos 	    f2open = 1;
   1019  1.1  christos 	}
   1020  1.1  christos     if (f2in)  ifd2 = fileno(f2in);
   1021  1.1  christos     if (ifd2 == 0) {
   1022  1.1  christos 	if (sis_verbose)
   1023  1.1  christos 	    printf("serial port B on stdin/stdout\n");
   1024  1.1  christos         if (!dumbio) {
   1025  1.1  christos             tcgetattr(ifd2, &ioc2);
   1026  1.1  christos             iocold2 = ioc2;
   1027  1.1  christos             ioc2.c_lflag &= ~(ICANON | ECHO);
   1028  1.1  christos             ioc2.c_cc[VMIN] = 0;
   1029  1.1  christos             ioc2.c_cc[VTIME] = 0;
   1030  1.1  christos         }
   1031  1.1  christos 	f2open = 1;
   1032  1.1  christos     }
   1033  1.1  christos 
   1034  1.1  christos     if (f2out) {
   1035  1.1  christos 	ofd2 = fileno(f2out);
   1036  1.1  christos         if (!dumbio && ofd2 == 1) setbuf(f2out, NULL);
   1037  1.1  christos     }
   1038  1.1  christos 
   1039  1.1  christos     wnuma = wnumb = 0;
   1040  1.1  christos 
   1041  1.1  christos }
   1042  1.1  christos 
   1043  1.1  christos static uint32
   1044  1.1  christos read_uart(addr)
   1045  1.1  christos     uint32          addr;
   1046  1.1  christos {
   1047  1.1  christos 
   1048  1.1  christos     unsigned        tmp;
   1049  1.1  christos 
   1050  1.1  christos     tmp = 0;
   1051  1.1  christos     switch (addr & 0xff) {
   1052  1.1  christos 
   1053  1.1  christos     case 0xE0:			/* UART 1 */
   1054  1.1  christos #ifndef _WIN32
   1055  1.1  christos #ifdef FAST_UART
   1056  1.1  christos 
   1057  1.1  christos 	if (aind < anum) {
   1058  1.1  christos 	    if ((aind + 1) < anum)
   1059  1.1  christos 		mec_irq(4);
   1060  1.1  christos 	    return (0x700 | (uint32) aq[aind++]);
   1061  1.1  christos 	} else {
   1062  1.1  christos 	    if (f1open) {
   1063  1.1  christos 	        anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
   1064  1.1  christos 	    }
   1065  1.1  christos 	    if (anum > 0) {
   1066  1.1  christos 		aind = 0;
   1067  1.1  christos 		if ((aind + 1) < anum)
   1068  1.1  christos 		    mec_irq(4);
   1069  1.1  christos 		return (0x700 | (uint32) aq[aind++]);
   1070  1.1  christos 	    } else {
   1071  1.1  christos 		return (0x600 | (uint32) aq[aind]);
   1072  1.1  christos 	    }
   1073  1.1  christos 
   1074  1.1  christos 	}
   1075  1.1  christos #else
   1076  1.1  christos 	tmp = uarta_data;
   1077  1.1  christos 	uarta_data &= ~UART_DR;
   1078  1.1  christos 	uart_stat_reg &= ~UARTA_DR;
   1079  1.1  christos 	return tmp;
   1080  1.1  christos #endif
   1081  1.1  christos #else
   1082  1.1  christos 	return(0);
   1083  1.1  christos #endif
   1084  1.1  christos 	break;
   1085  1.1  christos 
   1086  1.1  christos     case 0xE4:			/* UART 2 */
   1087  1.1  christos #ifndef _WIN32
   1088  1.1  christos #ifdef FAST_UART
   1089  1.1  christos 	if (bind < bnum) {
   1090  1.1  christos 	    if ((bind + 1) < bnum)
   1091  1.1  christos 		mec_irq(5);
   1092  1.1  christos 	    return (0x700 | (uint32) bq[bind++]);
   1093  1.1  christos 	} else {
   1094  1.1  christos 	    if (f2open) {
   1095  1.1  christos 		bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
   1096  1.1  christos 	    }
   1097  1.1  christos 	    if (bnum > 0) {
   1098  1.1  christos 		bind = 0;
   1099  1.1  christos 		if ((bind + 1) < bnum)
   1100  1.1  christos 		    mec_irq(5);
   1101  1.1  christos 		return (0x700 | (uint32) bq[bind++]);
   1102  1.1  christos 	    } else {
   1103  1.1  christos 		return (0x600 | (uint32) bq[bind]);
   1104  1.1  christos 	    }
   1105  1.1  christos 
   1106  1.1  christos 	}
   1107  1.1  christos #else
   1108  1.1  christos 	tmp = uartb_data;
   1109  1.1  christos 	uartb_data &= ~UART_DR;
   1110  1.1  christos 	uart_stat_reg &= ~UARTB_DR;
   1111  1.1  christos 	return tmp;
   1112  1.1  christos #endif
   1113  1.1  christos #else
   1114  1.1  christos 	return(0);
   1115  1.1  christos #endif
   1116  1.1  christos 	break;
   1117  1.1  christos 
   1118  1.1  christos     case 0xE8:			/* UART status register	 */
   1119  1.1  christos #ifndef _WIN32
   1120  1.1  christos #ifdef FAST_UART
   1121  1.1  christos 
   1122  1.1  christos 	Ucontrol = 0;
   1123  1.1  christos 	if (aind < anum) {
   1124  1.1  christos 	    Ucontrol |= 0x00000001;
   1125  1.1  christos 	} else {
   1126  1.1  christos 	    if (f1open) {
   1127  1.1  christos 	        anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
   1128  1.1  christos             }
   1129  1.1  christos 	    if (anum > 0) {
   1130  1.1  christos 		Ucontrol |= 0x00000001;
   1131  1.1  christos 		aind = 0;
   1132  1.1  christos 		mec_irq(4);
   1133  1.1  christos 	    }
   1134  1.1  christos 	}
   1135  1.1  christos 	if (bind < bnum) {
   1136  1.1  christos 	    Ucontrol |= 0x00010000;
   1137  1.1  christos 	} else {
   1138  1.1  christos 	    if (f2open) {
   1139  1.1  christos 		bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
   1140  1.1  christos 	    }
   1141  1.1  christos 	    if (bnum > 0) {
   1142  1.1  christos 		Ucontrol |= 0x00010000;
   1143  1.1  christos 		bind = 0;
   1144  1.1  christos 		mec_irq(5);
   1145  1.1  christos 	    }
   1146  1.1  christos 	}
   1147  1.1  christos 
   1148  1.1  christos 	Ucontrol |= 0x00060006;
   1149  1.1  christos 	return (Ucontrol);
   1150  1.1  christos #else
   1151  1.1  christos 	return (uart_stat_reg);
   1152  1.1  christos #endif
   1153  1.1  christos #else
   1154  1.1  christos 	return(0x00060006);
   1155  1.1  christos #endif
   1156  1.1  christos 	break;
   1157  1.1  christos     default:
   1158  1.1  christos 	if (sis_verbose)
   1159  1.1  christos 	    printf("Read from unimplemented MEC register (%x)\n", addr);
   1160  1.1  christos 
   1161  1.1  christos     }
   1162  1.1  christos     return (0);
   1163  1.1  christos }
   1164  1.1  christos 
   1165  1.1  christos static void
   1166  1.1  christos write_uart(addr, data)
   1167  1.1  christos     uint32          addr;
   1168  1.1  christos     uint32          data;
   1169  1.1  christos {
   1170  1.1  christos     unsigned char   c;
   1171  1.1  christos 
   1172  1.1  christos     c = (unsigned char) data;
   1173  1.1  christos     switch (addr & 0xff) {
   1174  1.1  christos 
   1175  1.1  christos     case 0xE0:			/* UART A */
   1176  1.1  christos #ifdef FAST_UART
   1177  1.1  christos 	if (f1open) {
   1178  1.1  christos 	    if (wnuma < UARTBUF)
   1179  1.1  christos 	        wbufa[wnuma++] = c;
   1180  1.1  christos 	    else {
   1181  1.1  christos 	        while (wnuma)
   1182  1.1  christos 		    wnuma -= fwrite(wbufa, 1, wnuma, f1out);
   1183  1.1  christos 	        wbufa[wnuma++] = c;
   1184  1.1  christos 	    }
   1185  1.1  christos 	}
   1186  1.1  christos 	mec_irq(4);
   1187  1.1  christos #else
   1188  1.1  christos 	if (uart_stat_reg & UARTA_SRE) {
   1189  1.1  christos 	    uarta_sreg = c;
   1190  1.1  christos 	    uart_stat_reg &= ~UARTA_SRE;
   1191  1.1  christos 	    event(uarta_tx, 0, UART_TX_TIME);
   1192  1.1  christos 	} else {
   1193  1.1  christos 	    uarta_hreg = c;
   1194  1.1  christos 	    uart_stat_reg &= ~UARTA_HRE;
   1195  1.1  christos 	}
   1196  1.1  christos #endif
   1197  1.1  christos 	break;
   1198  1.1  christos 
   1199  1.1  christos     case 0xE4:			/* UART B */
   1200  1.1  christos #ifdef FAST_UART
   1201  1.1  christos 	if (f2open) {
   1202  1.1  christos 	    if (wnumb < UARTBUF)
   1203  1.1  christos 		wbufb[wnumb++] = c;
   1204  1.1  christos 	    else {
   1205  1.1  christos 		while (wnumb)
   1206  1.1  christos 		    wnumb -= fwrite(wbufb, 1, wnumb, f2out);
   1207  1.1  christos 		wbufb[wnumb++] = c;
   1208  1.1  christos 	    }
   1209  1.1  christos 	}
   1210  1.1  christos 	mec_irq(5);
   1211  1.1  christos #else
   1212  1.1  christos 	if (uart_stat_reg & UARTB_SRE) {
   1213  1.1  christos 	    uartb_sreg = c;
   1214  1.1  christos 	    uart_stat_reg &= ~UARTB_SRE;
   1215  1.1  christos 	    event(uartb_tx, 0, UART_TX_TIME);
   1216  1.1  christos 	} else {
   1217  1.1  christos 	    uartb_hreg = c;
   1218  1.1  christos 	    uart_stat_reg &= ~UARTB_HRE;
   1219  1.1  christos 	}
   1220  1.1  christos #endif
   1221  1.1  christos 	break;
   1222  1.1  christos     case 0xE8:			/* UART status register */
   1223  1.1  christos #ifndef FAST_UART
   1224  1.1  christos 	if (data & UARTA_CLR) {
   1225  1.1  christos 	    uart_stat_reg &= 0xFFFF0000;
   1226  1.1  christos 	    uart_stat_reg |= UARTA_SRE | UARTA_HRE;
   1227  1.1  christos 	}
   1228  1.1  christos 	if (data & UARTB_CLR) {
   1229  1.1  christos 	    uart_stat_reg &= 0x0000FFFF;
   1230  1.1  christos 	    uart_stat_reg |= UARTB_SRE | UARTB_HRE;
   1231  1.1  christos 	}
   1232  1.1  christos #endif
   1233  1.1  christos 	break;
   1234  1.1  christos     default:
   1235  1.1  christos 	if (sis_verbose)
   1236  1.1  christos 	    printf("Write to unimplemented MEC register (%x)\n", addr);
   1237  1.1  christos 
   1238  1.1  christos     }
   1239  1.1  christos }
   1240  1.1  christos 
   1241  1.1  christos static void
   1242  1.1  christos flush_uart()
   1243  1.1  christos {
   1244  1.1  christos     while (wnuma && f1open)
   1245  1.1  christos 	wnuma -= fwrite(wbufa, 1, wnuma, f1out);
   1246  1.1  christos     while (wnumb && f2open)
   1247  1.1  christos 	wnumb -= fwrite(wbufb, 1, wnumb, f2out);
   1248  1.1  christos }
   1249  1.1  christos 
   1250  1.1  christos 
   1251  1.1  christos 
   1252  1.1  christos static void
   1253  1.1  christos uarta_tx()
   1254  1.1  christos {
   1255  1.1  christos 
   1256  1.1  christos     while (f1open && fwrite(&uarta_sreg, 1, 1, f1out) != 1);
   1257  1.1  christos     if (uart_stat_reg & UARTA_HRE) {
   1258  1.1  christos 	uart_stat_reg |= UARTA_SRE;
   1259  1.1  christos     } else {
   1260  1.1  christos 	uarta_sreg = uarta_hreg;
   1261  1.1  christos 	uart_stat_reg |= UARTA_HRE;
   1262  1.1  christos 	event(uarta_tx, 0, UART_TX_TIME);
   1263  1.1  christos     }
   1264  1.1  christos     mec_irq(4);
   1265  1.1  christos }
   1266  1.1  christos 
   1267  1.1  christos static void
   1268  1.1  christos uartb_tx()
   1269  1.1  christos {
   1270  1.1  christos     while (f2open && fwrite(&uartb_sreg, 1, 1, f2out) != 1);
   1271  1.1  christos     if (uart_stat_reg & UARTB_HRE) {
   1272  1.1  christos 	uart_stat_reg |= UARTB_SRE;
   1273  1.1  christos     } else {
   1274  1.1  christos 	uartb_sreg = uartb_hreg;
   1275  1.1  christos 	uart_stat_reg |= UARTB_HRE;
   1276  1.1  christos 	event(uartb_tx, 0, UART_TX_TIME);
   1277  1.1  christos     }
   1278  1.1  christos     mec_irq(5);
   1279  1.1  christos }
   1280  1.1  christos 
   1281  1.1  christos static void
   1282  1.1  christos uart_rx(arg)
   1283  1.1  christos     caddr_t         arg;
   1284  1.1  christos {
   1285  1.1  christos     int32           rsize;
   1286  1.1  christos     char            rxd;
   1287  1.1  christos 
   1288  1.1  christos 
   1289  1.1  christos     rsize = 0;
   1290  1.1  christos     if (f1open)
   1291  1.1  christos         rsize = DO_STDIO_READ(ifd1, &rxd, 1);
   1292  1.1  christos     if (rsize > 0) {
   1293  1.1  christos 	uarta_data = UART_DR | rxd;
   1294  1.1  christos 	if (uart_stat_reg & UARTA_HRE)
   1295  1.1  christos 	    uarta_data |= UART_THE;
   1296  1.1  christos 	if (uart_stat_reg & UARTA_SRE)
   1297  1.1  christos 	    uarta_data |= UART_TSE;
   1298  1.1  christos 	if (uart_stat_reg & UARTA_DR) {
   1299  1.1  christos 	    uart_stat_reg |= UARTA_OR;
   1300  1.1  christos 	    mec_irq(7);		/* UART error interrupt */
   1301  1.1  christos 	}
   1302  1.1  christos 	uart_stat_reg |= UARTA_DR;
   1303  1.1  christos 	mec_irq(4);
   1304  1.1  christos     }
   1305  1.1  christos     rsize = 0;
   1306  1.1  christos     if (f2open)
   1307  1.1  christos         rsize = DO_STDIO_READ(ifd2, &rxd, 1);
   1308  1.1  christos     if (rsize) {
   1309  1.1  christos 	uartb_data = UART_DR | rxd;
   1310  1.1  christos 	if (uart_stat_reg & UARTB_HRE)
   1311  1.1  christos 	    uartb_data |= UART_THE;
   1312  1.1  christos 	if (uart_stat_reg & UARTB_SRE)
   1313  1.1  christos 	    uartb_data |= UART_TSE;
   1314  1.1  christos 	if (uart_stat_reg & UARTB_DR) {
   1315  1.1  christos 	    uart_stat_reg |= UARTB_OR;
   1316  1.1  christos 	    mec_irq(7);		/* UART error interrupt */
   1317  1.1  christos 	}
   1318  1.1  christos 	uart_stat_reg |= UARTB_DR;
   1319  1.1  christos 	mec_irq(5);
   1320  1.1  christos     }
   1321  1.1  christos     event(uart_rx, 0, UART_RX_TIME);
   1322  1.1  christos }
   1323  1.1  christos 
   1324  1.1  christos static void
   1325  1.1  christos uart_intr(arg)
   1326  1.1  christos     caddr_t         arg;
   1327  1.1  christos {
   1328  1.1  christos     read_uart(0xE8);		/* Check for UART interrupts every 1000 clk */
   1329  1.1  christos     flush_uart();		/* Flush UART ports      */
   1330  1.1  christos     event(uart_intr, 0, UART_FLUSH_TIME);
   1331  1.1  christos }
   1332  1.1  christos 
   1333  1.1  christos 
   1334  1.1  christos static void
   1335  1.1  christos uart_irq_start()
   1336  1.1  christos {
   1337  1.1  christos #ifdef FAST_UART
   1338  1.1  christos     event(uart_intr, 0, UART_FLUSH_TIME);
   1339  1.1  christos #else
   1340  1.1  christos #ifndef _WIN32
   1341  1.1  christos     event(uart_rx, 0, UART_RX_TIME);
   1342  1.1  christos #endif
   1343  1.1  christos #endif
   1344  1.1  christos }
   1345  1.1  christos 
   1346  1.1  christos /* Watch-dog */
   1347  1.1  christos 
   1348  1.1  christos static void
   1349  1.1  christos wdog_intr(arg)
   1350  1.1  christos     caddr_t         arg;
   1351  1.1  christos {
   1352  1.1  christos     if (wdog_status == disabled) {
   1353  1.1  christos 	wdog_status = stopped;
   1354  1.1  christos     } else {
   1355  1.1  christos 
   1356  1.1  christos 	if (wdog_counter) {
   1357  1.1  christos 	    wdog_counter--;
   1358  1.1  christos 	    event(wdog_intr, 0, wdog_scaler + 1);
   1359  1.1  christos 	} else {
   1360  1.1  christos 	    if (wdog_rston) {
   1361  1.1  christos 		printf("Watchdog reset!\n");
   1362  1.1  christos 		sys_reset();
   1363  1.1  christos 		mec_ersr = 0xC000;
   1364  1.1  christos 	    } else {
   1365  1.1  christos 		mec_irq(15);
   1366  1.1  christos 		wdog_rston = 1;
   1367  1.1  christos 		wdog_counter = wdog_rst_delay;
   1368  1.1  christos 		event(wdog_intr, 0, wdog_scaler + 1);
   1369  1.1  christos 	    }
   1370  1.1  christos 	}
   1371  1.1  christos     }
   1372  1.1  christos }
   1373  1.1  christos 
   1374  1.1  christos static void
   1375  1.1  christos wdog_start()
   1376  1.1  christos {
   1377  1.1  christos     event(wdog_intr, 0, wdog_scaler + 1);
   1378  1.1  christos     if (sis_verbose)
   1379  1.1  christos 	printf("Watchdog started, scaler = %d, counter = %d\n",
   1380  1.1  christos 	       wdog_scaler, wdog_counter);
   1381  1.1  christos }
   1382  1.1  christos 
   1383  1.1  christos 
   1384  1.1  christos /* MEC timers */
   1385  1.1  christos 
   1386  1.1  christos 
   1387  1.1  christos static void
   1388  1.1  christos rtc_intr(arg)
   1389  1.1  christos     caddr_t         arg;
   1390  1.1  christos {
   1391  1.1  christos     if (rtc_counter == 0) {
   1392  1.1  christos 
   1393  1.1  christos 	mec_irq(13);
   1394  1.1  christos 	if (rtc_cr)
   1395  1.1  christos 	    rtc_counter = rtc_reload;
   1396  1.1  christos 	else
   1397  1.1  christos 	    rtc_se = 0;
   1398  1.1  christos     } else
   1399  1.1  christos 	rtc_counter -= 1;
   1400  1.1  christos     if (rtc_se) {
   1401  1.1  christos 	event(rtc_intr, 0, rtc_scaler + 1);
   1402  1.1  christos 	rtc_scaler_start = now();
   1403  1.1  christos 	rtc_enabled = 1;
   1404  1.1  christos     } else {
   1405  1.1  christos 	if (sis_verbose)
   1406  1.1  christos 	    printf("RTC stopped\n\r");
   1407  1.1  christos 	rtc_enabled = 0;
   1408  1.1  christos     }
   1409  1.1  christos }
   1410  1.1  christos 
   1411  1.1  christos static void
   1412  1.1  christos rtc_start()
   1413  1.1  christos {
   1414  1.1  christos     if (sis_verbose)
   1415  1.1  christos 	printf("RTC started (period %d)\n\r", rtc_scaler + 1);
   1416  1.1  christos     event(rtc_intr, 0, rtc_scaler + 1);
   1417  1.1  christos     rtc_scaler_start = now();
   1418  1.1  christos     rtc_enabled = 1;
   1419  1.1  christos }
   1420  1.1  christos 
   1421  1.1  christos static uint32
   1422  1.1  christos rtc_counter_read()
   1423  1.1  christos {
   1424  1.1  christos     return (rtc_counter);
   1425  1.1  christos }
   1426  1.1  christos 
   1427  1.1  christos static void
   1428  1.1  christos rtc_scaler_set(val)
   1429  1.1  christos     uint32          val;
   1430  1.1  christos {
   1431  1.1  christos     rtc_scaler = val & 0x0ff;	/* eight-bit scaler only */
   1432  1.1  christos }
   1433  1.1  christos 
   1434  1.1  christos static void
   1435  1.1  christos rtc_reload_set(val)
   1436  1.1  christos     uint32          val;
   1437  1.1  christos {
   1438  1.1  christos     rtc_reload = val;
   1439  1.1  christos }
   1440  1.1  christos 
   1441  1.1  christos static void
   1442  1.1  christos gpt_intr(arg)
   1443  1.1  christos     caddr_t         arg;
   1444  1.1  christos {
   1445  1.1  christos     if (gpt_counter == 0) {
   1446  1.1  christos 	mec_irq(12);
   1447  1.1  christos 	if (gpt_cr)
   1448  1.1  christos 	    gpt_counter = gpt_reload;
   1449  1.1  christos 	else
   1450  1.1  christos 	    gpt_se = 0;
   1451  1.1  christos     } else
   1452  1.1  christos 	gpt_counter -= 1;
   1453  1.1  christos     if (gpt_se) {
   1454  1.1  christos 	event(gpt_intr, 0, gpt_scaler + 1);
   1455  1.1  christos 	gpt_scaler_start = now();
   1456  1.1  christos 	gpt_enabled = 1;
   1457  1.1  christos     } else {
   1458  1.1  christos 	if (sis_verbose)
   1459  1.1  christos 	    printf("GPT stopped\n\r");
   1460  1.1  christos 	gpt_enabled = 0;
   1461  1.1  christos     }
   1462  1.1  christos }
   1463  1.1  christos 
   1464  1.1  christos static void
   1465  1.1  christos gpt_start()
   1466  1.1  christos {
   1467  1.1  christos     if (sis_verbose)
   1468  1.1  christos 	printf("GPT started (period %d)\n\r", gpt_scaler + 1);
   1469  1.1  christos     event(gpt_intr, 0, gpt_scaler + 1);
   1470  1.1  christos     gpt_scaler_start = now();
   1471  1.1  christos     gpt_enabled = 1;
   1472  1.1  christos }
   1473  1.1  christos 
   1474  1.1  christos static uint32
   1475  1.1  christos gpt_counter_read()
   1476  1.1  christos {
   1477  1.1  christos     return (gpt_counter);
   1478  1.1  christos }
   1479  1.1  christos 
   1480  1.1  christos static void
   1481  1.1  christos gpt_scaler_set(val)
   1482  1.1  christos     uint32          val;
   1483  1.1  christos {
   1484  1.1  christos     gpt_scaler = val & 0x0ffff;	/* 16-bit scaler */
   1485  1.1  christos }
   1486  1.1  christos 
   1487  1.1  christos static void
   1488  1.1  christos gpt_reload_set(val)
   1489  1.1  christos     uint32          val;
   1490  1.1  christos {
   1491  1.1  christos     gpt_reload = val;
   1492  1.1  christos }
   1493  1.1  christos 
   1494  1.1  christos static void
   1495  1.1  christos timer_ctrl(val)
   1496  1.1  christos     uint32          val;
   1497  1.1  christos {
   1498  1.1  christos 
   1499  1.1  christos     rtc_cr = ((val & TCR_TCRCR) != 0);
   1500  1.1  christos     if (val & TCR_TCRCL) {
   1501  1.1  christos 	rtc_counter = rtc_reload;
   1502  1.1  christos     }
   1503  1.1  christos     if (val & TCR_TCRSL) {
   1504  1.1  christos     }
   1505  1.1  christos     rtc_se = ((val & TCR_TCRSE) != 0);
   1506  1.1  christos     if (rtc_se && (rtc_enabled == 0))
   1507  1.1  christos 	rtc_start();
   1508  1.1  christos 
   1509  1.1  christos     gpt_cr = (val & TCR_GACR);
   1510  1.1  christos     if (val & TCR_GACL) {
   1511  1.1  christos 	gpt_counter = gpt_reload;
   1512  1.1  christos     }
   1513  1.1  christos     if (val & TCR_GACL) {
   1514  1.1  christos     }
   1515  1.1  christos     gpt_se = (val & TCR_GASE) >> 2;
   1516  1.1  christos     if (gpt_se && (gpt_enabled == 0))
   1517  1.1  christos 	gpt_start();
   1518  1.1  christos }
   1519  1.1  christos 
   1520  1.1  christos 
   1521  1.1  christos /* Retrieve data from target memory.  MEM points to location from which
   1522  1.1  christos    to read the data; DATA points to words where retrieved data will be
   1523  1.1  christos    stored in host byte order.  SZ contains log(2) of the number of bytes
   1524  1.1  christos    to retrieve, and can be 0 (1 byte), 1 (one half-word), 2 (one word),
   1525  1.1  christos    or 3 (two words). */
   1526  1.1  christos 
   1527  1.1  christos static void
   1528  1.1  christos fetch_bytes (asi, mem, data, sz)
   1529  1.1  christos     int		    asi;
   1530  1.1  christos     unsigned char  *mem;
   1531  1.1  christos     uint32	   *data;
   1532  1.1  christos     int		    sz;
   1533  1.1  christos {
   1534  1.1  christos     if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
   1535  1.1  christos 	|| asi == 8 || asi == 9) {
   1536  1.1  christos 	switch (sz) {
   1537  1.1  christos 	case 3:
   1538  1.1  christos 	    data[1] =  (((uint32) mem[7]) & 0xff) |
   1539  1.1  christos 		      ((((uint32) mem[6]) & 0xff) <<  8) |
   1540  1.1  christos 		      ((((uint32) mem[5]) & 0xff) << 16) |
   1541  1.1  christos 		      ((((uint32) mem[4]) & 0xff) << 24);
   1542  1.1  christos 	    /* Fall through to 2 */
   1543  1.1  christos 	case 2:
   1544  1.1  christos 	    data[0] =  (((uint32) mem[3]) & 0xff) |
   1545  1.1  christos 		      ((((uint32) mem[2]) & 0xff) <<  8) |
   1546  1.1  christos 		      ((((uint32) mem[1]) & 0xff) << 16) |
   1547  1.1  christos 		      ((((uint32) mem[0]) & 0xff) << 24);
   1548  1.1  christos 	    break;
   1549  1.1  christos 	case 1:
   1550  1.1  christos 	    data[0] =  (((uint32) mem[1]) & 0xff) |
   1551  1.1  christos 		      ((((uint32) mem[0]) & 0xff) << 8);
   1552  1.1  christos 	    break;
   1553  1.1  christos 	case 0:
   1554  1.1  christos 	    data[0] = mem[0] & 0xff;
   1555  1.1  christos 	    break;
   1556  1.1  christos 
   1557  1.1  christos 	}
   1558  1.1  christos     } else {
   1559  1.1  christos 	switch (sz) {
   1560  1.1  christos 	case 3:
   1561  1.1  christos 	    data[1] = ((((uint32) mem[7]) & 0xff) << 24) |
   1562  1.1  christos 		      ((((uint32) mem[6]) & 0xff) << 16) |
   1563  1.1  christos 		      ((((uint32) mem[5]) & 0xff) <<  8) |
   1564  1.1  christos 		       (((uint32) mem[4]) & 0xff);
   1565  1.1  christos 	    /* Fall through to 4 */
   1566  1.1  christos 	case 2:
   1567  1.1  christos 	    data[0] = ((((uint32) mem[3]) & 0xff) << 24) |
   1568  1.1  christos 		      ((((uint32) mem[2]) & 0xff) << 16) |
   1569  1.1  christos 		      ((((uint32) mem[1]) & 0xff) <<  8) |
   1570  1.1  christos 		       (((uint32) mem[0]) & 0xff);
   1571  1.1  christos 	    break;
   1572  1.1  christos 	case 1:
   1573  1.1  christos 	    data[0] = ((((uint32) mem[1]) & 0xff) <<  8) |
   1574  1.1  christos 		       (((uint32) mem[0]) & 0xff);
   1575  1.1  christos 	    break;
   1576  1.1  christos 	case 0:
   1577  1.1  christos 	    data[0] = mem[0] & 0xff;
   1578  1.1  christos 	    break;
   1579  1.1  christos 	}
   1580  1.1  christos     }
   1581  1.1  christos }
   1582  1.1  christos 
   1583  1.1  christos 
   1584  1.1  christos /* Store data in target byte order.  MEM points to location to store data;
   1585  1.1  christos    DATA points to words in host byte order to be stored.  SZ contains log(2)
   1586  1.1  christos    of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
   1587  1.1  christos    2 (one word), or 3 (two words). */
   1588  1.1  christos 
   1589  1.1  christos static void
   1590  1.1  christos store_bytes (mem, data, sz)
   1591  1.1  christos     unsigned char  *mem;
   1592  1.1  christos     uint32	   *data;
   1593  1.1  christos     int		    sz;
   1594  1.1  christos {
   1595  1.1  christos     if (CURRENT_TARGET_BYTE_ORDER == LITTLE_ENDIAN) {
   1596  1.1  christos 	switch (sz) {
   1597  1.1  christos 	case 3:
   1598  1.1  christos 	    mem[7] = (data[1] >> 24) & 0xff;
   1599  1.1  christos 	    mem[6] = (data[1] >> 16) & 0xff;
   1600  1.1  christos 	    mem[5] = (data[1] >>  8) & 0xff;
   1601  1.1  christos 	    mem[4] = data[1] & 0xff;
   1602  1.1  christos 	    /* Fall through to 2 */
   1603  1.1  christos 	case 2:
   1604  1.1  christos 	    mem[3] = (data[0] >> 24) & 0xff;
   1605  1.1  christos 	    mem[2] = (data[0] >> 16) & 0xff;
   1606  1.1  christos 	    /* Fall through to 1 */
   1607  1.1  christos 	case 1:
   1608  1.1  christos 	    mem[1] = (data[0] >>  8) & 0xff;
   1609  1.1  christos 	    /* Fall through to 0 */
   1610  1.1  christos 	case 0:
   1611  1.1  christos 	    mem[0] = data[0] & 0xff;
   1612  1.1  christos 	    break;
   1613  1.1  christos 	}
   1614  1.1  christos     } else {
   1615  1.1  christos 	switch (sz) {
   1616  1.1  christos 	case 3:
   1617  1.1  christos 	    mem[7] = data[1] & 0xff;
   1618  1.1  christos 	    mem[6] = (data[1] >>  8) & 0xff;
   1619  1.1  christos 	    mem[5] = (data[1] >> 16) & 0xff;
   1620  1.1  christos 	    mem[4] = (data[1] >> 24) & 0xff;
   1621  1.1  christos 	    /* Fall through to 2 */
   1622  1.1  christos 	case 2:
   1623  1.1  christos 	    mem[3] = data[0] & 0xff;
   1624  1.1  christos 	    mem[2] = (data[0] >>  8) & 0xff;
   1625  1.1  christos 	    mem[1] = (data[0] >> 16) & 0xff;
   1626  1.1  christos 	    mem[0] = (data[0] >> 24) & 0xff;
   1627  1.1  christos 	    break;
   1628  1.1  christos 	case 1:
   1629  1.1  christos 	    mem[1] = data[0] & 0xff;
   1630  1.1  christos 	    mem[0] = (data[0] >> 8) & 0xff;
   1631  1.1  christos 	    break;
   1632  1.1  christos 	case 0:
   1633  1.1  christos 	    mem[0] = data[0] & 0xff;
   1634  1.1  christos 	    break;
   1635  1.1  christos 
   1636  1.1  christos 	}
   1637  1.1  christos     }
   1638  1.1  christos }
   1639  1.1  christos 
   1640  1.1  christos 
   1641  1.1  christos /* Memory emulation */
   1642  1.1  christos 
   1643  1.1  christos int
   1644  1.1  christos memory_read(asi, addr, data, sz, ws)
   1645  1.1  christos     int32           asi;
   1646  1.1  christos     uint32          addr;
   1647  1.1  christos     uint32         *data;
   1648  1.1  christos     int32           sz;
   1649  1.1  christos     int32          *ws;
   1650  1.1  christos {
   1651  1.1  christos     int32           mexc;
   1652  1.1  christos 
   1653  1.1  christos #ifdef ERRINJ
   1654  1.1  christos     if (errmec) {
   1655  1.1  christos 	if (sis_verbose)
   1656  1.1  christos 	    printf("Inserted MEC error %d\n",errmec);
   1657  1.1  christos 	set_sfsr(errmec, addr, asi, 1);
   1658  1.1  christos 	if (errmec == 5) mecparerror();
   1659  1.1  christos 	if (errmec == 6) iucomperr();
   1660  1.1  christos 	errmec = 0;
   1661  1.1  christos 	return(1);
   1662  1.1  christos     }
   1663  1.1  christos #endif
   1664  1.1  christos 
   1665  1.1  christos     if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
   1666  1.1  christos 	fetch_bytes (asi, &ramb[addr & mem_rammask], data, sz);
   1667  1.1  christos 	*ws = mem_ramr_ws;
   1668  1.1  christos 	return (0);
   1669  1.1  christos     } else if ((addr >= MEC_START) && (addr < MEC_END)) {
   1670  1.1  christos 	mexc = mec_read(addr, asi, data);
   1671  1.1  christos 	if (mexc) {
   1672  1.1  christos 	    set_sfsr(MEC_ACC, addr, asi, 1);
   1673  1.1  christos 	    *ws = MEM_EX_WS;
   1674  1.1  christos 	} else {
   1675  1.1  christos 	    *ws = 0;
   1676  1.1  christos 	}
   1677  1.1  christos 	return (mexc);
   1678  1.1  christos 
   1679  1.1  christos #ifdef ERA
   1680  1.1  christos 
   1681  1.1  christos     } else if (era) {
   1682  1.1  christos     	if ((addr < 0x100000) ||
   1683  1.1  christos 	    ((addr>= 0x80000000) && (addr < 0x80100000))) {
   1684  1.1  christos 	    fetch_bytes (asi, &romb[addr & ROM_MASK], data, sz);
   1685  1.1  christos 	    *ws = 4;
   1686  1.1  christos 	    return (0);
   1687  1.1  christos 	} else if ((addr >= 0x10000000) &&
   1688  1.1  christos 		   (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
   1689  1.1  christos 		   (mec_iocr & 0x10))  {
   1690  1.1  christos 	    *data = erareg;
   1691  1.1  christos 	    return (0);
   1692  1.1  christos 	}
   1693  1.1  christos 
   1694  1.1  christos     } else  if (addr < mem_romsz) {
   1695  1.1  christos 	    fetch_bytes (asi, &romb[addr], data, sz);
   1696  1.1  christos 	    *ws = mem_romr_ws;
   1697  1.1  christos 	    return (0);
   1698  1.1  christos 
   1699  1.1  christos #else
   1700  1.1  christos     } else if (addr < mem_romsz) {
   1701  1.1  christos 	fetch_bytes (asi, &romb[addr], data, sz);
   1702  1.1  christos 	*ws = mem_romr_ws;
   1703  1.1  christos 	return (0);
   1704  1.1  christos #endif
   1705  1.1  christos 
   1706  1.1  christos     }
   1707  1.1  christos 
   1708  1.1  christos     printf("Memory exception at %x (illegal address)\n", addr);
   1709  1.1  christos     set_sfsr(UIMP_ACC, addr, asi, 1);
   1710  1.1  christos     *ws = MEM_EX_WS;
   1711  1.1  christos     return (1);
   1712  1.1  christos }
   1713  1.1  christos 
   1714  1.1  christos int
   1715  1.1  christos memory_write(asi, addr, data, sz, ws)
   1716  1.1  christos     int32           asi;
   1717  1.1  christos     uint32          addr;
   1718  1.1  christos     uint32         *data;
   1719  1.1  christos     int32           sz;
   1720  1.1  christos     int32          *ws;
   1721  1.1  christos {
   1722  1.1  christos     uint32          byte_addr;
   1723  1.1  christos     uint32          byte_mask;
   1724  1.1  christos     uint32          waddr;
   1725  1.1  christos     uint32         *ram;
   1726  1.1  christos     int32           mexc;
   1727  1.1  christos     int             i;
   1728  1.1  christos     int             wphit[2];
   1729  1.1  christos 
   1730  1.1  christos #ifdef ERRINJ
   1731  1.1  christos     if (errmec) {
   1732  1.1  christos 	if (sis_verbose)
   1733  1.1  christos 	    printf("Inserted MEC error %d\n",errmec);
   1734  1.1  christos 	set_sfsr(errmec, addr, asi, 0);
   1735  1.1  christos 	if (errmec == 5) mecparerror();
   1736  1.1  christos 	if (errmec == 6) iucomperr();
   1737  1.1  christos 	errmec = 0;
   1738  1.1  christos 	return(1);
   1739  1.1  christos     }
   1740  1.1  christos #endif
   1741  1.1  christos 
   1742  1.1  christos     if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
   1743  1.1  christos 	if (mem_accprot) {
   1744  1.1  christos 
   1745  1.1  christos 	    waddr = (addr & 0x7fffff) >> 2;
   1746  1.1  christos 	    for (i = 0; i < 2; i++)
   1747  1.1  christos 		wphit[i] =
   1748  1.1  christos 		    (((asi == 0xa) && (mec_wpr[i] & 1)) ||
   1749  1.1  christos 		     ((asi == 0xb) && (mec_wpr[i] & 2))) &&
   1750  1.1  christos 		    ((waddr >= mec_ssa[i]) && ((waddr | (sz == 3)) < mec_sea[i]));
   1751  1.1  christos 
   1752  1.1  christos 	    if (((mem_blockprot) && (wphit[0] || wphit[1])) ||
   1753  1.1  christos 		((!mem_blockprot) &&
   1754  1.1  christos 		 !((mec_wpr[0] && wphit[0]) || (mec_wpr[1] && wphit[1]))
   1755  1.1  christos 		 )) {
   1756  1.1  christos 		if (sis_verbose)
   1757  1.1  christos 		    printf("Memory access protection error at 0x%08x\n", addr);
   1758  1.1  christos 		set_sfsr(PROT_EXC, addr, asi, 0);
   1759  1.1  christos 		*ws = MEM_EX_WS;
   1760  1.1  christos 		return (1);
   1761  1.1  christos 	    }
   1762  1.1  christos 	}
   1763  1.1  christos 
   1764  1.1  christos 	store_bytes (&ramb[addr & mem_rammask], data, sz);
   1765  1.1  christos 
   1766  1.1  christos 	switch (sz) {
   1767  1.1  christos 	case 0:
   1768  1.1  christos 	case 1:
   1769  1.1  christos 	    *ws = mem_ramw_ws + 3;
   1770  1.1  christos 	    break;
   1771  1.1  christos 	case 2:
   1772  1.1  christos 	    *ws = mem_ramw_ws;
   1773  1.1  christos 	    break;
   1774  1.1  christos 	case 3:
   1775  1.1  christos 	    *ws = 2 * mem_ramw_ws + STD_WS;
   1776  1.1  christos 	    break;
   1777  1.1  christos 	}
   1778  1.1  christos 	return (0);
   1779  1.1  christos     } else if ((addr >= MEC_START) && (addr < MEC_END)) {
   1780  1.1  christos 	if ((sz != 2) || (asi != 0xb)) {
   1781  1.1  christos 	    set_sfsr(MEC_ACC, addr, asi, 0);
   1782  1.1  christos 	    *ws = MEM_EX_WS;
   1783  1.1  christos 	    return (1);
   1784  1.1  christos 	}
   1785  1.1  christos 	mexc = mec_write(addr, *data);
   1786  1.1  christos 	if (mexc) {
   1787  1.1  christos 	    set_sfsr(MEC_ACC, addr, asi, 0);
   1788  1.1  christos 	    *ws = MEM_EX_WS;
   1789  1.1  christos 	} else {
   1790  1.1  christos 	    *ws = 0;
   1791  1.1  christos 	}
   1792  1.1  christos 	return (mexc);
   1793  1.1  christos 
   1794  1.1  christos #ifdef ERA
   1795  1.1  christos 
   1796  1.1  christos     } else if (era) {
   1797  1.1  christos     	if ((erareg & 2) &&
   1798  1.1  christos 	((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) {
   1799  1.1  christos 	    addr &= ROM_MASK;
   1800  1.1  christos 	    *ws = sz == 3 ? 8 : 4;
   1801  1.1  christos 	    store_bytes (&romb[addr], data, sz);
   1802  1.1  christos             return (0);
   1803  1.1  christos 	} else if ((addr >= 0x10000000) &&
   1804  1.1  christos 		   (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
   1805  1.1  christos 		   (mec_iocr & 0x10))  {
   1806  1.1  christos 	    erareg = *data & 0x0e;
   1807  1.1  christos 	    return (0);
   1808  1.1  christos 	}
   1809  1.1  christos 
   1810  1.1  christos     } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) &&
   1811  1.1  christos                (((mec_memcfg & 0x20000) && (sz > 1)) ||
   1812  1.1  christos 		(!(mec_memcfg & 0x20000) && (sz == 0)))) {
   1813  1.1  christos 
   1814  1.1  christos 	*ws = mem_romw_ws + 1;
   1815  1.1  christos 	if (sz == 3)
   1816  1.1  christos 	    *ws += mem_romw_ws + STD_WS;
   1817  1.1  christos 	store_bytes (&romb[addr], data, sz);
   1818  1.1  christos         return (0);
   1819  1.1  christos 
   1820  1.1  christos #else
   1821  1.1  christos     } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) &&
   1822  1.1  christos                (((mec_memcfg & 0x20000) && (sz > 1)) ||
   1823  1.1  christos 		(!(mec_memcfg & 0x20000) && (sz == 0)))) {
   1824  1.1  christos 
   1825  1.1  christos 	*ws = mem_romw_ws + 1;
   1826  1.1  christos 	if (sz == 3)
   1827  1.1  christos             *ws += mem_romw_ws + STD_WS;
   1828  1.1  christos 	store_bytes (&romb[addr], data, sz);
   1829  1.1  christos         return (0);
   1830  1.1  christos 
   1831  1.1  christos #endif
   1832  1.1  christos 
   1833  1.1  christos     }
   1834  1.1  christos 
   1835  1.1  christos     *ws = MEM_EX_WS;
   1836  1.1  christos     set_sfsr(UIMP_ACC, addr, asi, 0);
   1837  1.1  christos     return (1);
   1838  1.1  christos }
   1839  1.1  christos 
   1840  1.1  christos static unsigned char  *
   1841  1.1  christos get_mem_ptr(addr, size)
   1842  1.1  christos     uint32          addr;
   1843  1.1  christos     uint32          size;
   1844  1.1  christos {
   1845  1.1  christos     if ((addr + size) < ROM_SZ) {
   1846  1.1  christos 	return (&romb[addr]);
   1847  1.1  christos     } else if ((addr >= mem_ramstart) && ((addr + size) < mem_ramend)) {
   1848  1.1  christos 	return (&ramb[addr & mem_rammask]);
   1849  1.1  christos     }
   1850  1.1  christos 
   1851  1.1  christos #ifdef ERA
   1852  1.1  christos       else if ((era) && ((addr <0x100000) ||
   1853  1.1  christos 	((addr >= (unsigned) 0x80000000) && ((addr + size) < (unsigned) 0x80100000)))) {
   1854  1.1  christos 	return (&romb[addr & ROM_MASK]);
   1855  1.1  christos     }
   1856  1.1  christos #endif
   1857  1.1  christos 
   1858  1.1  christos     return ((char *) -1);
   1859  1.1  christos }
   1860  1.1  christos 
   1861  1.1  christos int
   1862  1.1  christos sis_memory_write(addr, data, length)
   1863  1.1  christos     uint32               addr;
   1864  1.1  christos     const unsigned char *data;
   1865  1.1  christos     uint32               length;
   1866  1.1  christos {
   1867  1.1  christos     char           *mem;
   1868  1.1  christos 
   1869  1.1  christos     if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
   1870  1.1  christos 	return (0);
   1871  1.1  christos 
   1872  1.1  christos     memcpy(mem, data, length);
   1873  1.1  christos     return (length);
   1874  1.1  christos }
   1875  1.1  christos 
   1876  1.1  christos int
   1877  1.1  christos sis_memory_read(addr, data, length)
   1878  1.1  christos     uint32          addr;
   1879  1.1  christos     char           *data;
   1880  1.1  christos     uint32          length;
   1881  1.1  christos {
   1882  1.1  christos     char           *mem;
   1883  1.1  christos 
   1884  1.1  christos     if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
   1885  1.1  christos 	return (0);
   1886  1.1  christos 
   1887  1.1  christos     memcpy(data, mem, length);
   1888  1.1  christos     return (length);
   1889  1.1  christos }
   1890