From: <gerg@snapgear.com>
To: linux-m68k@vger.kernel.org, uclinux-dev@uclinux.org
Cc: Greg Ungerer <gerg@uclinux.org>
Subject: [PATCH 24/35] m68k: ColdFire V4e MMU paging init code and miss handler
Date: Fri, 23 Dec 2011 13:15:37 +1000 [thread overview]
Message-ID: <1324610148-20666-25-git-send-email-gerg@snapgear.com> (raw)
In-Reply-To: <1324610148-20666-1-git-send-email-gerg@snapgear.com>
From: Greg Ungerer <gerg@uclinux.org>
The different ColdFire V4e MMU requires its own dedicated paging init
code, and a TLB miss handler for its software driven TLB.
Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Matt Waddel <mwaddel@yahoo.com>
Acked-by: Kurt Mahan <kmahan@xmission.com>
---
arch/m68k/include/asm/mcfmmu.h | 2 +
arch/m68k/mm/mcfmmu.c | 198 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 200 insertions(+), 0 deletions(-)
create mode 100644 arch/m68k/mm/mcfmmu.c
diff --git a/arch/m68k/include/asm/mcfmmu.h b/arch/m68k/include/asm/mcfmmu.h
index 8fdcfed..26cc3d5 100644
--- a/arch/m68k/include/asm/mcfmmu.h
+++ b/arch/m68k/include/asm/mcfmmu.h
@@ -105,6 +105,8 @@ static inline void mmu_write(u32 a, u32 v)
__asm__ __volatile__ ("nop");
}
+int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word);
+
#endif
#endif /* MCFMMU_H */
diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
new file mode 100644
index 0000000..babd5a9
--- /dev/null
+++ b/arch/m68k/mm/mcfmmu.c
@@ -0,0 +1,198 @@
+/*
+ * Based upon linux/arch/m68k/mm/sun3mmu.c
+ * Based upon linux/arch/ppc/mm/mmu_context.c
+ *
+ * Implementations of mm routines specific to the Coldfire MMU.
+ *
+ * Copyright (c) 2008 Freescale Semiconductor, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/mcf_pgalloc.h>
+#include <asm/tlbflush.h>
+
+#define KMAPAREA(x) ((x >= VMALLOC_START) && (x < KMAP_END))
+
+mm_context_t next_mmu_context;
+unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
+atomic_t nr_free_contexts;
+struct mm_struct *context_mm[LAST_CONTEXT+1];
+extern unsigned long num_pages;
+
+void free_initmem(void)
+{
+}
+
+/*
+ * ColdFire paging_init derived from sun3.
+ */
+void __init paging_init(void)
+{
+ pgd_t *pg_dir;
+ pte_t *pg_table;
+ unsigned long address, size;
+ unsigned long next_pgtable, bootmem_end;
+ unsigned long zones_size[MAX_NR_ZONES];
+ enum zone_type zone;
+ int i;
+
+ empty_zero_page = (void *) alloc_bootmem_pages(PAGE_SIZE);
+ memset((void *) empty_zero_page, 0, PAGE_SIZE);
+
+ pg_dir = swapper_pg_dir;
+ memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
+
+ size = num_pages * sizeof(pte_t);
+ size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
+ next_pgtable = (unsigned long) alloc_bootmem_pages(size);
+
+ bootmem_end = (next_pgtable + size + PAGE_SIZE) & PAGE_MASK;
+ pg_dir += PAGE_OFFSET >> PGDIR_SHIFT;
+
+ address = PAGE_OFFSET;
+ while (address < (unsigned long)high_memory) {
+ pg_table = (pte_t *) next_pgtable;
+ next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
+ pgd_val(*pg_dir) = (unsigned long) pg_table;
+ pg_dir++;
+
+ /* now change pg_table to kernel virtual addresses */
+ for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
+ pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
+ if (address >= (unsigned long) high_memory)
+ pte_val(pte) = 0;
+
+ set_pte(pg_table, pte);
+ address += PAGE_SIZE;
+ }
+ }
+
+ current->mm = NULL;
+
+ for (zone = 0; zone < MAX_NR_ZONES; zone++)
+ zones_size[zone] = 0x0;
+ zones_size[ZONE_DMA] = num_pages;
+ free_area_init(zones_size);
+}
+
+int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
+{
+ unsigned long flags, mmuar;
+ struct mm_struct *mm;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ int asid;
+
+ local_irq_save(flags);
+
+ mmuar = (dtlb) ? mmu_read(MMUAR) :
+ regs->pc + (extension_word * sizeof(long));
+
+ mm = (!user_mode(regs) && KMAPAREA(mmuar)) ? &init_mm : current->mm;
+ if (!mm) {
+ local_irq_restore(flags);
+ return -1;
+ }
+
+ pgd = pgd_offset(mm, mmuar);
+ if (pgd_none(*pgd)) {
+ local_irq_restore(flags);
+ return -1;
+ }
+
+ pmd = pmd_offset(pgd, mmuar);
+ if (pmd_none(*pmd)) {
+ local_irq_restore(flags);
+ return -1;
+ }
+
+ pte = (KMAPAREA(mmuar)) ? pte_offset_kernel(pmd, mmuar)
+ : pte_offset_map(pmd, mmuar);
+ if (pte_none(*pte) || !pte_present(*pte)) {
+ local_irq_restore(flags);
+ return -1;
+ }
+
+ if (write) {
+ if (!pte_write(*pte)) {
+ local_irq_restore(flags);
+ return -1;
+ }
+ set_pte(pte, pte_mkdirty(*pte));
+ }
+
+ set_pte(pte, pte_mkyoung(*pte));
+ asid = mm->context & 0xff;
+ if (!pte_dirty(*pte) && !KMAPAREA(mmuar))
+ set_pte(pte, pte_wrprotect(*pte));
+
+ mmu_write(MMUTR, (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) |
+ (((int)(pte->pte) & (int)CF_PAGE_MMUTR_MASK)
+ >> CF_PAGE_MMUTR_SHIFT) | MMUTR_V);
+
+ mmu_write(MMUDR, (pte_val(*pte) & PAGE_MASK) |
+ ((pte->pte) & CF_PAGE_MMUDR_MASK) | MMUDR_SZ_8KB | MMUDR_X);
+
+ if (dtlb)
+ mmu_write(MMUOR, MMUOR_ACC | MMUOR_UAA);
+ else
+ mmu_write(MMUOR, MMUOR_ITLB | MMUOR_ACC | MMUOR_UAA);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+/*
+ * Initialize the context management stuff.
+ * The following was taken from arch/ppc/mmu_context.c
+ */
+void __init mmu_context_init(void)
+{
+ /*
+ * Some processors have too few contexts to reserve one for
+ * init_mm, and require using context 0 for a normal task.
+ * Other processors reserve the use of context zero for the kernel.
+ * This code assumes FIRST_CONTEXT < 32.
+ */
+ context_map[0] = (1 << FIRST_CONTEXT) - 1;
+ next_mmu_context = FIRST_CONTEXT;
+ atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
+}
+
+/*
+ * Steal a context from a task that has one at the moment.
+ * This is only used on 8xx and 4xx and we presently assume that
+ * they don't do SMP. If they do then thicfpgalloc.hs will have to check
+ * whether the MM we steal is in use.
+ * We also assume that this is only used on systems that don't
+ * use an MMU hash table - this is true for 8xx and 4xx.
+ * This isn't an LRU system, it just frees up each context in
+ * turn (sort-of pseudo-random replacement :). This would be the
+ * place to implement an LRU scheme if anyone was motivated to do it.
+ * -- paulus
+ */
+void steal_context(void)
+{
+ struct mm_struct *mm;
+ /*
+ * free up context `next_mmu_context'
+ * if we shouldn't free context 0, don't...
+ */
+ if (next_mmu_context < FIRST_CONTEXT)
+ next_mmu_context = FIRST_CONTEXT;
+ mm = context_mm[next_mmu_context];
+ flush_tlb_mm(mm);
+ destroy_context(mm);
+}
+
--
1.7.0.4
next prev parent reply other threads:[~2011-12-23 3:15 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-23 3:15 [PATCH 00/35 v4] m68k: ColdFire MMU support gerg
2011-12-23 3:15 ` [PATCH 01/35] m68k: add machine and CPU definitions for ColdFire cores gerg
2011-12-23 3:15 ` [PATCH 02/35] m68k: show ColdFire CPU/FPU/MMU type gerg
2011-12-23 3:15 ` [PATCH 03/35] m68k: definitions for the ColdFire V4e MMU hardware gerg
2011-12-23 3:15 ` [PATCH 04/35] m68k: make interrupt definitions conditional on correct CPU types gerg
2011-12-23 3:15 ` [PATCH 05/35] m68k: add TASK definitions for ColdFires running with MMU gerg
2011-12-23 3:15 ` [PATCH 06/35] m68k: modify user space access functions to support ColdFire CPUs gerg
2011-12-25 19:56 ` Geert Uytterhoeven
2011-12-23 3:15 ` [PATCH 07/35] m68k: use addr_limit checking for m68k CPUs that do no support address spaces gerg
2011-12-25 20:01 ` Geert Uytterhoeven
2011-12-27 12:30 ` Greg Ungerer
2011-12-23 3:15 ` [PATCH 08/35] m68k: init the MMU hardware for the 54xx ColdFire gerg
2011-12-23 3:15 ` [PATCH 09/35] m68k: add ColdFire 54xx CPU MMU memory init code gerg
2011-12-25 20:05 ` Geert Uytterhoeven
2011-12-23 3:15 ` [PATCH 10/35] m68k: set register a2 to current if MMU enabled on ColdFire gerg
2011-12-25 20:09 ` Geert Uytterhoeven
2011-12-23 3:15 ` [PATCH 11/35] m68k: page table support definitions and code for ColdFire MMU gerg
2011-12-23 3:15 ` [PATCH 12/35] m68k: add page table size definitions for ColdFire V4e MMU gerg
2011-12-23 3:15 ` [PATCH 13/35] m68k: add ColdFire paging exception handling code gerg
2011-12-23 3:15 ` [PATCH 14/35] m68k: add cache support for V4e ColdFire cores running with MMU enabled gerg
2011-12-23 3:15 ` [PATCH 15/35] m68k: modify ColdFire 54xx cache support for " gerg
2011-12-23 3:15 ` [PATCH 16/35] m68k: add TLB flush support for the ColdFire V4e MMU hardware gerg
2011-12-23 3:15 ` [PATCH 17/35] m68k: define PAGE_OFFSET_RAW for ColdFire CPU with MMU enabled gerg
2011-12-25 20:15 ` Geert Uytterhoeven
2011-12-27 12:08 ` Greg Ungerer
2011-12-23 3:15 ` [PATCH 18/35] m68k: set ColdFire MMU page size gerg
2011-12-23 3:15 ` [PATCH 19/35] m68k: MMU enabled ColdFire needs 8k ELF alignment gerg
2011-12-23 3:15 ` [PATCH 20/35] m68k: ColdFire V4e MMU context support code gerg
2011-12-23 3:15 ` [PATCH 21/35] m68k: use tracehook_report_syscall_entry/exit for ColdFire MMU ptrace path gerg
2011-12-23 3:15 ` [PATCH 22/35] m68k: modify cache push and clear code for ColdFire with MMU enable gerg
2011-12-23 3:15 ` [PATCH 23/35] m68k: use ColdFire MMU read/write bit flags when ioremapping gerg
2011-12-25 20:23 ` Geert Uytterhoeven
2011-12-23 3:15 ` gerg [this message]
2011-12-23 3:15 ` [PATCH 25/35] m68k: compile appropriate mm arch files for ColdFire MMU support gerg
2011-12-23 3:15 ` [PATCH 26/35] m68k: create ColdFire MMU pgalloc code gerg
2011-12-23 3:15 ` [PATCH 27/35] m68k: use non-MMU entry.S code when compiling for ColdFire CPU gerg
2011-12-23 3:15 ` [PATCH 28/35] m68k: add code to setup a ColdFire 54xx platform when MMU enabled gerg
2011-12-23 3:15 ` [PATCH 29/35] m68k: ColdFire with MMU enabled uses same clocking code as non-MMU gerg
2011-12-25 20:24 ` Geert Uytterhoeven
2011-12-23 3:15 ` [PATCH 30/35] m68k: use non-MMU linker script for ColdFire MMU builds gerg
2011-12-23 3:15 ` [PATCH 31/35] m68k: adjustments to stack frame for ColdFire with MMU enabled gerg
2011-12-23 3:15 ` [PATCH 32/35] m68k: add ColdFire FPU support for the V4e ColdFire CPU's gerg
2011-12-24 19:38 ` Geert Uytterhoeven
2011-12-27 12:36 ` Greg Ungerer
2011-12-28 5:53 ` Greg Ungerer
2011-12-28 10:06 ` Geert Uytterhoeven
2011-12-28 12:32 ` Greg Ungerer
2011-12-28 12:47 ` Andreas Schwab
2011-12-28 11:17 ` Joshua Juran
2011-12-28 12:57 ` Greg Ungerer
2011-12-23 3:15 ` [PATCH 33/35] m68k: do not use m68k startup or interrupt code for " gerg
2011-12-25 20:33 ` Geert Uytterhoeven
2011-12-27 12:24 ` Greg Ungerer
2011-12-27 18:30 ` Geert Uytterhoeven
2011-12-28 0:22 ` Greg Ungerer
2011-12-28 10:09 ` Geert Uytterhoeven
2011-12-29 2:01 ` Greg Ungerer
2011-12-23 3:15 ` [PATCH 34/35] m68k: add ColdFire with MMU enabled support to the m68k mem init code gerg
2011-12-23 3:15 ` [PATCH 35/35] m68k: allow ColdFire 547x and 548x CPUs to be built with MMU enabled gerg
2011-12-26 19:32 ` Geert Uytterhoeven
2011-12-26 19:33 ` Geert Uytterhoeven
2011-12-28 1:35 ` Greg Ungerer
2011-12-29 4:52 ` Greg Ungerer
-- strict thread matches above, loose matches on Subject: below --
2011-12-16 12:35 [PATCH 00/35 v3] m68k: ColdFire MMU support gerg
2011-12-16 12:36 ` [PATCH 24/35] m68k: ColdFire V4e MMU paging init code and miss handler gerg
2011-11-25 3:40 [PATCH 00/35 v2] m68k: ColdFire MMU support gerg
2011-11-25 3:41 ` [PATCH 24/35] m68k: ColdFire V4e MMU paging init code and miss handler gerg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1324610148-20666-25-git-send-email-gerg@snapgear.com \
--to=gerg@snapgear.com \
--cc=gerg@uclinux.org \
--cc=linux-m68k@vger.kernel.org \
--cc=uclinux-dev@uclinux.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox