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