mmu.h revision 224110
1234287Sdim/*- 2234287Sdim * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights 3234287Sdim * reserved. 4234287Sdim * 5234287Sdim * Redistribution and use in source and binary forms, with or without 6234287Sdim * modification, are permitted provided that the following conditions are 7234287Sdim * met: 8234287Sdim * 9234287Sdim * 1. Redistributions of source code must retain the above copyright 10234287Sdim * notice, this list of conditions and the following disclaimer. 11234287Sdim * 2. Redistributions in binary form must reproduce the above copyright 12234287Sdim * notice, this list of conditions and the following disclaimer in 13234287Sdim * the documentation and/or other materials provided with the 14234287Sdim * distribution. 15234287Sdim * 16234287Sdim * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND 17234287Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18234287Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19234287Sdim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE 20234287Sdim * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21234287Sdim * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22234287Sdim * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23234287Sdim * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24234287Sdim * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25234287Sdim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26234287Sdim * THE POSSIBILITY OF SUCH DAMAGE. 27234287Sdim * 28234287Sdim * $FreeBSD: head/sys/mips/nlm/hal/mmu.h 224110 2011-07-16 19:35:44Z jchandra $ 29234287Sdim * NETLOGIC_BSD */ 30234287Sdim 31234287Sdim#ifndef __XLP_MMU_H__ 32234287Sdim#define __XLP_MMU_H__ 33234287Sdim 34234287Sdim#include <mips/nlm/hal/cop0.h> 35234287Sdim#include <mips/nlm/hal/mips-extns.h> 36234287Sdim 37234287Sdim#define XLP_MMU_SETUP_REG 0x400 38234287Sdim#define XLP_MMU_LFSRSEED_REG 0x401 39234287Sdim#define XLP_MMU_HPW_NUM_PAGE_LVL_REG 0x410 40234287Sdim#define XLP_MMU_PGWKR_PGDBASE_REG 0x411 41234287Sdim#define XLP_MMU_PGWKR_PGDSHFT_REG 0x412 42234287Sdim#define XLP_MMU_PGWKR_PGDMASK_REG 0x413 43234287Sdim#define XLP_MMU_PGWKR_PUDSHFT_REG 0x414 44234287Sdim#define XLP_MMU_PGWKR_PUDMASK_REG 0x415 45234287Sdim#define XLP_MMU_PGWKR_PMDSHFT_REG 0x416 46234287Sdim#define XLP_MMU_PGWKR_PMDMASK_REG 0x417 47234287Sdim#define XLP_MMU_PGWKR_PTESHFT_REG 0x418 48234287Sdim#define XLP_MMU_PGWKR_PTEMASK_REG 0x419 49234287Sdim 50234287Sdimtypedef struct hw_pagewalker { 51234287Sdim int pgd_present; 52234287Sdim int pud_present; 53234287Sdim int pmd_present; 54234287Sdim int pte_present; 55234287Sdim uint64_t pgd_baseaddr; 56234287Sdim uint32_t pgd_shift; 57234287Sdim uint32_t pgd_mask; 58234287Sdim uint32_t pud_shift; 59234287Sdim uint32_t pud_mask; 60234287Sdim uint32_t pmd_shift; 61234287Sdim uint32_t pmd_mask; 62234287Sdim uint32_t pte_shift; 63234287Sdim uint32_t pte_mask; 64234287Sdim} nlm_pagewalker; 65234287Sdim 66234287Sdim/** 67234287Sdim * On power on reset, XLP comes up with 64 TLBs. 68234287Sdim * Large-variable-tlb's (ELVT) and extended TLB is disabled. 69234287Sdim * Enabling large-variable-tlb's sets up the standard 70234287Sdim * TLB size from 64 to 128 TLBs. 71234287Sdim * Enabling fixed TLB (EFT) sets up an additional 2048 tlbs. 72234287Sdim * ELVT + EFT = 128 + 2048 = 2176 TLB entries. 73234287Sdim * threads 64-entry-standard-tlb 128-entry-standard-tlb 74234287Sdim * per std-tlb-only| std+EFT | std-tlb-only| std+EFT 75234287Sdim * core | | | 76234287Sdim * -------------------------------------------------------- 77234287Sdim * 1 64 64+2048 128 128+2048 78234287Sdim * 2 64 64+1024 64 64+1024 79234287Sdim * 4 32 32+512 32 32+512 80234287Sdim * 81234287Sdim * 1(G) 64 64+2048 128 128+2048 82234287Sdim * 2(G) 128 128+2048 128 128+2048 83234287Sdim * 4(G) 128 128+2048 128 128+2048 84234287Sdim * (G) = Global mode 85 */ 86 87 88/* en = 1 to enable 89 * en = 0 to disable 90 */ 91static __inline__ void nlm_large_variable_tlb_en (int en) 92{ 93 unsigned int val; 94 95 val = nlm_read_c0_config6(); 96 val |= (en << 5); 97 nlm_write_c0_config6(val); 98 return; 99} 100 101/* en = 1 to enable 102 * en = 0 to disable 103 */ 104static __inline__ void nlm_pagewalker_en (int en) 105{ 106 unsigned int val; 107 108 val = nlm_read_c0_config6(); 109 val |= (en << 3); 110 nlm_write_c0_config6(val); 111 return; 112} 113 114/* en = 1 to enable 115 * en = 0 to disable 116 */ 117static __inline__ void nlm_extended_tlb_en (int en) 118{ 119 unsigned int val; 120 121 val = nlm_read_c0_config6(); 122 val |= (en << 2); 123 nlm_write_c0_config6(val); 124 return; 125} 126 127static __inline__ int nlm_get_num_combined_tlbs(void) 128{ 129 return (((nlm_read_c0_config6() >> 16) & 0xffff) + 1); 130} 131 132/* get number of variable TLB entries */ 133static __inline__ int nlm_get_num_vtlbs(void) 134{ 135 return (((nlm_read_c0_config6() >> 6) & 0x3ff) + 1); 136} 137 138static __inline__ void nlm_setup_extended_pagemask (int mask) 139{ 140 nlm_write_c0_config7(mask); 141} 142 143/* hashindex_en = 1 to enable hash mode, hashindex_en=0 to disable 144 * global_mode = 1 to enable global mode, global_mode=0 to disable 145 * clk_gating = 0 to enable clock gating, clk_gating=1 to disable 146 */ 147static __inline__ void nlm_mmu_setup(int hashindex_en, int global_mode, 148 int clk_gating) 149{ 150 /*uint32_t mmusetup = nlm_mfcr(XLP_MMU_SETUP_REG);*/ 151 152 uint32_t mmusetup = 0; 153 mmusetup |= (hashindex_en << 13); 154 mmusetup |= (clk_gating << 3); 155 mmusetup |= (global_mode << 0); 156 nlm_mtcr(XLP_MMU_SETUP_REG, mmusetup); 157} 158 159static __inline__ void nlm_mmu_lfsr_seed (int thr0_seed, int thr1_seed, 160 int thr2_seed, int thr3_seed) 161{ 162 uint32_t seed = nlm_mfcr(XLP_MMU_LFSRSEED_REG); 163 seed |= ((thr3_seed & 0x7f) << 23); 164 seed |= ((thr2_seed & 0x7f) << 16); 165 seed |= ((thr1_seed & 0x7f) << 7); 166 seed |= ((thr0_seed & 0x7f) << 0); 167 nlm_mtcr(XLP_MMU_LFSRSEED_REG, seed); 168} 169 170static __inline__ void nlm_pagewalker_setup (nlm_pagewalker *walker) 171{ 172 uint64_t val; 173 174 if (!walker->pgd_present) 175 return; 176 177 val = nlm_mfcr(XLP_MMU_HPW_NUM_PAGE_LVL_REG); 178 179 if (walker->pgd_present) 180 val |= (1 << 3); 181 182 if (walker->pud_present) 183 val |= (1 << 2); 184 185 if (walker->pmd_present) 186 val |= (1 << 1); 187 188 if (walker->pte_present) 189 val |= (1 << 0); 190 191 nlm_mtcr(XLP_MMU_HPW_NUM_PAGE_LVL_REG, val); 192 193 nlm_mtcr(XLP_MMU_PGWKR_PGDBASE_REG, walker->pgd_baseaddr); 194 nlm_mtcr(XLP_MMU_PGWKR_PGDSHFT_REG, walker->pgd_shift); 195 nlm_mtcr(XLP_MMU_PGWKR_PGDMASK_REG, walker->pgd_mask); 196 nlm_mtcr(XLP_MMU_PGWKR_PUDSHFT_REG, walker->pud_shift); 197 nlm_mtcr(XLP_MMU_PGWKR_PUDMASK_REG, walker->pud_mask); 198 nlm_mtcr(XLP_MMU_PGWKR_PMDSHFT_REG, walker->pmd_shift); 199 nlm_mtcr(XLP_MMU_PGWKR_PMDMASK_REG, walker->pmd_mask); 200 nlm_mtcr(XLP_MMU_PGWKR_PTESHFT_REG, walker->pte_shift); 201 nlm_mtcr(XLP_MMU_PGWKR_PTEMASK_REG, walker->pte_mask); 202} 203 204#endif 205