162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * pgtsrmmu.h:  SRMMU page table defines and code.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef _SPARC_PGTSRMMU_H
962306a36Sopenharmony_ci#define _SPARC_PGTSRMMU_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <asm/page.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#ifdef __ASSEMBLY__
1462306a36Sopenharmony_ci#include <asm/thread_info.h>	/* TI_UWINMASK for WINDOW_FLUSH */
1562306a36Sopenharmony_ci#endif
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/* Number of contexts is implementation-dependent; 64k is the most we support */
1862306a36Sopenharmony_ci#define SRMMU_MAX_CONTEXTS	65536
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define SRMMU_PTE_TABLE_SIZE		(PTRS_PER_PTE*4)
2162306a36Sopenharmony_ci#define SRMMU_PMD_TABLE_SIZE		(PTRS_PER_PMD*4)
2262306a36Sopenharmony_ci#define SRMMU_PGD_TABLE_SIZE		(PTRS_PER_PGD*4)
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci/* Definition of the values in the ET field of PTD's and PTE's */
2562306a36Sopenharmony_ci#define SRMMU_ET_MASK         0x3
2662306a36Sopenharmony_ci#define SRMMU_ET_INVALID      0x0
2762306a36Sopenharmony_ci#define SRMMU_ET_PTD          0x1
2862306a36Sopenharmony_ci#define SRMMU_ET_PTE          0x2
2962306a36Sopenharmony_ci#define SRMMU_ET_REPTE        0x3 /* AIEEE, SuperSparc II reverse endian page! */
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/* Physical page extraction from PTP's and PTE's. */
3262306a36Sopenharmony_ci#define SRMMU_CTX_PMASK    0xfffffff0
3362306a36Sopenharmony_ci#define SRMMU_PTD_PMASK    0xfffffff0
3462306a36Sopenharmony_ci#define SRMMU_PTE_PMASK    0xffffff00
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/* The pte non-page bits.  Some notes:
3762306a36Sopenharmony_ci * 1) cache, dirty, valid, and ref are frobbable
3862306a36Sopenharmony_ci *    for both supervisor and user pages.
3962306a36Sopenharmony_ci * 2) exec and write will only give the desired effect
4062306a36Sopenharmony_ci *    on user pages
4162306a36Sopenharmony_ci * 3) use priv and priv_readonly for changing the
4262306a36Sopenharmony_ci *    characteristics of supervisor ptes
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_ci#define SRMMU_CACHE        0x80
4562306a36Sopenharmony_ci#define SRMMU_DIRTY        0x40
4662306a36Sopenharmony_ci#define SRMMU_REF          0x20
4762306a36Sopenharmony_ci#define SRMMU_NOREAD       0x10
4862306a36Sopenharmony_ci#define SRMMU_EXEC         0x08
4962306a36Sopenharmony_ci#define SRMMU_WRITE        0x04
5062306a36Sopenharmony_ci#define SRMMU_VALID        0x02 /* SRMMU_ET_PTE */
5162306a36Sopenharmony_ci#define SRMMU_PRIV         0x1c
5262306a36Sopenharmony_ci#define SRMMU_PRIV_RDONLY  0x18
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#define SRMMU_CHG_MASK    (0xffffff00 | SRMMU_REF | SRMMU_DIRTY)
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/* SRMMU swap entry encoding */
5762306a36Sopenharmony_ci#define SRMMU_SWP_TYPE_MASK	0x1f
5862306a36Sopenharmony_ci#define SRMMU_SWP_TYPE_SHIFT	7
5962306a36Sopenharmony_ci#define SRMMU_SWP_OFF_MASK	0xfffff
6062306a36Sopenharmony_ci#define SRMMU_SWP_OFF_SHIFT	(SRMMU_SWP_TYPE_SHIFT + 5)
6162306a36Sopenharmony_ci/* We borrow bit 6 to store the exclusive marker in swap PTEs. */
6262306a36Sopenharmony_ci#define SRMMU_SWP_EXCLUSIVE	SRMMU_DIRTY
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/* Some day I will implement true fine grained access bits for
6562306a36Sopenharmony_ci * user pages because the SRMMU gives us the capabilities to
6662306a36Sopenharmony_ci * enforce all the protection levels that vma's can have.
6762306a36Sopenharmony_ci * XXX But for now...
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_ci#define SRMMU_PAGE_NONE    __pgprot(SRMMU_CACHE | \
7062306a36Sopenharmony_ci				    SRMMU_PRIV | SRMMU_REF)
7162306a36Sopenharmony_ci#define SRMMU_PAGE_SHARED  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
7262306a36Sopenharmony_ci				    SRMMU_EXEC | SRMMU_WRITE | SRMMU_REF)
7362306a36Sopenharmony_ci#define SRMMU_PAGE_COPY    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
7462306a36Sopenharmony_ci				    SRMMU_EXEC | SRMMU_REF)
7562306a36Sopenharmony_ci#define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
7662306a36Sopenharmony_ci				    SRMMU_EXEC | SRMMU_REF)
7762306a36Sopenharmony_ci#define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
7862306a36Sopenharmony_ci				    SRMMU_DIRTY | SRMMU_REF)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/* SRMMU Register addresses in ASI 0x4.  These are valid for all
8162306a36Sopenharmony_ci * current SRMMU implementations that exist.
8262306a36Sopenharmony_ci */
8362306a36Sopenharmony_ci#define SRMMU_CTRL_REG           0x00000000
8462306a36Sopenharmony_ci#define SRMMU_CTXTBL_PTR         0x00000100
8562306a36Sopenharmony_ci#define SRMMU_CTX_REG            0x00000200
8662306a36Sopenharmony_ci#define SRMMU_FAULT_STATUS       0x00000300
8762306a36Sopenharmony_ci#define SRMMU_FAULT_ADDR         0x00000400
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#define WINDOW_FLUSH(tmp1, tmp2)					\
9062306a36Sopenharmony_ci	mov	0, tmp1;						\
9162306a36Sopenharmony_ci98:	ld	[%g6 + TI_UWINMASK], tmp2;				\
9262306a36Sopenharmony_ci	orcc	%g0, tmp2, %g0;						\
9362306a36Sopenharmony_ci	add	tmp1, 1, tmp1;						\
9462306a36Sopenharmony_ci	bne	98b;							\
9562306a36Sopenharmony_ci	 save	%sp, -64, %sp;						\
9662306a36Sopenharmony_ci99:	subcc	tmp1, 1, tmp1;						\
9762306a36Sopenharmony_ci	bne	99b;							\
9862306a36Sopenharmony_ci	 restore %g0, %g0, %g0;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci#ifndef __ASSEMBLY__
10162306a36Sopenharmony_ciextern unsigned long last_valid_pfn;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/* This makes sense. Honest it does - Anton */
10462306a36Sopenharmony_ci/* XXX Yes but it's ugly as sin.  FIXME. -KMW */
10562306a36Sopenharmony_ciextern void *srmmu_nocache_pool;
10662306a36Sopenharmony_ci#define __nocache_pa(VADDR) (((unsigned long)VADDR) - SRMMU_NOCACHE_VADDR + __pa((unsigned long)srmmu_nocache_pool))
10762306a36Sopenharmony_ci#define __nocache_va(PADDR) (__va((unsigned long)PADDR) - (unsigned long)srmmu_nocache_pool + SRMMU_NOCACHE_VADDR)
10862306a36Sopenharmony_ci#define __nocache_fix(VADDR) ((__typeof__(VADDR))__va(__nocache_pa(VADDR)))
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/* Accessing the MMU control register. */
11162306a36Sopenharmony_ciunsigned int srmmu_get_mmureg(void);
11262306a36Sopenharmony_civoid srmmu_set_mmureg(unsigned long regval);
11362306a36Sopenharmony_civoid srmmu_set_ctable_ptr(unsigned long paddr);
11462306a36Sopenharmony_civoid srmmu_set_context(int context);
11562306a36Sopenharmony_ciint srmmu_get_context(void);
11662306a36Sopenharmony_ciunsigned int srmmu_get_fstatus(void);
11762306a36Sopenharmony_ciunsigned int srmmu_get_faddr(void);
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/* This is guaranteed on all SRMMU's. */
12062306a36Sopenharmony_cistatic inline void srmmu_flush_whole_tlb(void)
12162306a36Sopenharmony_ci{
12262306a36Sopenharmony_ci	__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
12362306a36Sopenharmony_ci			     "r" (0x400),        /* Flush entire TLB!! */
12462306a36Sopenharmony_ci			     "i" (ASI_M_FLUSH_PROBE) : "memory");
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistatic inline int
12962306a36Sopenharmony_cisrmmu_get_pte (unsigned long addr)
13062306a36Sopenharmony_ci{
13162306a36Sopenharmony_ci	register unsigned long entry;
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	__asm__ __volatile__("\n\tlda [%1] %2,%0\n\t" :
13462306a36Sopenharmony_ci				"=r" (entry):
13562306a36Sopenharmony_ci				"r" ((addr & 0xfffff000) | 0x400), "i" (ASI_M_FLUSH_PROBE));
13662306a36Sopenharmony_ci	return entry;
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci#endif /* !(__ASSEMBLY__) */
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci#endif /* !(_SPARC_PGTSRMMU_H) */
142