Loading arch/parisc/include/asm/cacheflush.h +4 −3 Original line number Diff line number Diff line Loading @@ -26,8 +26,6 @@ void flush_user_dcache_range_asm(unsigned long, unsigned long); void flush_kernel_dcache_range_asm(unsigned long, unsigned long); void flush_kernel_dcache_page_asm(void *); void flush_kernel_icache_page(void *); void flush_user_dcache_page(unsigned long); void flush_user_icache_page(unsigned long); void flush_user_dcache_range(unsigned long, unsigned long); void flush_user_icache_range(unsigned long, unsigned long); Loading Loading @@ -90,12 +88,15 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); /* defined in pacache.S exported in cache.c used by flush_anon_page */ void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); #define ARCH_HAS_FLUSH_ANON_PAGE static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) { if (PageAnon(page)) flush_user_dcache_page(vmaddr); flush_dcache_page_asm(page_to_phys(page), vmaddr); } #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE Loading arch/parisc/include/asm/pgtable.h +4 −10 Original line number Diff line number Diff line Loading @@ -138,8 +138,7 @@ struct vm_area_struct; #define _PAGE_NO_CACHE_BIT 24 /* (0x080) Uncached Page (U bit) */ #define _PAGE_ACCESSED_BIT 23 /* (0x100) Software: Page Accessed */ #define _PAGE_PRESENT_BIT 22 /* (0x200) Software: translation valid */ #define _PAGE_FLUSH_BIT 21 /* (0x400) Software: translation valid */ /* for cache flushing only */ /* bit 21 was formerly the FLUSH bit but is now unused */ #define _PAGE_USER_BIT 20 /* (0x800) Software: User accessible page */ /* N.B. The bits are defined in terms of a 32 bit word above, so the */ Loading Loading @@ -173,7 +172,6 @@ struct vm_area_struct; #define _PAGE_NO_CACHE (1 << xlate_pabit(_PAGE_NO_CACHE_BIT)) #define _PAGE_ACCESSED (1 << xlate_pabit(_PAGE_ACCESSED_BIT)) #define _PAGE_PRESENT (1 << xlate_pabit(_PAGE_PRESENT_BIT)) #define _PAGE_FLUSH (1 << xlate_pabit(_PAGE_FLUSH_BIT)) #define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT)) #define _PAGE_FILE (1 << xlate_pabit(_PAGE_FILE_BIT)) Loading Loading @@ -213,7 +211,6 @@ struct vm_area_struct; #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) #define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ) #define PAGE_FLUSH __pgprot(_PAGE_FLUSH) /* Loading Loading @@ -261,7 +258,7 @@ extern unsigned long *empty_zero_page; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) #define pte_none(x) ((pte_val(x) == 0) || (pte_val(x) & _PAGE_FLUSH)) #define pte_none(x) (pte_val(x) == 0) #define pte_present(x) (pte_val(x) & _PAGE_PRESENT) #define pte_clear(mm,addr,xp) do { pte_val(*(xp)) = 0; } while (0) Loading Loading @@ -444,13 +441,10 @@ struct mm_struct; static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t old_pte; pte_t pte; spin_lock(&pa_dbit_lock); pte = old_pte = *ptep; pte_val(pte) &= ~_PAGE_PRESENT; pte_val(pte) |= _PAGE_FLUSH; set_pte_at(mm,addr,ptep,pte); old_pte = *ptep; pte_clear(mm,addr,ptep); spin_unlock(&pa_dbit_lock); return old_pte; Loading arch/parisc/kernel/cache.c +17 −92 Original line number Diff line number Diff line Loading @@ -27,12 +27,17 @@ #include <asm/pgalloc.h> #include <asm/processor.h> #include <asm/sections.h> #include <asm/shmparam.h> int split_tlb __read_mostly; int dcache_stride __read_mostly; int icache_stride __read_mostly; EXPORT_SYMBOL(dcache_stride); void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); EXPORT_SYMBOL(flush_dcache_page_asm); void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr); /* On some machines (e.g. ones with the Merced bus), there can be * only a single PxTLB broadcast at a time; this must be guaranteed Loading Loading @@ -259,81 +264,13 @@ void disable_sr_hashing(void) panic("SpaceID hashing is still on!\n"); } /* Simple function to work out if we have an existing address translation * for a user space vma. */ static inline int translation_exists(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) { pgd_t *pgd = pgd_offset(vma->vm_mm, addr); pmd_t *pmd; pte_t pte; if(pgd_none(*pgd)) return 0; pmd = pmd_offset(pgd, addr); if(pmd_none(*pmd) || pmd_bad(*pmd)) return 0; /* We cannot take the pte lock here: flush_cache_page is usually * called with pte lock already held. Whereas flush_dcache_page * takes flush_dcache_mmap_lock, which is lower in the hierarchy: * the vma itself is secure, but the pte might come or go racily. */ pte = *pte_offset_map(pmd, addr); /* But pte_unmap() does nothing on this architecture */ /* Filter out coincidental file entries and swap entries */ if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT))) return 0; return pte_pfn(pte) == pfn; } /* Private function to flush a page from the cache of a non-current * process. cr25 contains the Page Directory of the current user * process; we're going to hijack both it and the user space %sr3 to * temporarily make the non-current process current. We have to do * this because cache flushing may cause a non-access tlb miss which * the handlers have to fill in from the pgd of the non-current * process. */ static inline void flush_user_cache_page_non_current(struct vm_area_struct *vma, unsigned long vmaddr) { /* save the current process space and pgd */ unsigned long space = mfsp(3), pgd = mfctl(25); /* we don't mind taking interrupts since they may not * do anything with user space, but we can't * be preempted here */ preempt_disable(); /* make us current */ mtctl(__pa(vma->vm_mm->pgd), 25); mtsp(vma->vm_mm->context, 3); flush_user_dcache_page(vmaddr); if(vma->vm_flags & VM_EXEC) flush_user_icache_page(vmaddr); /* put the old current process back */ mtsp(space, 3); mtctl(pgd, 25); preempt_enable(); } static inline void __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr) __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long physaddr) { if (likely(vma->vm_mm->context == mfsp(3))) { flush_user_dcache_page(vmaddr); flush_dcache_page_asm(physaddr, vmaddr); if (vma->vm_flags & VM_EXEC) flush_user_icache_page(vmaddr); } else { flush_user_cache_page_non_current(vma, vmaddr); } flush_icache_page_asm(physaddr, vmaddr); } void flush_dcache_page(struct page *page) Loading @@ -342,10 +279,8 @@ void flush_dcache_page(struct page *page) struct vm_area_struct *mpnt; struct prio_tree_iter iter; unsigned long offset; unsigned long addr; unsigned long addr, old_addr = 0; pgoff_t pgoff; unsigned long pfn = page_to_pfn(page); if (mapping && !mapping_mapped(mapping)) { set_bit(PG_dcache_dirty, &page->flags); Loading @@ -369,20 +304,11 @@ void flush_dcache_page(struct page *page) offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; addr = mpnt->vm_start + offset; /* Flush instructions produce non access tlb misses. * On PA, we nullify these instructions rather than * taking a page fault if the pte doesn't exist. * This is just for speed. If the page translation * isn't there, there's no point exciting the * nadtlb handler into a nullification frenzy. * * Make sure we really have this page: the private * mappings may cover this area but have COW'd this * particular page. */ if (translation_exists(mpnt, addr, pfn)) { __flush_cache_page(mpnt, addr); break; if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) { __flush_cache_page(mpnt, addr, page_to_phys(page)); if (old_addr) printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? mpnt->vm_file->f_path.dentry->d_name.name : "(null)"); old_addr = addr; } } flush_dcache_mmap_unlock(mapping); Loading Loading @@ -573,7 +499,6 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long { BUG_ON(!vma->vm_mm->context); if (likely(translation_exists(vma, vmaddr, pfn))) __flush_cache_page(vma, vmaddr); __flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn))); } arch/parisc/kernel/entry.S +126 −91 Original line number Diff line number Diff line Loading @@ -225,22 +225,13 @@ #ifndef CONFIG_64BIT /* * naitlb miss interruption handler (parisc 1.1 - 32 bit) * * Note: naitlb misses will be treated * as an ordinary itlb miss for now. * However, note that naitlb misses * have the faulting address in the * IOR/ISR. */ .macro naitlb_11 code mfctl %isr,spc b itlb_miss_11 b naitlb_miss_11 mfctl %ior,va /* FIXME: If user causes a naitlb miss, the priv level may not be in * lower bits of va, where the itlb miss handler is expecting them */ .align 32 .endm Loading @@ -248,26 +239,17 @@ /* * naitlb miss interruption handler (parisc 2.0) * * Note: naitlb misses will be treated * as an ordinary itlb miss for now. * However, note that naitlb misses * have the faulting address in the * IOR/ISR. */ .macro naitlb_20 code mfctl %isr,spc #ifdef CONFIG_64BIT b itlb_miss_20w b naitlb_miss_20w #else b itlb_miss_20 b naitlb_miss_20 #endif mfctl %ior,va /* FIXME: If user causes a naitlb miss, the priv level may not be in * lower bits of va, where the itlb miss handler is expecting them */ .align 32 .endm Loading Loading @@ -581,7 +563,24 @@ copy \va,\tmp1 depi 0,31,23,\tmp1 cmpb,COND(<>),n \tmp,\tmp1,\fault ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot mfctl %cr19,\tmp /* iir */ /* get the opcode (first six bits) into \tmp */ extrw,u \tmp,5,6,\tmp /* * Only setting the T bit prevents data cache movein * Setting access rights to zero prevents instruction cache movein * * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go * to type field and _PAGE_READ goes to top bit of PL1 */ ldi (_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot /* * so if the opcode is one (i.e. this is a memory management * instruction) nullify the next load so \prot is only T. * Otherwise this is a normal data operation */ cmpiclr,= 0x01,\tmp,%r0 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot depd,z \prot,8,7,\prot /* * OK, it is in the temp alias region, check whether "from" or "to". Loading Loading @@ -631,11 +630,7 @@ ENTRY(fault_vector_20) def 13 def 14 dtlb_20 15 #if 0 naitlb_20 16 #else def 16 #endif nadtlb_20 17 def 18 def 19 Loading Loading @@ -678,11 +673,7 @@ ENTRY(fault_vector_11) def 13 def 14 dtlb_11 15 #if 0 naitlb_11 16 #else def 16 #endif nadtlb_11 17 def 18 def 19 Loading Loading @@ -1203,7 +1194,7 @@ nadtlb_miss_20w: get_pgd spc,ptp space_check spc,t0,nadtlb_fault L3_ptep ptp,pte,t0,va,nadtlb_check_flush_20w L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w update_ptep ptp,pte,t0,t1 Loading @@ -1214,16 +1205,8 @@ nadtlb_miss_20w: rfir nop nadtlb_check_flush_20w: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ depdi,z 7,7,3,prot depdi 1,10,1,prot /* Drop prot bits from pte and convert to page addr for idtlbt */ convert_for_tlb_insert20 pte nadtlb_check_alias_20w: do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlbt pte,prot Loading Loading @@ -1255,25 +1238,7 @@ dtlb_miss_11: nop dtlb_check_alias_11: /* Check to see if fault is in the temporary alias region */ cmpib,<>,n 0,spc,dtlb_fault /* forward */ ldil L%(TMPALIAS_MAP_START),t0 copy va,t1 depwi 0,31,23,t1 cmpb,<>,n t0,t1,dtlb_fault /* forward */ ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot depw,z prot,8,7,prot /* * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26. */ extrw,u,= va,9,1,r0 or,tr %r23,%r0,pte /* If "from" use "from" page */ or %r26,%r0,pte /* else "to", use "to" page */ do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlba pte,(va) idtlbp prot,(va) Loading @@ -1286,7 +1251,7 @@ nadtlb_miss_11: space_check spc,t0,nadtlb_fault L2_ptep ptp,pte,t0,va,nadtlb_check_flush_11 L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11 update_ptep ptp,pte,t0,t1 Loading @@ -1304,26 +1269,11 @@ nadtlb_miss_11: rfir nop nadtlb_check_flush_11: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ zdepi 7,7,3,prot depi 1,10,1,prot nadtlb_check_alias_11: do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate /* Get rid of prot bits and convert to page addr for idtlba */ depi 0,31,ASM_PFN_PTE_SHIFT,pte SHRREG pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 idtlba pte,(%sr1,va) idtlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ idtlba pte,(va) idtlbp prot,(va) rfir nop Loading Loading @@ -1359,7 +1309,7 @@ nadtlb_miss_20: space_check spc,t0,nadtlb_fault L2_ptep ptp,pte,t0,va,nadtlb_check_flush_20 L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20 update_ptep ptp,pte,t0,t1 Loading @@ -1372,21 +1322,14 @@ nadtlb_miss_20: rfir nop nadtlb_check_flush_20: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ depdi,z 7,7,3,prot depdi 1,10,1,prot /* Drop prot bits from pte and convert to page addr for idtlbt */ convert_for_tlb_insert20 pte nadtlb_check_alias_20: do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlbt pte,prot rfir nop #endif nadtlb_emulate: Loading Loading @@ -1484,6 +1427,36 @@ itlb_miss_20w: rfir nop naitlb_miss_20w: /* * I miss is a little different, since we allow users to fault * on the gateway page which is in the kernel address space. */ space_adjust spc,va,t0 get_pgd spc,ptp space_check spc,t0,naitlb_fault L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot iitlbt pte,prot rfir nop naitlb_check_alias_20w: do_alias spc,t0,t1,va,pte,prot,naitlb_fault iitlbt pte,prot rfir nop #else itlb_miss_11: Loading @@ -1508,6 +1481,38 @@ itlb_miss_11: rfir nop naitlb_miss_11: get_pgd spc,ptp space_check spc,t0,naitlb_fault L2_ptep ptp,pte,t0,va,naitlb_check_alias_11 update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 iitlba pte,(%sr1,va) iitlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ rfir nop naitlb_check_alias_11: do_alias spc,t0,t1,va,pte,prot,itlb_fault iitlba pte,(%sr0, va) iitlbp prot,(%sr0, va) rfir nop itlb_miss_20: get_pgd spc,ptp Loading @@ -1526,6 +1531,32 @@ itlb_miss_20: rfir nop naitlb_miss_20: get_pgd spc,ptp space_check spc,t0,naitlb_fault L2_ptep ptp,pte,t0,va,naitlb_check_alias_20 update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 iitlbt pte,prot rfir nop naitlb_check_alias_20: do_alias spc,t0,t1,va,pte,prot,naitlb_fault iitlbt pte,prot rfir nop #endif #ifdef CONFIG_64BIT Loading Loading @@ -1662,6 +1693,10 @@ nadtlb_fault: b intr_save ldi 17,%r8 naitlb_fault: b intr_save ldi 16,%r8 dtlb_fault: b intr_save ldi 15,%r8 Loading arch/parisc/kernel/pacache.S +109 −136 Original line number Diff line number Diff line Loading @@ -608,93 +608,131 @@ ENTRY(__clear_user_page_asm) .procend ENDPROC(__clear_user_page_asm) ENTRY(flush_kernel_dcache_page_asm) ENTRY(flush_dcache_page_asm) .proc .callinfo NO_CALLS .entry ldil L%(TMPALIAS_MAP_START), %r28 #ifdef CONFIG_64BIT #if (TMPALIAS_MAP_START >= 0x80000000) depdi 0, 31,32, %r28 /* clear any sign extension */ /* FIXME: page size dependend */ #endif extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ depdi 0, 63,12, %r28 /* Clear any offset bits */ #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depwi 0, 31,12, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ pdtlb 0(%r28) ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 ldw R%dcache_stride(%r1), %r1 #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 #else depwi,z 1, 31-PAGE_SHIFT,1, %r25 #endif add %r26, %r25, %r25 sub %r25, %r23, %r25 1: fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) cmpb,COND(<<) %r26, %r25,1b fdc,m %r23(%r26) add %r28, %r25, %r25 sub %r25, %r1, %r25 1: fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) cmpb,COND(<<) %r28, %r25,1b fdc,m %r1(%r28) sync bv %r0(%r2) nop pdtlb (%r25) .exit .procend ENDPROC(flush_kernel_dcache_page_asm) ENDPROC(flush_dcache_page_asm) ENTRY(flush_user_dcache_page) ENTRY(flush_icache_page_asm) .proc .callinfo NO_CALLS .entry ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 ldil L%(TMPALIAS_MAP_START), %r28 #ifdef CONFIG_64BIT #if (TMPALIAS_MAP_START >= 0x80000000) depdi 0, 31,32, %r28 /* clear any sign extension */ /* FIXME: page size dependend */ #endif extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ depdi 0, 63,12, %r28 /* Clear any offset bits */ #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depwi 0, 31,12, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ pitlb (%sr0,%r28) ldil L%icache_stride, %r1 ldw R%icache_stride(%r1), %r1 #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 #else depwi,z 1, 31-PAGE_SHIFT,1, %r25 #endif add %r26, %r25, %r25 sub %r25, %r23, %r25 1: fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) cmpb,COND(<<) %r26, %r25,1b fdc,m %r23(%sr3, %r26) add %r28, %r25, %r25 sub %r25, %r1, %r25 1: fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) cmpb,COND(<<) %r28, %r25,1b fic,m %r1(%r28) sync bv %r0(%r2) nop pitlb (%sr0,%r25) .exit .procend ENDPROC(flush_user_dcache_page) ENDPROC(flush_icache_page_asm) ENTRY(flush_user_icache_page) ENTRY(flush_kernel_dcache_page_asm) .proc .callinfo NO_CALLS .entry Loading @@ -711,23 +749,23 @@ ENTRY(flush_user_icache_page) sub %r25, %r23, %r25 1: fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) 1: fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) cmpb,COND(<<) %r26, %r25,1b fic,m %r23(%sr3, %r26) fdc,m %r23(%r26) sync bv %r0(%r2) Loading @@ -735,8 +773,7 @@ ENTRY(flush_user_icache_page) .exit .procend ENDPROC(flush_user_icache_page) ENDPROC(flush_kernel_dcache_page_asm) ENTRY(purge_kernel_dcache_page) .proc Loading Loading @@ -780,69 +817,6 @@ ENTRY(purge_kernel_dcache_page) .procend ENDPROC(purge_kernel_dcache_page) #if 0 /* Currently not used, but it still is a possible alternate * solution. */ ENTRY(flush_alias_page) .proc .callinfo NO_CALLS .entry tophys_r1 %r26 ldil L%(TMPALIAS_MAP_START), %r28 #ifdef CONFIG_64BIT extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ depdi 0, 63,12, %r28 /* Clear any offset bits */ #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depwi 0, 31,12, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ pdtlb 0(%r28) ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r29 #else depwi,z 1, 31-PAGE_SHIFT,1, %r29 #endif add %r28, %r29, %r29 sub %r29, %r23, %r29 1: fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) cmpb,COND(<<) %r28, %r29, 1b fdc,m %r23(%r28) sync bv %r0(%r2) nop .exit .procend #endif .export flush_user_dcache_range_asm Loading @@ -865,7 +839,6 @@ flush_user_dcache_range_asm: .exit .procend ENDPROC(flush_alias_page) ENTRY(flush_kernel_dcache_range_asm) .proc Loading Loading
arch/parisc/include/asm/cacheflush.h +4 −3 Original line number Diff line number Diff line Loading @@ -26,8 +26,6 @@ void flush_user_dcache_range_asm(unsigned long, unsigned long); void flush_kernel_dcache_range_asm(unsigned long, unsigned long); void flush_kernel_dcache_page_asm(void *); void flush_kernel_icache_page(void *); void flush_user_dcache_page(unsigned long); void flush_user_icache_page(unsigned long); void flush_user_dcache_range(unsigned long, unsigned long); void flush_user_icache_range(unsigned long, unsigned long); Loading Loading @@ -90,12 +88,15 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); /* defined in pacache.S exported in cache.c used by flush_anon_page */ void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); #define ARCH_HAS_FLUSH_ANON_PAGE static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) { if (PageAnon(page)) flush_user_dcache_page(vmaddr); flush_dcache_page_asm(page_to_phys(page), vmaddr); } #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE Loading
arch/parisc/include/asm/pgtable.h +4 −10 Original line number Diff line number Diff line Loading @@ -138,8 +138,7 @@ struct vm_area_struct; #define _PAGE_NO_CACHE_BIT 24 /* (0x080) Uncached Page (U bit) */ #define _PAGE_ACCESSED_BIT 23 /* (0x100) Software: Page Accessed */ #define _PAGE_PRESENT_BIT 22 /* (0x200) Software: translation valid */ #define _PAGE_FLUSH_BIT 21 /* (0x400) Software: translation valid */ /* for cache flushing only */ /* bit 21 was formerly the FLUSH bit but is now unused */ #define _PAGE_USER_BIT 20 /* (0x800) Software: User accessible page */ /* N.B. The bits are defined in terms of a 32 bit word above, so the */ Loading Loading @@ -173,7 +172,6 @@ struct vm_area_struct; #define _PAGE_NO_CACHE (1 << xlate_pabit(_PAGE_NO_CACHE_BIT)) #define _PAGE_ACCESSED (1 << xlate_pabit(_PAGE_ACCESSED_BIT)) #define _PAGE_PRESENT (1 << xlate_pabit(_PAGE_PRESENT_BIT)) #define _PAGE_FLUSH (1 << xlate_pabit(_PAGE_FLUSH_BIT)) #define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT)) #define _PAGE_FILE (1 << xlate_pabit(_PAGE_FILE_BIT)) Loading Loading @@ -213,7 +211,6 @@ struct vm_area_struct; #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) #define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ) #define PAGE_FLUSH __pgprot(_PAGE_FLUSH) /* Loading Loading @@ -261,7 +258,7 @@ extern unsigned long *empty_zero_page; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) #define pte_none(x) ((pte_val(x) == 0) || (pte_val(x) & _PAGE_FLUSH)) #define pte_none(x) (pte_val(x) == 0) #define pte_present(x) (pte_val(x) & _PAGE_PRESENT) #define pte_clear(mm,addr,xp) do { pte_val(*(xp)) = 0; } while (0) Loading Loading @@ -444,13 +441,10 @@ struct mm_struct; static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t old_pte; pte_t pte; spin_lock(&pa_dbit_lock); pte = old_pte = *ptep; pte_val(pte) &= ~_PAGE_PRESENT; pte_val(pte) |= _PAGE_FLUSH; set_pte_at(mm,addr,ptep,pte); old_pte = *ptep; pte_clear(mm,addr,ptep); spin_unlock(&pa_dbit_lock); return old_pte; Loading
arch/parisc/kernel/cache.c +17 −92 Original line number Diff line number Diff line Loading @@ -27,12 +27,17 @@ #include <asm/pgalloc.h> #include <asm/processor.h> #include <asm/sections.h> #include <asm/shmparam.h> int split_tlb __read_mostly; int dcache_stride __read_mostly; int icache_stride __read_mostly; EXPORT_SYMBOL(dcache_stride); void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); EXPORT_SYMBOL(flush_dcache_page_asm); void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr); /* On some machines (e.g. ones with the Merced bus), there can be * only a single PxTLB broadcast at a time; this must be guaranteed Loading Loading @@ -259,81 +264,13 @@ void disable_sr_hashing(void) panic("SpaceID hashing is still on!\n"); } /* Simple function to work out if we have an existing address translation * for a user space vma. */ static inline int translation_exists(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) { pgd_t *pgd = pgd_offset(vma->vm_mm, addr); pmd_t *pmd; pte_t pte; if(pgd_none(*pgd)) return 0; pmd = pmd_offset(pgd, addr); if(pmd_none(*pmd) || pmd_bad(*pmd)) return 0; /* We cannot take the pte lock here: flush_cache_page is usually * called with pte lock already held. Whereas flush_dcache_page * takes flush_dcache_mmap_lock, which is lower in the hierarchy: * the vma itself is secure, but the pte might come or go racily. */ pte = *pte_offset_map(pmd, addr); /* But pte_unmap() does nothing on this architecture */ /* Filter out coincidental file entries and swap entries */ if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT))) return 0; return pte_pfn(pte) == pfn; } /* Private function to flush a page from the cache of a non-current * process. cr25 contains the Page Directory of the current user * process; we're going to hijack both it and the user space %sr3 to * temporarily make the non-current process current. We have to do * this because cache flushing may cause a non-access tlb miss which * the handlers have to fill in from the pgd of the non-current * process. */ static inline void flush_user_cache_page_non_current(struct vm_area_struct *vma, unsigned long vmaddr) { /* save the current process space and pgd */ unsigned long space = mfsp(3), pgd = mfctl(25); /* we don't mind taking interrupts since they may not * do anything with user space, but we can't * be preempted here */ preempt_disable(); /* make us current */ mtctl(__pa(vma->vm_mm->pgd), 25); mtsp(vma->vm_mm->context, 3); flush_user_dcache_page(vmaddr); if(vma->vm_flags & VM_EXEC) flush_user_icache_page(vmaddr); /* put the old current process back */ mtsp(space, 3); mtctl(pgd, 25); preempt_enable(); } static inline void __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr) __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long physaddr) { if (likely(vma->vm_mm->context == mfsp(3))) { flush_user_dcache_page(vmaddr); flush_dcache_page_asm(physaddr, vmaddr); if (vma->vm_flags & VM_EXEC) flush_user_icache_page(vmaddr); } else { flush_user_cache_page_non_current(vma, vmaddr); } flush_icache_page_asm(physaddr, vmaddr); } void flush_dcache_page(struct page *page) Loading @@ -342,10 +279,8 @@ void flush_dcache_page(struct page *page) struct vm_area_struct *mpnt; struct prio_tree_iter iter; unsigned long offset; unsigned long addr; unsigned long addr, old_addr = 0; pgoff_t pgoff; unsigned long pfn = page_to_pfn(page); if (mapping && !mapping_mapped(mapping)) { set_bit(PG_dcache_dirty, &page->flags); Loading @@ -369,20 +304,11 @@ void flush_dcache_page(struct page *page) offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; addr = mpnt->vm_start + offset; /* Flush instructions produce non access tlb misses. * On PA, we nullify these instructions rather than * taking a page fault if the pte doesn't exist. * This is just for speed. If the page translation * isn't there, there's no point exciting the * nadtlb handler into a nullification frenzy. * * Make sure we really have this page: the private * mappings may cover this area but have COW'd this * particular page. */ if (translation_exists(mpnt, addr, pfn)) { __flush_cache_page(mpnt, addr); break; if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) { __flush_cache_page(mpnt, addr, page_to_phys(page)); if (old_addr) printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? mpnt->vm_file->f_path.dentry->d_name.name : "(null)"); old_addr = addr; } } flush_dcache_mmap_unlock(mapping); Loading Loading @@ -573,7 +499,6 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long { BUG_ON(!vma->vm_mm->context); if (likely(translation_exists(vma, vmaddr, pfn))) __flush_cache_page(vma, vmaddr); __flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn))); }
arch/parisc/kernel/entry.S +126 −91 Original line number Diff line number Diff line Loading @@ -225,22 +225,13 @@ #ifndef CONFIG_64BIT /* * naitlb miss interruption handler (parisc 1.1 - 32 bit) * * Note: naitlb misses will be treated * as an ordinary itlb miss for now. * However, note that naitlb misses * have the faulting address in the * IOR/ISR. */ .macro naitlb_11 code mfctl %isr,spc b itlb_miss_11 b naitlb_miss_11 mfctl %ior,va /* FIXME: If user causes a naitlb miss, the priv level may not be in * lower bits of va, where the itlb miss handler is expecting them */ .align 32 .endm Loading @@ -248,26 +239,17 @@ /* * naitlb miss interruption handler (parisc 2.0) * * Note: naitlb misses will be treated * as an ordinary itlb miss for now. * However, note that naitlb misses * have the faulting address in the * IOR/ISR. */ .macro naitlb_20 code mfctl %isr,spc #ifdef CONFIG_64BIT b itlb_miss_20w b naitlb_miss_20w #else b itlb_miss_20 b naitlb_miss_20 #endif mfctl %ior,va /* FIXME: If user causes a naitlb miss, the priv level may not be in * lower bits of va, where the itlb miss handler is expecting them */ .align 32 .endm Loading Loading @@ -581,7 +563,24 @@ copy \va,\tmp1 depi 0,31,23,\tmp1 cmpb,COND(<>),n \tmp,\tmp1,\fault ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot mfctl %cr19,\tmp /* iir */ /* get the opcode (first six bits) into \tmp */ extrw,u \tmp,5,6,\tmp /* * Only setting the T bit prevents data cache movein * Setting access rights to zero prevents instruction cache movein * * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go * to type field and _PAGE_READ goes to top bit of PL1 */ ldi (_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot /* * so if the opcode is one (i.e. this is a memory management * instruction) nullify the next load so \prot is only T. * Otherwise this is a normal data operation */ cmpiclr,= 0x01,\tmp,%r0 ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot depd,z \prot,8,7,\prot /* * OK, it is in the temp alias region, check whether "from" or "to". Loading Loading @@ -631,11 +630,7 @@ ENTRY(fault_vector_20) def 13 def 14 dtlb_20 15 #if 0 naitlb_20 16 #else def 16 #endif nadtlb_20 17 def 18 def 19 Loading Loading @@ -678,11 +673,7 @@ ENTRY(fault_vector_11) def 13 def 14 dtlb_11 15 #if 0 naitlb_11 16 #else def 16 #endif nadtlb_11 17 def 18 def 19 Loading Loading @@ -1203,7 +1194,7 @@ nadtlb_miss_20w: get_pgd spc,ptp space_check spc,t0,nadtlb_fault L3_ptep ptp,pte,t0,va,nadtlb_check_flush_20w L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w update_ptep ptp,pte,t0,t1 Loading @@ -1214,16 +1205,8 @@ nadtlb_miss_20w: rfir nop nadtlb_check_flush_20w: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ depdi,z 7,7,3,prot depdi 1,10,1,prot /* Drop prot bits from pte and convert to page addr for idtlbt */ convert_for_tlb_insert20 pte nadtlb_check_alias_20w: do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlbt pte,prot Loading Loading @@ -1255,25 +1238,7 @@ dtlb_miss_11: nop dtlb_check_alias_11: /* Check to see if fault is in the temporary alias region */ cmpib,<>,n 0,spc,dtlb_fault /* forward */ ldil L%(TMPALIAS_MAP_START),t0 copy va,t1 depwi 0,31,23,t1 cmpb,<>,n t0,t1,dtlb_fault /* forward */ ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot depw,z prot,8,7,prot /* * OK, it is in the temp alias region, check whether "from" or "to". * Check "subtle" note in pacache.S re: r23/r26. */ extrw,u,= va,9,1,r0 or,tr %r23,%r0,pte /* If "from" use "from" page */ or %r26,%r0,pte /* else "to", use "to" page */ do_alias spc,t0,t1,va,pte,prot,dtlb_fault idtlba pte,(va) idtlbp prot,(va) Loading @@ -1286,7 +1251,7 @@ nadtlb_miss_11: space_check spc,t0,nadtlb_fault L2_ptep ptp,pte,t0,va,nadtlb_check_flush_11 L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11 update_ptep ptp,pte,t0,t1 Loading @@ -1304,26 +1269,11 @@ nadtlb_miss_11: rfir nop nadtlb_check_flush_11: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ zdepi 7,7,3,prot depi 1,10,1,prot nadtlb_check_alias_11: do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate /* Get rid of prot bits and convert to page addr for idtlba */ depi 0,31,ASM_PFN_PTE_SHIFT,pte SHRREG pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 idtlba pte,(%sr1,va) idtlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ idtlba pte,(va) idtlbp prot,(va) rfir nop Loading Loading @@ -1359,7 +1309,7 @@ nadtlb_miss_20: space_check spc,t0,nadtlb_fault L2_ptep ptp,pte,t0,va,nadtlb_check_flush_20 L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20 update_ptep ptp,pte,t0,t1 Loading @@ -1372,21 +1322,14 @@ nadtlb_miss_20: rfir nop nadtlb_check_flush_20: bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate /* Insert a "flush only" translation */ depdi,z 7,7,3,prot depdi 1,10,1,prot /* Drop prot bits from pte and convert to page addr for idtlbt */ convert_for_tlb_insert20 pte nadtlb_check_alias_20: do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate idtlbt pte,prot rfir nop #endif nadtlb_emulate: Loading Loading @@ -1484,6 +1427,36 @@ itlb_miss_20w: rfir nop naitlb_miss_20w: /* * I miss is a little different, since we allow users to fault * on the gateway page which is in the kernel address space. */ space_adjust spc,va,t0 get_pgd spc,ptp space_check spc,t0,naitlb_fault L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot iitlbt pte,prot rfir nop naitlb_check_alias_20w: do_alias spc,t0,t1,va,pte,prot,naitlb_fault iitlbt pte,prot rfir nop #else itlb_miss_11: Loading @@ -1508,6 +1481,38 @@ itlb_miss_11: rfir nop naitlb_miss_11: get_pgd spc,ptp space_check spc,t0,naitlb_fault L2_ptep ptp,pte,t0,va,naitlb_check_alias_11 update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ mtsp spc,%sr1 iitlba pte,(%sr1,va) iitlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ rfir nop naitlb_check_alias_11: do_alias spc,t0,t1,va,pte,prot,itlb_fault iitlba pte,(%sr0, va) iitlbp prot,(%sr0, va) rfir nop itlb_miss_20: get_pgd spc,ptp Loading @@ -1526,6 +1531,32 @@ itlb_miss_20: rfir nop naitlb_miss_20: get_pgd spc,ptp space_check spc,t0,naitlb_fault L2_ptep ptp,pte,t0,va,naitlb_check_alias_20 update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 iitlbt pte,prot rfir nop naitlb_check_alias_20: do_alias spc,t0,t1,va,pte,prot,naitlb_fault iitlbt pte,prot rfir nop #endif #ifdef CONFIG_64BIT Loading Loading @@ -1662,6 +1693,10 @@ nadtlb_fault: b intr_save ldi 17,%r8 naitlb_fault: b intr_save ldi 16,%r8 dtlb_fault: b intr_save ldi 15,%r8 Loading
arch/parisc/kernel/pacache.S +109 −136 Original line number Diff line number Diff line Loading @@ -608,93 +608,131 @@ ENTRY(__clear_user_page_asm) .procend ENDPROC(__clear_user_page_asm) ENTRY(flush_kernel_dcache_page_asm) ENTRY(flush_dcache_page_asm) .proc .callinfo NO_CALLS .entry ldil L%(TMPALIAS_MAP_START), %r28 #ifdef CONFIG_64BIT #if (TMPALIAS_MAP_START >= 0x80000000) depdi 0, 31,32, %r28 /* clear any sign extension */ /* FIXME: page size dependend */ #endif extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ depdi 0, 63,12, %r28 /* Clear any offset bits */ #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depwi 0, 31,12, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ pdtlb 0(%r28) ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 ldw R%dcache_stride(%r1), %r1 #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 #else depwi,z 1, 31-PAGE_SHIFT,1, %r25 #endif add %r26, %r25, %r25 sub %r25, %r23, %r25 1: fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) cmpb,COND(<<) %r26, %r25,1b fdc,m %r23(%r26) add %r28, %r25, %r25 sub %r25, %r1, %r25 1: fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) fdc,m %r1(%r28) cmpb,COND(<<) %r28, %r25,1b fdc,m %r1(%r28) sync bv %r0(%r2) nop pdtlb (%r25) .exit .procend ENDPROC(flush_kernel_dcache_page_asm) ENDPROC(flush_dcache_page_asm) ENTRY(flush_user_dcache_page) ENTRY(flush_icache_page_asm) .proc .callinfo NO_CALLS .entry ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 ldil L%(TMPALIAS_MAP_START), %r28 #ifdef CONFIG_64BIT #if (TMPALIAS_MAP_START >= 0x80000000) depdi 0, 31,32, %r28 /* clear any sign extension */ /* FIXME: page size dependend */ #endif extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ depdi 0, 63,12, %r28 /* Clear any offset bits */ #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depwi 0, 31,12, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ pitlb (%sr0,%r28) ldil L%icache_stride, %r1 ldw R%icache_stride(%r1), %r1 #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r25 #else depwi,z 1, 31-PAGE_SHIFT,1, %r25 #endif add %r26, %r25, %r25 sub %r25, %r23, %r25 1: fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) fdc,m %r23(%sr3, %r26) cmpb,COND(<<) %r26, %r25,1b fdc,m %r23(%sr3, %r26) add %r28, %r25, %r25 sub %r25, %r1, %r25 1: fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) fic,m %r1(%r28) cmpb,COND(<<) %r28, %r25,1b fic,m %r1(%r28) sync bv %r0(%r2) nop pitlb (%sr0,%r25) .exit .procend ENDPROC(flush_user_dcache_page) ENDPROC(flush_icache_page_asm) ENTRY(flush_user_icache_page) ENTRY(flush_kernel_dcache_page_asm) .proc .callinfo NO_CALLS .entry Loading @@ -711,23 +749,23 @@ ENTRY(flush_user_icache_page) sub %r25, %r23, %r25 1: fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) fic,m %r23(%sr3, %r26) 1: fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) fdc,m %r23(%r26) cmpb,COND(<<) %r26, %r25,1b fic,m %r23(%sr3, %r26) fdc,m %r23(%r26) sync bv %r0(%r2) Loading @@ -735,8 +773,7 @@ ENTRY(flush_user_icache_page) .exit .procend ENDPROC(flush_user_icache_page) ENDPROC(flush_kernel_dcache_page_asm) ENTRY(purge_kernel_dcache_page) .proc Loading Loading @@ -780,69 +817,6 @@ ENTRY(purge_kernel_dcache_page) .procend ENDPROC(purge_kernel_dcache_page) #if 0 /* Currently not used, but it still is a possible alternate * solution. */ ENTRY(flush_alias_page) .proc .callinfo NO_CALLS .entry tophys_r1 %r26 ldil L%(TMPALIAS_MAP_START), %r28 #ifdef CONFIG_64BIT extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ depdi 0, 63,12, %r28 /* Clear any offset bits */ #else extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depwi 0, 31,12, %r28 /* Clear any offset bits */ #endif /* Purge any old translation */ pdtlb 0(%r28) ldil L%dcache_stride, %r1 ldw R%dcache_stride(%r1), %r23 #ifdef CONFIG_64BIT depdi,z 1, 63-PAGE_SHIFT,1, %r29 #else depwi,z 1, 31-PAGE_SHIFT,1, %r29 #endif add %r28, %r29, %r29 sub %r29, %r23, %r29 1: fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) fdc,m %r23(%r28) cmpb,COND(<<) %r28, %r29, 1b fdc,m %r23(%r28) sync bv %r0(%r2) nop .exit .procend #endif .export flush_user_dcache_range_asm Loading @@ -865,7 +839,6 @@ flush_user_dcache_range_asm: .exit .procend ENDPROC(flush_alias_page) ENTRY(flush_kernel_dcache_range_asm) .proc Loading