Annotation of qemu/hw/eccmemctl.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * QEMU Sparc Sun4m ECC memory controller emulation
                      3:  *
                      4:  * Copyright (c) 2007 Robert Reif
                      5:  *
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: #include "hw.h"
                     25: #include "sun4m.h"
                     26: #include "sysemu.h"
                     27: 
                     28: //#define DEBUG_ECC
                     29: 
                     30: #ifdef DEBUG_ECC
                     31: #define DPRINTF(fmt, args...)                           \
                     32:     do { printf("ECC: " fmt , ##args); } while (0)
                     33: #else
                     34: #define DPRINTF(fmt, args...)
                     35: #endif
                     36: 
                     37: /* There are 3 versions of this chip used in SMP sun4m systems:
                     38:  * MCC (version 0, implementation 0) SS-600MP
                     39:  * EMC (version 0, implementation 1) SS-10
                     40:  * SMC (version 0, implementation 2) SS-10SX and SS-20
                     41:  */
                     42: 
                     43: /* Register offsets */
                     44: #define ECC_FCR_REG    0
                     45: #define ECC_FSR_REG    8
                     46: #define ECC_FAR0_REG   16
                     47: #define ECC_FAR1_REG   20
                     48: #define ECC_DIAG_REG   24
                     49: 
                     50: /* ECC fault control register */
                     51: #define ECC_FCR_EE     0x00000001      /* Enable ECC checking */
                     52: #define ECC_FCR_EI     0x00000010      /* Enable Interrupts on correctable errors */
                     53: #define ECC_FCR_VER    0x0f000000      /* Version */
                     54: #define ECC_FCR_IMPL   0xf0000000      /* Implementation */
                     55: 
                     56: /* ECC fault status register */
                     57: #define ECC_FSR_CE     0x00000001      /* Correctable error */
                     58: #define ECC_FSR_BS     0x00000002      /* C2 graphics bad slot access */
                     59: #define ECC_FSR_TO     0x00000004      /* Timeout on write */
                     60: #define ECC_FSR_UE     0x00000008      /* Uncorrectable error */
                     61: #define ECC_FSR_DW     0x000000f0      /* Index of double word in block */
                     62: #define ECC_FSR_SYND   0x0000ff00      /* Syndrome for correctable error */
                     63: #define ECC_FSR_ME     0x00010000      /* Multiple errors */
                     64: #define ECC_FSR_C2ERR  0x00020000      /* C2 graphics error */
                     65: 
                     66: /* ECC fault address register 0 */
                     67: #define ECC_FAR0_PADDR 0x0000000f      /* PA[32-35] */
                     68: #define ECC_FAR0_TYPE  0x000000f0      /* Transaction type */
                     69: #define ECC_FAR0_SIZE  0x00000700      /* Transaction size */
                     70: #define ECC_FAR0_CACHE 0x00000800      /* Mapped cacheable */
                     71: #define ECC_FAR0_LOCK  0x00001000      /* Error occurred in attomic cycle */
                     72: #define ECC_FAR0_BMODE 0x00002000      /* Boot mode */
                     73: #define ECC_FAR0_VADDR 0x003fc000      /* VA[12-19] (superset bits) */
                     74: #define ECC_FAR0_S     0x08000000      /* Supervisor mode */
                     75: #define ECC_FARO_MID   0xf0000000      /* Module ID */
                     76: 
                     77: /* ECC diagnostic register */
                     78: #define ECC_DIAG_CBX   0x00000001
                     79: #define ECC_DIAG_CB0   0x00000002
                     80: #define ECC_DIAG_CB1   0x00000004
                     81: #define ECC_DIAG_CB2   0x00000008
                     82: #define ECC_DIAG_CB4   0x00000010
                     83: #define ECC_DIAG_CB8   0x00000020
                     84: #define ECC_DIAG_CB16  0x00000040
                     85: #define ECC_DIAG_CB32  0x00000080
                     86: #define ECC_DIAG_DMODE 0x00000c00
                     87: 
                     88: #define ECC_NREGS      8
                     89: #define ECC_SIZE       (ECC_NREGS * sizeof(uint32_t))
                     90: #define ECC_ADDR_MASK  (ECC_SIZE - 1)
                     91: 
                     92: typedef struct ECCState {
                     93:     uint32_t regs[ECC_NREGS];
                     94: } ECCState;
                     95: 
                     96: static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
                     97: {
                     98:     ECCState *s = opaque;
                     99: 
                    100:     switch (addr & ECC_ADDR_MASK) {
                    101:     case ECC_FCR_REG:
                    102:         s->regs[0] = (s->regs[0] & (ECC_FCR_VER | ECC_FCR_IMPL)) |
                    103:                      (val & ~(ECC_FCR_VER | ECC_FCR_IMPL));
                    104:         DPRINTF("Write fault control %08x\n", val);
                    105:         break;
                    106:     case 4:
                    107:         s->regs[1] =  val;
                    108:         DPRINTF("Write reg[1] %08x\n", val);
                    109:         break;
                    110:     case ECC_FSR_REG:
                    111:         s->regs[2] =  val;
                    112:         DPRINTF("Write fault status %08x\n", val);
                    113:         break;
                    114:     case 12:
                    115:         s->regs[3] =  val;
                    116:         DPRINTF("Write reg[3] %08x\n", val);
                    117:         break;
                    118:     case ECC_FAR0_REG:
                    119:         s->regs[4] =  val;
                    120:         DPRINTF("Write fault address 0 %08x\n", val);
                    121:         break;
                    122:     case ECC_FAR1_REG:
                    123:         s->regs[5] =  val;
                    124:         DPRINTF("Write fault address 1 %08x\n", val);
                    125:         break;
                    126:     case ECC_DIAG_REG:
                    127:         s->regs[6] =  val;
                    128:         DPRINTF("Write diag %08x\n", val);
                    129:         break;
                    130:     case 28:
                    131:         s->regs[7] =  val;
                    132:         DPRINTF("Write reg[7] %08x\n", val);
                    133:         break;
                    134:     }
                    135: }
                    136: 
                    137: static uint32_t ecc_mem_readl(void *opaque, target_phys_addr_t addr)
                    138: {
                    139:     ECCState *s = opaque;
                    140:     uint32_t ret = 0;
                    141: 
                    142:     switch (addr & ECC_ADDR_MASK) {
                    143:     case ECC_FCR_REG:
                    144:         ret = s->regs[0];
                    145:         DPRINTF("Read enable %08x\n", ret);
                    146:         break;
                    147:     case 4:
                    148:         ret = s->regs[1];
                    149:         DPRINTF("Read register[1] %08x\n", ret);
                    150:         break;
                    151:     case ECC_FSR_REG:
                    152:         ret = s->regs[2];
                    153:         DPRINTF("Read fault status %08x\n", ret);
                    154:         break;
                    155:     case 12:
                    156:         ret = s->regs[3];
                    157:         DPRINTF("Read reg[3] %08x\n", ret);
                    158:         break;
                    159:     case ECC_FAR0_REG:
                    160:         ret = s->regs[4];
                    161:         DPRINTF("Read fault address 0 %08x\n", ret);
                    162:         break;
                    163:     case ECC_FAR1_REG:
                    164:         ret = s->regs[5];
                    165:         DPRINTF("Read fault address 1 %08x\n", ret);
                    166:         break;
                    167:     case ECC_DIAG_REG:
                    168:         ret = s->regs[6];
                    169:         DPRINTF("Read diag %08x\n", ret);
                    170:         break;
                    171:     case 28:
                    172:         ret = s->regs[7];
                    173:         DPRINTF("Read reg[7] %08x\n", ret);
                    174:         break;
                    175:     }
                    176:     return ret;
                    177: }
                    178: 
                    179: static CPUReadMemoryFunc *ecc_mem_read[3] = {
                    180:     NULL,
                    181:     NULL,
                    182:     ecc_mem_readl,
                    183: };
                    184: 
                    185: static CPUWriteMemoryFunc *ecc_mem_write[3] = {
                    186:     NULL,
                    187:     NULL,
                    188:     ecc_mem_writel,
                    189: };
                    190: 
                    191: static int ecc_load(QEMUFile *f, void *opaque, int version_id)
                    192: {
                    193:     ECCState *s = opaque;
                    194:     int i;
                    195: 
                    196:     if (version_id != 1)
                    197:         return -EINVAL;
                    198: 
                    199:     for (i = 0; i < ECC_NREGS; i++)
                    200:         qemu_get_be32s(f, &s->regs[i]);
                    201: 
                    202:     return 0;
                    203: }
                    204: 
                    205: static void ecc_save(QEMUFile *f, void *opaque)
                    206: {
                    207:     ECCState *s = opaque;
                    208:     int i;
                    209: 
                    210:     for (i = 0; i < ECC_NREGS; i++)
                    211:         qemu_put_be32s(f, &s->regs[i]);
                    212: }
                    213: 
                    214: static void ecc_reset(void *opaque)
                    215: {
                    216:     ECCState *s = opaque;
                    217:     int i;
                    218: 
                    219:     s->regs[ECC_FCR_REG] &= (ECC_FCR_VER | ECC_FCR_IMPL);
                    220: 
                    221:     for (i = 1; i < ECC_NREGS; i++)
                    222:         s->regs[i] = 0;
                    223: }
                    224: 
                    225: void * ecc_init(target_phys_addr_t base, uint32_t version)
                    226: {
                    227:     int ecc_io_memory;
                    228:     ECCState *s;
                    229: 
                    230:     s = qemu_mallocz(sizeof(ECCState));
                    231:     if (!s)
                    232:         return NULL;
                    233: 
                    234:     s->regs[0] = version;
                    235: 
                    236:     ecc_io_memory = cpu_register_io_memory(0, ecc_mem_read, ecc_mem_write, s);
                    237:     cpu_register_physical_memory(base, ECC_SIZE, ecc_io_memory);
                    238:     register_savevm("ECC", base, 1, ecc_save, ecc_load, s);
                    239:     qemu_register_reset(ecc_reset, s);
                    240:     ecc_reset(s);
                    241:     return s;
                    242: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.