cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

motorola_pgtable.h (7677B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _MOTOROLA_PGTABLE_H
      3#define _MOTOROLA_PGTABLE_H
      4
      5
      6/*
      7 * Definitions for MMU descriptors
      8 */
      9#define _PAGE_PRESENT	0x001
     10#define _PAGE_SHORT	0x002
     11#define _PAGE_RONLY	0x004
     12#define _PAGE_READWRITE	0x000
     13#define _PAGE_ACCESSED	0x008
     14#define _PAGE_DIRTY	0x010
     15#define _PAGE_SUPER	0x080	/* 68040 supervisor only */
     16#define _PAGE_GLOBAL040	0x400	/* 68040 global bit, used for kva descs */
     17#define _PAGE_NOCACHE030 0x040	/* 68030 no-cache mode */
     18#define _PAGE_NOCACHE	0x060	/* 68040 cache mode, non-serialized */
     19#define _PAGE_NOCACHE_S	0x040	/* 68040 no-cache mode, serialized */
     20#define _PAGE_CACHE040	0x020	/* 68040 cache mode, cachable, copyback */
     21#define _PAGE_CACHE040W	0x000	/* 68040 cache mode, cachable, write-through */
     22
     23#define _DESCTYPE_MASK	0x003
     24
     25#define _CACHEMASK040	(~0x060)
     26
     27/*
     28 * Currently set to the minimum alignment of table pointers (256 bytes).
     29 * The hardware only uses the low 4 bits for state:
     30 *
     31 *    3 - Used
     32 *    2 - Write Protected
     33 *  0,1 - Descriptor Type
     34 *
     35 * and has the rest of the bits reserved.
     36 */
     37#define _TABLE_MASK	(0xffffff00)
     38
     39#define _PAGE_TABLE	(_PAGE_SHORT)
     40#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE)
     41
     42#define _PAGE_PROTNONE	0x004
     43
     44#ifndef __ASSEMBLY__
     45
     46/* This is the cache mode to be used for pages containing page descriptors for
     47 * processors >= '040. It is in pte_mknocache(), and the variable is defined
     48 * and initialized in head.S */
     49extern int m68k_pgtable_cachemode;
     50
     51/* This is the cache mode for normal pages, for supervisor access on
     52 * processors >= '040. It is used in pte_mkcache(), and the variable is
     53 * defined and initialized in head.S */
     54
     55#if defined(CPU_M68060_ONLY) && defined(CONFIG_060_WRITETHROUGH)
     56#define m68k_supervisor_cachemode _PAGE_CACHE040W
     57#elif defined(CPU_M68040_OR_M68060_ONLY)
     58#define m68k_supervisor_cachemode _PAGE_CACHE040
     59#elif defined(CPU_M68020_OR_M68030_ONLY)
     60#define m68k_supervisor_cachemode 0
     61#else
     62extern int m68k_supervisor_cachemode;
     63#endif
     64
     65#if defined(CPU_M68040_OR_M68060_ONLY)
     66#define mm_cachebits _PAGE_CACHE040
     67#elif defined(CPU_M68020_OR_M68030_ONLY)
     68#define mm_cachebits 0
     69#else
     70extern unsigned long mm_cachebits;
     71#endif
     72
     73#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED | mm_cachebits)
     74#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits)
     75#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
     76#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
     77#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits)
     78
     79/* Alternate definitions that are compile time constants, for
     80   initializing protection_map.  The cachebits are fixed later.  */
     81#define PAGE_NONE_C	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
     82#define PAGE_SHARED_C	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
     83#define PAGE_COPY_C	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
     84#define PAGE_READONLY_C	__pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
     85
     86/*
     87 * The m68k can't do page protection for execute, and considers that the same are read.
     88 * Also, write permissions imply read permissions. This is the closest we can get..
     89 */
     90#define __P000	PAGE_NONE_C
     91#define __P001	PAGE_READONLY_C
     92#define __P010	PAGE_COPY_C
     93#define __P011	PAGE_COPY_C
     94#define __P100	PAGE_READONLY_C
     95#define __P101	PAGE_READONLY_C
     96#define __P110	PAGE_COPY_C
     97#define __P111	PAGE_COPY_C
     98
     99#define __S000	PAGE_NONE_C
    100#define __S001	PAGE_READONLY_C
    101#define __S010	PAGE_SHARED_C
    102#define __S011	PAGE_SHARED_C
    103#define __S100	PAGE_READONLY_C
    104#define __S101	PAGE_READONLY_C
    105#define __S110	PAGE_SHARED_C
    106#define __S111	PAGE_SHARED_C
    107
    108#define pmd_pgtable(pmd) ((pgtable_t)pmd_page_vaddr(pmd))
    109
    110/*
    111 * Conversion functions: convert a page and protection to a page entry,
    112 * and a page entry and page directory to the page they refer to.
    113 */
    114#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
    115
    116static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
    117{
    118	pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
    119	return pte;
    120}
    121
    122static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
    123{
    124	pmd_val(*pmdp) = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED;
    125}
    126
    127static inline void pud_set(pud_t *pudp, pmd_t *pmdp)
    128{
    129	pud_val(*pudp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp);
    130}
    131
    132#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
    133#define pmd_page_vaddr(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
    134#define pud_pgtable(pud) ((pmd_t *)__va(pud_val(pud) & _TABLE_MASK))
    135
    136
    137#define pte_none(pte)		(!pte_val(pte))
    138#define pte_present(pte)	(pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE))
    139#define pte_clear(mm,addr,ptep)		({ pte_val(*(ptep)) = 0; })
    140
    141#define pte_page(pte)		virt_to_page(__va(pte_val(pte)))
    142#define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
    143#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
    144
    145#define pmd_none(pmd)		(!pmd_val(pmd))
    146#define pmd_bad(pmd)		((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE)
    147#define pmd_present(pmd)	(pmd_val(pmd) & _PAGE_TABLE)
    148#define pmd_clear(pmdp)		({ pmd_val(*pmdp) = 0; })
    149
    150#define pmd_pfn(pmd)		((pmd_val(pmd) & _TABLE_MASK) >> PAGE_SHIFT)
    151/*
    152 * m68k does not have huge pages (020/030 actually could), but generic code
    153 * expects pmd_page() to exists, only to then DCE it all. Provide a dummy to
    154 * make the compiler happy.
    155 */
    156#define pmd_page(pmd)		NULL
    157
    158
    159#define pud_none(pud)		(!pud_val(pud))
    160#define pud_bad(pud)		((pud_val(pud) & _DESCTYPE_MASK) != _PAGE_TABLE)
    161#define pud_present(pud)	(pud_val(pud) & _PAGE_TABLE)
    162#define pud_clear(pudp)		({ pud_val(*pudp) = 0; })
    163#define pud_page(pud)		(mem_map + ((unsigned long)(__va(pud_val(pud)) - PAGE_OFFSET) >> PAGE_SHIFT))
    164
    165#define pte_ERROR(e) \
    166	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
    167#define pmd_ERROR(e) \
    168	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
    169#define pgd_ERROR(e) \
    170	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
    171
    172
    173/*
    174 * The following only work if pte_present() is true.
    175 * Undefined behaviour if not..
    176 */
    177static inline int pte_write(pte_t pte)		{ return !(pte_val(pte) & _PAGE_RONLY); }
    178static inline int pte_dirty(pte_t pte)		{ return pte_val(pte) & _PAGE_DIRTY; }
    179static inline int pte_young(pte_t pte)		{ return pte_val(pte) & _PAGE_ACCESSED; }
    180
    181static inline pte_t pte_wrprotect(pte_t pte)	{ pte_val(pte) |= _PAGE_RONLY; return pte; }
    182static inline pte_t pte_mkclean(pte_t pte)	{ pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
    183static inline pte_t pte_mkold(pte_t pte)	{ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
    184static inline pte_t pte_mkwrite(pte_t pte)	{ pte_val(pte) &= ~_PAGE_RONLY; return pte; }
    185static inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= _PAGE_DIRTY; return pte; }
    186static inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
    187static inline pte_t pte_mknocache(pte_t pte)
    188{
    189	pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode;
    190	return pte;
    191}
    192static inline pte_t pte_mkcache(pte_t pte)
    193{
    194	pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode;
    195	return pte;
    196}
    197
    198#define swapper_pg_dir kernel_pg_dir
    199extern pgd_t kernel_pg_dir[128];
    200
    201/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
    202#define __swp_type(x)		(((x).val >> 4) & 0xff)
    203#define __swp_offset(x)		((x).val >> 12)
    204#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 4) | ((offset) << 12) })
    205#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
    206#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
    207
    208#endif	/* !__ASSEMBLY__ */
    209#endif /* _MOTOROLA_PGTABLE_H */