Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * linux/arch/m68k/kernel/sys_m68k.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This file contains various random system calls that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * have a non-standard calling sequence on the Linux/m68k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/sem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/msg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/shm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/ipc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <asm/cachectl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <asm/tlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 			     unsigned long error_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	unsigned long prot, unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	unsigned long fd, unsigned long pgoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	 * This is wrong for sun3 - there PAGE_SIZE is 8Kb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	 * so we need to shift the argument down by 1; m68k mmap64(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	 * (in libc) expects the last argument of mmap2 in 4Kb units.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	return ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /* Convert virtual (user) address VADDR to physical address PADDR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define virt_to_phys_040(vaddr)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) ({									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)   unsigned long _mmusr, _paddr;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)   __asm__ __volatile__ (".chip 68040\n\t"				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			"ptestr (%1)\n\t"				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			"movec %%mmusr,%0\n\t"				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			".chip 68k"					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			: "=r" (_mmusr)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			: "a" (vaddr));					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)   _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0;		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)   _paddr;								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)   unsigned long paddr, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)   switch (scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)     case FLUSH_SCOPE_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)       switch (cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	case FLUSH_CACHE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	  /* This nop is needed for some broken versions of the 68040.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	  __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 				".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				"cpusha %dc\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 				".chip 68k");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	  break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	case FLUSH_CACHE_INSN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	  __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				"cpusha %ic\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 				".chip 68k");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	  break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	case FLUSH_CACHE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	  __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 				".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				"cpusha %bc\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 				".chip 68k");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	  break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)       break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)     case FLUSH_SCOPE_LINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)       /* Find the physical address of the first mapped page in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	 address range.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)       if ((paddr = virt_to_phys_040(addr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)         paddr += addr & ~(PAGE_MASK | 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)         len = (len + (addr & 15) + 15) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)       } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (len <= tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	  return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	addr += tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	len -= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	tmp = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	for (;;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	    if ((paddr = virt_to_phys_040(addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	    if (len <= tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	      return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	    addr += tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	    len -= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	  }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	len = (len + 15) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)       }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)       i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)       while (len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	  switch (cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	    {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	    case FLUSH_CACHE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	      __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				    ".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				    "cpushl %%dc,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	    case FLUSH_CACHE_INSN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	      __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 				    ".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 				    "cpushl %%ic,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	    default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	    case FLUSH_CACHE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	      __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 				    ".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 				    "cpushl %%bc,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	  if (!--i && len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	    {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	      /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	       * No need to page align here since it is done by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	       * virt_to_phys_040().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	      addr += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	      i = PAGE_SIZE / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	      /* Recompute physical address when crossing a page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	         boundary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	      for (;;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		  if ((paddr = virt_to_phys_040(addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		    break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		  if (len <= i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		    return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		  len -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		  addr += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	  else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	    paddr += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)       break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)     default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)     case FLUSH_SCOPE_PAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)       len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)       for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	  if (!(paddr = virt_to_phys_040(addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	    continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	  switch (cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	    {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	    case FLUSH_CACHE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	      __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 				    ".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 				    "cpushp %%dc,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	    case FLUSH_CACHE_INSN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	      __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 				    ".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 				    "cpushp %%ic,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	    default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	    case FLUSH_CACHE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	      __asm__ __volatile__ ("nop\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 				    ".chip 68040\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 				    "cpushp %%bc,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)       break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)   return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define virt_to_phys_060(vaddr)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ({							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)   unsigned long paddr;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)   __asm__ __volatile__ (".chip 68060\n\t"		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			"plpar (%0)\n\t"		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			".chip 68k"			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			: "=a" (paddr)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			: "0" (vaddr));			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)   (paddr); /* XXX */					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)   unsigned long paddr, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)   /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)    * 68060 manual says:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)    *  cpush %dc : flush DC, remains valid (with our %cacr setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)    *  cpush %ic : invalidate IC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)    *  cpush %bc : flush DC + invalidate IC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)   switch (scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)     case FLUSH_SCOPE_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)       switch (cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	case FLUSH_CACHE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	  __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 				"cpusha %dc\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 				".chip 68k");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	  break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	case FLUSH_CACHE_INSN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	  __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				"cpusha %ic\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				".chip 68k");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	  break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	case FLUSH_CACHE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	  __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 				"cpusha %bc\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 				".chip 68k");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	  break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)       break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)     case FLUSH_SCOPE_LINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)       /* Find the physical address of the first mapped page in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	 address range.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)       len += addr & 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)       addr &= -16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)       if (!(paddr = virt_to_phys_060(addr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if (len <= tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	  return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	addr += tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	len -= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	tmp = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	for (;;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	    if ((paddr = virt_to_phys_060(addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	    if (len <= tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	      return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	    addr += tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	    len -= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	  }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)       }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)       len = (len + 15) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)       i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)       while (len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	  switch (cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	    {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	    case FLUSH_CACHE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	      __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 				    "cpushl %%dc,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	    case FLUSH_CACHE_INSN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	      __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 				    "cpushl %%ic,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	    default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	    case FLUSH_CACHE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	      __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 				    "cpushl %%bc,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	  if (!--i && len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	    {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	      /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	       * We just want to jump to the first cache line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	       * in the next page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	      addr += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	      addr &= PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	      i = PAGE_SIZE / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	      /* Recompute physical address when crossing a page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	         boundary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	      for (;;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	        {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	          if ((paddr = virt_to_phys_060(addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	            break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	          if (len <= i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	            return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	          len -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	          addr += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	        }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	  else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	    paddr += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)       break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)     default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)     case FLUSH_SCOPE_PAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)       len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)       addr &= PAGE_MASK;	/* Workaround for bug in some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 				   revisions of the 68060 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)       for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	  if (!(paddr = virt_to_phys_060(addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	    continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	  switch (cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	    {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	    case FLUSH_CACHE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	      __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				    "cpushp %%dc,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	    case FLUSH_CACHE_INSN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	      __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 				    "cpushp %%ic,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	    default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	    case FLUSH_CACHE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	      __asm__ __volatile__ (".chip 68060\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 				    "cpushp %%bc,(%0)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				    ".chip 68k"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 				    : : "a" (paddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	      break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)       break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)   return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* sys_cacheflush -- flush (part of) the processor cache.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) asmlinkage int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	    cache & ~FLUSH_CACHE_BOTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	if (scope == FLUSH_SCOPE_ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		/* Only the superuser may explicitly flush the whole cache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		ret = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		mmap_read_lock(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		/* Check for overflow.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		if (addr + len < addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		 * Verify that the specified address region actually belongs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		 * to this process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		mmap_read_lock(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		vma = find_vma(current->mm, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		if (!vma || addr < vma->vm_start || addr + len > vma->vm_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	if (CPU_IS_020_OR_030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		if (scope == FLUSH_SCOPE_LINE && len < 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			unsigned long cacr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			if (cache & FLUSH_CACHE_INSN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 				cacr |= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 			if (cache & FLUSH_CACHE_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 				cacr |= 0x400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			len >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			while (len--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 				__asm__ __volatile__ ("movec %1, %%caar\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 						      "movec %0, %%cacr"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 						      : /* no outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 						      : "r" (cacr), "r" (addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 				addr += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			/* Flush the whole cache, even if page granularity requested. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			unsigned long cacr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			if (cache & FLUSH_CACHE_INSN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 				cacr |= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			if (cache & FLUSH_CACHE_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				cacr |= 0x800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			__asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	    /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	     * 040 or 060: don't blindly trust 'scope', someone could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	     * try to flush a few megs of memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	     */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	    if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	        scope=FLUSH_SCOPE_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	    if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	        scope=FLUSH_SCOPE_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	    if (CPU_IS_040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		ret = cache_flush_040 (addr, scope, cache, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	    } else if (CPU_IS_060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		ret = cache_flush_060 (addr, scope, cache, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	mmap_read_unlock(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* This syscall gets its arguments in A0 (mem), D2 (oldval) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)    D1 (newval).  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) asmlinkage int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		      unsigned long __user * mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	/* This was borrowed from ARM's implementation.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		pgd_t *pgd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		p4d_t *p4d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		pud_t *pud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		pmd_t *pmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		pte_t *pte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		spinlock_t *ptl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		unsigned long mem_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		mmap_read_lock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		pgd = pgd_offset(mm, (unsigned long)mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		if (!pgd_present(*pgd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			goto bad_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		p4d = p4d_offset(pgd, (unsigned long)mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		if (!p4d_present(*p4d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			goto bad_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		pud = pud_offset(p4d, (unsigned long)mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		if (!pud_present(*pud))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			goto bad_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		pmd = pmd_offset(pud, (unsigned long)mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		if (!pmd_present(*pmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			goto bad_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		if (!pte_present(*pte) || !pte_dirty(*pte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		    || !pte_write(*pte)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			pte_unmap_unlock(pte, ptl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 			goto bad_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		 * No need to check for EFAULT; we know that the page is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		 * present and writable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		__get_user(mem_value, mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		if (mem_value == oldval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			__put_user(newval, mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		pte_unmap_unlock(pte, ptl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		return mem_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	      bad_access:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		/* This is not necessarily a bad access, we can get here if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		   a memory we're trying to write to should be copied-on-write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		   Make the kernel do the necessary page stuff, then re-iterate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		   Simulate a write access fault to do that.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 			/* The first argument of the function corresponds to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			   D1, which is the first field of struct pt_regs.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 			struct pt_regs *fp = (struct pt_regs *)&newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			/* '3' is an RMW flag.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			if (do_page_fault(fp, (unsigned long)mem, 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 				/* If the do_page_fault() failed, we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 				   have anything meaningful to return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 				   There should be a SIGSEGV pending for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 				   the process.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 				return 0xdeadbeef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* sys_cacheflush -- flush (part of) the processor cache.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) asmlinkage int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	flush_cache_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* This syscall gets its arguments in A0 (mem), D2 (oldval) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)    D1 (newval).  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) asmlinkage int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		      unsigned long __user * mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	unsigned long mem_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	mmap_read_lock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	mem_value = *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	if (mem_value == oldval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		*mem = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	return mem_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #endif /* CONFIG_MMU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) asmlinkage int sys_getpagesize(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	return PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) asmlinkage unsigned long sys_get_thread_area(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	return current_thread_info()->tp_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) asmlinkage int sys_set_thread_area(unsigned long tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	current_thread_info()->tp_value = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) asmlinkage int sys_atomic_barrier(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	/* no code needed for uniprocs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }