mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Add L2-cache writeback/flush operations. Supported 32,128-byte line-size,
else ignored. Cavium Networks also ignored as it has non-standard config registers. Obtained from: NetBSD Sponsored by: DARPA, AFRL
This commit is contained in:
parent
d455cc0410
commit
209fe5ef9a
6 changed files with 290 additions and 13 deletions
|
|
@ -67,5 +67,15 @@ void mipsNN_pdcache_wbinv_range_index_128(vm_offset_t, vm_size_t);
|
|||
void mipsNN_pdcache_inv_range_128(vm_offset_t, vm_size_t);
|
||||
void mipsNN_pdcache_wb_range_128(vm_offset_t, vm_size_t);
|
||||
#endif
|
||||
void mipsNN_sdcache_wbinv_all_32(void);
|
||||
void mipsNN_sdcache_wbinv_range_32(vm_paddr_t, vm_size_t);
|
||||
void mipsNN_sdcache_wbinv_range_index_32(vm_paddr_t, vm_size_t);
|
||||
void mipsNN_sdcache_inv_range_32(vm_paddr_t, vm_size_t);
|
||||
void mipsNN_sdcache_wb_range_32(vm_paddr_t, vm_size_t);
|
||||
void mipsNN_sdcache_wbinv_all_128(void);
|
||||
void mipsNN_sdcache_wbinv_range_128(vm_paddr_t, vm_size_t);
|
||||
void mipsNN_sdcache_wbinv_range_index_128(vm_paddr_t, vm_size_t);
|
||||
void mipsNN_sdcache_inv_range_128(vm_paddr_t, vm_size_t);
|
||||
void mipsNN_sdcache_wb_range_128(vm_paddr_t, vm_size_t);
|
||||
|
||||
#endif /* _MACHINE_CACHE_MIPSNN_H_ */
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ struct mips_cpuinfo {
|
|||
u_int8_t dc_nways;
|
||||
u_int16_t dc_nsets;
|
||||
} l1;
|
||||
struct {
|
||||
u_int32_t dc_size;
|
||||
u_int8_t dc_linesize;
|
||||
u_int8_t dc_nways;
|
||||
u_int16_t dc_nsets;
|
||||
} l2;
|
||||
};
|
||||
|
||||
extern struct mips_cpuinfo cpuinfo;
|
||||
|
|
|
|||
|
|
@ -550,6 +550,13 @@
|
|||
#define MIPS_CONFIG1_EP 0x00000002 /* EJTAG implemented */
|
||||
#define MIPS_CONFIG1_FP 0x00000001 /* FPU implemented */
|
||||
|
||||
#define MIPS_CONFIG2_SA_SHIFT 0 /* Secondary cache associativity */
|
||||
#define MIPS_CONFIG2_SA_MASK 0xf
|
||||
#define MIPS_CONFIG2_SL_SHIFT 4 /* Secondary cache line size */
|
||||
#define MIPS_CONFIG2_SL_MASK 0xf
|
||||
#define MIPS_CONFIG2_SS_SHIFT 8 /* Secondary cache sets per way */
|
||||
#define MIPS_CONFIG2_SS_MASK 0xf
|
||||
|
||||
#define MIPS_CONFIG4_MMUSIZEEXT 0x000000FF /* bits 7.. 0 MMU Size Extension */
|
||||
#define MIPS_CONFIG4_MMUEXTDEF 0x0000C000 /* bits 15.14 MMU Extension Definition */
|
||||
#define MIPS_CONFIG4_MMUEXTDEF_MMUSIZEEXT 0x00004000 /* This values denotes CONFIG4 bits */
|
||||
|
|
|
|||
|
|
@ -260,19 +260,42 @@ mips_config_cache(struct mips_cpuinfo * cpuinfo)
|
|||
panic("no pdcache_wb_range");
|
||||
}
|
||||
|
||||
/* XXXMIPS: No secondary cache handlers yet */
|
||||
#ifdef notyet
|
||||
if (mips_sdcache_size) {
|
||||
if (!mips_cache_ops.mco_sdcache_wbinv_all)
|
||||
panic("no sdcache_wbinv_all");
|
||||
if (!mips_cache_ops.mco_sdcache_wbinv_range)
|
||||
panic("no sdcache_wbinv_range");
|
||||
if (!mips_cache_ops.mco_sdcache_wbinv_range_index)
|
||||
panic("no sdcache_wbinv_range_index");
|
||||
if (!mips_cache_ops.mco_sdcache_inv_range)
|
||||
panic("no sdcache_inv_range");
|
||||
if (!mips_cache_ops.mco_sdcache_wb_range)
|
||||
panic("no sdcache_wb_range");
|
||||
/* L2 data cache */
|
||||
if (!cpuinfo->l2.dc_size) {
|
||||
/* No L2 found, ignore */
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cpuinfo->l2.dc_linesize) {
|
||||
case 32:
|
||||
mips_cache_ops.mco_sdcache_wbinv_all =
|
||||
mipsNN_sdcache_wbinv_all_32;
|
||||
mips_cache_ops.mco_sdcache_wbinv_range =
|
||||
mipsNN_sdcache_wbinv_range_32;
|
||||
mips_cache_ops.mco_sdcache_wbinv_range_index =
|
||||
mipsNN_sdcache_wbinv_range_index_32;
|
||||
mips_cache_ops.mco_sdcache_inv_range =
|
||||
mipsNN_sdcache_inv_range_32;
|
||||
mips_cache_ops.mco_sdcache_wb_range =
|
||||
mipsNN_sdcache_wb_range_32;
|
||||
break;
|
||||
case 128:
|
||||
mips_cache_ops.mco_sdcache_wbinv_all =
|
||||
mipsNN_sdcache_wbinv_all_128;
|
||||
mips_cache_ops.mco_sdcache_wbinv_range =
|
||||
mipsNN_sdcache_wbinv_range_128;
|
||||
mips_cache_ops.mco_sdcache_wbinv_range_index =
|
||||
mipsNN_sdcache_wbinv_range_index_128;
|
||||
mips_cache_ops.mco_sdcache_inv_range =
|
||||
mipsNN_sdcache_inv_range_128;
|
||||
mips_cache_ops.mco_sdcache_wb_range =
|
||||
mipsNN_sdcache_wb_range_128;
|
||||
break;
|
||||
default:
|
||||
#ifdef CACHE_DEBUG
|
||||
printf(" no sdcache ops for %d byte lines",
|
||||
cpuinfo->l2.dc_linesize);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ __FBSDID("$FreeBSD$");
|
|||
#define round_line32(x) (((x) + 31) & ~31)
|
||||
#define trunc_line32(x) ((x) & ~31)
|
||||
|
||||
#define round_line128(x) (((x) + 127) & ~127)
|
||||
#define trunc_line128(x) ((x) & ~127)
|
||||
|
||||
#if defined(CPU_NLM)
|
||||
static __inline void
|
||||
xlp_sync(void)
|
||||
|
|
@ -100,6 +103,10 @@ static int pdcache_size;
|
|||
static int pdcache_stride;
|
||||
static int pdcache_loopcount;
|
||||
static int pdcache_way_mask;
|
||||
static int sdcache_size;
|
||||
static int sdcache_stride;
|
||||
static int sdcache_loopcount;
|
||||
static int sdcache_way_mask;
|
||||
|
||||
void
|
||||
mipsNN_cache_init(struct mips_cpuinfo * cpuinfo)
|
||||
|
|
@ -142,6 +149,11 @@ mipsNN_cache_init(struct mips_cpuinfo * cpuinfo)
|
|||
pdcache_size = cpuinfo->l1.dc_size;
|
||||
pdcache_way_mask = cpuinfo->l1.dc_nways - 1;
|
||||
|
||||
sdcache_stride = cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize;
|
||||
sdcache_loopcount = cpuinfo->l2.dc_nways;
|
||||
sdcache_size = cpuinfo->l2.dc_size;
|
||||
sdcache_way_mask = cpuinfo->l2.dc_nways - 1;
|
||||
|
||||
#define CACHE_DEBUG
|
||||
#ifdef CACHE_DEBUG
|
||||
printf("Cache info:\n");
|
||||
|
|
@ -636,3 +648,195 @@ mipsNN_pdcache_wb_range_128(vm_offset_t va, vm_size_t size)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
mipsNN_sdcache_wbinv_all_32(void)
|
||||
{
|
||||
vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
|
||||
vm_offset_t eva = va + sdcache_size;
|
||||
|
||||
while (va < eva) {
|
||||
cache_r4k_op_32lines_32(va,
|
||||
CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
|
||||
va += (32 * 32);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t eva = round_line32(va + size);
|
||||
|
||||
va = trunc_line32(va);
|
||||
|
||||
while ((eva - va) >= (32 * 32)) {
|
||||
cache_r4k_op_32lines_32(va,
|
||||
CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
|
||||
va += (32 * 32);
|
||||
}
|
||||
|
||||
while (va < eva) {
|
||||
cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
|
||||
va += 32;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t eva;
|
||||
|
||||
/*
|
||||
* Since we're doing Index ops, we expect to not be able
|
||||
* to access the address we've been given. So, get the
|
||||
* bits that determine the cache index, and make a KSEG0
|
||||
* address out of them.
|
||||
*/
|
||||
va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
|
||||
|
||||
eva = round_line32(va + size);
|
||||
va = trunc_line32(va);
|
||||
|
||||
while ((eva - va) >= (32 * 32)) {
|
||||
cache_r4k_op_32lines_32(va,
|
||||
CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
|
||||
va += (32 * 32);
|
||||
}
|
||||
|
||||
while (va < eva) {
|
||||
cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
|
||||
va += 32;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t eva = round_line32(va + size);
|
||||
|
||||
va = trunc_line32(va);
|
||||
|
||||
while ((eva - va) >= (32 * 32)) {
|
||||
cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
|
||||
va += (32 * 32);
|
||||
}
|
||||
|
||||
while (va < eva) {
|
||||
cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
|
||||
va += 32;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t eva = round_line32(va + size);
|
||||
|
||||
va = trunc_line32(va);
|
||||
|
||||
while ((eva - va) >= (32 * 32)) {
|
||||
cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
|
||||
va += (32 * 32);
|
||||
}
|
||||
|
||||
while (va < eva) {
|
||||
cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
|
||||
va += 32;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_wbinv_all_128(void)
|
||||
{
|
||||
vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
|
||||
vm_offset_t eva = va + sdcache_size;
|
||||
|
||||
while (va < eva) {
|
||||
cache_r4k_op_32lines_128(va,
|
||||
CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
|
||||
va += (32 * 128);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t eva = round_line128(va + size);
|
||||
|
||||
va = trunc_line128(va);
|
||||
|
||||
while ((eva - va) >= (32 * 128)) {
|
||||
cache_r4k_op_32lines_128(va,
|
||||
CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
|
||||
va += (32 * 128);
|
||||
}
|
||||
|
||||
while (va < eva) {
|
||||
cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
|
||||
va += 128;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t eva;
|
||||
|
||||
/*
|
||||
* Since we're doing Index ops, we expect to not be able
|
||||
* to access the address we've been given. So, get the
|
||||
* bits that determine the cache index, and make a KSEG0
|
||||
* address out of them.
|
||||
*/
|
||||
va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
|
||||
|
||||
eva = round_line128(va + size);
|
||||
va = trunc_line128(va);
|
||||
|
||||
while ((eva - va) >= (32 * 128)) {
|
||||
cache_r4k_op_32lines_128(va,
|
||||
CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
|
||||
va += (32 * 128);
|
||||
}
|
||||
|
||||
while (va < eva) {
|
||||
cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
|
||||
va += 128;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_inv_range_128(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t eva = round_line128(va + size);
|
||||
|
||||
va = trunc_line128(va);
|
||||
|
||||
while ((eva - va) >= (32 * 128)) {
|
||||
cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
|
||||
va += (32 * 128);
|
||||
}
|
||||
|
||||
while (va < eva) {
|
||||
cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
|
||||
va += 128;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mipsNN_sdcache_wb_range_128(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t eva = round_line128(va + size);
|
||||
|
||||
va = trunc_line128(va);
|
||||
|
||||
while ((eva - va) >= (32 * 128)) {
|
||||
cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
|
||||
va += (32 * 128);
|
||||
}
|
||||
|
||||
while (va < eva) {
|
||||
cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
|
||||
va += 128;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo)
|
|||
u_int32_t prid;
|
||||
u_int32_t cfg0;
|
||||
u_int32_t cfg1;
|
||||
u_int32_t cfg2;
|
||||
#if defined(CPU_CNMIPS)
|
||||
u_int32_t cfg4;
|
||||
#endif
|
||||
|
|
@ -186,6 +187,31 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo)
|
|||
* cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nways;
|
||||
cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize
|
||||
* cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways;
|
||||
|
||||
#ifndef CPU_CNMIPS
|
||||
/* L2 cache */
|
||||
if (!(cfg1 & MIPS_CONFIG_CM)) {
|
||||
/* We don't have valid cfg2 register */
|
||||
return;
|
||||
}
|
||||
|
||||
cfg2 = mips_rd_config2();
|
||||
|
||||
tmp = (cfg2 >> MIPS_CONFIG2_SL_SHIFT) & MIPS_CONFIG2_SL_MASK;
|
||||
if (0 < tmp && tmp <= 7)
|
||||
cpuinfo->l2.dc_linesize = 2 << tmp;
|
||||
|
||||
tmp = (cfg2 >> MIPS_CONFIG2_SS_SHIFT) & MIPS_CONFIG2_SS_MASK;
|
||||
if (0 <= tmp && tmp <= 7)
|
||||
cpuinfo->l2.dc_nsets = 64 << tmp;
|
||||
|
||||
tmp = (cfg2 >> MIPS_CONFIG2_SA_SHIFT) & MIPS_CONFIG2_SA_MASK;
|
||||
if (0 <= tmp && tmp <= 7)
|
||||
cpuinfo->l2.dc_nways = tmp + 1;
|
||||
|
||||
cpuinfo->l2.dc_size = cpuinfo->l2.dc_linesize
|
||||
* cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_nways;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -355,6 +381,7 @@ static driver_t cpu_driver = {
|
|||
static int
|
||||
cpu_probe(device_t dev)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue