patch-2.1.48 linux/arch/m68k/kernel/sys_m68k.c
Next file: linux/arch/mips/config.in
Previous file: linux/arch/m68k/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 264
- Date:
Thu Jul 31 13:09:16 1997
- Orig file:
v2.1.47/linux/arch/m68k/kernel/sys_m68k.c
- Orig date:
Sat May 24 09:10:22 1997
diff -u --recursive --new-file v2.1.47/linux/arch/m68k/kernel/sys_m68k.c linux/arch/m68k/kernel/sys_m68k.c
@@ -205,11 +205,10 @@
return -ENOSYS;
}
-/* Convert virtual address VADDR to physical address PADDR, recording
- in VALID whether the virtual address is actually mapped. */
-#define virt_to_phys_040(vaddr, paddr, valid) \
-{ \
- unsigned long _mmusr; \
+/* Convert virtual address VADDR to physical address PADDR */
+#define virt_to_phys_040(vaddr) \
+({ \
+ unsigned long _mmusr, _paddr; \
\
__asm__ __volatile__ (".chip 68040\n\t" \
"ptestr (%1)\n\t" \
@@ -217,20 +216,14 @@
".chip 68k" \
: "=r" (_mmusr) \
: "a" (vaddr)); \
- if (!(_mmusr & MMU_R_040)) \
- (valid) = 0; \
- else \
- { \
- (valid) = 1; \
- (paddr) = _mmusr & PAGE_MASK; \
- } \
-}
+ _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \
+ _paddr; \
+})
static inline int
cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
{
- unsigned long paddr;
- int valid;
+ unsigned long paddr, i;
switch (scope)
{
@@ -261,19 +254,31 @@
break;
case FLUSH_SCOPE_LINE:
- len >>= 4;
/* Find the physical address of the first mapped page in the
address range. */
- for (;;)
- {
- virt_to_phys_040 (addr, paddr, valid);
- if (valid)
- break;
- if (len <= PAGE_SIZE / 16)
- return 0;
- len -= (PAGE_SIZE - (addr & PAGE_MASK)) / 16;
- addr = (addr + PAGE_SIZE) & PAGE_MASK;
- }
+ if ((paddr = virt_to_phys_040(addr))) {
+ paddr += addr & ~(PAGE_MASK | 15);
+ len = (len + (addr & 15) + 15) >> 4;
+ } else {
+ unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
+
+ if (len <= tmp)
+ return 0;
+ addr += tmp;
+ len -= tmp;
+ tmp = PAGE_SIZE;
+ for (;;)
+ {
+ if ((paddr = virt_to_phys_040(addr)))
+ break;
+ if (len <= tmp)
+ return 0;
+ addr += tmp;
+ len -= tmp;
+ }
+ len = (len + 15) >> 4;
+ }
+ i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
while (len--)
{
switch (cache)
@@ -301,36 +306,33 @@
: : "a" (paddr));
break;
}
- addr += 16;
- if (len)
+ if (!--i && len)
{
- if ((addr & (PAGE_SIZE-1)) < 16)
+ addr += PAGE_SIZE;
+ i = PAGE_SIZE / 16;
+ /* Recompute physical address when crossing a page
+ boundary. */
+ for (;;)
{
- /* Recompute physical address when crossing a page
- boundary. */
- for (;;)
- {
- virt_to_phys_040 (addr, paddr, valid);
- if (valid)
- break;
- if (len <= PAGE_SIZE / 16)
- return 0;
- len -= (PAGE_SIZE - (addr & PAGE_MASK)) / 16;
- addr = (addr + PAGE_SIZE) & PAGE_MASK;
- }
+ if ((paddr = virt_to_phys_040(addr)))
+ break;
+ if (len <= i)
+ return 0;
+ len -= i;
+ addr += PAGE_SIZE;
}
- else
- paddr += 16;
}
+ else
+ paddr += 16;
}
break;
default:
case FLUSH_SCOPE_PAGE:
+ len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
{
- virt_to_phys_040 (addr, paddr, valid);
- if (!valid)
+ if (!(paddr = virt_to_phys_040(addr)))
continue;
switch (cache)
{
@@ -363,21 +365,21 @@
return 0;
}
-#define virt_to_phys_060(vaddr, paddr, valid) \
-{ \
+#define virt_to_phys_060(vaddr) \
+({ \
+ unsigned long paddr; \
__asm__ __volatile__ (".chip 68060\n\t" \
"plpar (%0)\n\t" \
".chip 68k" \
: "=a" (paddr) \
: "0" (vaddr)); \
- (valid) = 1; /* XXX */ \
-}
+ (paddr); /* XXX */ \
+})
static inline int
cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
{
- unsigned long paddr;
- int valid;
+ unsigned long paddr, i;
switch (scope)
{
@@ -407,19 +409,30 @@
break;
case FLUSH_SCOPE_LINE:
- len >>= 4;
/* Find the physical address of the first mapped page in the
address range. */
- for (;;)
- {
- virt_to_phys_060 (addr, paddr, valid);
- if (valid)
- break;
- if (len <= PAGE_SIZE / 16)
- return 0;
- len -= (PAGE_SIZE - (addr & PAGE_MASK)) / 16;
- addr = (addr + PAGE_SIZE) & PAGE_MASK;
- }
+ len += addr & 15;
+ addr &= -16;
+ if (!(paddr = virt_to_phys_060(addr))) {
+ unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
+
+ if (len <= tmp)
+ return 0;
+ addr += tmp;
+ len -= tmp;
+ tmp = PAGE_SIZE;
+ for (;;)
+ {
+ if ((paddr = virt_to_phys_060(addr)))
+ break;
+ if (len <= tmp)
+ return 0;
+ addr += tmp;
+ len -= tmp;
+ }
+ }
+ len = (len + 15) >> 4;
+ i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
while (len--)
{
switch (cache)
@@ -447,36 +460,35 @@
: : "a" (paddr));
break;
}
- addr += 16;
- if (len)
+ if (!--i && len)
{
- if ((addr & (PAGE_SIZE-1)) < 16)
- {
- /* Recompute the physical address when crossing a
- page boundary. */
- for (;;)
- {
- virt_to_phys_060 (addr, paddr, valid);
- if (valid)
- break;
- if (len <= PAGE_SIZE / 16)
- return 0;
- len -= (PAGE_SIZE - (addr & PAGE_MASK)) / 16;
- addr = (addr + PAGE_SIZE) & PAGE_MASK;
- }
- }
- else
- paddr += 16;
+ addr += PAGE_SIZE;
+ i = PAGE_SIZE / 16;
+ /* Recompute physical address when crossing a page
+ boundary. */
+ for (;;)
+ {
+ if ((paddr = virt_to_phys_060(addr)))
+ break;
+ if (len <= i)
+ return 0;
+ len -= i;
+ addr += PAGE_SIZE;
+ }
}
+ else
+ paddr += 16;
}
break;
default:
case FLUSH_SCOPE_PAGE:
+ len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
+ addr &= PAGE_MASK; /* Workaround for bug in some
+ revisions of the 68060 */
for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
{
- virt_to_phys_060 (addr, paddr, valid);
- if (!valid)
+ if (!(paddr = virt_to_phys_060(addr)))
continue;
switch (cache)
{
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov