0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/ptrace.h>
0009 #include <linux/stddef.h>
0010
0011 #include <asm/fpu.h>
0012 #include <asm/mipsregs.h>
0013 #include <asm/r4kcache.h>
0014 #include <asm/hazards.h>
0015
0016
0017
0018
0019
0020 #define SPRAM_TAG0_ENABLE 0x00000080
0021 #define SPRAM_TAG0_PA_MASK 0xfffff000
0022 #define SPRAM_TAG1_SIZE_MASK 0xfffff000
0023
0024 #define SPRAM_TAG_STRIDE 8
0025
0026 #define ERRCTL_SPRAM (1 << 28)
0027
0028
0029 #define read_c0_errctl(x) read_c0_ecc(x)
0030 #define write_c0_errctl(x) write_c0_ecc(x)
0031
0032
0033
0034
0035 static unsigned int bis_c0_errctl(unsigned int set)
0036 {
0037 unsigned int res;
0038 res = read_c0_errctl();
0039 write_c0_errctl(res | set);
0040 return res;
0041 }
0042
0043 static void ispram_store_tag(unsigned int offset, unsigned int data)
0044 {
0045 unsigned int errctl;
0046
0047
0048 errctl = bis_c0_errctl(ERRCTL_SPRAM);
0049 ehb();
0050
0051 write_c0_taglo(data);
0052 ehb();
0053
0054 cache_op(Index_Store_Tag_I, CKSEG0|offset);
0055 ehb();
0056
0057 write_c0_errctl(errctl);
0058 ehb();
0059 }
0060
0061
0062 static unsigned int ispram_load_tag(unsigned int offset)
0063 {
0064 unsigned int data;
0065 unsigned int errctl;
0066
0067
0068 errctl = bis_c0_errctl(ERRCTL_SPRAM);
0069 ehb();
0070 cache_op(Index_Load_Tag_I, CKSEG0 | offset);
0071 ehb();
0072 data = read_c0_taglo();
0073 ehb();
0074 write_c0_errctl(errctl);
0075 ehb();
0076
0077 return data;
0078 }
0079
0080 static void dspram_store_tag(unsigned int offset, unsigned int data)
0081 {
0082 unsigned int errctl;
0083
0084
0085 errctl = bis_c0_errctl(ERRCTL_SPRAM);
0086 ehb();
0087 write_c0_dtaglo(data);
0088 ehb();
0089 cache_op(Index_Store_Tag_D, CKSEG0 | offset);
0090 ehb();
0091 write_c0_errctl(errctl);
0092 ehb();
0093 }
0094
0095
0096 static unsigned int dspram_load_tag(unsigned int offset)
0097 {
0098 unsigned int data;
0099 unsigned int errctl;
0100
0101 errctl = bis_c0_errctl(ERRCTL_SPRAM);
0102 ehb();
0103 cache_op(Index_Load_Tag_D, CKSEG0 | offset);
0104 ehb();
0105 data = read_c0_dtaglo();
0106 ehb();
0107 write_c0_errctl(errctl);
0108 ehb();
0109
0110 return data;
0111 }
0112
0113 static void probe_spram(char *type,
0114 unsigned int base,
0115 unsigned int (*read)(unsigned int),
0116 void (*write)(unsigned int, unsigned int))
0117 {
0118 unsigned int firstsize = 0, lastsize = 0;
0119 unsigned int firstpa = 0, lastpa = 0, pa = 0;
0120 unsigned int offset = 0;
0121 unsigned int size, tag0, tag1;
0122 unsigned int enabled;
0123 int i;
0124
0125
0126
0127
0128
0129
0130 for (i = 0; i < 8; i++) {
0131 tag0 = read(offset);
0132 tag1 = read(offset+SPRAM_TAG_STRIDE);
0133 pr_debug("DBG %s%d: tag0=%08x tag1=%08x\n",
0134 type, i, tag0, tag1);
0135
0136 size = tag1 & SPRAM_TAG1_SIZE_MASK;
0137
0138 if (size == 0)
0139 break;
0140
0141 if (i != 0) {
0142
0143 if ((pa == firstpa && size == firstsize) ||
0144 (pa == lastpa && size == lastsize))
0145 break;
0146 }
0147
0148
0149 base = (base + size - 1) & ~(size-1);
0150
0151
0152 tag0 = (base & SPRAM_TAG0_PA_MASK) | SPRAM_TAG0_ENABLE;
0153 write(offset, tag0);
0154
0155 base += size;
0156
0157
0158 tag0 = read(offset);
0159 pa = tag0 & SPRAM_TAG0_PA_MASK;
0160 enabled = tag0 & SPRAM_TAG0_ENABLE;
0161
0162 if (i == 0) {
0163 firstpa = pa;
0164 firstsize = size;
0165 }
0166
0167 lastpa = pa;
0168 lastsize = size;
0169
0170 if (strcmp(type, "DSPRAM") == 0) {
0171 unsigned int *vp = (unsigned int *)(CKSEG1 | pa);
0172 unsigned int v;
0173 #define TDAT 0x5a5aa5a5
0174 vp[0] = TDAT;
0175 vp[1] = ~TDAT;
0176
0177 mb();
0178
0179 v = vp[0];
0180 if (v != TDAT)
0181 printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
0182 vp, TDAT, v);
0183 v = vp[1];
0184 if (v != ~TDAT)
0185 printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
0186 vp+1, ~TDAT, v);
0187 }
0188
0189 pr_info("%s%d: PA=%08x,Size=%08x%s\n",
0190 type, i, pa, size, enabled ? ",enabled" : "");
0191 offset += 2 * SPRAM_TAG_STRIDE;
0192 }
0193 }
0194 void spram_config(void)
0195 {
0196 unsigned int config0;
0197
0198 switch (current_cpu_type()) {
0199 case CPU_24K:
0200 case CPU_34K:
0201 case CPU_74K:
0202 case CPU_1004K:
0203 case CPU_1074K:
0204 case CPU_INTERAPTIV:
0205 case CPU_PROAPTIV:
0206 case CPU_P5600:
0207 case CPU_QEMU_GENERIC:
0208 case CPU_I6400:
0209 case CPU_P6600:
0210 config0 = read_c0_config();
0211
0212 if (config0 & MIPS_CONF_ISP) {
0213 probe_spram("ISPRAM", 0x1c000000,
0214 &ispram_load_tag, &ispram_store_tag);
0215 }
0216 if (config0 & MIPS_CONF_DSP)
0217 probe_spram("DSPRAM", 0x1c100000,
0218 &dspram_load_tag, &dspram_store_tag);
0219 }
0220 }