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