sparc: eccmemctl.c
PATCH 1/1 sparc: eccmemctl.c
Updated based on information released recently by sun.
eccmemctl.c +159 -79
@@ -41,57 +41,87 @@*/ /* Register offsets */ -#define ECC_FCR_REG 0 -#define ECC_FSR_REG 8 -#define ECC_FAR0_REG 16 -#define ECC_FAR1_REG 20 -#define ECC_DIAG_REG 24 +#define ECC_MER 0/* Memory Enable Register */ +#define ECC_MDR 4/* Memory Delay Register */ +#define ECC_MFSR 8/* Memory Fault Status Register */ +#define ECC_VCR 12/* Video Configuration Register */ +#define ECC_MFAR0 16/* Memory Fault Address Register 0 */ +#define ECC_MFAR1 20/* Memory Fault Address Register 1 */ +#define ECC_DR 24/* Diagnostic Register */ +#define ECC_ECR0 28/* Event Count Register 0 */ +#define ECC_ECR1 32/* Event Count Register 1 */ /* ECC fault control register */ -#define ECC_FCR_EE 0x00000001/* Enable ECC checking */ -#define ECC_FCR_EI 0x00000010/* Enable Interrupts on correctable errors */ -#define ECC_FCR_VER 0x0f000000/* Version */ -#define ECC_FCR_IMPL 0xf0000000/* Implementation */ +#define ECC_MER_EE 0x00000001/* Enable ECC checking */ +#define ECC_MER_EI 0x00000002/* Enable Interrupts on correctable errors */ +#define ECC_MER_MRR0 0x00000004/* SIMM 0 */ +#define ECC_MER_MRR1 0x00000008/* SIMM 1 */ +#define ECC_MER_MRR2 0x00000010/* SIMM 2 */ +#define ECC_MER_MRR3 0x00000020/* SIMM 3 */ +#define ECC_MER_MRR4 0x00000040/* SIMM 4 */ +#define ECC_MER_MRR5 0x00000080/* SIMM 5 */ +#define ECC_MER_MRR6 0x00000100/* SIMM 6 */ +#define ECC_MER_MRR7 0x00000200/* SIMM 7 */ +#define ECC_MER_REU 0x00000200/* Memory Refresh Enable (600MP) */ +#define ECC_MER_MRR 0x000003fc/* MRR mask */ +#define ECC_MEM_A 0x00000400/* Memory controller addr map select */ +#define ECC_MER_DCI 0x00000800/* Dsiables Coherent Invalidate ACK */ +#define ECC_MER_VER 0x0f000000/* Version */ +#define ECC_MER_IMPL 0xf0000000/* Implementation */ +/* ECC memory delay register */ +#define ECC_MDR_RRI 0x000003ff/* Refresh Request Interval */ +#define ECC_MDR_MI 0x00001c00/* MIH Delay */ +#define ECC_MDR_CI 0x0000e000/* Coherent Invalidate Delay */ +#define ECC_MDR_MDL 0x001f0000/* MBus Master arbitration delay */ +#define ECC_MDR_MDH 0x03e00000/* MBus Master arbitration delay */ +#define ECC_MDR_GAD 0x7c000000/* Graphics Arbitration Delay */ +#define ECC_MDR_RSC 0x80000000/* Refresh load control */ +#define ECC_MDR_MASK 0x7fffffff +/* ECC fault status register */ -#define ECC_FSR_CE 0x00000001/* Correctable error */ -#define ECC_FSR_BS 0x00000002/* C2 graphics bad slot access */ -#define ECC_FSR_TO 0x00000004/* Timeout on write */ -#define ECC_FSR_UE 0x00000008/* Uncorrectable error */ -#define ECC_FSR_DW 0x000000f0/* Index of double word in block */ -#define ECC_FSR_SYND 0x0000ff00/* Syndrome for correctable error */ -#define ECC_FSR_ME 0x00010000/* Multiple errors */ -#define ECC_FSR_C2ERR 0x00020000/* C2 graphics error */ +#define ECC_MFSR_CE 0x00000001/* Correctable error */ +#define ECC_MFSR_BS 0x00000002/* C2 graphics bad slot access */ +#define ECC_MFSR_TO 0x00000004/* Timeout on write */ +#define ECC_MFSR_UE 0x00000008/* Uncorrectable error */ +#define ECC_MFSR_DW 0x000000f0/* Index of double word in block */ +#define ECC_MFSR_SYND 0x0000ff00/* Syndrome for correctable error */ +#define ECC_MFSR_ME 0x00010000/* Multiple errors */ +#define ECC_MFSR_C2ERR 0x00020000/* C2 graphics error */ /* ECC fault address register 0 */ -#define ECC_FAR0_PADDR 0x0000000f/* PA[32-35] */ -#define ECC_FAR0_TYPE 0x000000f0/* Transaction type */ -#define ECC_FAR0_SIZE 0x00000700/* Transaction size */ -#define ECC_FAR0_CACHE 0x00000800/* Mapped cacheable */ -#define ECC_FAR0_LOCK 0x00001000/* Error occurred in atomic cycle */ -#define ECC_FAR0_BMODE 0x00002000/* Boot mode */ -#define ECC_FAR0_VADDR 0x003fc000/* VA[12-19] (superset bits) */ -#define ECC_FAR0_S 0x08000000/* Supervisor mode */ -#define ECC_FARO_MID 0xf0000000/* Module ID */ +#define ECC_MFAR0_PADDR 0x0000000f/* PA[32-35] */ +#define ECC_MFAR0_TYPE 0x000000f0/* Transaction type */ +#define ECC_MFAR0_SIZE 0x00000700/* Transaction size */ +#define ECC_MFAR0_CACHE 0x00000800/* Mapped cacheable */ +#define ECC_MFAR0_LOCK 0x00001000/* Error occurred in atomic cycle */ +#define ECC_MFAR0_BMODE 0x00002000/* Boot mode */ +#define ECC_MFAR0_VADDR 0x003fc000/* VA[12-19] (superset bits) */ +#define ECC_MFAR0_S 0x08000000/* Supervisor mode */ +#define ECC_MFARO_MID 0xf0000000/* Module ID */ /* ECC diagnostic register */ -#define ECC_DIAG_CBX 0x00000001 -#define ECC_DIAG_CB0 0x00000002 -#define ECC_DIAG_CB1 0x00000004 -#define ECC_DIAG_CB2 0x00000008 -#define ECC_DIAG_CB4 0x00000010 -#define ECC_DIAG_CB8 0x00000020 -#define ECC_DIAG_CB16 0x00000040 -#define ECC_DIAG_CB32 0x00000080 -#define ECC_DIAG_DMODE 0x00000c00 +#define ECC_DR_CBX 0x00000001 +#define ECC_DR_CB0 0x00000002 +#define ECC_DR_CB1 0x00000004 +#define ECC_DR_CB2 0x00000008 +#define ECC_DR_CB4 0x00000010 +#define ECC_DR_CB8 0x00000020 +#define ECC_DR_CB16 0x00000040 +#define ECC_DR_CB32 0x00000080 +#define ECC_DR_DMODE 0x00000c00 -#define ECC_NREGS 8 +#define ECC_NREGS 9#define ECC_SIZE (ECC_NREGS * sizeof(uint32_t)) -#define ECC_ADDR_MASK (ECC_SIZE - 1) +#define ECC_ADDR_MASK 0x1f +#define ECC_DIAG_SIZE 4 +#define ECC_DIAG_MASK (ECC_DIAG_SIZE - 1) +typedef struct ECCState {qemu_irq irq;uint32_t regs[ECC_NREGS ]; +uint8_t diag[ECC_DIAG_SIZE ]; }ECCState ;static void ecc_mem_writel (void *opaque,target_phys_addr_t addr,uint32_t val)
@@ -99,39 +129,35 @@ECCState *s = opaque;switch (addr &ECC_ADDR_MASK ) { -case ECC_FCR_REG : - s->regs[0 ] = (s->regs[0 ] & (ECC_FCR_VER |ECC_FCR_IMPL )) | - (val & ~(ECC_FCR_VER |ECC_FCR_IMPL )); -DPRINTF ("Write fault control %08x\n" , val); +case ECC_MER : + s->regs[0 ] = (s->regs[0 ] & (ECC_MER_VER |ECC_MER_IMPL )) | + (val & ~(ECC_MER_VER |ECC_MER_IMPL )); +DPRINTF ("Write memory enable %08x\n" , val);break ; -case 4 : - s->regs[1 ] = val; -DPRINTF ("Write reg[1] %08x\n" , val); +case ECC_MDR : + s->regs[1 ] = val &ECC_MDR_MASK ; +DPRINTF ("Write memory delay %08x\n" , val);break ; -case ECC_FSR_REG : +case ECC_MFSR : s->regs[2 ] = val; -DPRINTF ("Write fault status %08x\n" , val); +DPRINTF ("Write memory fault status %08x\n" , val);break ; -case 12 : +case ECC_VCR : s->regs[3 ] = val; -DPRINTF ("Write reg[3] %08x\n" , val); +DPRINTF ("Write slot configuration %08x\n" , val);break ; -case ECC_FAR0_REG : - s->regs[4 ] = val; -DPRINTF ("Write fault address 0 %08x\n" , val); -break ; -case ECC_FAR1_REG : - s->regs[5 ] = val; -DPRINTF ("Write fault address 1 %08x\n" , val); -break ; -case ECC_DIAG_REG : +case ECC_DR : s->regs[6 ] = val; -DPRINTF ("Write diag %08x\n" , val); +DPRINTF ("Write diagnosiic %08x\n" , val);break ; -case 28 : +case ECC_ECR0 : s->regs[7 ] = val; -DPRINTF ("Write reg[7] %08x\n" , val); +DPRINTF ("Write event count 1 %08x\n" , val);break ; +case ECC_ECR1 : + s->regs[7 ] = val; +DPRINTF ("Write event count 2 %08x\n" , val); +break ; } }
@@ -141,38 +167,42 @@uint32_t ret =0 ;switch (addr &ECC_ADDR_MASK ) { -case ECC_FCR_REG : +case ECC_MER : ret = s->regs[0 ]; -DPRINTF ("Read enable %08x\n" , ret); +DPRINTF ("Read memory enable %08x\n" , ret);break ; -case 4 : +case ECC_MDR : ret = s->regs[1 ]; -DPRINTF ("Read register[1] %08x\n" , ret); +DPRINTF ("Read memory delay %08x\n" , ret);break ; -case ECC_FSR_REG : +case ECC_MFSR : ret = s->regs[2 ]; -DPRINTF ("Read fault status %08x\n" , ret); +DPRINTF ("Read memory fault status %08x\n" , ret);break ; -case 12 : +case ECC_VCR : ret = s->regs[3 ]; -DPRINTF ("Read reg[3] %08x\n" , ret); +DPRINTF ("Read slot configuration %08x\n" , ret);break ; -case ECC_FAR0_REG : +case ECC_MFAR0 : ret = s->regs[4 ]; -DPRINTF ("Read fault address 0 %08x\n" , ret); +DPRINTF ("Read memory fault address 0 %08x\n" , ret);break ; -case ECC_FAR1_REG : +case ECC_MFAR1 : ret = s->regs[5 ]; -DPRINTF ("Read fault address 1 %08x\n" , ret); +DPRINTF ("Read memory fault address 1 %08x\n" , ret);break ; -case ECC_DIAG_REG : +case ECC_DR : ret = s->regs[6 ]; -DPRINTF ("Read diag %08x\n" , ret); +DPRINTF ("Read diagnostic %08x\n" , ret);break ; -case 28 : +case ECC_ECR0 : ret = s->regs[7 ]; -DPRINTF ("Read reg[7] %08x\n" , ret); +DPRINTF ("Read event count 1 %08x\n" , ret);break ; +case ECC_ECR1 : + ret = s->regs[7 ]; +DPRINTF ("Read event count 2 %08x\n" , ret); +break ; }return ret; }
@@ -189,17 +219,49 @@ ecc_mem_writel, }; +static void ecc_diag_mem_writeb (void *opaque,target_phys_addr_t addr, +uint32_t val) +{ +ECCState *s = opaque; + +DPRINTF ("Write diagnostic[%d] = %02x\n" , (int )(addr &ECC_DIAG_MASK ), val); + s->diag[addr &ECC_DIAG_MASK ] = val; +} + +static uint32_t ecc_diag_mem_readb (void *opaque,target_phys_addr_t addr) +{ +ECCState *s = opaque; +uint32_t ret = s->diag[addr &ECC_DIAG_MASK ]; +DPRINTF ("Read diagnostic[%d] = %02x\n" , (int )(addr &ECC_DIAG_MASK ), ret); +return ret; +} + +static CPUReadMemoryFunc *ecc_diag_mem_read[3 ] = { + ecc_diag_mem_readb, +NULL , +NULL , +}; + +static CPUWriteMemoryFunc *ecc_diag_mem_write[3 ] = { + ecc_diag_mem_writeb, +NULL , +NULL , +}; +static int ecc_load (QEMUFile *f,void *opaque,int version_id) {ECCState *s = opaque;int i; -if (version_id !=1 ) +if (version_id !=2 )return -EINVAL ;for (i =0 ; i <ECC_NREGS ; i++)qemu_get_be32s (f, &s->regs[i]); +for (i =0 ; i <ECC_DIAG_SIZE ; i++) +qemu_get_8s (f, &s->diag[i]); +return 0 ; }
@@ -210,6 +272,9 @@for (i =0 ; i <ECC_NREGS ; i++)qemu_put_be32s (f, &s->regs[i]); + +for (i =0 ; i <ECC_DIAG_SIZE ; i++) +qemu_put_8s (f, &s->diag[i]); }static void ecc_reset (void *opaque)
@@ -217,7 +282,16 @@ECCState *s = opaque;int i; - s->regs[ECC_FCR_REG ] &= (ECC_FCR_VER |ECC_FCR_IMPL ); + s->regs[ECC_MER ] &= (ECC_MER_VER |ECC_MER_IMPL ); + s->regs[ECC_MER ] |=ECC_MER_MRR ; + s->regs[ECC_MDR ] =0x20 ; + s->regs[ECC_MFSR ] =0 ; + s->regs[ECC_VCR ] =0 ; + s->regs[ECC_MFAR0 ] =0x07c00000 ; + s->regs[ECC_MFAR1 ] =0 ; + s->regs[ECC_DR ] =0 ; + s->regs[ECC_ECR0 ] =0 ; + s->regs[ECC_ECR1 ] =0 ;for (i =1 ; i <ECC_NREGS ; i++) s->regs[i] =0 ;
@@ -237,7 +311,13 @@ ecc_io_memory =cpu_register_io_memory (0 , ecc_mem_read, ecc_mem_write, s);cpu_register_physical_memory (base,ECC_SIZE , ecc_io_memory); -register_savevm ("ECC" , base,1 , ecc_save, ecc_load, s); +if (version ==0 ) {// SS-600MP only + ecc_io_memory =cpu_register_io_memory (0 , ecc_diag_mem_read, + ecc_diag_mem_write, s); +cpu_register_physical_memory (base +0x1000 ,ECC_DIAG_SIZE , + ecc_io_memory); + } +register_savevm ("ECC" , base,2 , ecc_save, ecc_load, s);qemu_register_reset (ecc_reset, s);ecc_reset (s);return s;