Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:06

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  GRLIB L2CACHE Driver
0005  *
0006  *  COPYRIGHT (c) 2017
0007  *  Cobham Gaisler AB
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #include <stdlib.h>
0032 #include <string.h>
0033 #include <drvmgr/drvmgr.h>
0034 #include <grlib/ambapp_bus.h>
0035 #include <grlib/ambapp.h>
0036 #include <rtems.h>
0037 #include <rtems/bspIo.h>
0038 #include <grlib/grlib.h>
0039 #include <bsp.h>
0040 #include <grlib/l2c.h>
0041 #include <grlib/grlib_impl.h>
0042 
0043 #if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
0044 extern rtems_interrupt_lock leon3_l2c_lock;
0045 #endif
0046 
0047 /*#define STATIC*/
0048 #define STATIC static
0049 
0050 /*#define INLINE*/
0051 #define INLINE inline
0052 
0053 #define UNUSED __attribute__((unused))
0054 
0055 /*#define DEBUG 1*/
0056 
0057 #ifdef DEBUG
0058 #define DBG(x...) printk(x)
0059 #else
0060 #define DBG(x...)
0061 #endif
0062 
0063 /*
0064  * L2CACHE CTRL register fields
0065  */
0066 #define L2C_CTRL_EN (0x1 << L2C_CTRL_EN_BIT)
0067 #define L2C_CTRL_EDAC (0x1 << L2C_CTRL_EDAC_BIT)
0068 #define L2C_CTRL_REPL (0x3 << L2C_CTRL_REPL_BIT)
0069 #define L2C_CTRL_IWAY (0xf << L2C_CTRL_IWAY_BIT)
0070 #define L2C_CTRL_LOCK (0xf << L2C_CTRL_LOCK_BIT)
0071 #define L2C_CTRL_HPRHB (0x1 << L2C_CTRL_HPRHB_BIT)
0072 #define L2C_CTRL_HPB (0x1 << L2C_CTRL_HPB_BIT)
0073 #define L2C_CTRL_UC (0x1 << L2C_CTRL_UC_BIT)
0074 #define L2C_CTRL_HC (0x1 << L2C_CTRL_HC_BIT)
0075 #define L2C_CTRL_WP (0x1 << L2C_CTRL_WP_BIT)
0076 #define L2C_CTRL_HP (0x1 << L2C_CTRL_HP_BIT)
0077 
0078 #define L2C_CTRL_EN_BIT 31
0079 #define L2C_CTRL_EDAC_BIT 30
0080 #define L2C_CTRL_REPL_BIT 28
0081 #define L2C_CTRL_IWAY_BIT 12
0082 #define L2C_CTRL_LOCK_BIT 8
0083 #define L2C_CTRL_HPRHB_BIT 5
0084 #define L2C_CTRL_HPB_BIT 4
0085 #define L2C_CTRL_UC_BIT 3
0086 #define L2C_CTRL_HC_BIT 2
0087 #define L2C_CTRL_WP_BIT 1
0088 #define L2C_CTRL_HP_BIT 0
0089 
0090 /*
0091  * L2CACHE STATUS register fields
0092  */
0093 #define L2C_STAT_LS (0x1 << L2C_STAT_LS_BIT)
0094 #define L2C_STAT_AT (0x1 << L2C_STAT_AT_BIT)
0095 #define L2C_STAT_MP (0x1 << L2C_STAT_MP_BIT)
0096 #define L2C_STAT_MTRR (0x3f << L2C_STAT_MTRR_BIT)
0097 #define L2C_STAT_BBUSW (0x7 << L2C_STAT_BBUSW_BIT)
0098 #define L2C_STAT_WAYSIZE (0x7ff << L2C_STAT_WAYSIZE_BIT)
0099 #define L2C_STAT_WAY (0x3 << L2C_STAT_WAY_BIT)
0100 
0101 #define L2C_STAT_LS_BIT 24
0102 #define L2C_STAT_AT_BIT 23
0103 #define L2C_STAT_MP_BIT 22
0104 #define L2C_STAT_MTRR_BIT 16
0105 #define L2C_STAT_BBUSW_BIT 13
0106 #define L2C_STAT_WAYSIZE_BIT 2
0107 #define L2C_STAT_WAY_BIT 0
0108 
0109 /*
0110  * L2CACHE MTRR register fields
0111  */
0112 #define L2C_MTRR_ADDR (0x3fff << L2C_MTRR_ADDR_BIT)
0113 #define L2C_MTRR_ACC (0x3 << L2C_MTRR_ACC_BIT)
0114 #define L2C_MTRR_MASK (0x3fff << L2C_MTRR_MASK_BIT)
0115 #define L2C_MTRR_WP (0x1 << L2C_MTRR_WP_BIT)
0116 #define L2C_MTRR_AC (0x1 << L2C_MTRR_AC_BIT)
0117 
0118 #define L2C_MTRR_ADDR_BIT 18
0119 #define L2C_MTRR_ACC_BIT 16
0120 #define L2C_MTRR_MASK_BIT 2
0121 #define L2C_MTRR_WP_BIT 1
0122 #define L2C_MTRR_AC_BIT 0
0123 
0124 #define L2C_MTRR_UNCACHED 0
0125 #define L2C_MTRR_WRITETHROUGH (0x1 << L2C_MTRR_ACC_BIT)
0126 #define L2C_MTRR_WRITEPROT_ENABLE L2C_MTRR_WP
0127 #define L2C_MTRR_WRITEPROT_DISABLE 0
0128 #define L2C_MTRR_ACCESSCONTROL_ENABLE L2C_MTRR_AC
0129 #define L2C_MTRR_ACCESSCONTROL_DISABLE 0
0130 
0131 /*
0132  * L2CACHE FLUSHMEM register fields
0133  */
0134 #define L2C_FLUSH_ADDR (0x7ffffff << L2C_FLUSH_ADDR_BIT)
0135 #define L2C_FLUSH_DI (0x1 << L2C_FLUSH_DI_BIT)
0136 #define L2C_FLUSH_FMODE (0x7 << L2C_FLUSH_FMODE_BIT)
0137 
0138 #define L2C_FLUSH_ADDR_BIT 5
0139 #define L2C_FLUSH_DI_BIT 3
0140 #define L2C_FLUSH_FMODE_BIT 0
0141 
0142 #define L2C_FLUSH_FMODE_INV_ONE (0x1 << L2C_FLUSH_FMODE_BIT)
0143 #define L2C_FLUSH_FMODE_WB_ONE (0x2 << L2C_FLUSH_FMODE_BIT)
0144 #define L2C_FLUSH_FMODE_INV_WB_ONE (0x3 << L2C_FLUSH_FMODE_BIT)
0145 #define L2C_FLUSH_FMODE_INV_ALL (0x5 << L2C_FLUSH_FMODE_BIT)
0146 #define L2C_FLUSH_FMODE_WB_ALL (0x6 << L2C_FLUSH_FMODE_BIT)
0147 #define L2C_FLUSH_FMODE_INV_WB_ALL (0x7 << L2C_FLUSH_FMODE_BIT)
0148 
0149 /*
0150  * L2CACHE FLUSSETINDEX register fields
0151  */
0152 #define L2C_FLUSHSI_INDEX (0xffff << L2C_FLUSHSI_INDEX_BIT)
0153 #define L2C_FLUSHSI_TAG (0x3fffff << L2C_FLUSHSI_TAG_BIT)
0154 #define L2C_FLUSHSI_FL (0x1 << L2C_FLUSHSI_FL_BIT)
0155 #define L2C_FLUSHSI_VB (0x1 << L2C_FLUSHSI_VB_BIT)
0156 #define L2C_FLUSHSI_DB (0x1 << L2C_FLUSHSI_DB_BIT)
0157 #define L2C_FLUSHSI_WAY (0x3 << L2C_FLUSHSI_WAY_BIT)
0158 #define L2C_FLUSHSI_DI (0x1 << L2C_FLUSHSI_DI_BIT)
0159 #define L2C_FLUSHSI_WF (0x1 << L2C_FLUSHSI_WF_BIT)
0160 #define L2C_FLUSHSI_FMODE (0x3 << L2C_FLUSHSI_FMODE_BIT)
0161 
0162 #define L2C_FLUSHSI_INDEX_BIT 16
0163 #define L2C_FLUSHSI_TAG_BIT 10
0164 #define L2C_FLUSHSI_FL_BIT 9
0165 #define L2C_FLUSHSI_VB_BIT 8
0166 #define L2C_FLUSHSI_DB_BIT 7
0167 #define L2C_FLUSHSI_WAY_BIT 4
0168 #define L2C_FLUSHSI_DI_BIT 3
0169 #define L2C_FLUSHSI_WF_BIT 2
0170 #define L2C_FLUSHSI_FMODE_BIT 0
0171 
0172 #define L2C_FLUSHSI_FMODE_SET_INV_ONE (0x1 << L2C_FLUSHSI_FMODE_BIT)
0173 #define L2C_FLUSHSI_FMODE_SET_WB_ONE (0x2 << L2C_FLUSHSI_FMODE_BIT)
0174 #define L2C_FLUSHSI_FMODE_SET_INV_WB_ONE (0x3 << L2C_FLUSHSI_FMODE_BIT)
0175 #define L2C_FLUSHSI_FMODE_WAY_UPDATE (0x1 << L2C_FLUSHSI_FMODE_BIT)
0176 #define L2C_FLUSHSI_FMODE_WAY_WB (0x2 << L2C_FLUSHSI_FMODE_BIT)
0177 #define L2C_FLUSHSI_FMODE_WAY_UPDATE_WB_ALL (0x3 << L2C_FLUSHSI_FMODE_BIT)
0178 
0179 /*
0180  * L2CACHE ERROR register fields
0181  */
0182 #define L2C_ERROR_AHBM (0xf << L2C_ERROR_AHBM_BIT)
0183 #define L2C_ERROR_SCRUB (0x1 << L2C_ERROR_SCRUB_BIT)
0184 #define L2C_ERROR_TYPE (0x7 << L2C_ERROR_TYPE_BIT)
0185 #define L2C_ERROR_TAG (0x1 << L2C_ERROR_TAG_BIT)
0186 #define L2C_ERROR_COR (0x1 << L2C_ERROR_COR_BIT)
0187 #define L2C_ERROR_MULTI (0x1 << L2C_ERROR_MULTI_BIT)
0188 #define L2C_ERROR_VALID (0x1 << L2C_ERROR_VALID_BIT)
0189 #define L2C_ERROR_DISERESP (0x1 << L2C_ERROR_DISERESP_BIT)
0190 #define L2C_ERROR_CEC (0x7 << L2C_ERROR_CEC_BIT)
0191 #define L2C_ERROR_IRQP (0xf << L2C_ERROR_IRQP_BIT)
0192 #define L2C_ERROR_IRQM (0xf << L2C_ERROR_IRQM_BIT)
0193 #define L2C_ERROR_IRQM_BCKEND (0x1 << L2C_ERROR_IRQM_BCKEND_BIT)
0194 #define L2C_ERROR_IRQM_WPROT (0x1 << L2C_ERROR_IRQM_WPROT_BIT)
0195 #define L2C_ERROR_IRQM_UNCORR (0x1 << L2C_ERROR_IRQM_UNCORR_BIT)
0196 #define L2C_ERROR_IRQM_CORR (0x1 << L2C_ERROR_IRQM_CORR_BIT)
0197 #define L2C_ERROR_SCB (0x3 << L2C_ERROR_SCB_BIT)
0198 #define L2C_ERROR_STCB (0x3 << L2C_ERROR_STCB_BIT)
0199 #define L2C_ERROR_XCB (0x1 << L2C_ERROR_XCB_BIT)
0200 #define L2C_ERROR_RCB (0x1 << L2C_ERROR_RCB_BIT)
0201 #define L2C_ERROR_COMP (0x1 << L2C_ERROR_COMP_BIT)
0202 #define L2C_ERROR_RST (0x1 << L2C_ERROR_RST_BIT)
0203 
0204 #define L2C_ERROR_AHBM_BIT 28
0205 #define L2C_ERROR_SCRUB_BIT 27
0206 #define L2C_ERROR_TYPE_BIT 24
0207 #define L2C_ERROR_TAG_BIT 23
0208 #define L2C_ERROR_COR_BIT 22
0209 #define L2C_ERROR_MULTI_BIT 21
0210 #define L2C_ERROR_VALID_BIT 20
0211 #define L2C_ERROR_DISERESP_BIT 19
0212 #define L2C_ERROR_CEC_BIT 16
0213 #define L2C_ERROR_IRQP_BIT 12
0214 #define L2C_ERROR_IRQM_BCKEND_BIT 11
0215 #define L2C_ERROR_IRQM_WPROT_BIT 10
0216 #define L2C_ERROR_IRQM_UNCORR_BIT 9
0217 #define L2C_ERROR_IRQM_CORR_BIT 8
0218 #define L2C_ERROR_IRQM_BIT 8
0219 #define L2C_ERROR_SCB_BIT 6
0220 #define L2C_ERROR_STCB_BIT 4
0221 #define L2C_ERROR_XCB_BIT 3
0222 #define L2C_ERROR_RCB_BIT 2
0223 #define L2C_ERROR_COMP_BIT 1
0224 #define L2C_ERROR_RST_BIT 0
0225 
0226 /*
0227  * L2CACHE DATA CHECK BITS register fields
0228  */
0229 #define L2C_DCB_CB (0xfffffff << L2C_DCB_CB_BIT)
0230 
0231 #define L2C_DCB_CB_BIT 0
0232 
0233 /*
0234  * L2CACHE SCRUB register fields
0235  */
0236 #define L2C_SCRUB_INDEX (0xffff << L2C_SCRUB_INDEX_BIT)
0237 #define L2C_SCRUB_WAY (0x3 << L2C_SCRUB_WAY_BIT)
0238 #define L2C_SCRUB_PEN (0x1 << L2C_SCRUB_PEN_BIT)
0239 #define L2C_SCRUB_EN (0x1 << L2C_SCRUB_EN_BIT)
0240 
0241 #define L2C_SCRUB_INDEX_BIT 16
0242 #define L2C_SCRUB_WAY_BIT 2
0243 #define L2C_SCRUB_PEN_BIT 1
0244 #define L2C_SCRUB_EN_BIT 0
0245 
0246 /*
0247  * L2CACHE SCRUBDELAY register fields
0248  */
0249 #define L2C_SCRUB_DEL (0xffff << L2C_SCRUB_DEL_BIT)
0250 
0251 #define L2C_SCRUB_DEL_BIT 0
0252 
0253 /*
0254  * L2CACHE ERROR INJECT register fields
0255  */
0256 #define L2C_ERRINJ_ADDR (0x3fffffff << L2C_ERRINJ_ADDR_BIT)
0257 #define L2C_ERRINJ_EN (0x1 << L2C_ERRINJ_EN_BIT)
0258 
0259 #define L2C_ERRINJ_ADDR_BIT 2
0260 #define L2C_ERRINJ_EN_BIT 0
0261 
0262 /*
0263  * L2CACHE ACCESS CONTROL register fields
0264  */
0265 #define L2C_ACCCTRL_DSC (0x1 << L2C_ACCCTRL_DSC_BIT)
0266 #define L2C_ACCCTRL_SH (0x1 << L2C_ACCCTRL_SH_BIT)
0267 #define L2C_ACCCTRL_SPLITQ (0x1 << L2C_ACCCTRL_SPLITQ_BIT)
0268 #define L2C_ACCCTRL_NHM (0x1 << L2C_ACCCTRL_NHM_BIT)
0269 #define L2C_ACCCTRL_BERR (0x1 << L2C_ACCCTRL_BERR_BIT)
0270 #define L2C_ACCCTRL_OAPM (0x1 << L2C_ACCCTRL_OAPM_BIT)
0271 #define L2C_ACCCTRL_FLINE (0x1 << L2C_ACCCTRL_FLINE_BIT)
0272 #define L2C_ACCCTRL_DBPF (0x1 << L2C_ACCCTRL_DBPF_BIT)
0273 #define L2C_ACCCTRL_128WF (0x1 << L2C_ACCCTRL_128WF_BIT)
0274 #define L2C_ACCCTRL_DBPWS (0x1 << L2C_ACCCTRL_DBPWS_BIT)
0275 #define L2C_ACCCTRL_SPLIT (0x1 << L2C_ACCCTRL_SPLIT_BIT)
0276 
0277 #define L2C_ACCCTRL_DSC_BIT 14
0278 #define L2C_ACCCTRL_SH_BIT 13
0279 #define L2C_ACCCTRL_SPLITQ_BIT 10
0280 #define L2C_ACCCTRL_NHM_BIT 9
0281 #define L2C_ACCCTRL_BERR_BIT 8
0282 #define L2C_ACCCTRL_OAPM_BIT 7
0283 #define L2C_ACCCTRL_FLINE_BIT 6
0284 #define L2C_ACCCTRL_DBPF_BIT 5
0285 #define L2C_ACCCTRL_128WF_BIT 4
0286 #define L2C_ACCCTRL_DBPWS_BIT 2
0287 #define L2C_ACCCTRL_SPLIT_BIT 1
0288 
0289 #ifdef TEST_L2CACHE
0290 /*
0291  * L2CACHE TAG fields
0292  */
0293 #define L2C_TAG_TAG (0xfffffc << L2C_TAG_TAG_BIT)
0294 #define L2C_TAG_VALID (0x3 << L2C_TAG_VALID_BIT)
0295 #define L2C_TAG_DIRTY (0x3 << L2C_TAG_DIRTY_BIT)
0296 #define L2C_TAG_LRU (0x3 << L2C_TAG_LRU_BIT)
0297 
0298 #define L2C_TAG_TAG_BIT 10
0299 #define L2C_TAG_VALID_BIT 8
0300 #define L2C_TAG_DIRTY_BIT 6
0301 #define L2C_TAG_LRU_BIT 0
0302 
0303 #endif /* TEST_L2CACHE */
0304 
0305 #define DEVNAME_LEN 9
0306 /*
0307  * L2CACHE Driver private data struture
0308  */
0309 struct l2cache_priv {
0310     struct drvmgr_dev   *dev;
0311     char devname[DEVNAME_LEN];
0312 
0313     /* L2CACHE control registers */
0314     struct l2c_regs *regs;
0315 
0316     /* L2CACHE status */
0317     int ways;
0318     int waysize;
0319     int linesize;
0320     int index;
0321     int mtrr;
0322     int ft_support;
0323     int split_support;
0324     int atomic_flush;
0325 
0326     /* User defined ISR */
0327     l2cache_isr_t isr;
0328     void *isr_arg;
0329 };
0330 
0331 /*
0332  * L2CACHE internal prototypes
0333  */
0334 /* -Register access functions */
0335 STATIC INLINE int l2cache_reg_ctrl_enable(void);
0336 STATIC INLINE int l2cache_reg_ctrl_disable(void);
0337 STATIC INLINE int l2cache_reg_ctrl_locked_set(int locked);
0338 STATIC INLINE int l2cache_reg_ctrl_edac_set(int edac);
0339 STATIC INLINE int l2cache_reg_ctrl_repl(int policy);
0340 STATIC INLINE int l2cache_reg_ctrl_iway(int way);
0341 STATIC INLINE int l2cache_reg_ctrl_writep(int policy);
0342 STATIC INLINE unsigned int l2cache_reg_ctrl(void);
0343 STATIC INLINE unsigned int l2cache_reg_status(void);
0344 STATIC INLINE int l2cache_reg_mtrr_set(int index, unsigned int addr,
0345         unsigned int mask, int options);
0346 UNUSED STATIC INLINE unsigned int l2cache_reg_mtrr_get(int index);
0347 STATIC INLINE int l2cache_reg_flushmem(unsigned int addr, int options);
0348 STATIC INLINE int l2cache_reg_flushline(int way, int index, int options);
0349 STATIC INLINE int l2cache_reg_flushway(unsigned int tag, int way, int options);
0350 STATIC INLINE unsigned int l2cache_reg_error(void);
0351 STATIC INLINE int l2cache_reg_error_reset(void);
0352 STATIC INLINE int l2cache_reg_error_irqmask(int mask);
0353 STATIC INLINE unsigned int l2cache_reg_error_addr(void);
0354 STATIC INLINE unsigned int l2cache_reg_scrub(void);
0355 STATIC INLINE int l2cache_reg_scrub_enable(int delay);
0356 STATIC INLINE int l2cache_reg_scrub_disable(void);
0357 STATIC INLINE unsigned int l2cache_reg_scrub_delay(void);
0358 STATIC INLINE int l2cache_reg_scrub_line(int way, int index);
0359 STATIC INLINE unsigned int l2cache_reg_accctrl(void);
0360 STATIC INLINE int l2cache_reg_accctrl_split_disable(void);
0361 STATIC INLINE int l2cache_reg_accctrl_split_enable(void);
0362 #ifdef TEST_L2CACHE
0363 STATIC INLINE int l2cache_reg_error_dcb(unsigned int cb);
0364 STATIC INLINE int l2cache_reg_error_inject(unsigned int addr);
0365 STATIC INLINE unsigned int l2cache_reg_diagtag(int way, int index);
0366 STATIC INLINE unsigned int l2cache_reg_diagdata(int way, int index, int word);
0367 STATIC unsigned int log2int(unsigned int v);
0368 #endif /* TEST_L2CACHE */
0369 
0370 /* -Control functions */
0371 STATIC int l2cache_ctrl_status(void);
0372 STATIC void l2cache_flushwait(void);
0373 
0374 /* -Init function */
0375 STATIC int l2cache_init(struct l2cache_priv *priv);
0376 
0377 /* -Init function called by drvmgr */
0378 int l2cache_init1(struct drvmgr_dev *dev);
0379 
0380 /* -IRQ handler */
0381 void l2cache_isr(void *arg);
0382 
0383 /*
0384  * L2CACHE static members
0385  */
0386 static struct l2cache_priv *l2cachepriv = NULL;
0387 #ifdef DEBUG
0388 static char * repl_names[4] = {"LRU","Random","Master-Idx-1","Master-IDx-2"};
0389 #endif
0390 
0391 static void REG_WRITE(volatile unsigned int *addr, unsigned int val) {
0392     SPIN_IRQFLAGS(irqflags);
0393 
0394     SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
0395     *addr = val;
0396     SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
0397 }
0398 
0399 static unsigned int REG_READ(volatile unsigned int *addr) {
0400     SPIN_IRQFLAGS(irqflags);
0401     unsigned int val;
0402 
0403     SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
0404     val = *addr;
0405     SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
0406     return val;
0407 }
0408 
0409 #if defined(__sparc__)
0410 static inline uint32_t atomic_swap32(uint32_t *addr, uint32_t val) {
0411     __asm__ volatile (
0412         "swapa [%1] 1, %0\n" :
0413         "+r" (val) : /* output and input */
0414         "r" (addr) : /* input */
0415         "memory"
0416     );
0417     return val;
0418 }
0419 
0420 static void REG_WRITE_ATOMIC(volatile unsigned int *addr, unsigned int val) {
0421     SPIN_IRQFLAGS(irqflags);
0422 
0423     SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
0424     atomic_swap32((uint32_t *) addr, val);
0425     SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
0426 }
0427 
0428 #else
0429 #define REG_WRITE_ATOMIC(addr, val) REG_WRITE(addr, val)
0430 #endif
0431 
0432 /* L2CACHE DRIVER */
0433 
0434 struct drvmgr_drv_ops l2cache_ops =
0435 {
0436     .init = {l2cache_init1, NULL, NULL, NULL},
0437     .remove = NULL,
0438     .info = NULL
0439 };
0440 
0441 struct amba_dev_id l2cache_ids[] =
0442 {
0443     {VENDOR_GAISLER, GAISLER_L2CACHE},
0444     {0, 0}      /* Mark end of table */
0445 };
0446 
0447 struct amba_drv_info l2cache_info =
0448 {
0449     {
0450         DRVMGR_OBJ_DRV,                 /* Driver */
0451         NULL,               /* Next driver */
0452         NULL,               /* Device list */
0453         DRIVER_AMBAPP_GAISLER_L2CACHE_ID,/* Driver ID */
0454         "L2CACHE_DRV",          /* Driver Name */
0455         DRVMGR_BUS_TYPE_AMBAPP,     /* Bus Type */
0456         &l2cache_ops,
0457         NULL,               /* Funcs */
0458         0,              /* No devices yet */
0459         sizeof(struct l2cache_priv),    /* Make drvmgr alloc private */
0460     },
0461     &l2cache_ids[0]
0462 };
0463 
0464 void l2cache_register_drv(void)
0465 {
0466     DBG("Registering L2CACHE driver\n");
0467     drvmgr_drv_register(&l2cache_info.general);
0468 }
0469 
0470 /* Initializes the L2CACHE core and driver
0471  *
0472  * Return values
0473  *  0             Successful initalization
0474  */
0475 STATIC int l2cache_init(struct l2cache_priv *priv)
0476 {
0477     struct ambapp_ahb_info *ahb;
0478     struct amba_dev_info *ainfo = priv->dev->businfo;
0479 
0480     /* Find L2CACHE core from Plug&Play information */
0481     ahb = ainfo->info.ahb_slv;
0482 
0483     /* Found L2CACHE core, init private structure */
0484     priv->regs = (struct l2c_regs *)ahb->start[1];
0485 
0486     /* Initialize L2CACHE status */
0487     unsigned int status = l2cache_reg_status();
0488     priv->ways = (status & L2C_STAT_WAY) + 1;
0489     priv->waysize =
0490         ((status & L2C_STAT_WAYSIZE) >> L2C_STAT_WAYSIZE_BIT) * 1024;
0491     priv->linesize = ((status & L2C_STAT_LS)? 64 : 32);
0492     priv->index = ((priv->waysize)/(priv->linesize));
0493     priv->mtrr = (status & L2C_STAT_MTRR) >> L2C_STAT_MTRR_BIT;
0494     priv->ft_support = (status & L2C_STAT_MP) >> L2C_STAT_MP_BIT;
0495 
0496     priv->atomic_flush = 1;
0497 
0498     /* Probe split support. */
0499     int split_old = 0;
0500     int split_new = 0;
0501     split_old = (l2cache_reg_accctrl() & L2C_ACCCTRL_SPLIT);
0502     if (split_old){
0503         l2cache_reg_accctrl_split_disable();
0504     }else{
0505         l2cache_reg_accctrl_split_enable();
0506     }
0507     split_new = (l2cache_reg_accctrl() & L2C_ACCCTRL_SPLIT);
0508     if (split_old){
0509         l2cache_reg_accctrl_split_enable();
0510     }else{
0511         l2cache_reg_accctrl_split_disable();
0512     }
0513     priv->split_support =
0514         ((split_new ^ split_old) >> L2C_ACCCTRL_SPLIT_BIT) & 1;
0515 
0516     DBG("L2CACHE driver initialized\n");
0517 
0518     return 0;
0519 }
0520 
0521 /* Called when a core is found with the AMBA device and vendor ID
0522  * given in l2cache_ids[]. IRQ, Console does not work here
0523  */
0524 int l2cache_init1(struct drvmgr_dev *dev)
0525 {
0526     int status;
0527     struct l2cache_priv *priv;
0528 
0529     DBG("L2CACHE[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0530 
0531     if (l2cachepriv) {
0532         DBG("Driver only supports one L2CACHE core\n");
0533         return DRVMGR_FAIL;
0534     }
0535 
0536     priv = dev->priv;
0537     if (!priv)
0538         return DRVMGR_NOMEM;
0539 
0540     priv->dev = dev;
0541     strncpy(&priv->devname[0], "l2cache0", DEVNAME_LEN);
0542     l2cachepriv = priv;
0543 
0544     /* Initialize L2CACHE Hardware */
0545     status = l2cache_init(priv);
0546     if (status) {
0547         printk("Failed to initialize l2cache driver %d\n", status);
0548         return -1;
0549     }
0550 
0551     return DRVMGR_OK;
0552 }
0553 
0554 STATIC INLINE int l2cache_reg_ctrl_enable(void)
0555 {
0556     struct l2cache_priv *priv = l2cachepriv;
0557 
0558     unsigned int ctrl = REG_READ(&priv->regs->control);
0559     REG_WRITE(&priv->regs->control, (ctrl | L2C_CTRL_EN));
0560     return 0;
0561 }
0562 
0563 STATIC INLINE int l2cache_reg_ctrl_disable(void)
0564 {
0565     struct l2cache_priv *priv = l2cachepriv;
0566 
0567     unsigned int ctrl = REG_READ(&priv->regs->control);
0568     REG_WRITE(&priv->regs->control, (ctrl & ~(L2C_CTRL_EN)));
0569     return 0;
0570 }
0571 
0572 STATIC INLINE int l2cache_reg_ctrl_repl(int policy)
0573 {
0574     struct l2cache_priv *priv = l2cachepriv;
0575 
0576     unsigned int ctrl = REG_READ(&priv->regs->control);
0577     REG_WRITE(&priv->regs->control,
0578         ((ctrl & ~(L2C_CTRL_REPL)) |
0579          ((policy << L2C_CTRL_REPL_BIT) & L2C_CTRL_REPL))
0580     );
0581     return 0;
0582 }
0583 
0584 STATIC INLINE int l2cache_reg_ctrl_iway(int way)
0585 {
0586     struct l2cache_priv *priv = l2cachepriv;
0587 
0588     unsigned int ctrl = REG_READ(&priv->regs->control);
0589     REG_WRITE(&priv->regs->control,
0590         ((ctrl & ~(L2C_CTRL_IWAY)) |
0591          ((way << L2C_CTRL_IWAY_BIT) & L2C_CTRL_IWAY))
0592     );
0593     return 0;
0594 }
0595 
0596 STATIC INLINE int l2cache_reg_ctrl_writep(int policy)
0597 {
0598     struct l2cache_priv *priv = l2cachepriv;
0599 
0600     unsigned int ctrl = REG_READ(&priv->regs->control);
0601     REG_WRITE(&priv->regs->control,
0602         ((ctrl & ~(L2C_CTRL_WP)) | ((policy << L2C_CTRL_WP_BIT) & L2C_CTRL_WP))
0603     );
0604     return 0;
0605 }
0606 
0607 STATIC INLINE int l2cache_reg_ctrl_locked_set(int locked)
0608 {
0609     struct l2cache_priv *priv = l2cachepriv;
0610 
0611     unsigned int ctrl = REG_READ(&priv->regs->control);
0612     ctrl = (ctrl & ~(L2C_CTRL_LOCK));
0613     REG_WRITE(&priv->regs->control,
0614             ctrl |
0615             ((locked << L2C_CTRL_LOCK_BIT) & L2C_CTRL_LOCK));
0616     return 0;
0617 }
0618 
0619 STATIC INLINE int l2cache_reg_ctrl_edac_set(int edac)
0620 {
0621     struct l2cache_priv *priv = l2cachepriv;
0622 
0623     unsigned int ctrl = REG_READ(&priv->regs->control);
0624     REG_WRITE(&priv->regs->control,
0625             (ctrl & ~(L2C_CTRL_EDAC)) |
0626             (edac? L2C_CTRL_EDAC:0));
0627     return 0;
0628 }
0629 
0630 STATIC INLINE unsigned int l2cache_reg_ctrl(void)
0631 {
0632     struct l2cache_priv *priv = l2cachepriv;
0633 
0634     return REG_READ(&priv->regs->control);
0635 }
0636 
0637 STATIC INLINE unsigned int l2cache_reg_status(void)
0638 {
0639     struct l2cache_priv *priv = l2cachepriv;
0640 
0641     return REG_READ(&priv->regs->status);
0642 }
0643 
0644 STATIC INLINE int l2cache_reg_mtrr_set(int index, unsigned int addr,
0645         unsigned int mask, int options)
0646 {
0647     struct l2cache_priv *priv = l2cachepriv;
0648 
0649     /* Set mtrr */
0650     addr = addr & L2C_MTRR_ADDR;
0651     mask = (mask >> 16) & L2C_MTRR_MASK;
0652     options = ((options & ~(L2C_MTRR_ADDR)) & ~(L2C_MTRR_MASK));
0653     unsigned int mtrr = 0 | addr | mask | options;
0654     REG_WRITE(&priv->regs->mtrr[index], mtrr);
0655     return 0;
0656 }
0657 
0658 UNUSED STATIC INLINE unsigned int l2cache_reg_mtrr_get(int index)
0659 {
0660     struct l2cache_priv *priv = l2cachepriv;
0661 
0662     return REG_READ(&priv->regs->mtrr[index]);
0663 }
0664 
0665 STATIC INLINE int l2cache_reg_flushmem(unsigned int addr, int options)
0666 {
0667     struct l2cache_priv *priv = l2cachepriv;
0668     unsigned int val;
0669 
0670     options = (options & ~(L2C_FLUSH_ADDR));
0671     val = (addr & L2C_FLUSH_ADDR) | options;
0672 
0673     if (priv->atomic_flush)
0674         REG_WRITE_ATOMIC(&priv->regs->flush_mem_addr, val);
0675     else
0676         REG_WRITE(&priv->regs->flush_mem_addr, val);
0677 
0678     return 0;
0679 }
0680 
0681 STATIC INLINE int l2cache_reg_flushline(int way, int index, int options)
0682 {
0683     struct l2cache_priv *priv = l2cachepriv;
0684     unsigned int val;
0685 
0686     options = 0 | (options & (L2C_FLUSHSI_FMODE));
0687     val = ((index << L2C_FLUSHSI_INDEX_BIT) & L2C_FLUSHSI_INDEX) |
0688             ((way << L2C_FLUSHSI_WAY_BIT) & L2C_FLUSHSI_WAY) |
0689             options;
0690 
0691     if (priv->atomic_flush)
0692         REG_WRITE_ATOMIC(&priv->regs->flush_set_index, val);
0693     else
0694         REG_WRITE(&priv->regs->flush_set_index, val);
0695 
0696     return 0;
0697 }
0698 
0699 STATIC INLINE int l2cache_reg_flushway(unsigned int tag, int way, int options)
0700 {
0701     struct l2cache_priv *priv = l2cachepriv;
0702     unsigned int val;
0703 
0704     options = (options & ~(L2C_FLUSHSI_TAG | L2C_FLUSHSI_WAY))
0705         | L2C_FLUSHSI_WF;
0706     val = (tag & L2C_FLUSHSI_TAG) |
0707           ( (way << L2C_FLUSHSI_WAY_BIT) & L2C_FLUSHSI_WAY) |
0708             options;
0709     if (priv->atomic_flush)
0710         REG_WRITE_ATOMIC(&priv->regs->flush_set_index, val);
0711     else
0712         REG_WRITE(&priv->regs->flush_set_index, val);
0713 
0714     return 0;
0715 }
0716 
0717 STATIC INLINE unsigned int l2cache_reg_error(void)
0718 {
0719     struct l2cache_priv *priv = l2cachepriv;
0720 
0721     return REG_READ(&priv->regs->error_status_control);
0722 }
0723 
0724 STATIC INLINE int l2cache_reg_error_reset(void)
0725 {
0726     struct l2cache_priv *priv = l2cachepriv;
0727 
0728     unsigned int ctrl = REG_READ(&priv->regs->error_status_control);
0729     REG_WRITE(&priv->regs->error_status_control, ctrl | L2C_ERROR_RST);
0730     return 0;
0731 }
0732 
0733 STATIC INLINE int l2cache_reg_error_irqmask(int mask)
0734 {
0735     struct l2cache_priv *priv = l2cachepriv;
0736 
0737     unsigned int ctrl = REG_READ(&priv->regs->error_status_control);
0738     REG_WRITE(&priv->regs->error_status_control,
0739             (ctrl & ~(L2C_ERROR_IRQM)) | (mask & L2C_ERROR_IRQM));
0740     return 0;
0741 }
0742 
0743 STATIC INLINE unsigned int l2cache_reg_error_addr(void)
0744 {
0745     struct l2cache_priv *priv = l2cachepriv;
0746 
0747     return REG_READ(&priv->regs->error_addr);
0748 }
0749 
0750 STATIC INLINE unsigned int l2cache_reg_scrub(void)
0751 {
0752     struct l2cache_priv *priv = l2cachepriv;
0753 
0754     return REG_READ(&priv->regs->scrub_control_status);
0755 }
0756 
0757 STATIC INLINE int l2cache_reg_scrub_enable(int delay)
0758 {
0759     struct l2cache_priv *priv = l2cachepriv;
0760 
0761     unsigned int accc = REG_READ(&priv->regs->access_control);
0762     REG_WRITE(&priv->regs->access_control,
0763             accc | L2C_ACCCTRL_DSC | L2C_ACCCTRL_SH);
0764 
0765     unsigned int ctrl = REG_READ(&priv->regs->scrub_control_status);
0766     REG_WRITE(&priv->regs->scrub_delay,
0767             (delay << L2C_SCRUB_DEL_BIT) & L2C_SCRUB_DEL);
0768     REG_WRITE(&priv->regs->scrub_control_status,  ctrl | L2C_SCRUB_EN);
0769     return 0;
0770 }
0771 
0772 STATIC INLINE int l2cache_reg_scrub_disable(void)
0773 {
0774     struct l2cache_priv *priv = l2cachepriv;
0775 
0776     unsigned int ctrl = REG_READ(&priv->regs->scrub_control_status);
0777     REG_WRITE(&priv->regs->scrub_control_status,  ctrl & ~(L2C_SCRUB_EN));
0778     return 0;
0779 }
0780 
0781 STATIC INLINE int l2cache_reg_scrub_line(int way, int index)
0782 {
0783     struct l2cache_priv *priv = l2cachepriv;
0784 
0785     REG_WRITE(&priv->regs->scrub_control_status,
0786             ((index << L2C_SCRUB_INDEX_BIT) & L2C_SCRUB_INDEX) |
0787             ((way << L2C_SCRUB_WAY_BIT) & L2C_SCRUB_WAY) |
0788             L2C_SCRUB_PEN);
0789     return 0;
0790 }
0791 
0792 STATIC INLINE unsigned int l2cache_reg_scrub_delay(void)
0793 {
0794     struct l2cache_priv *priv = l2cachepriv;
0795 
0796     return REG_READ(&priv->regs->scrub_delay);
0797 }
0798 
0799 STATIC INLINE unsigned int l2cache_reg_accctrl(void){
0800     struct l2cache_priv *priv = l2cachepriv;
0801 
0802     return REG_READ(&priv->regs->access_control);
0803 }
0804 
0805 STATIC INLINE int l2cache_reg_accctrl_split_disable(void)
0806 {
0807     struct l2cache_priv *priv = l2cachepriv;
0808 
0809     /* Disable split */
0810     unsigned int ctrl = REG_READ(&priv->regs->access_control);
0811     REG_WRITE(&priv->regs->access_control, (ctrl & ~(L2C_ACCCTRL_SPLIT)));
0812     return 0;
0813 }
0814 
0815 STATIC INLINE int l2cache_reg_accctrl_split_enable(void)
0816 {
0817     struct l2cache_priv *priv = l2cachepriv;
0818 
0819     /* Enable split */
0820     unsigned int ctrl = REG_READ(&priv->regs->access_control);
0821     REG_WRITE(&priv->regs->access_control, (ctrl | (L2C_ACCCTRL_SPLIT)));
0822     return 0;
0823 }
0824 
0825 STATIC INLINE int l2cache_ctrl_status(void)
0826 {
0827     return ((l2cache_reg_ctrl() >> L2C_CTRL_EN_BIT) & 0x1);
0828 }
0829 
0830 STATIC void l2cache_flushwait(void)
0831 {
0832     /* Read any L2cache register to wait until flush is done */
0833     /* The L2 will block any access until the flush is done */
0834     /* Force read operation */
0835     //asm volatile ("" : : "r" (l2cache_reg_status()));
0836     (void) l2cache_reg_status();
0837     return;
0838 }
0839 
0840 #ifdef TEST_L2CACHE
0841 STATIC INLINE int l2cache_reg_error_dcb(unsigned int cb)
0842 {
0843     struct l2cache_priv *priv = l2cachepriv;
0844 
0845     REG_WRITE(&priv->regs->data_check_bit, (cb & L2C_DCB_CB));
0846     return 0;
0847 }
0848 
0849 STATIC INLINE int l2cache_reg_error_inject(unsigned int addr)
0850 {
0851     struct l2cache_priv *priv = l2cachepriv;
0852 
0853     REG_WRITE(&priv->regs->error_injection,
0854             (addr & L2C_ERRINJ_ADDR) | L2C_ERRINJ_EN);
0855     return 0;
0856 }
0857 
0858 STATIC INLINE unsigned int l2cache_reg_diagtag(int way, int index)
0859 {
0860     struct l2cache_priv *priv = l2cachepriv;
0861 
0862     int offset = (index*8 + way);
0863     return REG_READ(&priv->regs->diag_iface_tag[offset]);
0864 }
0865 
0866 STATIC INLINE unsigned int l2cache_reg_diagdata(int way, int index, int word)
0867 {
0868     struct l2cache_priv *priv = l2cachepriv;
0869 
0870     int offset = (index*(priv->linesize/4) + way*0x20000 + word);
0871     return REG_READ(&priv->regs->diag_iface_data[offset]);
0872 }
0873 
0874 STATIC unsigned int log2int(unsigned int v)
0875 {
0876     unsigned r = 0;
0877     while (v >>= 1) {
0878         r++;
0879     }
0880     return r;
0881 }
0882 
0883 /* Return the index for a given addr */
0884 int l2cache_get_index( uint32_t addr)
0885 {
0886     struct l2cache_priv * priv = l2cachepriv;
0887 
0888     if (priv == NULL){
0889         DBG("L2CACHE not initialized.\n");
0890         return L2CACHE_ERR_NOINIT;
0891     }
0892 
0893     return (addr % priv->waysize)/(priv->linesize);
0894 }
0895 
0896 /* Return the tag for a given addr */
0897 uint32_t l2cache_get_tag( uint32_t addr)
0898 {
0899     struct l2cache_priv * priv = l2cachepriv;
0900 
0901     if (priv == NULL){
0902         DBG("L2CACHE not initialized.\n");
0903         return L2CACHE_ERR_NOINIT;
0904     }
0905 
0906     uint32_t tmp;
0907     int i = log2int(priv->waysize);
0908     tmp = (addr >> i);
0909     tmp = (tmp << i);
0910     return tmp;
0911 }
0912 
0913 int l2cache_lookup(uint32_t addr, int * way)
0914 {
0915     struct l2cache_priv * priv = l2cachepriv;
0916     int i;
0917     struct l2cache_tag gottag;
0918     int ret;
0919 
0920     if (priv == NULL){
0921         DBG("L2CACHE not initialized.\n");
0922         return L2CACHE_ERR_NOINIT;
0923     }
0924 
0925     uint32_t exptag = l2cache_get_tag(addr);
0926     int index = l2cache_get_index(addr);
0927 
0928     /* Check all tags in the set */
0929     for(i=0; i< priv->ways; i++){
0930         ret = l2cache_diag_tag(i, index, &gottag);
0931         if (ret != L2CACHE_ERR_OK){
0932             return ret;
0933         }
0934         /*DBG("L2CACHE gottag: way=%d, valid=%d, tag=0x%08x.\n",
0935          *      i, gottag.valid, gottag.tag);*/
0936         /* Check if valid */
0937         if (gottag.valid){
0938             /* Check if they are the same */
0939             if (gottag.tag == exptag){
0940                 /* HIT! */
0941                 if (way){
0942                     *way = i;
0943                 }
0944                 DBG("L2CACHE lookup: index=%d, tag=0x%08x HIT way=%d.\n",
0945                         index, (unsigned int) exptag, i);
0946                 return L2CACHE_HIT;
0947             }
0948         }
0949     }
0950     DBG("L2CACHE lookup: index=%d, tag=0x%08x MISS.\n",
0951             index, (unsigned int) exptag);
0952     /* MISS! */
0953     return L2CACHE_MISS;
0954 }
0955 
0956 /* Diagnostic Accesses */
0957 #define l2cache_tag_valid(val) ((val & L2C_TAG_VALID) >> L2C_TAG_VALID_BIT)
0958 #define l2cache_tag_dirty(val) ((val & L2C_TAG_DIRTY) >> L2C_TAG_DIRTY_BIT)
0959 #define l2cache_tag_lru(val) ((val & L2C_TAG_LRU) >> L2C_TAG_LRU_BIT)
0960 int l2cache_diag_tag( int way, int index, struct l2cache_tag * tag)
0961 {
0962     struct l2cache_priv * priv = l2cachepriv;
0963 
0964     if (priv == NULL){
0965         DBG("L2CACHE not initialized.\n");
0966         return L2CACHE_ERR_NOINIT;
0967     }
0968 
0969     if (way >= priv->ways){
0970         DBG("L2CACHE has only %d ways.\n", priv->ways);
0971         return L2CACHE_ERR_EINVAL;
0972     }
0973 
0974     if (index >= priv->index){
0975         DBG("L2CACHE has only %d lines.\n", priv->index);
0976         return L2CACHE_ERR_EINVAL;
0977     }
0978 
0979     if (tag){
0980         unsigned int val = l2cache_reg_diagtag(way,index);
0981 
0982         tag->tag   = l2cache_get_tag(val);
0983         tag->valid = l2cache_tag_valid(val);
0984         tag->dirty = l2cache_tag_dirty(val);
0985         tag->lru   = l2cache_tag_lru(val);
0986     }else{
0987         return L2CACHE_ERR_EINVAL;
0988     }
0989     return L2CACHE_ERR_OK;
0990 }
0991 
0992 int l2cache_diag_line( int way, int index, struct l2cache_dataline * dataline)
0993 {
0994     struct l2cache_priv * priv = l2cachepriv;
0995     int i;
0996 
0997     if (priv == NULL){
0998         DBG("L2CACHE not initialized.\n");
0999         return L2CACHE_ERR_NOINIT;
1000     }
1001 
1002     if (way >= priv->ways){
1003         DBG("L2CACHE has only %d ways.\n", priv->ways);
1004         return L2CACHE_ERR_EINVAL;
1005     }
1006 
1007     if (index >= priv->index){
1008         DBG("L2CACHE has only %d lines.\n", priv->index);
1009         return L2CACHE_ERR_EINVAL;
1010     }
1011 
1012     if (dataline){
1013         dataline->words = (priv->linesize/4);
1014         for (i=0; i< (priv->linesize/4); i++){
1015             dataline->data[i] = l2cache_reg_diagdata(way,index,i);
1016         }
1017     }else{
1018         return L2CACHE_ERR_EINVAL;
1019     }
1020     return L2CACHE_ERR_OK;
1021 }
1022 
1023 /* Inject an error on a given addr */
1024 int l2cache_error_inject_address( uint32_t addr, uint32_t mask)
1025 {
1026     struct l2cache_priv * priv = l2cachepriv;
1027     int word;
1028 
1029     if (priv == NULL){
1030         DBG("L2CACHE not initialized.\n");
1031         return L2CACHE_ERR_NOINIT;
1032     }
1033 
1034     if (!priv->ft_support){
1035         DBG("L2CACHE does not have EDAC support.\n");
1036         return L2CACHE_ERR_ERROR;
1037     }
1038 
1039     if (addr & 0x3){
1040         DBG("Address not aligned to 32-bit.\n");
1041         return L2CACHE_ERR_EINVAL;
1042     }
1043 
1044     /* Get word index */
1045     word = (addr % priv->linesize)/4;
1046 
1047     /* Shift mask to proper word */
1048     mask = (mask << (7*(priv->ways - word - 1)));
1049 
1050     /* Write DCB mask to XOR */
1051     l2cache_reg_error_dcb(mask);
1052 
1053     /* Inject error */
1054     l2cache_reg_error_inject(addr);
1055 
1056     DBG("L2CACHE error injected in 0x%08x (0x%08x).\n",
1057             (unsigned int) addr, (unsigned int) mask);
1058 
1059     return L2CACHE_ERR_OK;
1060 }
1061 
1062 #endif /* TEST_L2CACHE */
1063 
1064 /* L2CACHE Interrupt handler, called when there may be a L2CACHE interrupt.
1065  */
1066 void l2cache_isr(void *arg)
1067 {
1068     struct l2cache_priv *priv = arg;
1069     unsigned int sts = l2cache_reg_error();
1070     unsigned int addr = l2cache_reg_error_addr();
1071 
1072     /* Make sure that the interrupt is pending and unmasked,
1073      * otherwise it migth have been other core
1074      * sharing the same interrupt line */
1075     if ( ((sts & L2C_ERROR_IRQP) >> L2C_ERROR_IRQP_BIT) &
1076             ((sts & L2C_ERROR_IRQM) >> L2C_ERROR_IRQM_BIT)){
1077         /* Reset error status */
1078         l2cache_reg_error_reset();
1079         /* Execute user IRQ (ther will always be one ISR */
1080         /* Give cacheline address */
1081         (priv->isr)(priv->isr_arg, (addr & ~(0x1f)), sts);
1082     }
1083 }
1084 
1085 /* Enable L2CACHE:
1086  */
1087 int l2cache_enable(int flush)
1088 {
1089     int ret;
1090 
1091     /* Flush checks flus parameter and INIT state */
1092     ret = l2cache_flush(flush);
1093     if (ret < 0){
1094         return ret;
1095     }
1096 
1097     l2cache_reg_ctrl_enable();
1098 
1099     DBG("L2CACHE enabled\n");
1100     return L2CACHE_ERR_OK;
1101 }
1102 
1103 /* Disable L2CACHE:
1104  */
1105 int l2cache_disable(int flush)
1106 {
1107     struct l2cache_priv * priv = l2cachepriv;
1108 
1109     if (priv == NULL){
1110         DBG("L2CACHE not initialized.\n");
1111         return L2CACHE_ERR_NOINIT;
1112     }
1113 
1114     if ((flush < 0) ||
1115             (flush >
1116              (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1117             ){
1118         DBG("L2CACHE wrong flush option.\n");
1119         return L2CACHE_ERR_EINVAL;
1120     }
1121 
1122     /* Flush & invalidate all cache. Also disable L2C */
1123     switch(flush & 0x3){
1124         case L2CACHE_OPTIONS_FLUSH_NONE:
1125             l2cache_reg_ctrl_disable();
1126             break;
1127         case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1128             l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_INV_WB_ALL | L2C_FLUSH_DI);
1129             break;
1130         case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1131             l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_WB_ALL | L2C_FLUSH_DI);
1132             break;
1133         case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1134         default:
1135             l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_INV_ALL | L2C_FLUSH_DI);
1136             break;
1137     }
1138 
1139     if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1140         l2cache_flushwait();
1141     }
1142 
1143     DBG("L2CACHE disabled\n");
1144     return L2CACHE_ERR_OK;
1145 }
1146 
1147 /* Status L2CACHE:
1148  */
1149 int l2cache_status(void)
1150 {
1151     struct l2cache_priv * priv = l2cachepriv;
1152     int status;
1153 
1154     if (priv == NULL){
1155         DBG("L2CACHE not initialized.\n");
1156         return L2CACHE_ERR_NOINIT;
1157     }
1158 
1159     unsigned int ctrl = l2cache_reg_ctrl();
1160     int locked = (ctrl & L2C_CTRL_LOCK) >> L2C_CTRL_LOCK_BIT;
1161     int enabled = ((ctrl & L2C_CTRL_EN) >> L2C_CTRL_EN_BIT) & 0x1;
1162     int edac = (ctrl & L2C_CTRL_EDAC) >> L2C_CTRL_EDAC_BIT;
1163     int repl = (ctrl & L2C_CTRL_REPL) >> L2C_CTRL_REPL_BIT;
1164     int writep = (ctrl & L2C_CTRL_WP) >> L2C_CTRL_WP_BIT;
1165 
1166     unsigned int acc = l2cache_reg_accctrl();
1167     int split = (acc & L2C_ACCCTRL_SPLIT) >> L2C_ACCCTRL_SPLIT_BIT;
1168 
1169     unsigned int err = l2cache_reg_error();
1170     int interrupts = (err & L2C_ERROR_IRQM) >> L2C_ERROR_IRQM_BIT;
1171 
1172     unsigned int scr = l2cache_reg_scrub();
1173     int scrub = (scr & L2C_SCRUB_EN) >> L2C_SCRUB_EN_BIT;
1174 
1175     unsigned int dly = l2cache_reg_scrub_delay();
1176     int delay = (dly & L2C_SCRUB_DEL) >> L2C_SCRUB_DEL_BIT;
1177 
1178     status = 0|
1179         (enabled? L2CACHE_STATUS_ENABLED: 0) |
1180         (split? L2CACHE_STATUS_SPLIT_ENABLED: 0) |
1181         (edac? L2CACHE_STATUS_EDAC_ENABLED: 0) |
1182         ((repl & 0x3) << L2CACHE_STATUS_REPL_BIT) |
1183         (writep? L2CACHE_STATUS_WRITETHROUGH: 0) |
1184         ((locked & 0xf) << L2CACHE_STATUS_LOCK_BIT) |
1185         ((interrupts & 0xf) << L2CACHE_STATUS_INT_BIT) |
1186         (scrub? L2CACHE_STATUS_SCRUB_ENABLED: 0) |
1187         ((delay & 0xffff) << L2CACHE_STATUS_SCRUB_DELAY_BIT);
1188 
1189     return status;
1190 }
1191 
1192 /* Flush L2CACHE:
1193  */
1194 int l2cache_flush(int flush)
1195 {
1196     struct l2cache_priv * priv = l2cachepriv;
1197 
1198     if (priv == NULL){
1199         DBG("L2CACHE not initialized.\n");
1200         return L2CACHE_ERR_NOINIT;
1201     }
1202 
1203     if ((flush < 0) ||
1204             (flush >
1205              (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1206             ){
1207         DBG("L2CACHE wrong flush option.\n");
1208         return L2CACHE_ERR_EINVAL;
1209     }
1210 
1211     switch(flush & 0x3){
1212         case L2CACHE_OPTIONS_FLUSH_NONE:
1213             break;
1214         case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1215             l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_INV_WB_ALL);
1216             break;
1217         case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1218             l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_WB_ALL);
1219             break;
1220         case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1221         default:
1222             l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_INV_ALL);
1223             break;
1224     }
1225 
1226     if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1227         l2cache_flushwait();
1228     }
1229 
1230     DBG("L2CACHE flushed\n");
1231     return L2CACHE_ERR_OK;
1232 }
1233 
1234 /* Flush L2CACHE address:
1235  */
1236 int l2cache_flush_address(uint32_t addr, int size, int flush)
1237 {
1238     struct l2cache_priv * priv = l2cachepriv;
1239     uint32_t endaddr;
1240     int options;
1241 
1242     if (priv == NULL){
1243         DBG("L2CACHE not initialized.\n");
1244         return L2CACHE_ERR_NOINIT;
1245     }
1246 
1247     if ((flush < 0) ||
1248             (flush >
1249              (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1250             ){
1251         DBG("L2CACHE wrong flush option.\n");
1252         return L2CACHE_ERR_EINVAL;
1253     }
1254 
1255     if (size <= 0){
1256         DBG("L2CACHE wrong size.\n");
1257         return L2CACHE_ERR_EINVAL;
1258     }
1259 
1260     switch(flush & 0x3){
1261         case L2CACHE_OPTIONS_FLUSH_NONE:
1262             break;
1263         case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1264             options=L2C_FLUSH_FMODE_INV_WB_ONE;
1265             break;
1266         case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1267             options=L2C_FLUSH_FMODE_WB_ONE;
1268             break;
1269         case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1270         default:
1271             options=L2C_FLUSH_FMODE_INV_ONE;
1272             break;
1273     }
1274 
1275     if ( (flush & 0x3) == L2CACHE_OPTIONS_FLUSH_NONE){
1276         return L2CACHE_ERR_OK;
1277     }
1278 
1279     /* Get the end address */
1280     endaddr = (addr + size);
1281 
1282     /* Start on first cacheline address */
1283     addr = addr - (addr % priv->linesize);
1284     while( addr < endaddr){
1285         /* Flush address */
1286         l2cache_reg_flushmem(addr, options);
1287         /* Update next line */
1288         addr += priv->linesize;
1289     }
1290 
1291     if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1292         l2cache_flushwait();
1293     }
1294 
1295     DBG("L2CACHE address range flushed\n");
1296     return L2CACHE_ERR_OK;
1297 }
1298 
1299 /* Flush L2CACHE line:
1300  */
1301 int l2cache_flush_line(int way, int index, int flush)
1302 {
1303     struct l2cache_priv * priv = l2cachepriv;
1304 
1305     if (priv == NULL){
1306         DBG("L2CACHE not initialized.\n");
1307         return L2CACHE_ERR_NOINIT;
1308     }
1309 
1310     if ((flush < 0) ||
1311             (flush >
1312              (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1313             ){
1314         DBG("L2CACHE wrong flush option.\n");
1315         return L2CACHE_ERR_EINVAL;
1316     }
1317 
1318     if ((index < 0) || (index >= priv->index)){
1319         DBG("L2CACHE only has %d lines.\n", priv->index);
1320         return L2CACHE_ERR_EINVAL;
1321     }
1322 
1323     if ((way < 0 ) || (way >= priv->ways)){
1324         DBG("L2CACHE only has %d ways.\n", priv->ways);
1325         return L2CACHE_ERR_EINVAL;
1326     }
1327 
1328     switch(flush & 0x3){
1329         case L2CACHE_OPTIONS_FLUSH_NONE:
1330             break;
1331         case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1332             l2cache_reg_flushline(way, index,
1333                     L2C_FLUSHSI_FMODE_SET_INV_WB_ONE);
1334             break;
1335         case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1336             l2cache_reg_flushline(way, index, L2C_FLUSHSI_FMODE_SET_WB_ONE);
1337             break;
1338         case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1339         default:
1340             l2cache_reg_flushline(way, index, L2C_FLUSHSI_FMODE_SET_INV_ONE);
1341             break;
1342     }
1343 
1344     if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1345         l2cache_flushwait();
1346     }
1347 
1348     DBG("L2CACHE line [%d,%d] flushed\n", way, index);
1349     return L2CACHE_ERR_OK;
1350 }
1351 
1352 /* Flush L2CACHE way:
1353  */
1354 int l2cache_flush_way(int way, int flush)
1355 {
1356     struct l2cache_priv * priv = l2cachepriv;
1357 
1358     if (priv == NULL){
1359         DBG("L2CACHE not initialized.\n");
1360         return L2CACHE_ERR_NOINIT;
1361     }
1362 
1363     if ((flush < 0) ||
1364             (flush >
1365              (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1366             ){
1367         DBG("L2CACHE wrong flush option.\n");
1368         return L2CACHE_ERR_EINVAL;
1369     }
1370 
1371     if ((way < 0 ) || (way >= priv->ways)){
1372         DBG("L2CACHE only has %d ways.\n", priv->ways);
1373         return L2CACHE_ERR_EINVAL;
1374     }
1375 
1376     switch(flush & 0x3){
1377         case L2CACHE_OPTIONS_FLUSH_NONE:
1378             break;
1379         case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1380             l2cache_reg_flushway(0, way, L2C_FLUSHSI_FMODE_WAY_UPDATE);
1381             break;
1382         case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1383             l2cache_reg_flushway(0, way, L2C_FLUSHSI_FMODE_WAY_WB);
1384             break;
1385         case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1386         default:
1387             l2cache_reg_flushway(0, way, L2C_FLUSHSI_FMODE_WAY_UPDATE_WB_ALL);
1388             break;
1389     }
1390 
1391     if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1392         l2cache_flushwait();
1393     }
1394 
1395     DBG("L2CACHE way [%d] flushed\n",way);
1396     return L2CACHE_ERR_OK;
1397 }
1398 
1399 /* Fill L2CACHE way:
1400  */
1401 int l2cache_fill_way(int way, uint32_t tag, int options, int flush)
1402 {
1403     struct l2cache_priv * priv = l2cachepriv;
1404     int flags;
1405 
1406     if (priv == NULL){
1407         DBG("L2CACHE not initialized.\n");
1408         return L2CACHE_ERR_NOINIT;
1409     }
1410 
1411     if ((way < 0 ) || (way >= priv->ways)){
1412         DBG("L2CACHE only has %d ways.\n", priv->ways);
1413         return L2CACHE_ERR_EINVAL;
1414     }
1415 
1416     /* Check input parameters */
1417     if (tag & 0x000003ff){
1418         DBG("Only using bits 31:10 of Addr/Mask\n");
1419         return L2CACHE_ERR_EINVAL;
1420     }
1421 
1422     /* Perform the Way-flush */
1423     flags = ((options & L2CACHE_OPTIONS_FETCH)? L2C_FLUSHSI_FL:0) |
1424              ((options & L2CACHE_OPTIONS_VALID)? L2C_FLUSHSI_VB:0) |
1425              ((options & L2CACHE_OPTIONS_DIRTY)? L2C_FLUSHSI_DB:0);
1426 
1427     /*DBG("L2CACHE lock way: Locked=%d, way=%d, option=0x%04x\n",
1428      *      locked, way, flags);*/
1429 
1430     switch(flush & 0x3){
1431         case L2CACHE_OPTIONS_FLUSH_NONE:
1432             break;
1433         case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1434             l2cache_reg_flushway(tag, way,
1435                     flags | L2C_FLUSHSI_FMODE_WAY_UPDATE);
1436             break;
1437         case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1438             l2cache_reg_flushway(tag, way, flags | L2C_FLUSHSI_FMODE_WAY_WB);
1439             break;
1440         case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1441         default:
1442             l2cache_reg_flushway(tag, way,
1443                     flags | L2C_FLUSHSI_FMODE_WAY_UPDATE_WB_ALL);
1444             break;
1445     }
1446 
1447     if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1448         l2cache_flushwait();
1449     }
1450 
1451     DBG("Way[%d] filled with Tag 0x%08x\n", way, (unsigned int) tag);
1452 
1453     return L2CACHE_ERR_OK;
1454 }
1455 
1456 /* Lock L2CACHE way:
1457  */
1458 int l2cache_lock_way(uint32_t tag, int options, int flush, int enable)
1459 {
1460     struct l2cache_priv * priv = l2cachepriv;
1461     int enabled;
1462     int way;
1463     int locked;
1464     int flags;
1465     int ret;
1466 
1467     if (priv == NULL){
1468         DBG("L2CACHE not initialized.\n");
1469         return L2CACHE_ERR_NOINIT;
1470     }
1471 
1472     locked = L2CACHE_LOCKED_WAYS(l2cache_status());
1473     if (locked >= priv->ways){
1474         DBG("L2CACHE only has %d ways.\n", priv->ways);
1475         return L2CACHE_ERR_TOOMANY;
1476     }
1477 
1478     /* Check input parameters */
1479     if (tag & 0x000003ff){
1480         DBG("Only using bits 31:10 of Addr/Mask\n");
1481         return L2CACHE_ERR_EINVAL;
1482     }
1483 
1484     /* Check L2C status */
1485     enabled = l2cache_ctrl_status();
1486 
1487     /* Disable L2C */
1488     ret = l2cache_disable(flush);
1489     if (ret < 0){
1490         return ret;
1491     }
1492 
1493     /* Increase number of locked ways */
1494     locked++;
1495     way = priv->ways - locked;
1496     l2cache_reg_ctrl_locked_set(locked);
1497 
1498     /* Perform the Way-flush */
1499     flags = ((options & L2CACHE_OPTIONS_FETCH)? L2C_FLUSHSI_FL:0) |
1500              ((options & L2CACHE_OPTIONS_VALID)? L2C_FLUSHSI_VB:0) |
1501              ((options & L2CACHE_OPTIONS_DIRTY)? L2C_FLUSHSI_DB:0);
1502 
1503     /*DBG("L2CACHE lock way: Locked=%d, way=%d, option=0x%04x\n",
1504      *      locked, way, flags);*/
1505 
1506     switch(flush & 0x3){
1507         case L2CACHE_OPTIONS_FLUSH_NONE:
1508             break;
1509         case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1510             l2cache_reg_flushway(tag, way,
1511                     flags | L2C_FLUSHSI_FMODE_WAY_UPDATE);
1512             break;
1513         case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1514             l2cache_reg_flushway(tag, way, flags | L2C_FLUSHSI_FMODE_WAY_WB);
1515             break;
1516         case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1517         default:
1518             l2cache_reg_flushway(tag, way,
1519                     flags | L2C_FLUSHSI_FMODE_WAY_UPDATE_WB_ALL);
1520             break;
1521     }
1522 
1523     /* Reenable L2C if required */
1524     switch(enable){
1525         case L2CACHE_OPTIONS_ENABLE:
1526             l2cache_reg_ctrl_enable();
1527             break;
1528         case L2CACHE_OPTIONS_DISABLE:
1529             break;
1530         case L2CACHE_OPTIONS_NONE:
1531         default:
1532             if (enabled) {
1533                 l2cache_reg_ctrl_enable();
1534             }
1535             break;
1536     }
1537 
1538     if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1539         l2cache_flushwait();
1540     }
1541 
1542     DBG("Way[%d] locked with Tag 0x%08x\n", way, (unsigned int) tag);
1543 
1544     return L2CACHE_ERR_OK;
1545 }
1546 
1547 /* Unlock L2CACHE waw:
1548  */
1549 int l2cache_unlock()
1550 {
1551     struct l2cache_priv * priv = l2cachepriv;
1552 
1553     if (priv == NULL){
1554         DBG("L2CACHE not initialized.\n");
1555         return L2CACHE_ERR_NOINIT;
1556     }
1557 
1558     /* Set number of locked ways to 0*/
1559     l2cache_reg_ctrl_locked_set(0);
1560 
1561     DBG("L2CACHE ways unlocked\n");
1562 
1563     return L2CACHE_ERR_OK;
1564 }
1565 
1566 /* Setup L2CACHE:
1567  * Parameters:
1568  * -options: Can be:
1569  */
1570 int l2cache_mtrr_enable(int index, uint32_t addr, uint32_t mask, int options,
1571         int flush)
1572 {
1573     struct l2cache_priv * priv = l2cachepriv;
1574     int enabled;
1575     int flags;
1576     int ret;
1577 
1578     if (priv == NULL){
1579         DBG("L2CACHE not initialized.\n");
1580         return L2CACHE_ERR_NOINIT;
1581     }
1582 
1583     if (index < 0){
1584         DBG("Wrong index\n");
1585         return L2CACHE_ERR_EINVAL;
1586     }
1587 
1588     if (index >= priv->mtrr){
1589         DBG("Not enough MTRR registers\n");
1590         return L2CACHE_ERR_TOOMANY;
1591     }
1592 
1593     /* Check input parameters */
1594     if ((addr & 0x0003ffff) || (mask & 0x0003ffff)){
1595         DBG("Only using bits 31:18 of Addr/Mask\n");
1596         return L2CACHE_ERR_EINVAL;
1597     }
1598 
1599     /* Check L2C status */
1600     enabled = l2cache_ctrl_status();
1601 
1602     /* Disable L2C */
1603     ret = l2cache_disable(flush);
1604     if (ret < 0){
1605         return ret;
1606     }
1607 
1608     /* Decode options */
1609     flags = 0 |
1610         (options & L2CACHE_OPTIONS_MTRR_ACCESS_WRITETHROUGH?
1611             L2C_MTRR_WRITETHROUGH   :
1612             L2C_MTRR_UNCACHED)      |
1613         (options & L2CACHE_OPTIONS_MTRR_WRITEPROT_ENABLE?
1614             L2C_MTRR_WRITEPROT_ENABLE   :
1615             L2C_MTRR_WRITEPROT_DISABLE) |
1616         L2C_MTRR_ACCESSCONTROL_ENABLE;
1617 
1618     /* Configure mtrr */
1619     l2cache_reg_mtrr_set(index, addr, mask, flags);
1620 
1621     /* Enable cache again (if needed) */
1622     if (enabled){
1623         l2cache_reg_ctrl_enable();
1624     }
1625 
1626     DBG("MTRR[%d] succesfully configured for 0x%08x (mask 0x%08x), "
1627             "access=%s, wprot=%s\n",
1628         index, (unsigned int) addr, (unsigned int) mask,
1629         (options & L2CACHE_OPTIONS_MTRR_ACCESS_WRITETHROUGH?
1630                 "WRITETHROUGH":"UNCACHED"),
1631         (options & L2CACHE_OPTIONS_MTRR_WRITEPROT_ENABLE? "ENABLE":"DISABLE")
1632         );
1633 
1634     return L2CACHE_ERR_OK;
1635 }
1636 
1637 /* Setup L2CACHE:
1638  * Parameters:
1639  * -options: Can be:
1640  */
1641 int l2cache_mtrr_disable(int index)
1642 {
1643     struct l2cache_priv * priv = l2cachepriv;
1644 
1645     if (priv == NULL){
1646         DBG("L2CACHE not initialized.\n");
1647         return L2CACHE_ERR_NOINIT;
1648     }
1649 
1650     if (index < 0){
1651         DBG("Wrong index\n");
1652         return L2CACHE_ERR_EINVAL;
1653     }
1654 
1655     if (index >= priv->mtrr){
1656         DBG("Not enough MTRR registers\n");
1657         return L2CACHE_ERR_TOOMANY;
1658     }
1659 
1660     /* Configure mtrr */
1661     l2cache_reg_mtrr_set(index, 0, 0, L2C_MTRR_ACCESSCONTROL_DISABLE);
1662 
1663     DBG("MTRR[%d] disabled\n", index);
1664 
1665     return L2CACHE_ERR_OK;
1666 }
1667 
1668 /* Print L2CACHE status
1669  * DEBUG function
1670  */
1671 int l2cache_print(void)
1672 {
1673     struct l2cache_priv * priv = l2cachepriv;
1674 
1675     if (priv == NULL){
1676         DBG("L2CACHE not initialized.\n");
1677         return L2CACHE_ERR_NOINIT;
1678     }
1679 
1680     #ifdef DEBUG
1681     int status = l2cache_status();
1682     if (status < 0){
1683         return status;
1684     }
1685     printf("L2cache: Ways:%d. Waysize:%d, Linesize:%d, Lines:%d\n"
1686            "         MTRR:%d, FT:%s, Locked:%d, Split:%s\n"
1687            "         REPL:%s, WP:%s, EDAC:%s, Enabled:%s\n"
1688            "         Scrub:%s, S-Delay:%d\n",
1689         priv->ways,
1690         priv->waysize,
1691         priv->linesize,
1692         (priv->index * priv->ways),
1693         priv->mtrr,
1694         (priv->ft_support? "Available":"N/A"),
1695         L2CACHE_LOCKED_WAYS(status),
1696         (priv->split_support? (L2CACHE_SPLIT_ENABLED(status)?
1697                                "Enabled":"Disabled"):"N/A"),
1698         repl_names[L2CACHE_REPL(status)],
1699         (L2CACHE_WRITETHROUGH(status)? "Write-through":"Write-back"),
1700         (L2CACHE_EDAC_ENABLED(status)? "Enabled":"Disabled"),
1701         (L2CACHE_ENABLED(status)? "Yes":"No"),
1702         (L2CACHE_SCRUB_ENABLED(status)? "Enabled":"Disabled"),
1703         L2CACHE_SCRUB_DELAY(status)
1704     );
1705     if (l2cache_ctrl_status()){
1706         printf("L2cache enabled.\n");
1707     }else{
1708         printf("L2cache disabled.\n");
1709     }
1710     #endif
1711     return L2CACHE_ERR_OK;
1712 }
1713 
1714 int l2cache_split_enable(void)
1715 {
1716     struct l2cache_priv * priv = l2cachepriv;
1717 
1718     if (priv == NULL){
1719         DBG("L2CACHE not initialized.\n");
1720         return L2CACHE_ERR_NOINIT;
1721     }
1722 
1723     if (!priv->split_support){
1724         DBG("L2CACHE does not have split support.\n");
1725         return L2CACHE_ERR_ERROR;
1726     }
1727 
1728     l2cache_reg_accctrl_split_enable();
1729     DBG("L2CACHE split is now enabled\n");
1730 
1731     return L2CACHE_ERR_OK;
1732 }
1733 
1734 int l2cache_split_disable(void)
1735 {
1736     struct l2cache_priv * priv = l2cachepriv;
1737 
1738     if (priv == NULL){
1739         DBG("L2CACHE not initialized.\n");
1740         return L2CACHE_ERR_NOINIT;
1741     }
1742 
1743     if (!priv->split_support){
1744         DBG("L2CACHE does not have split support.\n");
1745         return L2CACHE_ERR_ERROR;
1746     }
1747 
1748     l2cache_reg_accctrl_split_disable();
1749     DBG("L2CACHE split is now disabled\n");
1750 
1751     return L2CACHE_ERR_OK;
1752 }
1753 
1754 int l2cache_edac_enable(int flush)
1755 {
1756     struct l2cache_priv * priv = l2cachepriv;
1757     int enabled;
1758     int ret;
1759 
1760     if (priv == NULL){
1761         DBG("L2CACHE not initialized.\n");
1762         return L2CACHE_ERR_NOINIT;
1763     }
1764 
1765     if (!priv->ft_support){
1766         DBG("L2CACHE does not have EDAC support.\n");
1767         return L2CACHE_ERR_ERROR;
1768     }
1769 
1770     /* Check that L2C is enabled */
1771     enabled = l2cache_ctrl_status();
1772 
1773     /* Disable&Flush L2C */
1774     ret = l2cache_disable(flush);
1775     if (ret < 0){
1776         return ret;
1777     }
1778 
1779     /* Clear error register */
1780     l2cache_reg_error_reset();
1781 
1782     /* Enable EDAC */
1783     l2cache_reg_ctrl_edac_set(1);
1784 
1785     /* Enable cache again */
1786     if (enabled){
1787         l2cache_reg_ctrl_enable();
1788     }
1789 
1790     DBG("L2CACHE EDAC is now enabled\n");
1791 
1792     return L2CACHE_ERR_OK;
1793 }
1794 
1795 int l2cache_edac_disable(int flush)
1796 {
1797     struct l2cache_priv * priv = l2cachepriv;
1798     int enabled;
1799     int ret;
1800 
1801     if (priv == NULL){
1802         DBG("L2CACHE not initialized.\n");
1803         return L2CACHE_ERR_NOINIT;
1804     }
1805 
1806     if (!priv->ft_support){
1807         DBG("L2CACHE does not have EDAC support.\n");
1808         return L2CACHE_ERR_ERROR;
1809     }
1810 
1811     /* Check that L2C is enabled */
1812     enabled = l2cache_ctrl_status();
1813 
1814     /* Disable&Flush L2C */
1815     ret = l2cache_disable(flush);
1816     if (ret < 0){
1817         return ret;
1818     }
1819 
1820     /* Disable EDAC */
1821     l2cache_reg_ctrl_edac_set(0);
1822 
1823     /* Clear error register */
1824     l2cache_reg_error_reset();
1825 
1826     /* Enable cache again */
1827     if (enabled){
1828         l2cache_reg_ctrl_enable();
1829     }
1830 
1831     DBG("L2CACHE EDAC is now disabled\n");
1832 
1833     return L2CACHE_ERR_OK;
1834 }
1835 
1836 int l2cache_scrub_enable(int delay)
1837 {
1838     struct l2cache_priv * priv = l2cachepriv;
1839 
1840     if (priv == NULL){
1841         DBG("L2CACHE not initialized.\n");
1842         return L2CACHE_ERR_NOINIT;
1843     }
1844 
1845     if (!priv->ft_support){
1846         DBG("L2CACHE does not have EDAC support.\n");
1847         return L2CACHE_ERR_ERROR;
1848     }
1849 
1850     /* Enable Scrub */
1851     l2cache_reg_scrub_enable(delay);
1852 
1853     DBG("L2CACHE Scrub is now enabled\n");
1854 
1855     return L2CACHE_ERR_OK;
1856 }
1857 
1858 int l2cache_scrub_disable(void)
1859 {
1860     struct l2cache_priv * priv = l2cachepriv;
1861 
1862     if (priv == NULL){
1863         DBG("L2CACHE not initialized.\n");
1864         return L2CACHE_ERR_NOINIT;
1865     }
1866 
1867     if (!priv->ft_support){
1868         DBG("L2CACHE does not have EDAC support.\n");
1869         return L2CACHE_ERR_ERROR;
1870     }
1871 
1872     /* Disable Scrub */
1873     l2cache_reg_scrub_disable();
1874 
1875     DBG("L2CACHE Scrub is now disabled\n");
1876 
1877     return L2CACHE_ERR_OK;
1878 }
1879 
1880 int l2cache_scrub_line(int way, int index)
1881 {
1882     struct l2cache_priv * priv = l2cachepriv;
1883     unsigned int scrub;
1884 
1885     if (priv == NULL){
1886         DBG("L2CACHE not initialized.\n");
1887         return L2CACHE_ERR_NOINIT;
1888     }
1889 
1890     if (!priv->ft_support){
1891         DBG("L2CACHE does not have EDAC support.\n");
1892         return L2CACHE_ERR_ERROR;
1893     }
1894 
1895     if ((index < 0) || (index >= priv->index)){
1896         DBG("L2CACHE only has %d lines.\n", priv->index);
1897         return L2CACHE_ERR_EINVAL;
1898     }
1899 
1900     if ((way < 0) || (way >= priv->ways)){
1901         DBG("L2CACHE only has %d ways.\n", priv->ways);
1902         return L2CACHE_ERR_EINVAL;
1903     }
1904 
1905     /* Check pending bit */
1906     scrub = l2cache_reg_scrub();
1907     if ( (scrub & L2C_SCRUB_PEN) || (scrub & L2C_SCRUB_EN) ){
1908         DBG("L2CACHE already scrubbing.\n");
1909         return L2CACHE_ERR_ERROR;
1910     }
1911 
1912     /* Scrub line */
1913     l2cache_reg_scrub_line(way, index);
1914 
1915     DBG("L2CACHE Scrub line [%d,%d]\n",way,index);
1916 
1917     return L2CACHE_ERR_OK;
1918 }
1919 
1920 int l2cache_writethrough(int flush)
1921 {
1922     struct l2cache_priv * priv = l2cachepriv;
1923     int enabled;
1924     int ret;
1925 
1926     if (priv == NULL){
1927         DBG("L2CACHE not initialized.\n");
1928         return L2CACHE_ERR_NOINIT;
1929     }
1930 
1931     /* Check that L2C is enabled */
1932     enabled = l2cache_ctrl_status();
1933 
1934     /* Disable&Flush L2C */
1935     ret = l2cache_disable(flush);
1936     if (ret < 0){
1937         return ret;
1938     }
1939 
1940     /* Configure writethrough */
1941     l2cache_reg_ctrl_writep(1);
1942 
1943     /* Enable cache again */
1944     if (enabled){
1945         l2cache_reg_ctrl_enable();
1946     }
1947 
1948     DBG("L2CACHE now is writethrough\n");
1949 
1950     return L2CACHE_ERR_OK;
1951 }
1952 
1953 int l2cache_writeback(int flush)
1954 {
1955     struct l2cache_priv * priv = l2cachepriv;
1956     int enabled;
1957     int ret;
1958 
1959     if (priv == NULL){
1960         DBG("L2CACHE not initialized.\n");
1961         return L2CACHE_ERR_NOINIT;
1962     }
1963 
1964     /* Check that L2C is enabled */
1965     enabled = l2cache_ctrl_status();
1966 
1967     /* Disable&Flush L2C */
1968     ret = l2cache_disable(flush);
1969     if (ret < 0){
1970         return ret;
1971     }
1972 
1973     /* Configure writeback */
1974     l2cache_reg_ctrl_writep(0);
1975 
1976     /* Enable cache again */
1977     if (enabled){
1978         l2cache_reg_ctrl_enable();
1979     }
1980 
1981     DBG("L2CACHE now is writeback\n");
1982 
1983     return L2CACHE_ERR_OK;
1984 }
1985 
1986 int l2cache_replacement(int options, int flush)
1987 {
1988     struct l2cache_priv * priv = l2cachepriv;
1989     int enabled;
1990     int ret;
1991     int way;
1992 
1993     if (priv == NULL){
1994         DBG("L2CACHE not initialized.\n");
1995         return L2CACHE_ERR_NOINIT;
1996     }
1997 
1998     /* Check that L2C is enabled */
1999     enabled = l2cache_ctrl_status();
2000 
2001     /* Disable&Flush L2C */
2002     ret = l2cache_disable(flush);
2003     if (ret < 0){
2004         return ret;
2005     }
2006 
2007     if ( (options & 0x3) == L2CACHE_OPTIONS_REPL_MASTERIDX_IDX){
2008         /* Set iway */
2009         way = (options >> 2) & 0x3;
2010         l2cache_reg_ctrl_iway(way);
2011     }
2012 
2013     /* Configure writeback */
2014     l2cache_reg_ctrl_repl(options & 0x3);
2015 
2016     /* Enable cache again */
2017     if (enabled){
2018         l2cache_reg_ctrl_enable();
2019     }
2020 
2021     DBG("L2CACHE replacement set to %d\n", (options & 0x3));
2022 
2023     return L2CACHE_ERR_OK;
2024 
2025 }
2026 
2027 int l2cache_isr_register(l2cache_isr_t isr, void * arg, int options)
2028 {
2029     struct l2cache_priv *priv = l2cachepriv;
2030     unsigned int mask;
2031 
2032     if (priv == NULL){
2033         DBG("L2CACHE not initialized.\n");
2034         return L2CACHE_ERR_NOINIT;
2035     }
2036 
2037     if (isr == NULL){
2038         DBG("L2CACHE wrong isr.\n");
2039         return L2CACHE_ERR_EINVAL;
2040     }
2041 
2042     /* Get mask */
2043     mask = 0 |
2044         ((options & L2CACHE_INTERRUPT_BACKENDERROR)? L2C_ERROR_IRQM_BCKEND:0) |
2045         ((options & L2CACHE_INTERRUPT_WPROTHIT)? L2C_ERROR_IRQM_WPROT:0) |
2046         ((options & L2CACHE_INTERRUPT_CORRERROR)? L2C_ERROR_IRQM_CORR:0) |
2047         ((options & L2CACHE_INTERRUPT_UNCORRERROR)? L2C_ERROR_IRQM_UNCORR:0);
2048 
2049     /* Clear previous interrupts and mask them*/
2050     l2cache_reg_error_reset();
2051     l2cache_reg_error_irqmask(0);
2052 
2053     /* First time registering an ISR */
2054     if (priv->isr == NULL){
2055         /* Install and Enable L2CACHE interrupt handler */
2056         drvmgr_interrupt_register(priv->dev, 0, priv->devname, l2cache_isr,
2057                 priv);
2058     }
2059 
2060     /* Install user ISR */
2061     priv->isr=isr;
2062     priv->isr_arg=arg;
2063 
2064     /* Now it is safe to unmask interrupts */
2065     l2cache_reg_error_irqmask(mask);
2066 
2067     return L2CACHE_ERR_OK;
2068 }
2069 
2070 int l2cache_isr_unregister(void)
2071 {
2072     struct l2cache_priv *priv = l2cachepriv;
2073 
2074     if (priv == NULL){
2075         DBG("L2CACHE not initialized.\n");
2076         return L2CACHE_ERR_NOINIT;
2077     }
2078 
2079     if (priv->isr == NULL){
2080         DBG("L2CACHE wrong isr.\n");
2081         return L2CACHE_ERR_EINVAL;
2082     }
2083 
2084     /* Clear previous interrupts and mask them*/
2085     l2cache_reg_error_reset();
2086     l2cache_reg_error_irqmask(0);
2087 
2088     /* Uninstall and disable L2CACHE interrupt handler */
2089     drvmgr_interrupt_unregister(priv->dev, 0, l2cache_isr, priv);
2090 
2091     /* Uninstall user ISR */
2092     priv->isr=NULL;
2093     priv->isr_arg=NULL;
2094 
2095     return L2CACHE_ERR_OK;
2096 }
2097 
2098 int l2cache_interrupt_unmask(int options)
2099 {
2100     struct l2cache_priv *priv = l2cachepriv;
2101     unsigned int mask, irq;
2102 
2103     if (priv == NULL){
2104         DBG("L2CACHE not initialized.\n");
2105         return L2CACHE_ERR_NOINIT;
2106     }
2107 
2108     if (priv->isr == NULL){
2109         DBG("L2CACHE wrong isr.\n");
2110         return L2CACHE_ERR_EINVAL;
2111     }
2112 
2113     /* Unmask interrupts in  L2CACHE */
2114     mask = 0 |
2115         ((options & L2CACHE_INTERRUPT_BACKENDERROR)? L2C_ERROR_IRQM_BCKEND:0) |
2116         ((options & L2CACHE_INTERRUPT_WPROTHIT)? L2C_ERROR_IRQM_WPROT:0) |
2117         ((options & L2CACHE_INTERRUPT_CORRERROR)? L2C_ERROR_IRQM_CORR:0) |
2118         ((options & L2CACHE_INTERRUPT_UNCORRERROR)? L2C_ERROR_IRQM_UNCORR:0);
2119 
2120     /* Clear previous interrupts*/
2121     l2cache_reg_error_reset();
2122 
2123     /* Get previous mask */
2124     irq = ((l2cache_reg_error() & L2C_ERROR_IRQM) >> L2C_ERROR_IRQM_BIT);
2125 
2126     /* Set new mask */
2127     l2cache_reg_error_irqmask(irq | mask);
2128 
2129     return L2CACHE_ERR_OK;
2130 }
2131 
2132 int l2cache_interrupt_mask(int options)
2133 {
2134     struct l2cache_priv *priv = l2cachepriv;
2135     unsigned int mask, irq;
2136 
2137     if (priv == NULL){
2138         DBG("L2CACHE not initialized.\n");
2139         return L2CACHE_ERR_NOINIT;
2140     }
2141 
2142     /* Mask interrupts in  L2CACHE */
2143     mask = 0 |
2144         ((options & L2CACHE_INTERRUPT_BACKENDERROR)? L2C_ERROR_IRQM_BCKEND:0) |
2145         ((options & L2CACHE_INTERRUPT_WPROTHIT)? L2C_ERROR_IRQM_WPROT:0) |
2146         ((options & L2CACHE_INTERRUPT_CORRERROR)? L2C_ERROR_IRQM_CORR:0) |
2147         ((options & L2CACHE_INTERRUPT_UNCORRERROR)? L2C_ERROR_IRQM_UNCORR:0);
2148 
2149     /* Clear previous interrupts */
2150     l2cache_reg_error_reset();
2151 
2152     /* Get previous mask */
2153     irq = ((l2cache_reg_error() & L2C_ERROR_IRQM) >> L2C_ERROR_IRQM_BIT);
2154 
2155     /* Set new mask */
2156     l2cache_reg_error_irqmask(irq & ~(mask));
2157 
2158     return L2CACHE_ERR_OK;
2159 }
2160 
2161 int l2cache_error_status(uint32_t * addr, uint32_t * status)
2162 {
2163     struct l2cache_priv *priv = l2cachepriv;
2164     unsigned int sts;
2165     unsigned int erraddr;
2166 
2167     if (priv == NULL){
2168         DBG("L2CACHE not initialized.\n");
2169         return L2CACHE_ERR_NOINIT;
2170     }
2171 
2172     /* Get error register */
2173     sts = l2cache_reg_error();
2174     erraddr = l2cache_reg_error_addr();
2175 
2176     /* Check if an error occurred */
2177     if (sts & L2C_ERROR_VALID){
2178         /* Reset error register */
2179         l2cache_reg_error_reset();
2180 
2181         /* Update user variables if needed */
2182         if (addr != NULL){
2183             *addr = (erraddr & ~(0x1f));
2184         }
2185 
2186         if(status != NULL){
2187             *status = sts;
2188         }
2189 
2190         /* Return status */
2191         if (sts & L2C_ERROR_MULTI){
2192             return L2CACHE_STATUS_MULTIPLEERRORS;
2193         }else{
2194             return L2CACHE_STATUS_NEWERROR;
2195         }
2196     }else{
2197         /* Return status */
2198         return L2CACHE_STATUS_NOERROR;
2199     }
2200 }