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