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