18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * pgtsrmmu.h:  SRMMU page table defines and code.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef _SPARC_PGTSRMMU_H
98c2ecf20Sopenharmony_ci#define _SPARC_PGTSRMMU_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <asm/page.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__
148c2ecf20Sopenharmony_ci#include <asm/thread_info.h>	/* TI_UWINMASK for WINDOW_FLUSH */
158c2ecf20Sopenharmony_ci#endif
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci/* Number of contexts is implementation-dependent; 64k is the most we support */
188c2ecf20Sopenharmony_ci#define SRMMU_MAX_CONTEXTS	65536
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#define SRMMU_PTE_TABLE_SIZE		(PTRS_PER_PTE*4)
218c2ecf20Sopenharmony_ci#define SRMMU_PMD_TABLE_SIZE		(PTRS_PER_PMD*4)
228c2ecf20Sopenharmony_ci#define SRMMU_PGD_TABLE_SIZE		(PTRS_PER_PGD*4)
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/* Definition of the values in the ET field of PTD's and PTE's */
258c2ecf20Sopenharmony_ci#define SRMMU_ET_MASK         0x3
268c2ecf20Sopenharmony_ci#define SRMMU_ET_INVALID      0x0
278c2ecf20Sopenharmony_ci#define SRMMU_ET_PTD          0x1
288c2ecf20Sopenharmony_ci#define SRMMU_ET_PTE          0x2
298c2ecf20Sopenharmony_ci#define SRMMU_ET_REPTE        0x3 /* AIEEE, SuperSparc II reverse endian page! */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/* Physical page extraction from PTP's and PTE's. */
328c2ecf20Sopenharmony_ci#define SRMMU_CTX_PMASK    0xfffffff0
338c2ecf20Sopenharmony_ci#define SRMMU_PTD_PMASK    0xfffffff0
348c2ecf20Sopenharmony_ci#define SRMMU_PTE_PMASK    0xffffff00
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* The pte non-page bits.  Some notes:
378c2ecf20Sopenharmony_ci * 1) cache, dirty, valid, and ref are frobbable
388c2ecf20Sopenharmony_ci *    for both supervisor and user pages.
398c2ecf20Sopenharmony_ci * 2) exec and write will only give the desired effect
408c2ecf20Sopenharmony_ci *    on user pages
418c2ecf20Sopenharmony_ci * 3) use priv and priv_readonly for changing the
428c2ecf20Sopenharmony_ci *    characteristics of supervisor ptes
438c2ecf20Sopenharmony_ci */
448c2ecf20Sopenharmony_ci#define SRMMU_CACHE        0x80
458c2ecf20Sopenharmony_ci#define SRMMU_DIRTY        0x40
468c2ecf20Sopenharmony_ci#define SRMMU_REF          0x20
478c2ecf20Sopenharmony_ci#define SRMMU_NOREAD       0x10
488c2ecf20Sopenharmony_ci#define SRMMU_EXEC         0x08
498c2ecf20Sopenharmony_ci#define SRMMU_WRITE        0x04
508c2ecf20Sopenharmony_ci#define SRMMU_VALID        0x02 /* SRMMU_ET_PTE */
518c2ecf20Sopenharmony_ci#define SRMMU_PRIV         0x1c
528c2ecf20Sopenharmony_ci#define SRMMU_PRIV_RDONLY  0x18
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#define SRMMU_CHG_MASK    (0xffffff00 | SRMMU_REF | SRMMU_DIRTY)
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci/* SRMMU swap entry encoding
578c2ecf20Sopenharmony_ci *
588c2ecf20Sopenharmony_ci * We use 5 bits for the type and 19 for the offset.  This gives us
598c2ecf20Sopenharmony_ci * 32 swapfiles of 4GB each.  Encoding looks like:
608c2ecf20Sopenharmony_ci *
618c2ecf20Sopenharmony_ci * oooooooooooooooooootttttRRRRRRRR
628c2ecf20Sopenharmony_ci * fedcba9876543210fedcba9876543210
638c2ecf20Sopenharmony_ci *
648c2ecf20Sopenharmony_ci * The bottom 7 bits are reserved for protection and status bits, especially
658c2ecf20Sopenharmony_ci * PRESENT.
668c2ecf20Sopenharmony_ci */
678c2ecf20Sopenharmony_ci#define SRMMU_SWP_TYPE_MASK	0x1f
688c2ecf20Sopenharmony_ci#define SRMMU_SWP_TYPE_SHIFT	7
698c2ecf20Sopenharmony_ci#define SRMMU_SWP_OFF_MASK	0xfffff
708c2ecf20Sopenharmony_ci#define SRMMU_SWP_OFF_SHIFT	(SRMMU_SWP_TYPE_SHIFT + 5)
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci/* Some day I will implement true fine grained access bits for
738c2ecf20Sopenharmony_ci * user pages because the SRMMU gives us the capabilities to
748c2ecf20Sopenharmony_ci * enforce all the protection levels that vma's can have.
758c2ecf20Sopenharmony_ci * XXX But for now...
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_ci#define SRMMU_PAGE_NONE    __pgprot(SRMMU_CACHE | \
788c2ecf20Sopenharmony_ci				    SRMMU_PRIV | SRMMU_REF)
798c2ecf20Sopenharmony_ci#define SRMMU_PAGE_SHARED  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
808c2ecf20Sopenharmony_ci				    SRMMU_EXEC | SRMMU_WRITE | SRMMU_REF)
818c2ecf20Sopenharmony_ci#define SRMMU_PAGE_COPY    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
828c2ecf20Sopenharmony_ci				    SRMMU_EXEC | SRMMU_REF)
838c2ecf20Sopenharmony_ci#define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
848c2ecf20Sopenharmony_ci				    SRMMU_EXEC | SRMMU_REF)
858c2ecf20Sopenharmony_ci#define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
868c2ecf20Sopenharmony_ci				    SRMMU_DIRTY | SRMMU_REF)
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci/* SRMMU Register addresses in ASI 0x4.  These are valid for all
898c2ecf20Sopenharmony_ci * current SRMMU implementations that exist.
908c2ecf20Sopenharmony_ci */
918c2ecf20Sopenharmony_ci#define SRMMU_CTRL_REG           0x00000000
928c2ecf20Sopenharmony_ci#define SRMMU_CTXTBL_PTR         0x00000100
938c2ecf20Sopenharmony_ci#define SRMMU_CTX_REG            0x00000200
948c2ecf20Sopenharmony_ci#define SRMMU_FAULT_STATUS       0x00000300
958c2ecf20Sopenharmony_ci#define SRMMU_FAULT_ADDR         0x00000400
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci#define WINDOW_FLUSH(tmp1, tmp2)					\
988c2ecf20Sopenharmony_ci	mov	0, tmp1;						\
998c2ecf20Sopenharmony_ci98:	ld	[%g6 + TI_UWINMASK], tmp2;				\
1008c2ecf20Sopenharmony_ci	orcc	%g0, tmp2, %g0;						\
1018c2ecf20Sopenharmony_ci	add	tmp1, 1, tmp1;						\
1028c2ecf20Sopenharmony_ci	bne	98b;							\
1038c2ecf20Sopenharmony_ci	 save	%sp, -64, %sp;						\
1048c2ecf20Sopenharmony_ci99:	subcc	tmp1, 1, tmp1;						\
1058c2ecf20Sopenharmony_ci	bne	99b;							\
1068c2ecf20Sopenharmony_ci	 restore %g0, %g0, %g0;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
1098c2ecf20Sopenharmony_ciextern unsigned long last_valid_pfn;
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci/* This makes sense. Honest it does - Anton */
1128c2ecf20Sopenharmony_ci/* XXX Yes but it's ugly as sin.  FIXME. -KMW */
1138c2ecf20Sopenharmony_ciextern void *srmmu_nocache_pool;
1148c2ecf20Sopenharmony_ci#define __nocache_pa(VADDR) (((unsigned long)VADDR) - SRMMU_NOCACHE_VADDR + __pa((unsigned long)srmmu_nocache_pool))
1158c2ecf20Sopenharmony_ci#define __nocache_va(PADDR) (__va((unsigned long)PADDR) - (unsigned long)srmmu_nocache_pool + SRMMU_NOCACHE_VADDR)
1168c2ecf20Sopenharmony_ci#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci/* Accessing the MMU control register. */
1198c2ecf20Sopenharmony_ciunsigned int srmmu_get_mmureg(void);
1208c2ecf20Sopenharmony_civoid srmmu_set_mmureg(unsigned long regval);
1218c2ecf20Sopenharmony_civoid srmmu_set_ctable_ptr(unsigned long paddr);
1228c2ecf20Sopenharmony_civoid srmmu_set_context(int context);
1238c2ecf20Sopenharmony_ciint srmmu_get_context(void);
1248c2ecf20Sopenharmony_ciunsigned int srmmu_get_fstatus(void);
1258c2ecf20Sopenharmony_ciunsigned int srmmu_get_faddr(void);
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci/* This is guaranteed on all SRMMU's. */
1288c2ecf20Sopenharmony_cistatic inline void srmmu_flush_whole_tlb(void)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
1318c2ecf20Sopenharmony_ci			     "r" (0x400),        /* Flush entire TLB!! */
1328c2ecf20Sopenharmony_ci			     "i" (ASI_M_FLUSH_PROBE) : "memory");
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistatic inline int
1378c2ecf20Sopenharmony_cisrmmu_get_pte (unsigned long addr)
1388c2ecf20Sopenharmony_ci{
1398c2ecf20Sopenharmony_ci	register unsigned long entry;
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	__asm__ __volatile__("\n\tlda [%1] %2,%0\n\t" :
1428c2ecf20Sopenharmony_ci				"=r" (entry):
1438c2ecf20Sopenharmony_ci				"r" ((addr & 0xfffff000) | 0x400), "i" (ASI_M_FLUSH_PROBE));
1448c2ecf20Sopenharmony_ci	return entry;
1458c2ecf20Sopenharmony_ci}
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci#endif /* !(__ASSEMBLY__) */
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci#endif /* !(_SPARC_PGTSRMMU_H) */
150