patch-2.1.36 linux/arch/sparc/mm/srmmu.c
Next file: linux/arch/sparc/mm/viking.S
Previous file: linux/arch/sparc/mm/init.c
Back to the patch index
Back to the overall index
- Lines: 403
- Date:
Tue Apr 22 22:39:12 1997
- Orig file:
v2.1.35/linux/arch/sparc/mm/srmmu.c
- Orig date:
Mon Apr 14 16:28:08 1997
diff -u --recursive --new-file v2.1.35/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.135 1997/04/14 05:38:49 davem Exp $
+/* $Id: srmmu.c,v 1.136 1997/04/20 14:11:51 ecd Exp $
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -74,7 +74,10 @@
ctxd_t *srmmu_ctx_table_phys;
ctxd_t *srmmu_context_table;
-static struct srmmu_trans {
+/* Don't change this without changing access to this
+ * in arch/sparc/mm/viking.S
+ */
+struct srmmu_trans {
unsigned long vbase;
unsigned long pbase;
unsigned long size;
@@ -705,7 +708,7 @@
} while(line != page);
}
-static void srmmu_set_pte_nocache_nomxccvik(pte_t *ptep, pte_t pteval)
+static void srmmu_set_pte_nocache_viking(pte_t *ptep, pte_t pteval)
{
unsigned long vaddr;
int set;
@@ -1083,255 +1086,6 @@
* with respect to cache coherency.
*/
-/* Viking flushes. For Sun's mainline MBUS processor it is pretty much
- * a crappy mmu. The on-chip I&D caches only have full flushes, no fine
- * grained cache invalidations. It only has these "flash clear" things
- * just like the MicroSparcI. Added to this many revs of the chip are
- * teaming with hardware buggery. Someday maybe we'll do direct
- * diagnostic tag accesses for page level flushes as those should
- * be painless and will increase performance due to the frequency of
- * page level flushes. This is a must to _really_ flush the caches,
- * crazy hardware ;-)
- */
-
-static void viking_flush_cache_all(void)
-{
-}
-
-static void viking_flush_cache_mm(struct mm_struct *mm)
-{
-}
-
-static void viking_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-}
-
-static void viking_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
-{
-}
-
-/* Non-mxcc vikings are copy-back but are pure-physical so no flushing. */
-static void viking_flush_page_to_ram(unsigned long page)
-{
-}
-
-static void viking_mxcc_flush_chunk(unsigned long chunk)
-{
-}
-
-/* All vikings have an icache which snoops the processor bus and is fully
- * coherent with the dcache, so no flush is necessary at all.
- */
-static void viking_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
-{
-}
-
-static void viking_mxcc_flush_page(unsigned long page)
-{
- unsigned long ppage = srmmu_v2p(page & PAGE_MASK);
- unsigned long paddr0, paddr1;
-
- if (ppage == 0xffffffffUL)
- return;
-
- paddr0 = 0x10; /* Set cacheable bit. */
- paddr1 = ppage;
-
- /* Read the page's data through the stream registers,
- * and write it back to memory. This will issue
- * coherent write invalidates to all other caches, thus
- * should also be sufficient in an MP system.
- */
- __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t"
- "or %%g0, %1, %%g3\n"
- "1:\n\t"
- "stda %%g2, [%2] %5\n\t"
- "stda %%g2, [%3] %5\n\t"
- "add %%g3, %4, %%g3\n\t"
- "btst 0xfff, %%g3\n\t"
- "bne 1b\n\t"
- "nop\n\t" : :
- "r" (paddr0), "r" (paddr1),
- "r" (MXCC_SRCSTREAM),
- "r" (MXCC_DESSTREAM),
- "r" (MXCC_STREAM_SIZE),
- "i" (ASI_M_MXCC) : "g2", "g3", "cc");
-
- /* This was handcoded after a look at the gcc output from
- *
- * do {
- * mxcc_set_stream_src(paddr);
- * mxcc_set_stream_dst(paddr);
- * paddr[1] += MXCC_STREAM_SIZE;
- * } while (paddr[1] & ~PAGE_MASK);
- */
-}
-
-static void viking_no_mxcc_flush_page(unsigned long page)
-{
- unsigned long ppage = srmmu_v2p(page & PAGE_MASK);
- int set, block;
- unsigned long ptag[2];
- unsigned long vaddr;
- int i;
-
- if (ppage == 0xffffffffUL)
- return;
- ppage >>= 12;
-
- for (set = 0; set < 128; set++) {
- for (block = 0; block < 4; block++) {
-
- viking_get_dcache_ptag(set, block, ptag);
-
- if (ptag[1] != ppage)
- continue;
- if (!(ptag[0] & VIKING_PTAG_VALID))
- continue;
- if (!(ptag[0] & VIKING_PTAG_DIRTY))
- continue;
-
- /* There was a great cache from TI
- * with comfort as much as vi,
- * 4 pages to flush,
- * 4 pages, no rush,
- * since anything else makes him die.
- */
- vaddr = (KERNBASE + PAGE_SIZE) | (set << 5);
- for (i = 0; i < 8; i++) {
- __asm__ __volatile__ ("ld [%0], %%g2\n\t" : :
- "r" (vaddr) : "g2");
- vaddr += PAGE_SIZE;
- }
-
- /* Continue with next set. */
- break;
- }
- }
-}
-
-static void viking_nomxcc_flush_chunk(unsigned long chunk)
-{
- viking_no_mxcc_flush_page(chunk);
-}
-
-/* Viking is IO cache coherent, but really only on MXCC. */
-static void viking_flush_page_for_dma(unsigned long page)
-{
-}
-
-static void viking_flush_tlb_all(void)
-{
- register int ctr asm("g5");
-
- ctr = 0;
- __asm__ __volatile__("
- 1: ld [%%g6 + %2], %%g4 ! flush user windows
- orcc %%g0, %%g4, %%g0
- add %0, 1, %0
- bne 1b
- save %%sp, -64, %%sp
- 2: subcc %0, 1, %0
- bne 2b
- restore %%g0, %%g0, %%g0"
- : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc");
- srmmu_flush_whole_tlb();
- module_stats.invall++;
-}
-
-static void viking_flush_tlb_mm(struct mm_struct *mm)
-{
- register int ctr asm("g5");
-
- FLUSH_BEGIN(mm)
- ctr = 0;
- __asm__ __volatile__("
-1: ld [%%g6 + %7], %%g4 ! flush user windows
- orcc %%g0, %%g4, %%g0
- add %0, 1, %0
- bne 1b
- save %%sp, -64, %%sp
-2: subcc %0, 1, %0
- bne 2b
- restore %%g0, %%g0, %%g0
- lda [%1] %4, %0
- sta %3, [%1] %4
- sta %%g0, [%2] %5
- sta %0, [%1] %4"
- : "=&r" (ctr)
- : "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context),
- "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE), "0" (ctr),
- "i" (UWINMASK_OFFSET)
- : "g4", "cc");
- module_stats.invmm++;
- FLUSH_END
-}
-
-static void viking_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
- register int ctr asm("g5");
- unsigned long size;
-
- FLUSH_BEGIN(mm)
- ctr = 0;
- __asm__ __volatile__("
- 1: ld [%%g6 + %2], %%g4 ! flush user windows
- orcc %%g0, %%g4, %%g0
- add %0, 1, %0
- bne 1b
- save %%sp, -64, %%sp
- 2: subcc %0, 1, %0
- bne 2b
- restore %%g0, %%g0, %%g0"
- : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc");
- start &= SRMMU_PGDIR_MASK;
- size = SRMMU_PGDIR_ALIGN(end) - start;
- __asm__ __volatile__("
- lda [%0] %5, %%g5
- sta %1, [%0] %5
- 1: subcc %3, %4, %3
- bne 1b
- sta %%g0, [%2 + %3] %6
- sta %%g5, [%0] %5"
- : /* no outputs */
- : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (start | 0x200),
- "r" (size), "r" (SRMMU_PGDIR_SIZE), "i" (ASI_M_MMUREGS),
- "i" (ASI_M_FLUSH_PROBE)
- : "g5", "cc");
- module_stats.invrnge++;
- FLUSH_END
-}
-
-static void viking_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
- struct mm_struct *mm = vma->vm_mm;
- register int ctr asm("g5");
-
- FLUSH_BEGIN(mm)
- ctr = 0;
- __asm__ __volatile__("
- 1: ld [%%g6 + %2], %%g4 ! flush user windows
- orcc %%g0, %%g4, %%g0
- add %0, 1, %0
- bne 1b
- save %%sp, -64, %%sp
- 2: subcc %0, 1, %0
- bne 2b
- restore %%g0, %%g0, %%g0"
- : "=&r" (ctr) : "0" (ctr), "i" (UWINMASK_OFFSET) : "g4", "cc");
- __asm__ __volatile__("
- lda [%0] %3, %%g5
- sta %1, [%0] %3
- sta %%g0, [%2] %4
- sta %%g5, [%0] %3"
- : /* no outputs */
- : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK),
- "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
- : "g5");
- module_stats.invpg++;
- FLUSH_END
-}
-
/* Cypress flushes. */
static void cypress_flush_cache_all(void)
{
@@ -1576,6 +1330,27 @@
FLUSH_END
}
+/* viking.S */
+extern void viking_flush_cache_all(void);
+extern void viking_flush_cache_mm(struct mm_struct *mm);
+extern void viking_flush_cache_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end);
+extern void viking_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long page);
+extern void viking_flush_page_to_ram(unsigned long page);
+extern void viking_flush_page_for_dma(unsigned long page);
+extern void viking_flush_sig_insns(struct mm_struct *mm, unsigned long addr);
+extern void viking_flush_page(unsigned long page);
+extern void viking_mxcc_flush_page(unsigned long page);
+extern void viking_flush_chunk(unsigned long chunk);
+extern void viking_mxcc_flush_chunk(unsigned long chunk);
+extern void viking_flush_tlb_all(void);
+extern void viking_flush_tlb_mm(struct mm_struct *mm);
+extern void viking_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end);
+extern void viking_flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long page);
+
/* hypersparc.S */
extern void hypersparc_flush_cache_all(void);
extern void hypersparc_flush_cache_mm(struct mm_struct *mm);
@@ -1608,9 +1383,9 @@
}
}
-static void viking_no_mxcc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp)
+static void viking_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp)
{
- viking_no_mxcc_flush_page((unsigned long)pgdp);
+ viking_flush_page((unsigned long)pgdp);
if(tsk->mm->context != NO_CONTEXT) {
flush_cache_mm(current->mm);
ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp);
@@ -1768,11 +1543,11 @@
viking_mxcc_flush_page(start);
start += PAGE_SIZE;
}
- } else if(flush_page_for_dma == viking_no_mxcc_flush_page) {
+ } else if(flush_page_for_dma == viking_flush_page) {
unsigned long start = (unsigned long) iommu->page_table;
unsigned long end = (start + ptsize);
while(start < end) {
- viking_no_mxcc_flush_page(start);
+ viking_flush_page(start);
start += PAGE_SIZE;
}
}
@@ -1809,11 +1584,11 @@
viking_mxcc_flush_page(start);
start += PAGE_SIZE;
}
- } else if(flush_page_for_dma == viking_no_mxcc_flush_page) {
+ } else if(flush_page_for_dma == viking_flush_page) {
unsigned long start = (unsigned long) iommu;
unsigned long end = (start + 16 * PAGE_SIZE);
while(start < end) {
- viking_no_mxcc_flush_page(start);
+ viking_flush_page(start);
start += PAGE_SIZE;
}
}
@@ -2029,11 +1804,11 @@
viking_mxcc_flush_page(start);
start += PAGE_SIZE;
}
- } else if(flush_page_for_dma == viking_no_mxcc_flush_page) {
+ } else if(flush_page_for_dma == viking_flush_page) {
unsigned long start = ((unsigned long) iopte_first) & PAGE_MASK;
unsigned long end = PAGE_ALIGN(((unsigned long) iopte));
while(start < end) {
- viking_no_mxcc_flush_page(start);
+ viking_flush_page(start);
start += PAGE_SIZE;
}
}
@@ -2449,12 +2224,12 @@
start_mem = PAGE_ALIGN(mempool);
flush_cache_all();
- if(flush_page_for_dma == viking_no_mxcc_flush_page) {
+ if(flush_page_for_dma == viking_flush_page) {
unsigned long start = ptables_start;
unsigned long end = start_mem;
while(start < end) {
- viking_no_mxcc_flush_page(start);
+ viking_flush_page(start);
start += PAGE_SIZE;
}
}
@@ -2999,10 +2774,10 @@
msi_set_sync();
- set_pte = srmmu_set_pte_nocache_nomxccvik;
- sparc_update_rootmmu_dir = viking_no_mxcc_update_rootmmu_dir;
+ set_pte = srmmu_set_pte_nocache_viking;
+ sparc_update_rootmmu_dir = viking_update_rootmmu_dir;
- flush_chunk = viking_nomxcc_flush_chunk; /* local flush _only_ */
+ flush_chunk = viking_flush_chunk; /* local flush _only_ */
/* We need this to make sure old viking takes no hits
* on it's cache for dma snoops to workaround the
@@ -3010,7 +2785,7 @@
* This is only necessary because of the new way in
* which we use the IOMMU.
*/
- flush_page_for_dma = viking_no_mxcc_flush_page;
+ flush_page_for_dma = viking_flush_page;
} else {
srmmu_name = "TI Viking/MXCC";
viking_mxcc_present = 1;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov