Commit | Line | Data |
---|---|---|
196ba1fc PH |
1 | /* vax780_mem.c: VAX 11/780 memory controllers\r |
2 | \r | |
3 | Copyright (c) 2004-2005, Robert M Supnik\r | |
4 | \r | |
5 | Permission is hereby granted, free of charge, to any person obtaining a\r | |
6 | copy of this software and associated documentation files (the "Software"),\r | |
7 | to deal in the Software without restriction, including without limitation\r | |
8 | the rights to use, copy, modify, merge, publish, distribute, sublicense,\r | |
9 | and/or sell copies of the Software, and to permit persons to whom the\r | |
10 | Software is furnished to do so, subject to the following conditions:\r | |
11 | \r | |
12 | The above copyright notice and this permission notice shall be included in\r | |
13 | all copies or substantial portions of the Software.\r | |
14 | \r | |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r | |
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r | |
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r | |
18 | ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r | |
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r | |
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r | |
21 | \r | |
22 | Except as contained in this notice, the name of Robert M Supnik shall not be\r | |
23 | used in advertising or otherwise to promote the sale, use or other dealings\r | |
24 | in this Software without prior written authorization from Robert M Supnik.\r | |
25 | \r | |
26 | This module contains the VAX 11/780 system-specific registers and devices.\r | |
27 | \r | |
28 | mctl0, mctl1 MS780C/E memory controllers\r | |
29 | */\r | |
30 | \r | |
31 | #include "vax_defs.h"\r | |
32 | \r | |
33 | /* Memory controller register A */\r | |
34 | \r | |
35 | #define MCRA_OF 0x0\r | |
36 | #define MCRA_SUMM 0x00100000 /* err summ (MS780E) */\r | |
37 | #define MCRA_C_SIZE 0x00007E00 /* array size - fixed */\r | |
38 | #define MCRA_V_SIZE 9\r | |
39 | #define MCRA_ILVE 0x00000100 /* interleave wr enab */\r | |
40 | #define MCRA_TYPE 0x000000F8 /* type */\r | |
41 | #define MCRA_C_TYPE 0x00000010 /* 16k uninterleaved */\r | |
42 | #define MCRA_E_TYPE 0x0000006A /* 256k upper + lower */\r | |
43 | #define MCRA_ILV 0x00000007 /* interleave */\r | |
44 | #define MCRA_RD (0x00107FFF|SBI_FAULTS)\r | |
45 | #define MCRA_WR 0x00000100\r | |
46 | \r | |
47 | /* Memory controller register B */\r | |
48 | \r | |
49 | #define MCRB_OF 0x1\r | |
50 | #define MCRB_FP 0xF0000000 /* file pointers */\r | |
51 | #define MCRB_V_SA 15 /* start addr */\r | |
52 | #define MCRB_M_SA 0x1FFF\r | |
53 | #define MCRB_SA (MCRB_M_SA << MCRB_V_SA)\r | |
54 | #define MCRB_SAE 0x00004000 /* start addr wr enab */\r | |
55 | #define MCRB_INIT 0x00003000 /* init state */\r | |
56 | #define MCRB_REF 0x00000400 /* refresh */\r | |
57 | #define MCRB_ECC 0x000003FF /* ECC for diags */\r | |
58 | #define MCRB_RD 0xFFFFF7FF\r | |
59 | #define MCRB_WR 0x000043FF\r | |
60 | \r | |
61 | /* Memory controller register C,D */\r | |
62 | \r | |
63 | #define MCRC_OF 0x2\r | |
64 | #define MCRD_OF 0x3\r | |
65 | #define MCRC_DCRD 0x40000000 /* disable CRD */\r | |
66 | #define MCRC_HER 0x20000000 /* high error rate */\r | |
67 | #define MCRC_ERL 0x10000000 /* log error */\r | |
68 | #define MCRC_C_ER 0x0FFFFFFF /* MS780C error */\r | |
69 | #define MCRC_E_PE1 0x00080000 /* MS780E par ctl 1 */\r | |
70 | #define MCRC_E_PE0 0x00040000 /* MS780E par ctl 0 */\r | |
71 | #define MCRC_E_CRD 0x00000200 /* MS780E CRD */\r | |
72 | #define MCRC_E_PEW 0x00000100 /* MS780E par err wr */\r | |
73 | #define MCRC_E_USEQ 0x00000080 /* MS780E seq err */\r | |
74 | #define MCRC_C_RD 0x7FFFFFFF\r | |
75 | #define MCRC_E_RD 0x700C0380\r | |
76 | #define MCRC_WR 0x40000000\r | |
77 | #define MCRC_C_W1C 0x30000000\r | |
78 | #define MCRC_E_W1C 0x300C0380\r | |
79 | \r | |
80 | #define MCRROM_OF 0x400\r | |
81 | \r | |
82 | uint32 mcr_a[MCTL_NUM];\r | |
83 | uint32 mcr_b[MCTL_NUM];\r | |
84 | uint32 mcr_c[MCTL_NUM];\r | |
85 | uint32 mcr_d[MCTL_NUM];\r | |
86 | uint32 rom_lw[MCTL_NUM][ROMSIZE >> 2];\r | |
87 | \r | |
88 | extern UNIT cpu_unit;\r | |
89 | \r | |
90 | t_stat mctl_reset (DEVICE *dptr);\r | |
91 | t_stat mctl_rdreg (int32 *val, int32 pa, int32 mode);\r | |
92 | t_stat mctl_wrreg (int32 val, int32 pa, int32 mode);\r | |
93 | \r | |
94 | /* MCTLx data structures\r | |
95 | \r | |
96 | mctlx_dev MCTLx device descriptor\r | |
97 | mctlx_unit MCTLx unit\r | |
98 | mctlx_reg MCTLx register list\r | |
99 | */\r | |
100 | \r | |
101 | DIB mctl0_dib[] = { TR_MCTL0, 0, &mctl_rdreg, &mctl_wrreg, 0 };\r | |
102 | \r | |
103 | UNIT mctl0_unit = { UDATA (NULL, 0, 0) };\r | |
104 | \r | |
105 | REG mctl0_reg[] = {\r | |
106 | { HRDATA (CRA, mcr_a[0], 32) },\r | |
107 | { HRDATA (CRB, mcr_b[0], 32) },\r | |
108 | { HRDATA (CRC, mcr_c[0], 32) },\r | |
109 | { HRDATA (CRD, mcr_d[0], 32) },\r | |
110 | { BRDATA (ROM, rom_lw[0], 16, 32, ROMSIZE >> 2) },\r | |
111 | { NULL }\r | |
112 | };\r | |
113 | \r | |
114 | MTAB mctl0_mod[] = {\r | |
115 | { MTAB_XTD|MTAB_VDV, TR_MCTL0, "NEXUS", NULL,\r | |
116 | NULL, &show_nexus },\r | |
117 | { 0 }\r | |
118 | };\r | |
119 | \r | |
120 | DIB mctl1_dib[] = { TR_MCTL1, 0, &mctl_rdreg, &mctl_wrreg, 0 };\r | |
121 | \r | |
122 | UNIT mctl1_unit = { UDATA (NULL, 0, 0) };\r | |
123 | \r | |
124 | MTAB mctl1_mod[] = {\r | |
125 | { MTAB_XTD|MTAB_VDV, TR_MCTL1, "NEXUS", NULL,\r | |
126 | NULL, &show_nexus },\r | |
127 | { 0 } };\r | |
128 | \r | |
129 | REG mctl1_reg[] = {\r | |
130 | { HRDATA (CRA, mcr_a[1], 32) },\r | |
131 | { HRDATA (CRB, mcr_b[1], 32) },\r | |
132 | { HRDATA (CRC, mcr_c[1], 32) },\r | |
133 | { HRDATA (CRD, mcr_d[1], 32) },\r | |
134 | { BRDATA (ROM, rom_lw[1], 16, 32, ROMSIZE >> 2) },\r | |
135 | { NULL }\r | |
136 | };\r | |
137 | \r | |
138 | DEVICE mctl_dev[] = {\r | |
139 | {\r | |
140 | "MCTL0", &mctl0_unit, mctl0_reg, mctl0_mod,\r | |
141 | 1, 16, 16, 1, 16, 8,\r | |
142 | NULL, NULL, &mctl_reset,\r | |
143 | NULL, NULL, NULL,\r | |
144 | &mctl0_dib, DEV_NEXUS\r | |
145 | },\r | |
146 | {\r | |
147 | "MCTL1", &mctl1_unit, mctl1_reg, mctl1_mod,\r | |
148 | 1, 16, 16, 1, 16, 8,\r | |
149 | NULL, NULL, &mctl_reset,\r | |
150 | NULL, NULL, NULL,\r | |
151 | &mctl1_dib, DEV_NEXUS\r | |
152 | }\r | |
153 | };\r | |
154 | \r | |
155 | /* Memory controller register read */\r | |
156 | \r | |
157 | t_stat mctl_rdreg (int32 *val, int32 pa, int32 lnt)\r | |
158 | {\r | |
159 | int32 mctl, ofs;\r | |
160 | t_bool extmem = MEMSIZE > MAXMEMSIZE;\r | |
161 | \r | |
162 | if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */\r | |
163 | printf (">>MCTL: invalid adapter read mask, pa = %X, lnt = %d\r\n", pa, lnt);\r | |
164 | sbi_set_errcnf (); /* err confirmation */\r | |
165 | return SCPE_OK;\r | |
166 | }\r | |
167 | mctl = NEXUS_GETNEX (pa) - TR_MCTL0; /* get mctl num */\r | |
168 | ofs = NEXUS_GETOFS (pa); /* get offset */\r | |
169 | if (ofs >= MCRROM_OF) { /* ROM? */\r | |
170 | *val = rom_lw[mctl][ofs - MCRROM_OF]; /* get lw */\r | |
171 | return SCPE_OK;\r | |
172 | } \r | |
173 | switch (ofs) {\r | |
174 | \r | |
175 | case MCRA_OF: /* CR A */\r | |
176 | *val = mcr_a[mctl] & MCRA_RD;\r | |
177 | break;\r | |
178 | \r | |
179 | case MCRB_OF: /* CR B */\r | |
180 | *val = (mcr_b[mctl] & MCRB_RD) | MCRB_INIT;\r | |
181 | break;\r | |
182 | \r | |
183 | case MCRC_OF: /* CR C */\r | |
184 | *val = mcr_c[mctl] & (extmem? MCRC_E_RD: MCRC_C_RD);\r | |
185 | break;\r | |
186 | \r | |
187 | case MCRD_OF: /* CR D */\r | |
188 | if (!extmem) return SCPE_NXM; /* MS780E only */\r | |
189 | *val = mcr_d[mctl] & MCRC_E_RD;\r | |
190 | break;\r | |
191 | \r | |
192 | default:\r | |
193 | return SCPE_NXM;\r | |
194 | }\r | |
195 | \r | |
196 | return SCPE_OK;\r | |
197 | }\r | |
198 | \r | |
199 | /* Memory controller register write */\r | |
200 | \r | |
201 | t_stat mctl_wrreg (int32 val, int32 pa, int32 lnt)\r | |
202 | {\r | |
203 | int32 mctl, ofs, mask;\r | |
204 | t_bool extmem = MEMSIZE > MAXMEMSIZE;\r | |
205 | \r | |
206 | if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */\r | |
207 | printf (">>MCTL: invalid adapter write mask, pa = %X, lnt = %d\r\n", pa, lnt);\r | |
208 | sbi_set_errcnf (); /* err confirmation */\r | |
209 | return SCPE_OK;\r | |
210 | }\r | |
211 | mctl = NEXUS_GETNEX (pa) - TR_MCTL0; /* get mctl num */\r | |
212 | ofs = NEXUS_GETOFS (pa); /* get offset */\r | |
213 | switch (ofs) {\r | |
214 | \r | |
215 | case MCRA_OF: /* CR A */\r | |
216 | mask = MCRA_WR | ((val & MCRA_ILVE)? MCRA_ILV: 0);\r | |
217 | mcr_a[mctl] = (mcr_a[mctl] & ~mask) | (val & mask);\r | |
218 | break;\r | |
219 | \r | |
220 | case MCRB_OF: /* CR B */\r | |
221 | mask = MCRB_WR | ((val & MCRB_SAE)? MCRB_SA: 0);\r | |
222 | mcr_b[mctl] = (mcr_b[mctl] & ~mask) | (val & mask);\r | |
223 | break;\r | |
224 | \r | |
225 | case MCRC_OF: /* CR C */\r | |
226 | mcr_c[mctl] = ((mcr_c[mctl] & ~MCRC_WR) | (val & MCRC_WR)) &\r | |
227 | ~(val & (extmem? MCRC_E_W1C: MCRC_C_W1C));\r | |
228 | break;\r | |
229 | \r | |
230 | case MCRD_OF: /* CR D */\r | |
231 | if (!extmem) return SCPE_NXM; /* MS780E only */\r | |
232 | mcr_d[mctl] = ((mcr_d[mctl] & ~MCRC_WR) | (val & MCRC_WR)) &\r | |
233 | ~(val & MCRC_E_W1C);\r | |
234 | break;\r | |
235 | \r | |
236 | default:\r | |
237 | return SCPE_NXM;\r | |
238 | }\r | |
239 | \r | |
240 | return SCPE_OK;\r | |
241 | }\r | |
242 | \r | |
243 | /* Used by CPU and loader */\r | |
244 | \r | |
245 | void rom_wr_B (int32 pa, int32 val)\r | |
246 | {\r | |
247 | uint32 mctl = NEXUS_GETNEX (pa) - TR_MCTL0; /* get mctl num */\r | |
248 | uint32 ofs = NEXUS_GETOFS (pa) - MCRROM_OF; /* get offset */\r | |
249 | int32 sc = (pa & 3) << 3;\r | |
250 | \r | |
251 | rom_lw[mctl][ofs] = ((val & 0xFF) << sc) | (rom_lw[mctl][ofs] & ~(0xFF << sc));\r | |
252 | return;\r | |
253 | }\r | |
254 | \r | |
255 | /* MEMCTL reset */\r | |
256 | \r | |
257 | t_stat mctl_reset (DEVICE *dptr)\r | |
258 | {\r | |
259 | int32 i, amb;\r | |
260 | t_bool extmem = MEMSIZE > MAXMEMSIZE;\r | |
261 | \r | |
262 | amb = (int32) (MEMSIZE / 2) >> 20; /* array size MB */\r | |
263 | for (i = 0; i < MCTL_NUM; i++) { /* init for MS780C */\r | |
264 | if (extmem) { /* extended memory? */\r | |
265 | mcr_a[i] = ((amb - 1) << MCRA_V_SIZE) | MCRA_E_TYPE;\r | |
266 | mcr_b[i] = MCRB_INIT | ((i * amb) << (MCRB_V_SA + 4));\r | |
267 | }\r | |
268 | else {\r | |
269 | mcr_a[i] = MCRA_C_SIZE | MCRA_C_TYPE;\r | |
270 | mcr_b[i] = MCRB_INIT | (i << 21);\r | |
271 | }\r | |
272 | mcr_c[i] = 0;\r | |
273 | mcr_d[i] = 0;\r | |
274 | }\r | |
275 | return SCPE_OK;\r | |
276 | }\r |