#ifndef _MIPS_CACHE_H_
#define _MIPS_CACHE_H_
#ifdef _KERNEL_OPT
#include "opt_cputype.h"
#endif
#include <sys/types.h>
struct mips_cache_ops {
void (*mco_icache_sync_all)(void);
void (*mco_icache_sync_range)(register_t, vsize_t);
void (*mco_icache_sync_range_index)(vaddr_t, vsize_t);
void (*mco_pdcache_wbinv_all)(void);
void (*mco_pdcache_wbinv_range)(register_t, vsize_t);
void (*mco_pdcache_wbinv_range_index)(vaddr_t, vsize_t);
void (*mco_pdcache_inv_range)(register_t, vsize_t);
void (*mco_pdcache_wb_range)(register_t, vsize_t);
void (*mco_intern_icache_sync_range_index)(vaddr_t, vsize_t);
void (*mco_intern_icache_sync_range)(register_t, vsize_t);
void (*mco_intern_pdcache_sync_all)(void);
void (*mco_intern_pdcache_sync_range_index)(vaddr_t, vsize_t);
void (*mco_intern_pdcache_sync_range)(register_t, vsize_t);
void (*mco_intern_pdcache_wbinv_range_index)(vaddr_t, vsize_t);
void (*mco_sdcache_wbinv_all)(void);
void (*mco_sdcache_wbinv_range)(register_t, vsize_t);
void (*mco_sdcache_wbinv_range_index)(vaddr_t, vsize_t);
void (*mco_sdcache_inv_range)(register_t, vsize_t);
void (*mco_sdcache_wb_range)(register_t, vsize_t);
void (*mco_intern_sdcache_sync_all)(void);
void (*mco_intern_sdcache_sync_range_index)(vaddr_t, vsize_t);
void (*mco_intern_sdcache_sync_range)(register_t, vsize_t);
void (*mco_intern_sdcache_wbinv_range_index)(vaddr_t, vsize_t);
};
extern struct mips_cache_ops mips_cache_ops;
struct mips_cache_info {
u_int mci_picache_size;
u_int mci_picache_line_size;
u_int mci_picache_ways;
u_int mci_picache_way_size;
u_int mci_picache_way_mask;
bool mci_picache_vivt;
u_int mci_pdcache_size;
u_int mci_pdcache_line_size;
u_int mci_pdcache_ways;
u_int mci_pdcache_way_size;
u_int mci_pdcache_way_mask;
bool mci_pdcache_write_through;
bool mci_pcache_unified;
u_int mci_sicache_size;
u_int mci_sicache_line_size;
u_int mci_sicache_ways;
u_int mci_sicache_way_size;
u_int mci_sicache_way_mask;
u_int mci_sdcache_size;
u_int mci_sdcache_line_size;
u_int mci_sdcache_ways;
u_int mci_sdcache_way_size;
u_int mci_sdcache_way_mask;
bool mci_sdcache_write_through;
bool mci_scache_unified;
u_int mci_tcache_size;
u_int mci_tcache_line_size;
u_int mci_tcache_ways;
u_int mci_tcache_way_size;
u_int mci_tcache_way_mask;
bool mci_tcache_write_through;
u_int mci_dcache_align;
u_int mci_dcache_align_mask;
u_int mci_cache_prefer_mask;
u_int mci_cache_alias_mask;
u_int mci_icache_alias_mask;
bool mci_cache_virtual_alias;
bool mci_icache_virtual_alias;
};
#if (MIPS1 + MIPS64_RMIXL + MIPS64R2_RMIXL + MIPS64_OCTEON) > 0 && \
(MIPS3 + MIPS4) == 0 \
&& !defined(_MODULE)
#define MIPS_CACHE_ALIAS_MASK 0
#define MIPS_CACHE_VIRTUAL_ALIAS false
#else
#define MIPS_CACHE_ALIAS_MASK mips_cache_info.mci_cache_alias_mask
#define MIPS_CACHE_VIRTUAL_ALIAS mips_cache_info.mci_cache_virtual_alias
#endif
#if (MIPS1 + MIPS64_RMIXL + MIPS64_OCTEON) > 0 && \
(MIPS3 + MIPS4) == 0 \
&& !defined(_MODULE)
#define MIPS_ICACHE_ALIAS_MASK 0
#define MIPS_ICACHE_VIRTUAL_ALIAS false
#else
#define MIPS_ICACHE_ALIAS_MASK mips_cache_info.mci_icache_alias_mask
#define MIPS_ICACHE_VIRTUAL_ALIAS mips_cache_info.mci_icache_virtual_alias
#endif
extern struct mips_cache_info mips_cache_info;
#define mips_cache_indexof(x) (((vaddr_t)(x)) & MIPS_CACHE_ALIAS_MASK)
#define mips_cache_badalias(x,y) (((vaddr_t)(x)^(vaddr_t)(y)) & MIPS_CACHE_ALIAS_MASK)
#define __mco_noargs(prefix, x) \
do { \
(*mips_cache_ops.mco_ ## prefix ## p ## x )(); \
if (*mips_cache_ops.mco_ ## prefix ## s ## x ) \
(*mips_cache_ops.mco_ ## prefix ## s ## x )(); \
} while (0)
#define __mco_2args(prefix, x, a, b) \
do { \
(*mips_cache_ops.mco_ ## prefix ## p ## x )((a), (b)); \
if (*mips_cache_ops.mco_ ## prefix ## s ## x ) \
(*mips_cache_ops.mco_ ## prefix ## s ## x )((a), (b)); \
} while (0)
#define mips_icache_sync_all() \
(*mips_cache_ops.mco_icache_sync_all)()
#define mips_icache_sync_range(v, s) \
(*mips_cache_ops.mco_icache_sync_range)((v), (s))
#define mips_icache_sync_range_index(v, s) \
(*mips_cache_ops.mco_icache_sync_range_index)((v), (s))
#define mips_dcache_wbinv_all() \
__mco_noargs(, dcache_wbinv_all)
#define mips_dcache_wbinv_range(v, s) \
__mco_2args(, dcache_wbinv_range, (v), (s))
#define mips_dcache_wbinv_range_index(v, s) \
__mco_2args(, dcache_wbinv_range_index, (v), (s))
#define mips_dcache_inv_range(v, s) \
__mco_2args(, dcache_inv_range, (v), (s))
#define mips_dcache_wb_range(v, s) \
__mco_2args(, dcache_wb_range, (v), (s))
#define mips_intern_dcache_sync_all() \
__mco_noargs(intern_, dcache_sync_all)
#define mips_intern_dcache_sync_range_index(v, s) \
__mco_2args(intern_, dcache_sync_range_index, (v), (s))
#define mips_intern_dcache_sync_range(v, s) \
__mco_2args(intern_, dcache_sync_range, (v), (s))
#define mips_intern_pdcache_wbinv_range_index(v, s) \
(*mips_cache_ops.mco_intern_pdcache_wbinv_range_index)((v), (s))
#define mips_intern_sdcache_wbinv_range_index(v, s) \
(*mips_cache_ops.mco_intern_sdcache_wbinv_range_index)((v), (s))
#define mips_intern_icache_sync_range(v, s) \
(*mips_cache_ops.mco_intern_icache_sync_range)((v), (s))
#define mips_intern_icache_sync_range_index(v, s) \
(*mips_cache_ops.mco_intern_icache_sync_range_index)((v), (s))
void mips_config_cache(void);
void mips_dcache_compute_align(void);
#include <mips/cache_mipsNN.h>
#endif