Commit 0bb3602c44b73c647b8a478d7077192a576b5781
1 parent
963262de
Implement hw/eccmemctl.c version differences (Robert Reif)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6124 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
31 additions
and
10 deletions
hw/eccmemctl.c
... | ... | @@ -40,6 +40,10 @@ |
40 | 40 | * SMC (version 0, implementation 2) SS-10SX and SS-20 |
41 | 41 | */ |
42 | 42 | |
43 | +#define ECC_MCC 0x00000000 | |
44 | +#define ECC_EMC 0x10000000 | |
45 | +#define ECC_SMC 0x20000000 | |
46 | + | |
43 | 47 | /* Register indexes */ |
44 | 48 | #define ECC_MER 0 /* Memory Enable Register */ |
45 | 49 | #define ECC_MDR 1 /* Memory Delay Register */ |
... | ... | @@ -63,12 +67,15 @@ |
63 | 67 | #define ECC_MER_MRR5 0x00000080 /* SIMM 5 */ |
64 | 68 | #define ECC_MER_MRR6 0x00000100 /* SIMM 6 */ |
65 | 69 | #define ECC_MER_MRR7 0x00000200 /* SIMM 7 */ |
66 | -#define ECC_MER_REU 0x00000200 /* Memory Refresh Enable (600MP) */ | |
70 | +#define ECC_MER_REU 0x00000100 /* Memory Refresh Enable (600MP) */ | |
67 | 71 | #define ECC_MER_MRR 0x000003fc /* MRR mask */ |
68 | -#define ECC_MEM_A 0x00000400 /* Memory controller addr map select */ | |
72 | +#define ECC_MER_A 0x00000400 /* Memory controller addr map select */ | |
69 | 73 | #define ECC_MER_DCI 0x00000800 /* Disables Coherent Invalidate ACK */ |
70 | 74 | #define ECC_MER_VER 0x0f000000 /* Version */ |
71 | 75 | #define ECC_MER_IMPL 0xf0000000 /* Implementation */ |
76 | +#define ECC_MER_MASK_0 0x00000103 /* Version 0 (MCC) mask */ | |
77 | +#define ECC_MER_MASK_1 0x00000bff /* Version 1 (EMC) mask */ | |
78 | +#define ECC_MER_MASK_2 0x00000bff /* Version 2 (SMC) mask */ | |
72 | 79 | |
73 | 80 | /* ECC memory delay register */ |
74 | 81 | #define ECC_MDR_RRI 0x000003ff /* Refresh Request Interval */ |
... | ... | @@ -122,6 +129,7 @@ typedef struct ECCState { |
122 | 129 | qemu_irq irq; |
123 | 130 | uint32_t regs[ECC_NREGS]; |
124 | 131 | uint8_t diag[ECC_DIAG_SIZE]; |
132 | + uint32_t version; | |
125 | 133 | } ECCState; |
126 | 134 | |
127 | 135 | static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) |
... | ... | @@ -130,8 +138,12 @@ static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) |
130 | 138 | |
131 | 139 | switch (addr >> 2) { |
132 | 140 | case ECC_MER: |
133 | - s->regs[ECC_MER] = (s->regs[ECC_MER] & (ECC_MER_VER | ECC_MER_IMPL)) | | |
134 | - (val & ~(ECC_MER_VER | ECC_MER_IMPL)); | |
141 | + if (s->version == ECC_MCC) | |
142 | + s->regs[ECC_MER] = (val & ECC_MER_MASK_0); | |
143 | + else if (s->version == ECC_EMC) | |
144 | + s->regs[ECC_MER] = s->version | (val & ECC_MER_MASK_1); | |
145 | + else if (s->version == ECC_SMC) | |
146 | + s->regs[ECC_MER] = s->version | (val & ECC_MER_MASK_2); | |
135 | 147 | DPRINTF("Write memory enable %08x\n", val); |
136 | 148 | break; |
137 | 149 | case ECC_MDR: |
... | ... | @@ -140,6 +152,7 @@ static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) |
140 | 152 | break; |
141 | 153 | case ECC_MFSR: |
142 | 154 | s->regs[ECC_MFSR] = val; |
155 | + qemu_irq_lower(s->irq); | |
143 | 156 | DPRINTF("Write memory fault status %08x\n", val); |
144 | 157 | break; |
145 | 158 | case ECC_VCR: |
... | ... | @@ -148,7 +161,7 @@ static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) |
148 | 161 | break; |
149 | 162 | case ECC_DR: |
150 | 163 | s->regs[ECC_DR] = val; |
151 | - DPRINTF("Write diagnosiic %08x\n", val); | |
164 | + DPRINTF("Write diagnostic %08x\n", val); | |
152 | 165 | break; |
153 | 166 | case ECC_ECR0: |
154 | 167 | s->regs[ECC_ECR0] = val; |
... | ... | @@ -254,7 +267,7 @@ static int ecc_load(QEMUFile *f, void *opaque, int version_id) |
254 | 267 | ECCState *s = opaque; |
255 | 268 | int i; |
256 | 269 | |
257 | - if (version_id != 2) | |
270 | + if (version_id != 3) | |
258 | 271 | return -EINVAL; |
259 | 272 | |
260 | 273 | for (i = 0; i < ECC_NREGS; i++) |
... | ... | @@ -263,6 +276,8 @@ static int ecc_load(QEMUFile *f, void *opaque, int version_id) |
263 | 276 | for (i = 0; i < ECC_DIAG_SIZE; i++) |
264 | 277 | qemu_get_8s(f, &s->diag[i]); |
265 | 278 | |
279 | + qemu_get_be32s(f, &s->version); | |
280 | + | |
266 | 281 | return 0; |
267 | 282 | } |
268 | 283 | |
... | ... | @@ -276,14 +291,19 @@ static void ecc_save(QEMUFile *f, void *opaque) |
276 | 291 | |
277 | 292 | for (i = 0; i < ECC_DIAG_SIZE; i++) |
278 | 293 | qemu_put_8s(f, &s->diag[i]); |
294 | + | |
295 | + qemu_put_be32s(f, &s->version); | |
279 | 296 | } |
280 | 297 | |
281 | 298 | static void ecc_reset(void *opaque) |
282 | 299 | { |
283 | 300 | ECCState *s = opaque; |
284 | 301 | |
285 | - s->regs[ECC_MER] &= (ECC_MER_VER | ECC_MER_IMPL); | |
286 | - s->regs[ECC_MER] |= ECC_MER_MRR; | |
302 | + if (s->version == ECC_MCC) | |
303 | + s->regs[ECC_MER] &= ECC_MER_REU; | |
304 | + else | |
305 | + s->regs[ECC_MER] &= (ECC_MER_VER | ECC_MER_IMPL | ECC_MER_MRR | | |
306 | + ECC_MER_DCI); | |
287 | 307 | s->regs[ECC_MDR] = 0x20; |
288 | 308 | s->regs[ECC_MFSR] = 0; |
289 | 309 | s->regs[ECC_VCR] = 0; |
... | ... | @@ -303,18 +323,19 @@ void * ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version) |
303 | 323 | if (!s) |
304 | 324 | return NULL; |
305 | 325 | |
326 | + s->version = version; | |
306 | 327 | s->regs[0] = version; |
307 | 328 | s->irq = irq; |
308 | 329 | |
309 | 330 | ecc_io_memory = cpu_register_io_memory(0, ecc_mem_read, ecc_mem_write, s); |
310 | 331 | cpu_register_physical_memory(base, ECC_SIZE, ecc_io_memory); |
311 | - if (version == 0) { // SS-600MP only | |
332 | + if (version == ECC_MCC) { // SS-600MP only | |
312 | 333 | ecc_io_memory = cpu_register_io_memory(0, ecc_diag_mem_read, |
313 | 334 | ecc_diag_mem_write, s); |
314 | 335 | cpu_register_physical_memory(base + 0x1000, ECC_DIAG_SIZE, |
315 | 336 | ecc_io_memory); |
316 | 337 | } |
317 | - register_savevm("ECC", base, 2, ecc_save, ecc_load, s); | |
338 | + register_savevm("ECC", base, 3, ecc_save, ecc_load, s); | |
318 | 339 | qemu_register_reset(ecc_reset, s); |
319 | 340 | ecc_reset(s); |
320 | 341 | return s; | ... | ... |