1207537Smarius/*- 2223719Smarius * Copyright (c) 2010 - 2011 Marius Strobl <marius@FreeBSD.org> 3207537Smarius * All rights reserved. 4207537Smarius * 5207537Smarius * Redistribution and use in source and binary forms, with or without 6207537Smarius * modification, are permitted provided that the following conditions 7207537Smarius * are met: 8207537Smarius * 1. Redistributions of source code must retain the above copyright 9207537Smarius * notice, this list of conditions and the following disclaimer. 10207537Smarius * 2. Redistributions in binary form must reproduce the above copyright 11207537Smarius * notice, this list of conditions and the following disclaimer in the 12207537Smarius * documentation and/or other materials provided with the distribution. 13207537Smarius * 14207537Smarius * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15207537Smarius * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16207537Smarius * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17207537Smarius * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18207537Smarius * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19207537Smarius * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20207537Smarius * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21207537Smarius * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22207537Smarius * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23207537Smarius * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24207537Smarius * SUCH DAMAGE. 25207537Smarius */ 26207537Smarius 27207537Smarius#include <sys/cdefs.h> 28207537Smarius__FBSDID("$FreeBSD$"); 29207537Smarius 30207537Smarius#include <sys/param.h> 31207537Smarius#include <sys/systm.h> 32207537Smarius 33207537Smarius#include <machine/asi.h> 34207537Smarius#include <machine/cache.h> 35223719Smarius#include <machine/cpu.h> 36207537Smarius#include <machine/cpufunc.h> 37223719Smarius#include <machine/mcntl.h> 38223719Smarius#include <machine/lsu.h> 39223719Smarius#include <machine/tlb.h> 40223719Smarius#include <machine/tte.h> 41223719Smarius#include <machine/vmparam.h> 42207537Smarius 43223719Smarius#define ZEUS_FTLB_ENTRIES 32 44223719Smarius#define ZEUS_STLB_ENTRIES 2048 45223719Smarius 46207537Smarius/* 47223719Smarius * CPU-specific initialization for Fujitsu Zeus CPUs 48223719Smarius */ 49223719Smariusvoid 50223719Smariuszeus_init(u_int cpu_impl) 51223719Smarius{ 52223719Smarius u_long val; 53223719Smarius 54223719Smarius /* Ensure the TSB Extension Registers hold 0 as TSB_Base. */ 55223719Smarius 56223719Smarius stxa(AA_DMMU_TSB_PEXT_REG, ASI_DMMU, 0); 57223719Smarius stxa(AA_IMMU_TSB_PEXT_REG, ASI_IMMU, 0); 58223719Smarius membar(Sync); 59223719Smarius 60223719Smarius stxa(AA_DMMU_TSB_SEXT_REG, ASI_DMMU, 0); 61223719Smarius /* 62223719Smarius * NB: the secondary context was removed from the iMMU. 63223719Smarius */ 64223719Smarius membar(Sync); 65223719Smarius 66223719Smarius stxa(AA_DMMU_TSB_NEXT_REG, ASI_DMMU, 0); 67223719Smarius stxa(AA_IMMU_TSB_NEXT_REG, ASI_IMMU, 0); 68223719Smarius membar(Sync); 69223719Smarius 70223719Smarius val = ldxa(AA_MCNTL, ASI_MCNTL); 71223719Smarius /* Ensure MCNTL_JPS1_TSBP is 0. */ 72223719Smarius val &= ~MCNTL_JPS1_TSBP; 73223719Smarius /* 74223719Smarius * Ensure 4-Mbyte page entries are stored in the 1024-entry, 2-way set 75223719Smarius * associative TLB. 76223719Smarius */ 77223719Smarius val = (val & ~MCNTL_RMD_MASK) | MCNTL_RMD_1024; 78223719Smarius stxa(AA_MCNTL, ASI_MCNTL, val); 79223719Smarius} 80223719Smarius 81223719Smarius/* 82223719Smarius * Enable level 1 caches. 83223719Smarius */ 84223719Smariusvoid 85223719Smariuszeus_cache_enable(u_int cpu_impl) 86223719Smarius{ 87223719Smarius u_long lsu; 88223719Smarius 89223719Smarius lsu = ldxa(0, ASI_LSU_CTL_REG); 90223719Smarius stxa(0, ASI_LSU_CTL_REG, lsu | LSU_IC | LSU_DC); 91223719Smarius flush(KERNBASE); 92223719Smarius} 93223719Smarius 94223719Smarius/* 95207537Smarius * Flush all lines from the level 1 caches. 96207537Smarius */ 97207537Smariusvoid 98207537Smariuszeus_cache_flush(void) 99207537Smarius{ 100207537Smarius 101207537Smarius stxa_sync(0, ASI_FLUSH_L1I, 0); 102207537Smarius} 103207537Smarius 104207537Smarius/* 105207537Smarius * Flush a physical page from the data cache. Data cache consistency is 106207537Smarius * maintained by hardware. 107207537Smarius */ 108207537Smariusvoid 109207537Smariuszeus_dcache_page_inval(vm_paddr_t spa __unused) 110207537Smarius{ 111207537Smarius 112207537Smarius} 113207537Smarius 114207537Smarius/* 115207537Smarius * Flush a physical page from the intsruction cache. Instruction cache 116207537Smarius * consistency is maintained by hardware. 117207537Smarius */ 118207537Smariusvoid 119207537Smariuszeus_icache_page_inval(vm_paddr_t pa __unused) 120207537Smarius{ 121207537Smarius 122207537Smarius} 123223719Smarius 124223719Smarius/* 125223719Smarius * Flush all non-locked mappings from the TLBs. 126223719Smarius */ 127223719Smariusvoid 128223719Smariuszeus_tlb_flush_nonlocked(void) 129223719Smarius{ 130223719Smarius 131223719Smarius stxa(TLB_DEMAP_ALL, ASI_DMMU_DEMAP, 0); 132223719Smarius stxa(TLB_DEMAP_ALL, ASI_IMMU_DEMAP, 0); 133223719Smarius flush(KERNBASE); 134223719Smarius} 135223719Smarius 136223719Smarius/* 137223719Smarius * Flush all user mappings from the TLBs. 138223719Smarius */ 139223719Smariusvoid 140223719Smariuszeus_tlb_flush_user(void) 141223719Smarius{ 142223719Smarius u_long data, tag; 143223719Smarius u_int i, slot; 144223719Smarius 145223719Smarius for (i = 0; i < ZEUS_FTLB_ENTRIES; i++) { 146223719Smarius slot = TLB_DAR_SLOT(TLB_DAR_FTLB, i); 147223719Smarius data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG); 148223719Smarius tag = ldxa(slot, ASI_DTLB_TAG_READ_REG); 149223719Smarius if ((data & TD_V) != 0 && (data & TD_L) == 0 && 150223719Smarius TLB_TAR_CTX(tag) != TLB_CTX_KERNEL) 151223719Smarius stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0); 152223719Smarius data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG); 153223719Smarius tag = ldxa(slot, ASI_ITLB_TAG_READ_REG); 154223719Smarius if ((data & TD_V) != 0 && (data & TD_L) == 0 && 155223719Smarius TLB_TAR_CTX(tag) != TLB_CTX_KERNEL) 156223719Smarius stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0); 157223719Smarius } 158223719Smarius for (i = 0; i < ZEUS_STLB_ENTRIES; i++) { 159223719Smarius slot = TLB_DAR_SLOT(TLB_DAR_STLB, i); 160223719Smarius data = ldxa(slot, ASI_DTLB_DATA_ACCESS_REG); 161223719Smarius tag = ldxa(slot, ASI_DTLB_TAG_READ_REG); 162223719Smarius if ((data & TD_V) != 0 && (data & TD_L) == 0 && 163223719Smarius TLB_TAR_CTX(tag) != TLB_CTX_KERNEL) 164223719Smarius stxa_sync(slot, ASI_DTLB_DATA_ACCESS_REG, 0); 165223719Smarius data = ldxa(slot, ASI_ITLB_DATA_ACCESS_REG); 166223719Smarius tag = ldxa(slot, ASI_ITLB_TAG_READ_REG); 167223719Smarius if ((data & TD_V) != 0 && (data & TD_L) == 0 && 168223719Smarius TLB_TAR_CTX(tag) != TLB_CTX_KERNEL) 169223719Smarius stxa_sync(slot, ASI_ITLB_DATA_ACCESS_REG, 0); 170223719Smarius } 171223719Smarius} 172