|
@@ -577,244 +577,6 @@ void swift_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
|
|
|
* with respect to cache coherency.
|
|
|
*/
|
|
|
|
|
|
-/* Cypress flushes. */
|
|
|
-static void cypress_flush_cache_all(void)
|
|
|
-{
|
|
|
- volatile unsigned long cypress_sucks;
|
|
|
- unsigned long faddr, tagval;
|
|
|
-
|
|
|
- flush_user_windows();
|
|
|
- for(faddr = 0; faddr < 0x10000; faddr += 0x20) {
|
|
|
- __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" :
|
|
|
- "=r" (tagval) :
|
|
|
- "r" (faddr), "r" (0x40000),
|
|
|
- "i" (ASI_M_DATAC_TAG));
|
|
|
-
|
|
|
- /* If modified and valid, kick it. */
|
|
|
- if((tagval & 0x60) == 0x60)
|
|
|
- cypress_sucks = *(unsigned long *)(0xf0020000 + faddr);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void cypress_flush_cache_mm(struct mm_struct *mm)
|
|
|
-{
|
|
|
- register unsigned long a, b, c, d, e, f, g;
|
|
|
- unsigned long flags, faddr;
|
|
|
- int octx;
|
|
|
-
|
|
|
- FLUSH_BEGIN(mm)
|
|
|
- flush_user_windows();
|
|
|
- local_irq_save(flags);
|
|
|
- octx = srmmu_get_context();
|
|
|
- srmmu_set_context(mm->context);
|
|
|
- a = 0x20; b = 0x40; c = 0x60;
|
|
|
- d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
|
|
|
-
|
|
|
- faddr = (0x10000 - 0x100);
|
|
|
- goto inside;
|
|
|
- do {
|
|
|
- faddr -= 0x100;
|
|
|
- inside:
|
|
|
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %2] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %3] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %4] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %5] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %6] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %7] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %8] %1\n\t" : :
|
|
|
- "r" (faddr), "i" (ASI_M_FLUSH_CTX),
|
|
|
- "r" (a), "r" (b), "r" (c), "r" (d),
|
|
|
- "r" (e), "r" (f), "r" (g));
|
|
|
- } while(faddr);
|
|
|
- srmmu_set_context(octx);
|
|
|
- local_irq_restore(flags);
|
|
|
- FLUSH_END
|
|
|
-}
|
|
|
-
|
|
|
-static void cypress_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
|
|
|
-{
|
|
|
- struct mm_struct *mm = vma->vm_mm;
|
|
|
- register unsigned long a, b, c, d, e, f, g;
|
|
|
- unsigned long flags, faddr;
|
|
|
- int octx;
|
|
|
-
|
|
|
- FLUSH_BEGIN(mm)
|
|
|
- flush_user_windows();
|
|
|
- local_irq_save(flags);
|
|
|
- octx = srmmu_get_context();
|
|
|
- srmmu_set_context(mm->context);
|
|
|
- a = 0x20; b = 0x40; c = 0x60;
|
|
|
- d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
|
|
|
-
|
|
|
- start &= SRMMU_REAL_PMD_MASK;
|
|
|
- while(start < end) {
|
|
|
- faddr = (start + (0x10000 - 0x100));
|
|
|
- goto inside;
|
|
|
- do {
|
|
|
- faddr -= 0x100;
|
|
|
- inside:
|
|
|
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %2] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %3] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %4] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %5] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %6] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %7] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %8] %1\n\t" : :
|
|
|
- "r" (faddr),
|
|
|
- "i" (ASI_M_FLUSH_SEG),
|
|
|
- "r" (a), "r" (b), "r" (c), "r" (d),
|
|
|
- "r" (e), "r" (f), "r" (g));
|
|
|
- } while (faddr != start);
|
|
|
- start += SRMMU_REAL_PMD_SIZE;
|
|
|
- }
|
|
|
- srmmu_set_context(octx);
|
|
|
- local_irq_restore(flags);
|
|
|
- FLUSH_END
|
|
|
-}
|
|
|
-
|
|
|
-static void cypress_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
|
|
|
-{
|
|
|
- register unsigned long a, b, c, d, e, f, g;
|
|
|
- struct mm_struct *mm = vma->vm_mm;
|
|
|
- unsigned long flags, line;
|
|
|
- int octx;
|
|
|
-
|
|
|
- FLUSH_BEGIN(mm)
|
|
|
- flush_user_windows();
|
|
|
- local_irq_save(flags);
|
|
|
- octx = srmmu_get_context();
|
|
|
- srmmu_set_context(mm->context);
|
|
|
- a = 0x20; b = 0x40; c = 0x60;
|
|
|
- d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
|
|
|
-
|
|
|
- page &= PAGE_MASK;
|
|
|
- line = (page + PAGE_SIZE) - 0x100;
|
|
|
- goto inside;
|
|
|
- do {
|
|
|
- line -= 0x100;
|
|
|
- inside:
|
|
|
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %2] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %3] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %4] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %5] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %6] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %7] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %8] %1\n\t" : :
|
|
|
- "r" (line),
|
|
|
- "i" (ASI_M_FLUSH_PAGE),
|
|
|
- "r" (a), "r" (b), "r" (c), "r" (d),
|
|
|
- "r" (e), "r" (f), "r" (g));
|
|
|
- } while(line != page);
|
|
|
- srmmu_set_context(octx);
|
|
|
- local_irq_restore(flags);
|
|
|
- FLUSH_END
|
|
|
-}
|
|
|
-
|
|
|
-/* Cypress is copy-back, at least that is how we configure it. */
|
|
|
-static void cypress_flush_page_to_ram(unsigned long page)
|
|
|
-{
|
|
|
- register unsigned long a, b, c, d, e, f, g;
|
|
|
- unsigned long line;
|
|
|
-
|
|
|
- a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
|
|
|
- page &= PAGE_MASK;
|
|
|
- line = (page + PAGE_SIZE) - 0x100;
|
|
|
- goto inside;
|
|
|
- do {
|
|
|
- line -= 0x100;
|
|
|
- inside:
|
|
|
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %2] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %3] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %4] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %5] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %6] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %7] %1\n\t"
|
|
|
- "sta %%g0, [%0 + %8] %1\n\t" : :
|
|
|
- "r" (line),
|
|
|
- "i" (ASI_M_FLUSH_PAGE),
|
|
|
- "r" (a), "r" (b), "r" (c), "r" (d),
|
|
|
- "r" (e), "r" (f), "r" (g));
|
|
|
- } while(line != page);
|
|
|
-}
|
|
|
-
|
|
|
-/* Cypress is also IO cache coherent. */
|
|
|
-static void cypress_flush_page_for_dma(unsigned long page)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-/* Cypress has unified L2 VIPT, from which both instructions and data
|
|
|
- * are stored. It does not have an onboard icache of any sort, therefore
|
|
|
- * no flush is necessary.
|
|
|
- */
|
|
|
-static void cypress_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-static void cypress_flush_tlb_all(void)
|
|
|
-{
|
|
|
- srmmu_flush_whole_tlb();
|
|
|
-}
|
|
|
-
|
|
|
-static void cypress_flush_tlb_mm(struct mm_struct *mm)
|
|
|
-{
|
|
|
- FLUSH_BEGIN(mm)
|
|
|
- __asm__ __volatile__(
|
|
|
- "lda [%0] %3, %%g5\n\t"
|
|
|
- "sta %2, [%0] %3\n\t"
|
|
|
- "sta %%g0, [%1] %4\n\t"
|
|
|
- "sta %%g5, [%0] %3\n"
|
|
|
- : /* no outputs */
|
|
|
- : "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context),
|
|
|
- "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
|
|
|
- : "g5");
|
|
|
- FLUSH_END
|
|
|
-}
|
|
|
-
|
|
|
-static void cypress_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
|
|
|
-{
|
|
|
- struct mm_struct *mm = vma->vm_mm;
|
|
|
- unsigned long size;
|
|
|
-
|
|
|
- FLUSH_BEGIN(mm)
|
|
|
- start &= SRMMU_PGDIR_MASK;
|
|
|
- size = SRMMU_PGDIR_ALIGN(end) - start;
|
|
|
- __asm__ __volatile__(
|
|
|
- "lda [%0] %5, %%g5\n\t"
|
|
|
- "sta %1, [%0] %5\n"
|
|
|
- "1:\n\t"
|
|
|
- "subcc %3, %4, %3\n\t"
|
|
|
- "bne 1b\n\t"
|
|
|
- " sta %%g0, [%2 + %3] %6\n\t"
|
|
|
- "sta %%g5, [%0] %5\n"
|
|
|
- : /* 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");
|
|
|
- FLUSH_END
|
|
|
-}
|
|
|
-
|
|
|
-static void cypress_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
|
|
|
-{
|
|
|
- struct mm_struct *mm = vma->vm_mm;
|
|
|
-
|
|
|
- FLUSH_BEGIN(mm)
|
|
|
- __asm__ __volatile__(
|
|
|
- "lda [%0] %3, %%g5\n\t"
|
|
|
- "sta %1, [%0] %3\n\t"
|
|
|
- "sta %%g0, [%2] %4\n\t"
|
|
|
- "sta %%g5, [%0] %3\n"
|
|
|
- : /* no outputs */
|
|
|
- : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK),
|
|
|
- "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
|
|
|
- : "g5");
|
|
|
- FLUSH_END
|
|
|
-}
|
|
|
-
|
|
|
/* viking.S */
|
|
|
extern void viking_flush_cache_all(void);
|
|
|
extern void viking_flush_cache_mm(struct mm_struct *mm);
|
|
@@ -1307,90 +1069,6 @@ static void __init init_hypersparc(void)
|
|
|
hypersparc_setup_blockops();
|
|
|
}
|
|
|
|
|
|
-static void __cpuinit poke_cypress(void)
|
|
|
-{
|
|
|
- unsigned long mreg = srmmu_get_mmureg();
|
|
|
- unsigned long faddr, tagval;
|
|
|
- volatile unsigned long cypress_sucks;
|
|
|
- volatile unsigned long clear;
|
|
|
-
|
|
|
- clear = srmmu_get_faddr();
|
|
|
- clear = srmmu_get_fstatus();
|
|
|
-
|
|
|
- if (!(mreg & CYPRESS_CENABLE)) {
|
|
|
- for(faddr = 0x0; faddr < 0x10000; faddr += 20) {
|
|
|
- __asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t"
|
|
|
- "sta %%g0, [%0] %2\n\t" : :
|
|
|
- "r" (faddr), "r" (0x40000),
|
|
|
- "i" (ASI_M_DATAC_TAG));
|
|
|
- }
|
|
|
- } else {
|
|
|
- for(faddr = 0; faddr < 0x10000; faddr += 0x20) {
|
|
|
- __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" :
|
|
|
- "=r" (tagval) :
|
|
|
- "r" (faddr), "r" (0x40000),
|
|
|
- "i" (ASI_M_DATAC_TAG));
|
|
|
-
|
|
|
- /* If modified and valid, kick it. */
|
|
|
- if((tagval & 0x60) == 0x60)
|
|
|
- cypress_sucks = *(unsigned long *)
|
|
|
- (0xf0020000 + faddr);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* And one more, for our good neighbor, Mr. Broken Cypress. */
|
|
|
- clear = srmmu_get_faddr();
|
|
|
- clear = srmmu_get_fstatus();
|
|
|
-
|
|
|
- mreg |= (CYPRESS_CENABLE | CYPRESS_CMODE);
|
|
|
- srmmu_set_mmureg(mreg);
|
|
|
-}
|
|
|
-
|
|
|
-static const struct sparc32_cachetlb_ops cypress_ops = {
|
|
|
- .cache_all = cypress_flush_cache_all,
|
|
|
- .cache_mm = cypress_flush_cache_mm,
|
|
|
- .cache_page = cypress_flush_cache_page,
|
|
|
- .cache_range = cypress_flush_cache_range,
|
|
|
- .tlb_all = cypress_flush_tlb_all,
|
|
|
- .tlb_mm = cypress_flush_tlb_mm,
|
|
|
- .tlb_page = cypress_flush_tlb_page,
|
|
|
- .tlb_range = cypress_flush_tlb_range,
|
|
|
- .page_to_ram = cypress_flush_page_to_ram,
|
|
|
- .sig_insns = cypress_flush_sig_insns,
|
|
|
- .page_for_dma = cypress_flush_page_for_dma,
|
|
|
-};
|
|
|
-
|
|
|
-static void __init init_cypress_common(void)
|
|
|
-{
|
|
|
- init_vac_layout();
|
|
|
- sparc32_cachetlb_ops = &cypress_ops;
|
|
|
- poke_srmmu = poke_cypress;
|
|
|
-}
|
|
|
-
|
|
|
-static void __init init_cypress_604(void)
|
|
|
-{
|
|
|
- srmmu_name = "ROSS Cypress-604(UP)";
|
|
|
- srmmu_modtype = Cypress;
|
|
|
- init_cypress_common();
|
|
|
-}
|
|
|
-
|
|
|
-static void __init init_cypress_605(unsigned long mrev)
|
|
|
-{
|
|
|
- srmmu_name = "ROSS Cypress-605(MP)";
|
|
|
- if(mrev == 0xe) {
|
|
|
- srmmu_modtype = Cypress_vE;
|
|
|
- hwbug_bitmask |= HWBUG_COPYBACK_BROKEN;
|
|
|
- } else {
|
|
|
- if(mrev == 0xd) {
|
|
|
- srmmu_modtype = Cypress_vD;
|
|
|
- hwbug_bitmask |= HWBUG_ASIFLUSH_BROKEN;
|
|
|
- } else {
|
|
|
- srmmu_modtype = Cypress;
|
|
|
- }
|
|
|
- }
|
|
|
- init_cypress_common();
|
|
|
-}
|
|
|
-
|
|
|
static void __cpuinit poke_swift(void)
|
|
|
{
|
|
|
unsigned long mreg;
|
|
@@ -1912,22 +1590,15 @@ static void __init get_srmmu_type(void)
|
|
|
break;
|
|
|
case 0:
|
|
|
case 2:
|
|
|
- /* Uniprocessor Cypress */
|
|
|
- init_cypress_604();
|
|
|
- break;
|
|
|
case 10:
|
|
|
case 11:
|
|
|
case 12:
|
|
|
- /* _REALLY OLD_ Cypress MP chips... */
|
|
|
case 13:
|
|
|
case 14:
|
|
|
case 15:
|
|
|
- /* MP Cypress mmu/cache-controller */
|
|
|
- init_cypress_605(mod_rev);
|
|
|
- break;
|
|
|
default:
|
|
|
- /* Some other Cypress revision, assume a 605. */
|
|
|
- init_cypress_605(mod_rev);
|
|
|
+ prom_printf("Sparc-Linux Cypress support does not longer exit.\n");
|
|
|
+ prom_halt();
|
|
|
break;
|
|
|
}
|
|
|
return;
|