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