erc32.c revision 1.1.1.4 1 1.1.1.2 christos /* This file is part of SIS (SPARC instruction simulator)
2 1.1.1.2 christos
3 1.1.1.4 christos Copyright (C) 1995-2017 Free Software Foundation, Inc.
4 1.1.1.2 christos Contributed by Jiri Gaisler, European Space Agency
5 1.1.1.2 christos
6 1.1.1.2 christos This program is free software; you can redistribute it and/or modify
7 1.1.1.2 christos it under the terms of the GNU General Public License as published by
8 1.1.1.2 christos the Free Software Foundation; either version 3 of the License, or
9 1.1.1.2 christos (at your option) any later version.
10 1.1.1.2 christos
11 1.1.1.2 christos This program is distributed in the hope that it will be useful,
12 1.1.1.2 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1.1.2 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1.1.2 christos GNU General Public License for more details.
15 1.1.1.2 christos
16 1.1.1.2 christos You should have received a copy of the GNU General Public License
17 1.1.1.2 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 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 christos static void decode_ersr (void);
251 1.1 christos #ifdef ERRINJ
252 1.1 christos static void iucomperr (void);
253 1.1 christos #endif
254 1.1 christos static void mecparerror (void);
255 1.1 christos static void decode_memcfg (void);
256 1.1 christos static void decode_wcr (void);
257 1.1 christos static void decode_mcr (void);
258 1.1 christos static void close_port (void);
259 1.1 christos static void mec_reset (void);
260 1.1 christos static void mec_intack (int32 level);
261 1.1 christos static void chk_irq (void);
262 1.1 christos static void mec_irq (int32 level);
263 1.1 christos static void set_sfsr (uint32 fault, uint32 addr,
264 1.1 christos uint32 asi, uint32 read);
265 1.1 christos static int32 mec_read (uint32 addr, uint32 asi, uint32 *data);
266 1.1 christos static int mec_write (uint32 addr, uint32 data);
267 1.1 christos static void port_init (void);
268 1.1 christos static uint32 read_uart (uint32 addr);
269 1.1 christos static void write_uart (uint32 addr, uint32 data);
270 1.1 christos static void flush_uart (void);
271 1.1 christos static void uarta_tx (void);
272 1.1 christos static void uartb_tx (void);
273 1.1 christos static void uart_rx (caddr_t arg);
274 1.1 christos static void uart_intr (caddr_t arg);
275 1.1 christos static void uart_irq_start (void);
276 1.1 christos static void wdog_intr (caddr_t arg);
277 1.1 christos static void wdog_start (void);
278 1.1 christos static void rtc_intr (caddr_t arg);
279 1.1 christos static void rtc_start (void);
280 1.1 christos static uint32 rtc_counter_read (void);
281 1.1 christos static void rtc_scaler_set (uint32 val);
282 1.1 christos static void rtc_reload_set (uint32 val);
283 1.1 christos static void gpt_intr (caddr_t arg);
284 1.1 christos static void gpt_start (void);
285 1.1 christos static uint32 gpt_counter_read (void);
286 1.1 christos static void gpt_scaler_set (uint32 val);
287 1.1 christos static void gpt_reload_set (uint32 val);
288 1.1 christos static void timer_ctrl (uint32 val);
289 1.1 christos static unsigned char *
290 1.1 christos get_mem_ptr (uint32 addr, uint32 size);
291 1.1.1.2 christos static void store_bytes (unsigned char *mem, uint32 waddr,
292 1.1.1.2 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.2 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.2 christos case 0xF4: /* simulator RAM size in bytes */
735 1.1.1.2 christos *data = 4096*1024;
736 1.1.1.2 christos break;
737 1.1.1.2 christos
738 1.1.1.2 christos case 0xF8: /* simulator ROM size in bytes */
739 1.1.1.2 christos *data = 1024*1024;
740 1.1.1.2 christos break;
741 1.1.1.2 christos
742 1.1 christos default:
743 1.1 christos set_sfsr(MEC_ACC, addr, asi, 1);
744 1.1.1.2 christos return 1;
745 1.1 christos break;
746 1.1 christos }
747 1.1.1.2 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.2 christos return 1;
924 1.1 christos break;
925 1.1 christos }
926 1.1.1.2 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.2 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.2 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.2 christos return Ucontrol;
1146 1.1 christos #else
1147 1.1.1.2 christos return uart_stat_reg;
1148 1.1 christos #endif
1149 1.1 christos #else
1150 1.1.1.2 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.2 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.2 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.2 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.2 christos /* Store data in host byte order. MEM points to the beginning of the
1517 1.1.1.2 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.2 christos 2 (one word), or 3 (two words); WS should return the number of
1521 1.1.1.2 christos wait-states. */
1522 1.1 christos
1523 1.1 christos static void
1524 1.1.1.2 christos store_bytes (unsigned char *mem, uint32 waddr, uint32 *data, int32 sz,
1525 1.1.1.2 christos int32 *ws)
1526 1.1 christos {
1527 1.1.1.2 christos switch (sz) {
1528 1.1 christos case 0:
1529 1.1.1.2 christos waddr ^= EBT;
1530 1.1.1.2 christos mem[waddr] = *data & 0x0ff;
1531 1.1.1.2 christos *ws = mem_ramw_ws + 3;
1532 1.1 christos break;
1533 1.1 christos case 1:
1534 1.1.1.2 christos #ifdef HOST_LITTLE_ENDIAN
1535 1.1.1.2 christos waddr ^= 2;
1536 1.1.1.2 christos #endif
1537 1.1.1.2 christos memcpy (&mem[waddr], data, 2);
1538 1.1.1.2 christos *ws = mem_ramw_ws + 3;
1539 1.1 christos break;
1540 1.1.1.2 christos case 2:
1541 1.1.1.2 christos memcpy (&mem[waddr], data, 4);
1542 1.1.1.2 christos *ws = mem_ramw_ws;
1543 1.1.1.2 christos break;
1544 1.1.1.2 christos case 3:
1545 1.1.1.2 christos memcpy (&mem[waddr], data, 8);
1546 1.1.1.2 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.2 christos memory_iread (uint32 addr, uint32 *data, int32 *ws)
1556 1.1.1.2 christos {
1557 1.1.1.2 christos uint32 asi;
1558 1.1.1.2 christos if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
1559 1.1.1.2 christos memcpy (data, &ramb[addr & mem_rammask & ~3], 4);
1560 1.1.1.2 christos *ws = mem_ramr_ws;
1561 1.1.1.2 christos return 0;
1562 1.1.1.2 christos } else if (addr < mem_romsz) {
1563 1.1.1.2 christos memcpy (data, &romb[addr & ~3], 4);
1564 1.1.1.2 christos *ws = mem_romr_ws;
1565 1.1.1.2 christos return 0;
1566 1.1.1.2 christos }
1567 1.1.1.2 christos
1568 1.1.1.2 christos if (sis_verbose)
1569 1.1.1.2 christos printf ("Memory exception at %x (illegal address)\n", addr);
1570 1.1.1.2 christos if (sregs.psr & 0x080)
1571 1.1.1.2 christos asi = 9;
1572 1.1.1.2 christos else
1573 1.1.1.2 christos asi = 8;
1574 1.1.1.2 christos set_sfsr (UIMP_ACC, addr, asi, 1);
1575 1.1.1.2 christos *ws = MEM_EX_WS;
1576 1.1.1.2 christos return 1;
1577 1.1.1.2 christos }
1578 1.1.1.2 christos
1579 1.1.1.2 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.2 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.2 christos memcpy (data, &ramb[addr & mem_rammask & ~3], 4);
1603 1.1 christos *ws = mem_ramr_ws;
1604 1.1.1.2 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.2 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.2 christos memcpy (data, &romb[addr & ROM_MASK & ~3], 4);
1621 1.1 christos *ws = 4;
1622 1.1.1.2 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.2 christos return 0;
1628 1.1 christos }
1629 1.1 christos
1630 1.1 christos } else if (addr < mem_romsz) {
1631 1.1.1.2 christos memcpy (data, &romb[addr & ~3], 4);
1632 1.1.1.2 christos *ws = mem_romr_ws;
1633 1.1.1.2 christos return 0;
1634 1.1 christos #else
1635 1.1 christos } else if (addr < mem_romsz) {
1636 1.1.1.2 christos memcpy (data, &romb[addr & ~3], 4);
1637 1.1 christos *ws = mem_romr_ws;
1638 1.1.1.2 christos return 0;
1639 1.1 christos #endif
1640 1.1 christos
1641 1.1 christos }
1642 1.1 christos
1643 1.1.1.2 christos if (sis_verbose)
1644 1.1.1.2 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.2 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.2 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.2 christos return 1;
1697 1.1 christos }
1698 1.1 christos }
1699 1.1.1.2 christos waddr = addr & mem_rammask;
1700 1.1.1.2 christos store_bytes (ramb, waddr, data, sz, ws);
1701 1.1.1.2 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.2 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.2 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.2 christos store_bytes (romb, addr, data, sz, ws);
1725 1.1.1.2 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.2 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.2 christos store_bytes (romb, addr, data, sz, ws);
1741 1.1.1.2 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.2 christos store_bytes (romb, addr, data, sz, ws);
1752 1.1.1.2 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.2 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.2 christos return &romb[addr];
1770 1.1 christos } else if ((addr >= mem_ramstart) && ((addr + size) < mem_ramend)) {
1771 1.1.1.2 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.2 christos return &romb[addr & ROM_MASK];
1778 1.1 christos }
1779 1.1 christos #endif
1780 1.1 christos
1781 1.1.1.2 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.2 christos return 0;
1794 1.1 christos
1795 1.1 christos memcpy(mem, data, length);
1796 1.1.1.2 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.2 christos return 0;
1809 1.1 christos
1810 1.1 christos memcpy(data, mem, length);
1811 1.1.1.2 christos return length;
1812 1.1.1.2 christos }
1813 1.1.1.2 christos
1814 1.1.1.2 christos extern struct pstate sregs;
1815 1.1.1.2 christos
1816 1.1.1.2 christos void
1817 1.1.1.2 christos boot_init (void)
1818 1.1.1.2 christos {
1819 1.1.1.2 christos mec_write(MEC_WCR, 0); /* zero waitstates */
1820 1.1.1.2 christos mec_write(MEC_TRAPD, 0); /* turn off watch-dog */
1821 1.1.1.2 christos mec_write(MEC_RTC_SCALER, sregs.freq - 1); /* generate 1 MHz RTC tick */
1822 1.1.1.2 christos mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
1823 1.1.1.2 christos sregs.wim = 2;
1824 1.1.1.2 christos sregs.psr = 0x110010e0;
1825 1.1.1.2 christos sregs.r[30] = RAM_END;
1826 1.1.1.2 christos sregs.r[14] = sregs.r[30] - 96 * 4;
1827 1.1.1.2 christos mec_mcr |= 1; /* power-down enabled */
1828 1.1 christos }
1829