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