1 /* DEC 5000/200 Error Address and Check/Syndrome Status registers emulation.
2 Copyright 2003 Brian R. Gaeke.
3
4 This file is part of VMIPS.
5
6 VMIPS is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
10
11 VMIPS is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with VMIPS; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19
20 /* Memory-mapped device representing the Error Address Status Register
21 * and ECC Check/Syndrome Status Register in the DEC 5000/200 (KN02).
22 */
23
24 #include "deviceexc.h"
25 #include "cpu.h"
26 #include "decstat.h"
27 #include "mapper.h"
28 #include "vmips.h"
29
DECStatDevice()30 DECStatDevice::DECStatDevice ()
31 {
32 extent = 0x100000;
33 }
34
35 /* Bits in the DEC 5000/200 Error Address register: */
36 #define ERRADR_VALID 0x80000000 /* Error addr. data is valid */
37 #define ERRADR_CPU 0x40000000 /* Error was generated by cpu */
38 #define ERRADR_WRITE 0x20000000 /* Error was generated during a write */
39 #define ERRADR_ECCERR 0x10000000 /* ECC triggered the error (not in vmips!) */
40 #define ERRADR_RSRVD 0x08000000 /* (reserved) */
41 #define ERRADR_ADDRESS 0x07FFFFFF /* Address of the error */
42
43 uint32
fetch_word(uint32 offset,int mode,DeviceExc * client)44 DECStatDevice::fetch_word (uint32 offset, int mode, DeviceExc *client)
45 {
46 uint32 rv;
47 if (!(offset & 0x80000)) {
48 /* fprintf (stderr, "CHKSYN reg read as 0x%x\n", chksyn_reg); */
49 rv = chksyn_reg;
50 } else {
51 Mapper::BusErrorInfo berr;
52 machine->physmem->get_last_berr_info (berr);
53 if (berr.valid) {
54 erradr_reg = ERRADR_VALID;
55 if (berr.mode == DATASTORE) erradr_reg |= ERRADR_WRITE;
56 if (berr.client == dynamic_cast<DeviceExc *>(machine->cpu))
57 erradr_reg |= ERRADR_CPU;
58 // Simulate effects of pipelining - VMIPS's Mapper knows the
59 // exact address, but the DECstation would have had to wait 5
60 // cycles to get the address.
61 berr.addr >>= 2;
62 berr.addr = (berr.addr & ~0x0fffL) | ((berr.addr & 0x0fffL) + 5);
63 berr.addr &= ERRADR_ADDRESS;
64 erradr_reg |= berr.addr;
65 } else {
66 erradr_reg &= ~ERRADR_VALID;
67 }
68 /* fprintf (stderr, "ERRADR reg read as 0x%x\n", erradr_reg); */
69 rv = erradr_reg;
70 }
71 return machine->physmem->mips_to_host_word(rv);
72 }
73
74 void
store_word(uint32 offset,uint32 data,DeviceExc * client)75 DECStatDevice::store_word (uint32 offset, uint32 data, DeviceExc *client)
76 {
77 data = machine->physmem->host_to_mips_word(data);
78 if (!(offset & 0x80000)) {
79 /* fprintf (stderr, "CHKSYN reg cleared\n"); */
80 chksyn_reg = 0;
81 } else {
82 /* fprintf (stderr, "ERRADR reg cleared\n"); */
83 /* if (interrupt)
84 fprintf (stderr, "Interrupt cancelled\n"); */
85 erradr_reg = 0;
86 }
87 }
88