Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24ef7fc4 authored by Matt Fleming's avatar Matt Fleming
Browse files

sh: Acquire some more page flags for SH-5.



We need some more page flags to hook up _PAGE_WIRED (and eventually
other things). So use the unused PTE bits above the PPN field as no
implementations use these for anything currently.

Now that we have _PAGE_WIRED let's provide the SH-5 functions for wiring
up TLB entries.

Signed-off-by: default avatarMatt Fleming <matt@console-pimps.org>
parent 8eda5514
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ typedef struct { unsigned long pgd; } pgd_t;
#define __pte(x)	((pte_t) { (x) } )
#else
typedef struct { unsigned long long pte_low; } pte_t;
typedef struct { unsigned long pgprot; } pgprot_t;
typedef struct { unsigned long long pgprot; } pgprot_t;
typedef struct { unsigned long pgd; } pgd_t;
#define pte_val(x)	((x).pte_low)
#define __pte(x)	((pte_t) { (x) } )
+14 −1
Original line number Diff line number Diff line
@@ -123,8 +123,21 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
#define _PAGE_DIRTY	0x400  /* software: page accessed in write */
#define _PAGE_ACCESSED	0x800  /* software: page referenced */

/* Wrapper for extended mode pgprot twiddling */
#define _PAGE_EXT(x)		((unsigned long long)(x) << 32)

/*
 * We can use the sign-extended bits in the PTEL to get 32 bits of
 * software flags. This works for now because no implementations uses
 * anything above the PPN field.
 */
#define _PAGE_WIRED	_PAGE_EXT(0x001) /* software: wire the tlb entry */

#define _PAGE_CLEAR_FLAGS	(_PAGE_PRESENT | _PAGE_FILE | _PAGE_SHARED | \
				 _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED)

/* Mask which drops software flags */
#define _PAGE_FLAGS_HARDWARE_MASK	0xfffffffffffff3dbLL
#define _PAGE_FLAGS_HARDWARE_MASK	(NEFF_MASK & ~(_PAGE_CLEAR_FLAGS))

/*
 * HugeTLB support
+41 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#ifdef CONFIG_MMU
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>

/*
 * TLB handling.  This allows us to remove pages from the page
@@ -100,6 +101,46 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
#ifdef CONFIG_CPU_SH4
extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t);
extern void tlb_unwire_entry(void);
#elif defined(CONFIG_SUPERH64)
static int dtlb_entry;
static unsigned long long dtlb_entries[64];

static inline void tlb_wire_entry(struct vm_area_struct *vma,
				  unsigned long addr, pte_t pte)
{
	unsigned long long entry;
	unsigned long paddr, flags;

	BUG_ON(dtlb_entry == 64);

	local_irq_save(flags);

	entry = sh64_get_wired_dtlb_entry();
	dtlb_entries[dtlb_entry++] = entry;

	paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK;
	paddr &= ~PAGE_MASK;

	sh64_setup_tlb_slot(entry, addr, get_asid(), paddr);

	local_irq_restore(flags);
}

static inline void tlb_unwire_entry(void)
{
	unsigned long long entry;
	unsigned long flags;

	BUG_ON(!dtlb_entry);

	local_irq_save(flags);
	entry = dtlb_entries[dtlb_entry--];

	sh64_teardown_tlb_slot(entry);
	sh64_put_wired_dtlb_entry(entry);

	local_irq_restore(flags);
}
#else
static inline void tlb_wire_entry(struct vm_area_struct *vma ,
				  unsigned long addr, pte_t pte)
+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ extern void die(const char *,struct pt_regs *,long);

static inline void print_prots(pgprot_t prot)
{
	printk("prot is 0x%08lx\n",pgprot_val(prot));
	printk("prot is 0x%016llx\n",pgprot_val(prot));

	printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ),
	       PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER));