summaryrefslogtreecommitdiffstats
path: root/sys/mips/nlm/hal/mmu.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/mips/nlm/hal/mmu.h')
-rw-r--r--sys/mips/nlm/hal/mmu.h204
1 files changed, 204 insertions, 0 deletions
diff --git a/sys/mips/nlm/hal/mmu.h b/sys/mips/nlm/hal/mmu.h
new file mode 100644
index 0000000..a620727
--- /dev/null
+++ b/sys/mips/nlm/hal/mmu.h
@@ -0,0 +1,204 @@
+/*-
+ * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * NETLOGIC_BSD */
+
+#ifndef __XLP_MMU_H__
+#define __XLP_MMU_H__
+
+#include <mips/nlm/hal/cop0.h>
+#include <mips/nlm/hal/mips-extns.h>
+
+#define XLP_MMU_SETUP_REG 0x400
+#define XLP_MMU_LFSRSEED_REG 0x401
+#define XLP_MMU_HPW_NUM_PAGE_LVL_REG 0x410
+#define XLP_MMU_PGWKR_PGDBASE_REG 0x411
+#define XLP_MMU_PGWKR_PGDSHFT_REG 0x412
+#define XLP_MMU_PGWKR_PGDMASK_REG 0x413
+#define XLP_MMU_PGWKR_PUDSHFT_REG 0x414
+#define XLP_MMU_PGWKR_PUDMASK_REG 0x415
+#define XLP_MMU_PGWKR_PMDSHFT_REG 0x416
+#define XLP_MMU_PGWKR_PMDMASK_REG 0x417
+#define XLP_MMU_PGWKR_PTESHFT_REG 0x418
+#define XLP_MMU_PGWKR_PTEMASK_REG 0x419
+
+typedef struct hw_pagewalker {
+ int pgd_present;
+ int pud_present;
+ int pmd_present;
+ int pte_present;
+ uint64_t pgd_baseaddr;
+ uint32_t pgd_shift;
+ uint32_t pgd_mask;
+ uint32_t pud_shift;
+ uint32_t pud_mask;
+ uint32_t pmd_shift;
+ uint32_t pmd_mask;
+ uint32_t pte_shift;
+ uint32_t pte_mask;
+} nlm_pagewalker;
+
+/**
+ * On power on reset, XLP comes up with 64 TLBs.
+ * Large-variable-tlb's (ELVT) and extended TLB is disabled.
+ * Enabling large-variable-tlb's sets up the standard
+ * TLB size from 64 to 128 TLBs.
+ * Enabling fixed TLB (EFT) sets up an additional 2048 tlbs.
+ * ELVT + EFT = 128 + 2048 = 2176 TLB entries.
+ * threads 64-entry-standard-tlb 128-entry-standard-tlb
+ * per std-tlb-only| std+EFT | std-tlb-only| std+EFT
+ * core | | |
+ * --------------------------------------------------------
+ * 1 64 64+2048 128 128+2048
+ * 2 64 64+1024 64 64+1024
+ * 4 32 32+512 32 32+512
+ *
+ * 1(G) 64 64+2048 128 128+2048
+ * 2(G) 128 128+2048 128 128+2048
+ * 4(G) 128 128+2048 128 128+2048
+ * (G) = Global mode
+ */
+
+
+/* en = 1 to enable
+ * en = 0 to disable
+ */
+static __inline__ void nlm_large_variable_tlb_en (int en)
+{
+ unsigned int val;
+
+ val = nlm_read_c0_config6();
+ val |= (en << 5);
+ nlm_write_c0_config6(val);
+ return;
+}
+
+/* en = 1 to enable
+ * en = 0 to disable
+ */
+static __inline__ void nlm_pagewalker_en (int en)
+{
+ unsigned int val;
+
+ val = nlm_read_c0_config6();
+ val |= (en << 3);
+ nlm_write_c0_config6(val);
+ return;
+}
+
+/* en = 1 to enable
+ * en = 0 to disable
+ */
+static __inline__ void nlm_extended_tlb_en (int en)
+{
+ unsigned int val;
+
+ val = nlm_read_c0_config6();
+ val |= (en << 2);
+ nlm_write_c0_config6(val);
+ return;
+}
+
+static __inline__ int nlm_get_num_combined_tlbs(void)
+{
+ return (((nlm_read_c0_config6() >> 16) & 0xffff) + 1);
+}
+
+/* get number of variable TLB entries */
+static __inline__ int nlm_get_num_vtlbs(void)
+{
+ return (((nlm_read_c0_config6() >> 6) & 0x3ff) + 1);
+}
+
+static __inline__ void nlm_setup_extended_pagemask (int mask)
+{
+ nlm_write_c0_config7(mask);
+}
+
+/* hashindex_en = 1 to enable hash mode, hashindex_en=0 to disable
+ * global_mode = 1 to enable global mode, global_mode=0 to disable
+ * clk_gating = 0 to enable clock gating, clk_gating=1 to disable
+ */
+static __inline__ void nlm_mmu_setup(int hashindex_en, int global_mode,
+ int clk_gating)
+{
+ /*uint32_t mmusetup = nlm_mfcr(XLP_MMU_SETUP_REG);*/
+
+ uint32_t mmusetup = 0;
+ mmusetup |= (hashindex_en << 13);
+ mmusetup |= (clk_gating << 3);
+ mmusetup |= (global_mode << 0);
+ nlm_mtcr(XLP_MMU_SETUP_REG, mmusetup);
+}
+
+static __inline__ void nlm_mmu_lfsr_seed (int thr0_seed, int thr1_seed,
+ int thr2_seed, int thr3_seed)
+{
+ uint32_t seed = nlm_mfcr(XLP_MMU_LFSRSEED_REG);
+ seed |= ((thr3_seed & 0x7f) << 23);
+ seed |= ((thr2_seed & 0x7f) << 16);
+ seed |= ((thr1_seed & 0x7f) << 7);
+ seed |= ((thr0_seed & 0x7f) << 0);
+ nlm_mtcr(XLP_MMU_LFSRSEED_REG, seed);
+}
+
+static __inline__ void nlm_pagewalker_setup (nlm_pagewalker *walker)
+{
+ uint64_t val;
+
+ if (!walker->pgd_present)
+ return;
+
+ val = nlm_mfcr(XLP_MMU_HPW_NUM_PAGE_LVL_REG);
+
+ if (walker->pgd_present)
+ val |= (1 << 3);
+
+ if (walker->pud_present)
+ val |= (1 << 2);
+
+ if (walker->pmd_present)
+ val |= (1 << 1);
+
+ if (walker->pte_present)
+ val |= (1 << 0);
+
+ nlm_mtcr(XLP_MMU_HPW_NUM_PAGE_LVL_REG, val);
+
+ nlm_mtcr(XLP_MMU_PGWKR_PGDBASE_REG, walker->pgd_baseaddr);
+ nlm_mtcr(XLP_MMU_PGWKR_PGDSHFT_REG, walker->pgd_shift);
+ nlm_mtcr(XLP_MMU_PGWKR_PGDMASK_REG, walker->pgd_mask);
+ nlm_mtcr(XLP_MMU_PGWKR_PUDSHFT_REG, walker->pud_shift);
+ nlm_mtcr(XLP_MMU_PGWKR_PUDMASK_REG, walker->pud_mask);
+ nlm_mtcr(XLP_MMU_PGWKR_PMDSHFT_REG, walker->pmd_shift);
+ nlm_mtcr(XLP_MMU_PGWKR_PMDMASK_REG, walker->pmd_mask);
+ nlm_mtcr(XLP_MMU_PGWKR_PTESHFT_REG, walker->pte_shift);
+ nlm_mtcr(XLP_MMU_PGWKR_PTEMASK_REG, walker->pte_mask);
+}
+
+#endif
OpenPOWER on IntegriCloud