From 98d655a68f864588ff21ae372ddd3563a6699f1c Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 15:58:06 +1000 Subject: [PATCH 01/22] m68k: merge mmu and non-mmu versions of muldi3 The implementation of gcc's muldi3 support function differs only in the use of the machine's 64 bit sized mul or not. (It isn't based on using an MMU or not). Merge the current mmu and non-mmu versions of arc/m68k/lib/muldi3 and use the appropriate pre-processor conditionals to get the right version for all m68k processor types. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/lib/muldi3.c | 99 +++++++++++++++++++++++++++++++++++++-- arch/m68k/lib/muldi3_mm.c | 63 ------------------------- arch/m68k/lib/muldi3_no.c | 86 ---------------------------------- 3 files changed, 96 insertions(+), 152 deletions(-) delete mode 100644 arch/m68k/lib/muldi3_mm.c delete mode 100644 arch/m68k/lib/muldi3_no.c diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c index 16e0eb338ee0..079bafca073e 100644 --- a/arch/m68k/lib/muldi3.c +++ b/arch/m68k/lib/muldi3.c @@ -1,5 +1,98 @@ -#ifdef CONFIG_MMU -#include "muldi3_mm.c" +/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and + gcc-2.7.2.3/longlong.h which is: */ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#if defined(__mc68020__) || defined(__mc68030__) || \ + defined(__mc68040__) || defined(__mc68060__) || defined(__mcpu32__) + +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "%0" ((USItype)(u)), \ + "dmi" ((USItype)(v))) + #else -#include "muldi3_no.c" + +#define SI_TYPE_SIZE 32 +#define __BITS4 (SI_TYPE_SIZE / 4) +#define __ll_B (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((USItype) (t) % __ll_B) +#define __ll_highpart(t) ((USItype) (t) / __ll_B) + +#define umul_ppmm(w1, w0, u, v) \ + do { \ + USItype __x0, __x1, __x2, __x3; \ + USItype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (USItype) __ul * __vl; \ + __x1 = (USItype) __ul * __vh; \ + __x2 = (USItype) __uh * __vl; \ + __x3 = (USItype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) + #endif + +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype +__muldi3 (DItype u, DItype v) +{ + DIunion w; + DIunion uu, vv; + + uu.ll = u, + vv.ll = v; + + w.ll = __umulsidi3 (uu.s.low, vv.s.low); + w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high + + (USItype) uu.s.high * (USItype) vv.s.low); + + return w.ll; +} diff --git a/arch/m68k/lib/muldi3_mm.c b/arch/m68k/lib/muldi3_mm.c deleted file mode 100644 index be4f275649e3..000000000000 --- a/arch/m68k/lib/muldi3_mm.c +++ /dev/null @@ -1,63 +0,0 @@ -/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and - gcc-2.7.2.3/longlong.h which is: */ -/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define BITS_PER_UNIT 8 - -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("mulu%.l %3,%1:%0" \ - : "=d" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ - : "%0" ((USItype)(u)), \ - "dmi" ((USItype)(v))) - -#define __umulsidi3(u, v) \ - ({DIunion __w; \ - umul_ppmm (__w.s.high, __w.s.low, u, v); \ - __w.ll; }) - -typedef int SItype __attribute__ ((mode (SI))); -typedef unsigned int USItype __attribute__ ((mode (SI))); -typedef int DItype __attribute__ ((mode (DI))); -typedef int word_type __attribute__ ((mode (__word__))); - -struct DIstruct {SItype high, low;}; - -typedef union -{ - struct DIstruct s; - DItype ll; -} DIunion; - -DItype -__muldi3 (DItype u, DItype v) -{ - DIunion w; - DIunion uu, vv; - - uu.ll = u, - vv.ll = v; - - w.ll = __umulsidi3 (uu.s.low, vv.s.low); - w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high - + (USItype) uu.s.high * (USItype) vv.s.low); - - return w.ll; -} diff --git a/arch/m68k/lib/muldi3_no.c b/arch/m68k/lib/muldi3_no.c deleted file mode 100644 index 34af72c30303..000000000000 --- a/arch/m68k/lib/muldi3_no.c +++ /dev/null @@ -1,86 +0,0 @@ -/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and - gcc-2.7.2.3/longlong.h which is: */ -/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define BITS_PER_UNIT 8 -#define SI_TYPE_SIZE 32 - -#define __BITS4 (SI_TYPE_SIZE / 4) -#define __ll_B (1L << (SI_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((USItype) (t) % __ll_B) -#define __ll_highpart(t) ((USItype) (t) / __ll_B) - -#define umul_ppmm(w1, w0, u, v) \ - do { \ - USItype __x0, __x1, __x2, __x3; \ - USItype __ul, __vl, __uh, __vh; \ - \ - __ul = __ll_lowpart (u); \ - __uh = __ll_highpart (u); \ - __vl = __ll_lowpart (v); \ - __vh = __ll_highpart (v); \ - \ - __x0 = (USItype) __ul * __vl; \ - __x1 = (USItype) __ul * __vh; \ - __x2 = (USItype) __uh * __vl; \ - __x3 = (USItype) __uh * __vh; \ - \ - __x1 += __ll_highpart (__x0);/* this can't give carry */ \ - __x1 += __x2; /* but this indeed can */ \ - if (__x1 < __x2) /* did we get it? */ \ - __x3 += __ll_B; /* yes, add it in the proper pos. */ \ - \ - (w1) = __x3 + __ll_highpart (__x1); \ - (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ - } while (0) - -#define __umulsidi3(u, v) \ - ({DIunion __w; \ - umul_ppmm (__w.s.high, __w.s.low, u, v); \ - __w.ll; }) - -typedef int SItype __attribute__ ((mode (SI))); -typedef unsigned int USItype __attribute__ ((mode (SI))); -typedef int DItype __attribute__ ((mode (DI))); -typedef int word_type __attribute__ ((mode (__word__))); - -struct DIstruct {SItype high, low;}; - -typedef union -{ - struct DIstruct s; - DItype ll; -} DIunion; - -DItype -__muldi3 (DItype u, DItype v) -{ - DIunion w; - DIunion uu, vv; - - uu.ll = u, - vv.ll = v; - - w.ll = __umulsidi3 (uu.s.low, vv.s.low); - w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high - + (USItype) uu.s.high * (USItype) vv.s.low); - - return w.ll; -} From b82ed87e67b081e55608b86b3e6f6f9036cedbd3 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 15:58:49 +1000 Subject: [PATCH 02/22] m68k: merge mmu and non-mmu versions of lib/Makefile We can easily support the slight differences in libs needed by the mmu and non-mmu builds in a single Makefile, so merge them back into a single file again. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/lib/Makefile | 13 +++++++++++-- arch/m68k/lib/Makefile_mm | 6 ------ arch/m68k/lib/Makefile_no | 7 ------- 3 files changed, 11 insertions(+), 15 deletions(-) delete mode 100644 arch/m68k/lib/Makefile_mm delete mode 100644 arch/m68k/lib/Makefile_no diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index 1f95881d8437..3d85fb6e6d3b 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -1,5 +1,14 @@ + +# +# Makefile for m68k-specific library files.. +# + +lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o checksum.o + ifdef CONFIG_MMU -include arch/m68k/lib/Makefile_mm +lib-y += string.o uaccess.o else -include arch/m68k/lib/Makefile_no +lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ + memcpy.o memmove.o memset.o delay.o endif + diff --git a/arch/m68k/lib/Makefile_mm b/arch/m68k/lib/Makefile_mm deleted file mode 100644 index af9abf8d9d98..000000000000 --- a/arch/m68k/lib/Makefile_mm +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for m68k-specific library files.. -# - -lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - checksum.o string.o uaccess.o diff --git a/arch/m68k/lib/Makefile_no b/arch/m68k/lib/Makefile_no deleted file mode 100644 index 32d852e586d7..000000000000 --- a/arch/m68k/lib/Makefile_no +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for m68knommu specific library files.. -# - -lib-y := ashldi3.o ashrdi3.o lshrdi3.o \ - muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ - checksum.o memcpy.o memmove.o memset.o delay.o From 80160de89d0a7c9a93dfe91eef2b448cbc380cd0 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 16:44:28 +1000 Subject: [PATCH 03/22] m68k: remove duplicate memmove() implementation Merging the mmu and non-mmu directories we ended up with duplicate (and identical) implementations of memmove(). Remove one of them. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/lib/Makefile | 4 +- arch/m68k/lib/memmove.c | 2 - arch/m68k/lib/string.c | 95 ----------------------------------------- 3 files changed, 2 insertions(+), 99 deletions(-) diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index 3d85fb6e6d3b..ec479a9b9d7b 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -3,12 +3,12 @@ # Makefile for m68k-specific library files.. # -lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o checksum.o +lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o memmove.o checksum.o ifdef CONFIG_MMU lib-y += string.o uaccess.o else lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ - memcpy.o memmove.o memset.o delay.o + memcpy.o memset.o delay.o endif diff --git a/arch/m68k/lib/memmove.c b/arch/m68k/lib/memmove.c index b3dcfe9dab7e..6519f7f349f6 100644 --- a/arch/m68k/lib/memmove.c +++ b/arch/m68k/lib/memmove.c @@ -4,8 +4,6 @@ * for more details. */ -#define __IN_STRING_C - #include #include diff --git a/arch/m68k/lib/string.c b/arch/m68k/lib/string.c index d399c5f25636..711fa743e6be 100644 --- a/arch/m68k/lib/string.c +++ b/arch/m68k/lib/string.c @@ -148,98 +148,3 @@ void *memcpy(void *to, const void *from, size_t n) return xto; } EXPORT_SYMBOL(memcpy); - -void *memmove(void *dest, const void *src, size_t n) -{ - void *xdest = dest; - size_t temp; - - if (!n) - return xdest; - - if (dest < src) { - if ((long)dest & 1) { - char *cdest = dest; - const char *csrc = src; - *cdest++ = *csrc++; - dest = cdest; - src = csrc; - n--; - } - if (n > 2 && (long)dest & 2) { - short *sdest = dest; - const short *ssrc = src; - *sdest++ = *ssrc++; - dest = sdest; - src = ssrc; - n -= 2; - } - temp = n >> 2; - if (temp) { - long *ldest = dest; - const long *lsrc = src; - temp--; - do - *ldest++ = *lsrc++; - while (temp--); - dest = ldest; - src = lsrc; - } - if (n & 2) { - short *sdest = dest; - const short *ssrc = src; - *sdest++ = *ssrc++; - dest = sdest; - src = ssrc; - } - if (n & 1) { - char *cdest = dest; - const char *csrc = src; - *cdest = *csrc; - } - } else { - dest = (char *)dest + n; - src = (const char *)src + n; - if ((long)dest & 1) { - char *cdest = dest; - const char *csrc = src; - *--cdest = *--csrc; - dest = cdest; - src = csrc; - n--; - } - if (n > 2 && (long)dest & 2) { - short *sdest = dest; - const short *ssrc = src; - *--sdest = *--ssrc; - dest = sdest; - src = ssrc; - n -= 2; - } - temp = n >> 2; - if (temp) { - long *ldest = dest; - const long *lsrc = src; - temp--; - do - *--ldest = *--lsrc; - while (temp--); - dest = ldest; - src = lsrc; - } - if (n & 2) { - short *sdest = dest; - const short *ssrc = src; - *--sdest = *--ssrc; - dest = sdest; - src = ssrc; - } - if (n & 1) { - char *cdest = dest; - const char *csrc = src; - *--cdest = *--csrc; - } - } - return xdest; -} -EXPORT_SYMBOL(memmove); From d10ed2f5383cc6e6b7649f03540b8cb1838d5f67 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 16:48:00 +1000 Subject: [PATCH 04/22] m68k: remove duplicate memset() implementation Merging the mmu and non-mmu directories we ended up with duplicate implementations of memset(). One is a little more optimized for the >= 68020 case, but that can easily be inserted into a single implementation of memset(). Clean up the exporting of this symbol too, otherwise we end up exporting it twice on a no-mmu build. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/m68k_ksyms_no.c | 1 - arch/m68k/lib/Makefile | 5 +- arch/m68k/lib/memset.c | 114 +++++++++++++++++++------------ arch/m68k/lib/string.c | 61 ----------------- 4 files changed, 74 insertions(+), 107 deletions(-) diff --git a/arch/m68k/kernel/m68k_ksyms_no.c b/arch/m68k/kernel/m68k_ksyms_no.c index 39fe0a7aec32..346bce63bbf3 100644 --- a/arch/m68k/kernel/m68k_ksyms_no.c +++ b/arch/m68k/kernel/m68k_ksyms_no.c @@ -36,7 +36,6 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck); their interface isn't gonna change any time soon now, so it's OK to leave it out of version control. */ EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(memset); /* * libgcc functions - functions that are used internally by the diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index ec479a9b9d7b..ac275d5e9e3c 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -3,12 +3,13 @@ # Makefile for m68k-specific library files.. # -lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o memmove.o checksum.o +lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ + memset.o memmove.o checksum.o ifdef CONFIG_MMU lib-y += string.o uaccess.o else lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ - memcpy.o memset.o delay.o + memcpy.o delay.o endif diff --git a/arch/m68k/lib/memset.c b/arch/m68k/lib/memset.c index 1389bf455633..f649e6a2e644 100644 --- a/arch/m68k/lib/memset.c +++ b/arch/m68k/lib/memset.c @@ -1,47 +1,75 @@ -#include +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ -void * memset(void * s, int c, size_t count) +#include +#include + +void *memset(void *s, int c, size_t count) { - void *xs = s; - size_t temp; + void *xs = s; + size_t temp; - if (!count) - return xs; - c &= 0xff; - c |= c << 8; - c |= c << 16; - if ((long) s & 1) - { - char *cs = s; - *cs++ = c; - s = cs; - count--; - } - if (count > 2 && (long) s & 2) - { - short *ss = s; - *ss++ = c; - s = ss; - count -= 2; - } - temp = count >> 2; - if (temp) - { - long *ls = s; - for (; temp; temp--) - *ls++ = c; - s = ls; - } - if (count & 2) - { - short *ss = s; - *ss++ = c; - s = ss; - } - if (count & 1) - { - char *cs = s; - *cs = c; - } - return xs; + if (!count) + return xs; + c &= 0xff; + c |= c << 8; + c |= c << 16; + if ((long)s & 1) { + char *cs = s; + *cs++ = c; + s = cs; + count--; + } + if (count > 2 && (long)s & 2) { + short *ss = s; + *ss++ = c; + s = ss; + count -= 2; + } + temp = count >> 2; + if (temp) { + long *ls = s; +#if defined(__mc68020__) || defined(__mc68030__) || \ + defined(__mc68040__) || defined(__mc68060__) || defined(__mcpu32__) + size_t temp1; + asm volatile ( + " movel %1,%2\n" + " andw #7,%2\n" + " lsrl #3,%1\n" + " negw %2\n" + " jmp %%pc@(2f,%2:w:2)\n" + "1: movel %3,%0@+\n" + " movel %3,%0@+\n" + " movel %3,%0@+\n" + " movel %3,%0@+\n" + " movel %3,%0@+\n" + " movel %3,%0@+\n" + " movel %3,%0@+\n" + " movel %3,%0@+\n" + "2: dbra %1,1b\n" + " clrw %1\n" + " subql #1,%1\n" + " jpl 1b" + : "=a" (ls), "=d" (temp), "=&d" (temp1) + : "d" (c), "0" (ls), "1" (temp)); +#else + for (; temp; temp--) + *ls++ = c; +#endif + s = ls; + } + if (count & 2) { + short *ss = s; + *ss++ = c; + s = ss; + } + if (count & 1) { + char *cs = s; + *cs = c; + } + return xs; } +EXPORT_SYMBOL(memset); diff --git a/arch/m68k/lib/string.c b/arch/m68k/lib/string.c index 711fa743e6be..6d2461237a16 100644 --- a/arch/m68k/lib/string.c +++ b/arch/m68k/lib/string.c @@ -21,67 +21,6 @@ char *strcat(char *dest, const char *src) } EXPORT_SYMBOL(strcat); -void *memset(void *s, int c, size_t count) -{ - void *xs = s; - size_t temp, temp1; - - if (!count) - return xs; - c &= 0xff; - c |= c << 8; - c |= c << 16; - if ((long)s & 1) { - char *cs = s; - *cs++ = c; - s = cs; - count--; - } - if (count > 2 && (long)s & 2) { - short *ss = s; - *ss++ = c; - s = ss; - count -= 2; - } - temp = count >> 2; - if (temp) { - long *ls = s; - - asm volatile ( - " movel %1,%2\n" - " andw #7,%2\n" - " lsrl #3,%1\n" - " negw %2\n" - " jmp %%pc@(2f,%2:w:2)\n" - "1: movel %3,%0@+\n" - " movel %3,%0@+\n" - " movel %3,%0@+\n" - " movel %3,%0@+\n" - " movel %3,%0@+\n" - " movel %3,%0@+\n" - " movel %3,%0@+\n" - " movel %3,%0@+\n" - "2: dbra %1,1b\n" - " clrw %1\n" - " subql #1,%1\n" - " jpl 1b" - : "=a" (ls), "=d" (temp), "=&d" (temp1) - : "d" (c), "0" (ls), "1" (temp)); - s = ls; - } - if (count & 2) { - short *ss = s; - *ss++ = c; - s = ss; - } - if (count & 1) { - char *cs = s; - *cs = c; - } - return xs; -} -EXPORT_SYMBOL(memset); - void *memcpy(void *to, const void *from, size_t n) { void *xto = to; From 66d83ab32aec5d84d707d4d72717b9468ec33a96 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 16:53:37 +1000 Subject: [PATCH 05/22] m68k: remove duplicate memcpy() implementation Merging the mmu and non-mmu directories we ended up with duplicate implementations of memcpy(). One is a little more optimized for the >= 68020 case, but that can easily be inserted into a single implementation of memcpy(). Clean up the exporting of this symbol too, otherwise we end up exporting it twice on a no-mmu build. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/m68k_ksyms_no.c | 6 -- arch/m68k/lib/Makefile | 5 +- arch/m68k/lib/memcpy.c | 128 ++++++++++++++++++------------- arch/m68k/lib/string.c | 67 ---------------- 4 files changed, 75 insertions(+), 131 deletions(-) diff --git a/arch/m68k/kernel/m68k_ksyms_no.c b/arch/m68k/kernel/m68k_ksyms_no.c index 346bce63bbf3..10af0af4ddef 100644 --- a/arch/m68k/kernel/m68k_ksyms_no.c +++ b/arch/m68k/kernel/m68k_ksyms_no.c @@ -31,12 +31,6 @@ EXPORT_SYMBOL(kernel_thread); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy_nocheck); -/* The following are special because they're not called - explicitly (the C compiler generates them). Fortunately, - their interface isn't gonna change any time soon now, so - it's OK to leave it out of version control. */ -EXPORT_SYMBOL(memcpy); - /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index ac275d5e9e3c..2438d02ebf43 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -4,12 +4,11 @@ # lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - memset.o memmove.o checksum.o + memcpy.o memset.o memmove.o checksum.o ifdef CONFIG_MMU lib-y += string.o uaccess.o else -lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ - memcpy.o delay.o +lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o delay.o endif diff --git a/arch/m68k/lib/memcpy.c b/arch/m68k/lib/memcpy.c index b50dbcad4746..62182c81e91c 100644 --- a/arch/m68k/lib/memcpy.c +++ b/arch/m68k/lib/memcpy.c @@ -1,62 +1,80 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ -#include +#include +#include -void * memcpy(void * to, const void * from, size_t n) +void *memcpy(void *to, const void *from, size_t n) { -#ifdef CONFIG_COLDFIRE - void *xto = to; - size_t temp; + void *xto = to; + size_t temp, temp1; - if (!n) - return xto; - if ((long) to & 1) - { - char *cto = to; - const char *cfrom = from; - *cto++ = *cfrom++; - to = cto; - from = cfrom; - n--; - } - if (n > 2 && (long) to & 2) - { - short *sto = to; - const short *sfrom = from; - *sto++ = *sfrom++; - to = sto; - from = sfrom; - n -= 2; - } - temp = n >> 2; - if (temp) - { - long *lto = to; - const long *lfrom = from; - for (; temp; temp--) - *lto++ = *lfrom++; - to = lto; - from = lfrom; - } - if (n & 2) - { - short *sto = to; - const short *sfrom = from; - *sto++ = *sfrom++; - to = sto; - from = sfrom; - } - if (n & 1) - { - char *cto = to; - const char *cfrom = from; - *cto = *cfrom; - } - return xto; + if (!n) + return xto; + if ((long)to & 1) { + char *cto = to; + const char *cfrom = from; + *cto++ = *cfrom++; + to = cto; + from = cfrom; + n--; + } + if (n > 2 && (long)to & 2) { + short *sto = to; + const short *sfrom = from; + *sto++ = *sfrom++; + to = sto; + from = sfrom; + n -= 2; + } + temp = n >> 2; + if (temp) { + long *lto = to; + const long *lfrom = from; +#if defined(__mc68020__) || defined(__mc68030__) || \ + defined(__mc68040__) || defined(__mc68060__) || defined(__mcpu32__) + asm volatile ( + " movel %2,%3\n" + " andw #7,%3\n" + " lsrl #3,%2\n" + " negw %3\n" + " jmp %%pc@(1f,%3:w:2)\n" + "4: movel %0@+,%1@+\n" + " movel %0@+,%1@+\n" + " movel %0@+,%1@+\n" + " movel %0@+,%1@+\n" + " movel %0@+,%1@+\n" + " movel %0@+,%1@+\n" + " movel %0@+,%1@+\n" + " movel %0@+,%1@+\n" + "1: dbra %2,4b\n" + " clrw %2\n" + " subql #1,%2\n" + " jpl 4b" + : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1) + : "0" (lfrom), "1" (lto), "2" (temp)); #else - const char *c_from = from; - char *c_to = to; - while (n-- > 0) - *c_to++ = *c_from++; - return((void *) to); + for (; temp; temp--) + *lto++ = *lfrom++; #endif + to = lto; + from = lfrom; + } + if (n & 2) { + short *sto = to; + const short *sfrom = from; + *sto++ = *sfrom++; + to = sto; + from = sfrom; + } + if (n & 1) { + char *cto = to; + const char *cfrom = from; + *cto = *cfrom; + } + return xto; } +EXPORT_SYMBOL(memcpy); diff --git a/arch/m68k/lib/string.c b/arch/m68k/lib/string.c index 6d2461237a16..b9a57abfad08 100644 --- a/arch/m68k/lib/string.c +++ b/arch/m68k/lib/string.c @@ -20,70 +20,3 @@ char *strcat(char *dest, const char *src) return __kernel_strcpy(dest + __kernel_strlen(dest), src); } EXPORT_SYMBOL(strcat); - -void *memcpy(void *to, const void *from, size_t n) -{ - void *xto = to; - size_t temp, temp1; - - if (!n) - return xto; - if ((long)to & 1) { - char *cto = to; - const char *cfrom = from; - *cto++ = *cfrom++; - to = cto; - from = cfrom; - n--; - } - if (n > 2 && (long)to & 2) { - short *sto = to; - const short *sfrom = from; - *sto++ = *sfrom++; - to = sto; - from = sfrom; - n -= 2; - } - temp = n >> 2; - if (temp) { - long *lto = to; - const long *lfrom = from; - - asm volatile ( - " movel %2,%3\n" - " andw #7,%3\n" - " lsrl #3,%2\n" - " negw %3\n" - " jmp %%pc@(1f,%3:w:2)\n" - "4: movel %0@+,%1@+\n" - " movel %0@+,%1@+\n" - " movel %0@+,%1@+\n" - " movel %0@+,%1@+\n" - " movel %0@+,%1@+\n" - " movel %0@+,%1@+\n" - " movel %0@+,%1@+\n" - " movel %0@+,%1@+\n" - "1: dbra %2,4b\n" - " clrw %2\n" - " subql #1,%2\n" - " jpl 4b" - : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1) - : "0" (lfrom), "1" (lto), "2" (temp)); - to = lto; - from = lfrom; - } - if (n & 2) { - short *sto = to; - const short *sfrom = from; - *sto++ = *sfrom++; - to = sto; - from = sfrom; - } - if (n & 1) { - char *cto = to; - const char *cfrom = from; - *cto = *cfrom; - } - return xto; -} -EXPORT_SYMBOL(memcpy); From 9461702d2a54cd4d9da09b7755c96815791a9d07 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 18 Apr 2011 15:27:55 +1000 Subject: [PATCH 06/22] m68k: let Makefile sort out compiling mmu and non-mmu lib/checksum.c We don't need an arch/m68k/lib/checksum.c wrapper to include the correct mmu or non-mmu version of the checksum code. Let the Makefile just build the appropriate one. Signed-off-by: Greg Ungerer --- arch/m68k/lib/Makefile | 6 +++--- arch/m68k/lib/checksum.c | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) delete mode 100644 arch/m68k/lib/checksum.c diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index 2438d02ebf43..df421e501436 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -4,11 +4,11 @@ # lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - memcpy.o memset.o memmove.o checksum.o + memcpy.o memset.o memmove.o ifdef CONFIG_MMU -lib-y += string.o uaccess.o +lib-y += string.o uaccess.o checksum_mm.o else -lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o delay.o +lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o delay.o checksum_no.o endif diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c deleted file mode 100644 index 1297536060de..000000000000 --- a/arch/m68k/lib/checksum.c +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef CONFIG_MMU -#include "checksum_mm.c" -#else -#include "checksum_no.c" -#endif From 92474a2513e828c27e371728845f24cef98748b2 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 18:00:08 +1000 Subject: [PATCH 07/22] m68knommu: remove unused kernel_set_cachemode() None of the m68knommu platforms will ever use kernel_set_cachemode(). And it is specific to a couple of m68k devices. So remove it. Signed-off-by: Greg Ungerer --- arch/m68k/mm/kmap_no.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/m68k/mm/kmap_no.c b/arch/m68k/mm/kmap_no.c index ece8d5ad4e6c..38b2abe9d9a5 100644 --- a/arch/m68k/mm/kmap_no.c +++ b/arch/m68k/mm/kmap_no.c @@ -35,11 +35,3 @@ void iounmap(void *addr) { } -/* - * Set new cache mode for some kernel address space. - * The caller must push data for that range itself, if such data may already - * be in the cache. - */ -void kernel_set_cachemode(void *addr, unsigned long size, int cmode) -{ -} From 593732bd41a6f16eeed9880ae7d51920fc5350ff Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 22:32:05 +1000 Subject: [PATCH 08/22] m68knommu: remove stubs for __ioremap() and iounmap() The implementation of iounmap() and __ioremap() for non-mmu m68k is trivial. We can inline them in m68knommu headers and remove the trivial implementations. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/io_no.h | 8 ++++--- arch/m68k/kernel/m68k_ksyms_no.c | 2 -- arch/m68k/mm/Makefile_no | 2 +- arch/m68k/mm/kmap_no.c | 37 -------------------------------- 4 files changed, 6 insertions(+), 43 deletions(-) delete mode 100644 arch/m68k/mm/kmap_no.c diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index cf20f3097af6..353bf754a972 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -144,8 +144,10 @@ static inline void io_insl(unsigned int addr, void *buf, int len) #define IOMAP_NOCACHE_NONSER 2 #define IOMAP_WRITETHROUGH 3 -extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); - +static inline void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) +{ + return (void *) physaddr; +} static inline void *ioremap(unsigned long physaddr, unsigned long size) { return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); @@ -163,7 +165,7 @@ static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size return __ioremap(physaddr, size, IOMAP_FULL_CACHING); } -extern void iounmap(void *addr); +#define iounmap(addr) do { } while(0) /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem diff --git a/arch/m68k/kernel/m68k_ksyms_no.c b/arch/m68k/kernel/m68k_ksyms_no.c index 10af0af4ddef..c26717bcf306 100644 --- a/arch/m68k/kernel/m68k_ksyms_no.c +++ b/arch/m68k/kernel/m68k_ksyms_no.c @@ -20,8 +20,6 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); /* platform dependent support */ -EXPORT_SYMBOL(__ioremap); -EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(ip_fast_csum); diff --git a/arch/m68k/mm/Makefile_no b/arch/m68k/mm/Makefile_no index b54ab6b4b523..80579c6a6881 100644 --- a/arch/m68k/mm/Makefile_no +++ b/arch/m68k/mm/Makefile_no @@ -2,4 +2,4 @@ # Makefile for the linux m68knommu specific parts of the memory manager. # -obj-y += init.o kmap.o +obj-y += init.o diff --git a/arch/m68k/mm/kmap_no.c b/arch/m68k/mm/kmap_no.c deleted file mode 100644 index 38b2abe9d9a5..000000000000 --- a/arch/m68k/mm/kmap_no.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * linux/arch/m68knommu/mm/kmap.c - * - * Copyright (C) 2000 Lineo, - * Copyright (C) 2000-2002 David McCullough - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#undef DEBUG - -/* - * Map some physical address range into the kernel address space. - */ -void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) -{ - return (void *)physaddr; -} - -/* - * Unmap a ioremap()ed region again. - */ -void iounmap(void *addr) -{ -} - From 1bccc43c1010f2ac88156c005fab6823569b0a39 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 22:37:13 +1000 Subject: [PATCH 09/22] m68k: mv kmap_mm.c to kmap.c The non-mmu kmap_no.c has been removed. So we can move kmap_mm.c back to being the only kmap.c. Signed-off-by: Greg Ungerer --- arch/m68k/mm/kmap.c | 368 ++++++++++++++++++++++++++++++++++++++++- arch/m68k/mm/kmap_mm.c | 367 ---------------------------------------- 2 files changed, 365 insertions(+), 370 deletions(-) delete mode 100644 arch/m68k/mm/kmap_mm.c diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index a373d136b2b2..69345849454b 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c @@ -1,5 +1,367 @@ -#ifdef CONFIG_MMU -#include "kmap_mm.c" +/* + * linux/arch/m68k/mm/kmap.c + * + * Copyright (C) 1997 Roman Hodek + * + * 10/01/99 cleaned up the code and changing to the same interface + * used by other architectures /Roman Zippel + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +#define PTRTREESIZE (256*1024) + +/* + * For 040/060 we can use the virtual memory area like other architectures, + * but for 020/030 we want to use early termination page descriptor and we + * can't mix this with normal page descriptors, so we have to copy that code + * (mm/vmalloc.c) and return appriorate aligned addresses. + */ + +#ifdef CPU_M68040_OR_M68060_ONLY + +#define IO_SIZE PAGE_SIZE + +static inline struct vm_struct *get_io_area(unsigned long size) +{ + return get_vm_area(size, VM_IOREMAP); +} + + +static inline void free_io_area(void *addr) +{ + vfree((void *)(PAGE_MASK & (unsigned long)addr)); +} + #else -#include "kmap_no.c" + +#define IO_SIZE (256*1024) + +static struct vm_struct *iolist; + +static struct vm_struct *get_io_area(unsigned long size) +{ + unsigned long addr; + struct vm_struct **p, *tmp, *area; + + area = kmalloc(sizeof(*area), GFP_KERNEL); + if (!area) + return NULL; + addr = KMAP_START; + for (p = &iolist; (tmp = *p) ; p = &tmp->next) { + if (size + addr < (unsigned long)tmp->addr) + break; + if (addr > KMAP_END-size) { + kfree(area); + return NULL; + } + addr = tmp->size + (unsigned long)tmp->addr; + } + area->addr = (void *)addr; + area->size = size + IO_SIZE; + area->next = *p; + *p = area; + return area; +} + +static inline void free_io_area(void *addr) +{ + struct vm_struct **p, *tmp; + + if (!addr) + return; + addr = (void *)((unsigned long)addr & -IO_SIZE); + for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { + if (tmp->addr == addr) { + *p = tmp->next; + __iounmap(tmp->addr, tmp->size); + kfree(tmp); + return; + } + } +} + #endif + +/* + * Map some physical address range into the kernel address space. + */ +/* Rewritten by Andreas Schwab to remove all races. */ + +void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) +{ + struct vm_struct *area; + unsigned long virtaddr, retaddr; + long offset; + pgd_t *pgd_dir; + pmd_t *pmd_dir; + pte_t *pte_dir; + + /* + * Don't allow mappings that wrap.. + */ + if (!size || physaddr > (unsigned long)(-size)) + return NULL; + +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) { + if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000) + && (cacheflag == IOMAP_NOCACHE_SER)) + return (void __iomem *)physaddr; + } +#endif + +#ifdef DEBUG + printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag); +#endif + /* + * Mappings have to be aligned + */ + offset = physaddr & (IO_SIZE - 1); + physaddr &= -IO_SIZE; + size = (size + offset + IO_SIZE - 1) & -IO_SIZE; + + /* + * Ok, go for it.. + */ + area = get_io_area(size); + if (!area) + return NULL; + + virtaddr = (unsigned long)area->addr; + retaddr = virtaddr + offset; +#ifdef DEBUG + printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr); +#endif + + /* + * add cache and table flags to physical address + */ + if (CPU_IS_040_OR_060) { + physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 | + _PAGE_ACCESSED | _PAGE_DIRTY); + switch (cacheflag) { + case IOMAP_FULL_CACHING: + physaddr |= _PAGE_CACHE040; + break; + case IOMAP_NOCACHE_SER: + default: + physaddr |= _PAGE_NOCACHE_S; + break; + case IOMAP_NOCACHE_NONSER: + physaddr |= _PAGE_NOCACHE; + break; + case IOMAP_WRITETHROUGH: + physaddr |= _PAGE_CACHE040W; + break; + } + } else { + physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); + switch (cacheflag) { + case IOMAP_NOCACHE_SER: + case IOMAP_NOCACHE_NONSER: + default: + physaddr |= _PAGE_NOCACHE030; + break; + case IOMAP_FULL_CACHING: + case IOMAP_WRITETHROUGH: + break; + } + } + + while ((long)size > 0) { +#ifdef DEBUG + if (!(virtaddr & (PTRTREESIZE-1))) + printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); +#endif + pgd_dir = pgd_offset_k(virtaddr); + pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); + if (!pmd_dir) { + printk("ioremap: no mem for pmd_dir\n"); + return NULL; + } + + if (CPU_IS_020_OR_030) { + pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr; + physaddr += PTRTREESIZE; + virtaddr += PTRTREESIZE; + size -= PTRTREESIZE; + } else { + pte_dir = pte_alloc_kernel(pmd_dir, virtaddr); + if (!pte_dir) { + printk("ioremap: no mem for pte_dir\n"); + return NULL; + } + + pte_val(*pte_dir) = physaddr; + virtaddr += PAGE_SIZE; + physaddr += PAGE_SIZE; + size -= PAGE_SIZE; + } + } +#ifdef DEBUG + printk("\n"); +#endif + flush_tlb_all(); + + return (void __iomem *)retaddr; +} +EXPORT_SYMBOL(__ioremap); + +/* + * Unmap a ioremap()ed region again + */ +void iounmap(void __iomem *addr) +{ +#ifdef CONFIG_AMIGA + if ((!MACH_IS_AMIGA) || + (((unsigned long)addr < 0x40000000) || + ((unsigned long)addr > 0x60000000))) + free_io_area((__force void *)addr); +#else + free_io_area((__force void *)addr); +#endif +} +EXPORT_SYMBOL(iounmap); + +/* + * __iounmap unmaps nearly everything, so be careful + * it doesn't free currently pointer/page tables anymore but it + * wans't used anyway and might be added later. + */ +void __iounmap(void *addr, unsigned long size) +{ + unsigned long virtaddr = (unsigned long)addr; + pgd_t *pgd_dir; + pmd_t *pmd_dir; + pte_t *pte_dir; + + while ((long)size > 0) { + pgd_dir = pgd_offset_k(virtaddr); + if (pgd_bad(*pgd_dir)) { + printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); + pgd_clear(pgd_dir); + return; + } + pmd_dir = pmd_offset(pgd_dir, virtaddr); + + if (CPU_IS_020_OR_030) { + int pmd_off = (virtaddr/PTRTREESIZE) & 15; + int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK; + + if (pmd_type == _PAGE_PRESENT) { + pmd_dir->pmd[pmd_off] = 0; + virtaddr += PTRTREESIZE; + size -= PTRTREESIZE; + continue; + } else if (pmd_type == 0) + continue; + } + + if (pmd_bad(*pmd_dir)) { + printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); + pmd_clear(pmd_dir); + return; + } + pte_dir = pte_offset_kernel(pmd_dir, virtaddr); + + pte_val(*pte_dir) = 0; + virtaddr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + flush_tlb_all(); +} + +/* + * Set new cache mode for some kernel address space. + * The caller must push data for that range itself, if such data may already + * be in the cache. + */ +void kernel_set_cachemode(void *addr, unsigned long size, int cmode) +{ + unsigned long virtaddr = (unsigned long)addr; + pgd_t *pgd_dir; + pmd_t *pmd_dir; + pte_t *pte_dir; + + if (CPU_IS_040_OR_060) { + switch (cmode) { + case IOMAP_FULL_CACHING: + cmode = _PAGE_CACHE040; + break; + case IOMAP_NOCACHE_SER: + default: + cmode = _PAGE_NOCACHE_S; + break; + case IOMAP_NOCACHE_NONSER: + cmode = _PAGE_NOCACHE; + break; + case IOMAP_WRITETHROUGH: + cmode = _PAGE_CACHE040W; + break; + } + } else { + switch (cmode) { + case IOMAP_NOCACHE_SER: + case IOMAP_NOCACHE_NONSER: + default: + cmode = _PAGE_NOCACHE030; + break; + case IOMAP_FULL_CACHING: + case IOMAP_WRITETHROUGH: + cmode = 0; + } + } + + while ((long)size > 0) { + pgd_dir = pgd_offset_k(virtaddr); + if (pgd_bad(*pgd_dir)) { + printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); + pgd_clear(pgd_dir); + return; + } + pmd_dir = pmd_offset(pgd_dir, virtaddr); + + if (CPU_IS_020_OR_030) { + int pmd_off = (virtaddr/PTRTREESIZE) & 15; + + if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) { + pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] & + _CACHEMASK040) | cmode; + virtaddr += PTRTREESIZE; + size -= PTRTREESIZE; + continue; + } + } + + if (pmd_bad(*pmd_dir)) { + printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); + pmd_clear(pmd_dir); + return; + } + pte_dir = pte_offset_kernel(pmd_dir, virtaddr); + + pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode; + virtaddr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + flush_tlb_all(); +} +EXPORT_SYMBOL(kernel_set_cachemode); diff --git a/arch/m68k/mm/kmap_mm.c b/arch/m68k/mm/kmap_mm.c deleted file mode 100644 index 69345849454b..000000000000 --- a/arch/m68k/mm/kmap_mm.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * linux/arch/m68k/mm/kmap.c - * - * Copyright (C) 1997 Roman Hodek - * - * 10/01/99 cleaned up the code and changing to the same interface - * used by other architectures /Roman Zippel - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#undef DEBUG - -#define PTRTREESIZE (256*1024) - -/* - * For 040/060 we can use the virtual memory area like other architectures, - * but for 020/030 we want to use early termination page descriptor and we - * can't mix this with normal page descriptors, so we have to copy that code - * (mm/vmalloc.c) and return appriorate aligned addresses. - */ - -#ifdef CPU_M68040_OR_M68060_ONLY - -#define IO_SIZE PAGE_SIZE - -static inline struct vm_struct *get_io_area(unsigned long size) -{ - return get_vm_area(size, VM_IOREMAP); -} - - -static inline void free_io_area(void *addr) -{ - vfree((void *)(PAGE_MASK & (unsigned long)addr)); -} - -#else - -#define IO_SIZE (256*1024) - -static struct vm_struct *iolist; - -static struct vm_struct *get_io_area(unsigned long size) -{ - unsigned long addr; - struct vm_struct **p, *tmp, *area; - - area = kmalloc(sizeof(*area), GFP_KERNEL); - if (!area) - return NULL; - addr = KMAP_START; - for (p = &iolist; (tmp = *p) ; p = &tmp->next) { - if (size + addr < (unsigned long)tmp->addr) - break; - if (addr > KMAP_END-size) { - kfree(area); - return NULL; - } - addr = tmp->size + (unsigned long)tmp->addr; - } - area->addr = (void *)addr; - area->size = size + IO_SIZE; - area->next = *p; - *p = area; - return area; -} - -static inline void free_io_area(void *addr) -{ - struct vm_struct **p, *tmp; - - if (!addr) - return; - addr = (void *)((unsigned long)addr & -IO_SIZE); - for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { - if (tmp->addr == addr) { - *p = tmp->next; - __iounmap(tmp->addr, tmp->size); - kfree(tmp); - return; - } - } -} - -#endif - -/* - * Map some physical address range into the kernel address space. - */ -/* Rewritten by Andreas Schwab to remove all races. */ - -void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) -{ - struct vm_struct *area; - unsigned long virtaddr, retaddr; - long offset; - pgd_t *pgd_dir; - pmd_t *pmd_dir; - pte_t *pte_dir; - - /* - * Don't allow mappings that wrap.. - */ - if (!size || physaddr > (unsigned long)(-size)) - return NULL; - -#ifdef CONFIG_AMIGA - if (MACH_IS_AMIGA) { - if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000) - && (cacheflag == IOMAP_NOCACHE_SER)) - return (void __iomem *)physaddr; - } -#endif - -#ifdef DEBUG - printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag); -#endif - /* - * Mappings have to be aligned - */ - offset = physaddr & (IO_SIZE - 1); - physaddr &= -IO_SIZE; - size = (size + offset + IO_SIZE - 1) & -IO_SIZE; - - /* - * Ok, go for it.. - */ - area = get_io_area(size); - if (!area) - return NULL; - - virtaddr = (unsigned long)area->addr; - retaddr = virtaddr + offset; -#ifdef DEBUG - printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr); -#endif - - /* - * add cache and table flags to physical address - */ - if (CPU_IS_040_OR_060) { - physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 | - _PAGE_ACCESSED | _PAGE_DIRTY); - switch (cacheflag) { - case IOMAP_FULL_CACHING: - physaddr |= _PAGE_CACHE040; - break; - case IOMAP_NOCACHE_SER: - default: - physaddr |= _PAGE_NOCACHE_S; - break; - case IOMAP_NOCACHE_NONSER: - physaddr |= _PAGE_NOCACHE; - break; - case IOMAP_WRITETHROUGH: - physaddr |= _PAGE_CACHE040W; - break; - } - } else { - physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); - switch (cacheflag) { - case IOMAP_NOCACHE_SER: - case IOMAP_NOCACHE_NONSER: - default: - physaddr |= _PAGE_NOCACHE030; - break; - case IOMAP_FULL_CACHING: - case IOMAP_WRITETHROUGH: - break; - } - } - - while ((long)size > 0) { -#ifdef DEBUG - if (!(virtaddr & (PTRTREESIZE-1))) - printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); -#endif - pgd_dir = pgd_offset_k(virtaddr); - pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); - if (!pmd_dir) { - printk("ioremap: no mem for pmd_dir\n"); - return NULL; - } - - if (CPU_IS_020_OR_030) { - pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr; - physaddr += PTRTREESIZE; - virtaddr += PTRTREESIZE; - size -= PTRTREESIZE; - } else { - pte_dir = pte_alloc_kernel(pmd_dir, virtaddr); - if (!pte_dir) { - printk("ioremap: no mem for pte_dir\n"); - return NULL; - } - - pte_val(*pte_dir) = physaddr; - virtaddr += PAGE_SIZE; - physaddr += PAGE_SIZE; - size -= PAGE_SIZE; - } - } -#ifdef DEBUG - printk("\n"); -#endif - flush_tlb_all(); - - return (void __iomem *)retaddr; -} -EXPORT_SYMBOL(__ioremap); - -/* - * Unmap a ioremap()ed region again - */ -void iounmap(void __iomem *addr) -{ -#ifdef CONFIG_AMIGA - if ((!MACH_IS_AMIGA) || - (((unsigned long)addr < 0x40000000) || - ((unsigned long)addr > 0x60000000))) - free_io_area((__force void *)addr); -#else - free_io_area((__force void *)addr); -#endif -} -EXPORT_SYMBOL(iounmap); - -/* - * __iounmap unmaps nearly everything, so be careful - * it doesn't free currently pointer/page tables anymore but it - * wans't used anyway and might be added later. - */ -void __iounmap(void *addr, unsigned long size) -{ - unsigned long virtaddr = (unsigned long)addr; - pgd_t *pgd_dir; - pmd_t *pmd_dir; - pte_t *pte_dir; - - while ((long)size > 0) { - pgd_dir = pgd_offset_k(virtaddr); - if (pgd_bad(*pgd_dir)) { - printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); - pgd_clear(pgd_dir); - return; - } - pmd_dir = pmd_offset(pgd_dir, virtaddr); - - if (CPU_IS_020_OR_030) { - int pmd_off = (virtaddr/PTRTREESIZE) & 15; - int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK; - - if (pmd_type == _PAGE_PRESENT) { - pmd_dir->pmd[pmd_off] = 0; - virtaddr += PTRTREESIZE; - size -= PTRTREESIZE; - continue; - } else if (pmd_type == 0) - continue; - } - - if (pmd_bad(*pmd_dir)) { - printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); - pmd_clear(pmd_dir); - return; - } - pte_dir = pte_offset_kernel(pmd_dir, virtaddr); - - pte_val(*pte_dir) = 0; - virtaddr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - flush_tlb_all(); -} - -/* - * Set new cache mode for some kernel address space. - * The caller must push data for that range itself, if such data may already - * be in the cache. - */ -void kernel_set_cachemode(void *addr, unsigned long size, int cmode) -{ - unsigned long virtaddr = (unsigned long)addr; - pgd_t *pgd_dir; - pmd_t *pmd_dir; - pte_t *pte_dir; - - if (CPU_IS_040_OR_060) { - switch (cmode) { - case IOMAP_FULL_CACHING: - cmode = _PAGE_CACHE040; - break; - case IOMAP_NOCACHE_SER: - default: - cmode = _PAGE_NOCACHE_S; - break; - case IOMAP_NOCACHE_NONSER: - cmode = _PAGE_NOCACHE; - break; - case IOMAP_WRITETHROUGH: - cmode = _PAGE_CACHE040W; - break; - } - } else { - switch (cmode) { - case IOMAP_NOCACHE_SER: - case IOMAP_NOCACHE_NONSER: - default: - cmode = _PAGE_NOCACHE030; - break; - case IOMAP_FULL_CACHING: - case IOMAP_WRITETHROUGH: - cmode = 0; - } - } - - while ((long)size > 0) { - pgd_dir = pgd_offset_k(virtaddr); - if (pgd_bad(*pgd_dir)) { - printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); - pgd_clear(pgd_dir); - return; - } - pmd_dir = pmd_offset(pgd_dir, virtaddr); - - if (CPU_IS_020_OR_030) { - int pmd_off = (virtaddr/PTRTREESIZE) & 15; - - if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) { - pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] & - _CACHEMASK040) | cmode; - virtaddr += PTRTREESIZE; - size -= PTRTREESIZE; - continue; - } - } - - if (pmd_bad(*pmd_dir)) { - printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); - pmd_clear(pmd_dir); - return; - } - pte_dir = pte_offset_kernel(pmd_dir, virtaddr); - - pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode; - virtaddr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - flush_tlb_all(); -} -EXPORT_SYMBOL(kernel_set_cachemode); From f225c8675086b60d85264ef824568309163d79f8 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Mar 2011 22:38:48 +1000 Subject: [PATCH 10/22] m68k: merge the mmu and non-mmu mm/Makefile Its is trivial to megre the mmu and non-mmu arch/m68k/mm/Makefile's back into a single file. So do it. Signed-off-by: Greg Ungerer --- arch/m68k/mm/Makefile | 14 +++++++++----- arch/m68k/mm/Makefile_mm | 8 -------- arch/m68k/mm/Makefile_no | 5 ----- 3 files changed, 9 insertions(+), 18 deletions(-) delete mode 100644 arch/m68k/mm/Makefile_mm delete mode 100644 arch/m68k/mm/Makefile_no diff --git a/arch/m68k/mm/Makefile b/arch/m68k/mm/Makefile index b60270e4954b..09cadf1058d5 100644 --- a/arch/m68k/mm/Makefile +++ b/arch/m68k/mm/Makefile @@ -1,5 +1,9 @@ -ifdef CONFIG_MMU -include arch/m68k/mm/Makefile_mm -else -include arch/m68k/mm/Makefile_no -endif +# +# Makefile for the linux m68k-specific parts of the memory manager. +# + +obj-y := init.o + +obj-$(CONFIG_MMU) += cache.o fault.o hwtest.o +obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o +obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o diff --git a/arch/m68k/mm/Makefile_mm b/arch/m68k/mm/Makefile_mm deleted file mode 100644 index 5eaa43c4cb3c..000000000000 --- a/arch/m68k/mm/Makefile_mm +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the linux m68k-specific parts of the memory manager. -# - -obj-y := cache.o init.o fault.o hwtest.o - -obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o -obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o diff --git a/arch/m68k/mm/Makefile_no b/arch/m68k/mm/Makefile_no deleted file mode 100644 index 80579c6a6881..000000000000 --- a/arch/m68k/mm/Makefile_no +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the linux m68knommu specific parts of the memory manager. -# - -obj-y += init.o From b1ffa25925c8166003d985b2803854fedcd44604 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 29 Mar 2011 13:39:47 +1000 Subject: [PATCH 11/22] m68knommu: clean up mm/init_no.c The memory initialization code for m68knommu has grown a bit crufty, clean it up. . remove unused declaration for die_if_kernel() . remove un-needed declaration of free_initmem() . removed unused definitions of empty_bad_page and empty_bad_page_table . removed unused DEBUG code . make free_initmem() proper prototype Signed-off-by: Greg Ungerer --- arch/m68k/mm/init_no.c | 51 ++++-------------------------------------- 1 file changed, 4 insertions(+), 47 deletions(-) diff --git a/arch/m68k/mm/init_no.c b/arch/m68k/mm/init_no.c index 8a6653f56bd8..7cbd7bd1f8bc 100644 --- a/arch/m68k/mm/init_no.c +++ b/arch/m68k/mm/init_no.c @@ -38,28 +38,10 @@ #include #include -#undef DEBUG - -extern void die_if_kernel(char *,struct pt_regs *,long); -extern void free_initmem(void); - /* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving a inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * * ZERO_PAGE is a special page that is used for zero-initialized * data and COW. */ -static unsigned long empty_bad_page_table; - -static unsigned long empty_bad_page; - unsigned long empty_zero_page; extern unsigned long memory_start; @@ -77,22 +59,9 @@ void __init paging_init(void) * Make sure start_mem is page aligned, otherwise bootmem and * page_alloc get different views of the world. */ -#ifdef DEBUG - unsigned long start_mem = PAGE_ALIGN(memory_start); -#endif unsigned long end_mem = memory_end & PAGE_MASK; + unsigned long zones_size[MAX_NR_ZONES] = {0, }; -#ifdef DEBUG - printk (KERN_DEBUG "start_mem is %#lx\nvirtual_end is %#lx\n", - start_mem, end_mem); -#endif - - /* - * Initialize the bad page table and bad page to point - * to a couple of allocated pages. - */ - empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); memset((void *)empty_zero_page, 0, PAGE_SIZE); @@ -101,19 +70,8 @@ void __init paging_init(void) */ set_fs (USER_DS); -#ifdef DEBUG - printk (KERN_DEBUG "before free_area_init\n"); - - printk (KERN_DEBUG "free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n", - start_mem, end_mem); -#endif - - { - unsigned long zones_size[MAX_NR_ZONES] = {0, }; - - zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; - free_area_init(zones_size); - } + zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; + free_area_init(zones_size); } void __init mem_init(void) @@ -166,8 +124,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) } #endif -void -free_initmem() +void free_initmem(void) { #ifdef CONFIG_RAMKERNEL unsigned long addr; From 67cc09ed7093f49fc776164761507999991a6ef6 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 29 Mar 2011 14:03:26 +1000 Subject: [PATCH 12/22] m68knommu: move EXPORT of dump_fpu to function definition The EXPORT_SYMBOL(dump_fpu) belongs at the definition of the function, not in some other random code file. So move it there. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/m68k_ksyms_no.c | 4 ---- arch/m68k/kernel/process_no.c | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/m68k/kernel/m68k_ksyms_no.c b/arch/m68k/kernel/m68k_ksyms_no.c index c26717bcf306..ab747e477131 100644 --- a/arch/m68k/kernel/m68k_ksyms_no.c +++ b/arch/m68k/kernel/m68k_ksyms_no.c @@ -16,12 +16,8 @@ #include #include -extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); - /* platform dependent support */ -EXPORT_SYMBOL(dump_fpu); - EXPORT_SYMBOL(ip_fast_csum); EXPORT_SYMBOL(kernel_thread); diff --git a/arch/m68k/kernel/process_no.c b/arch/m68k/kernel/process_no.c index e2a63af5d517..eedadc2ff98a 100644 --- a/arch/m68k/kernel/process_no.c +++ b/arch/m68k/kernel/process_no.c @@ -283,6 +283,7 @@ int dump_fpu(struct pt_regs *regs, struct user_m68kfp_struct *fpu) #endif return 1; } +EXPORT_SYMBOL(dump_fpu); /* * Generic dumping code. Used for panic and debug. From b33972eb476401637c345b6eb91969b2df7e1ec0 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 29 Mar 2011 14:10:23 +1000 Subject: [PATCH 13/22] m68knommu: move EXPORT of local checksumming functions to definitions The EXPORT_SYMBOL() of the local lib checksum functions belongs with the definitions, not in some other random code file. So move then there. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/m68k_ksyms_no.c | 5 ----- arch/m68k/lib/checksum_no.c | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/m68k/kernel/m68k_ksyms_no.c b/arch/m68k/kernel/m68k_ksyms_no.c index ab747e477131..daed9326c4f1 100644 --- a/arch/m68k/kernel/m68k_ksyms_no.c +++ b/arch/m68k/kernel/m68k_ksyms_no.c @@ -18,13 +18,8 @@ /* platform dependent support */ -EXPORT_SYMBOL(ip_fast_csum); - EXPORT_SYMBOL(kernel_thread); -/* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial_copy_nocheck); - /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that diff --git a/arch/m68k/lib/checksum_no.c b/arch/m68k/lib/checksum_no.c index eccf25d3d73e..e4c6354da765 100644 --- a/arch/m68k/lib/checksum_no.c +++ b/arch/m68k/lib/checksum_no.c @@ -101,6 +101,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { return (__force __sum16)~do_csum(iph,ihl*4); } +EXPORT_SYMBOL(ip_fast_csum); #endif /* @@ -140,6 +141,7 @@ csum_partial_copy_from_user(const void __user *src, void *dst, memcpy(dst, (__force const void *)src, len); return csum_partial(dst, len, sum); } +EXPORT_SYMBOL(csum_partial_copy_from_user); /* * copy from ds while checksumming, otherwise like csum_partial @@ -151,3 +153,4 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) memcpy(dst, src, len); return csum_partial(dst, len, sum); } +EXPORT_SYMBOL(csum_partial_copy_nocheck); From dcc4d72fad84adcd98cb0a552f4287c1ed06d5d6 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 29 Mar 2011 14:14:21 +1000 Subject: [PATCH 14/22] m68knommu: move EXPORT of kernel_thread to function definition The EXPORT_SYMBOL(kernel_thread) belongs at the definition of that function, not in some other random code file. So move it there. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/m68k_ksyms_no.c | 4 ---- arch/m68k/kernel/process_no.c | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/m68k/kernel/m68k_ksyms_no.c b/arch/m68k/kernel/m68k_ksyms_no.c index daed9326c4f1..11effaa6d158 100644 --- a/arch/m68k/kernel/m68k_ksyms_no.c +++ b/arch/m68k/kernel/m68k_ksyms_no.c @@ -16,10 +16,6 @@ #include #include -/* platform dependent support */ - -EXPORT_SYMBOL(kernel_thread); - /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that diff --git a/arch/m68k/kernel/process_no.c b/arch/m68k/kernel/process_no.c index eedadc2ff98a..9b86ad11c68e 100644 --- a/arch/m68k/kernel/process_no.c +++ b/arch/m68k/kernel/process_no.c @@ -151,6 +151,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) set_fs(fs); return retval; } +EXPORT_SYMBOL(kernel_thread); void flush_thread(void) { From 2c7f3feb63276f08dd289a2cb29694af17ad70dd Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 29 Mar 2011 14:25:14 +1000 Subject: [PATCH 15/22] m68knommu: remove un-needed exporting of COLDFIRE symbols There is no reason most of the symbols enclosed in a conditional on CONFIG_COLDFIRE need to be exported. And they sure don't need to be doing it in m68k_ksyms_no.c. Move the dma symbols export (which are currently needed) to the definitions of those, and remove the rest of the exporting here. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/m68k_ksyms_no.c | 12 ------------ arch/m68k/platform/coldfire/dma.c | 3 +++ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/arch/m68k/kernel/m68k_ksyms_no.c b/arch/m68k/kernel/m68k_ksyms_no.c index 11effaa6d158..db6f87aa0a7f 100644 --- a/arch/m68k/kernel/m68k_ksyms_no.c +++ b/arch/m68k/kernel/m68k_ksyms_no.c @@ -42,15 +42,3 @@ EXPORT_SYMBOL(__mulsi3); EXPORT_SYMBOL(__udivsi3); EXPORT_SYMBOL(__umodsi3); -#ifdef CONFIG_COLDFIRE -extern unsigned int *dma_device_address; -extern unsigned long dma_base_addr, _ramend; -EXPORT_SYMBOL(dma_base_addr); -EXPORT_SYMBOL(dma_device_address); -EXPORT_SYMBOL(_ramend); - -extern asmlinkage void trap(void); -extern void *_ramvec; -EXPORT_SYMBOL(trap); -EXPORT_SYMBOL(_ramvec); -#endif /* CONFIG_COLDFIRE */ diff --git a/arch/m68k/platform/coldfire/dma.c b/arch/m68k/platform/coldfire/dma.c index e88b95e2cc62..df5ce20d181c 100644 --- a/arch/m68k/platform/coldfire/dma.c +++ b/arch/m68k/platform/coldfire/dma.c @@ -9,6 +9,7 @@ /***************************************************************************/ #include +#include #include #include #include @@ -33,7 +34,9 @@ unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = { MCFDMA_BASE3, #endif }; +EXPORT_SYMBOL(dma_base_addr); unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; +EXPORT_SYMBOL(dma_device_address); /***************************************************************************/ From a697dc934f52355494b746d7b5568227e0910ae8 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 29 Mar 2011 15:06:37 +1000 Subject: [PATCH 16/22] m68k: merge non-mmu and mmu versions of m68k_ksyms.c After cleaning up m68k_ksyms_no.c it is now strait forward to merge the non-mmu and mmu versions of m68k_ksyms.c. The need for the extra gcc functions is not strictly based on having an MMU or not. It is based on the family the processor belongs too, so use an appropriate conditional check. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/m68k_ksyms.c | 36 +++++++++++++++++++++++--- arch/m68k/kernel/m68k_ksyms_mm.c | 16 ------------ arch/m68k/kernel/m68k_ksyms_no.c | 44 -------------------------------- 3 files changed, 32 insertions(+), 64 deletions(-) delete mode 100644 arch/m68k/kernel/m68k_ksyms_mm.c delete mode 100644 arch/m68k/kernel/m68k_ksyms_no.c diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index 4752c28ce0ac..33f82769547c 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c @@ -1,5 +1,33 @@ -#ifdef CONFIG_MMU -#include "m68k_ksyms_mm.c" -#else -#include "m68k_ksyms_no.c" +#include + +asmlinkage long long __ashldi3 (long long, int); +asmlinkage long long __ashrdi3 (long long, int); +asmlinkage long long __lshrdi3 (long long, int); +asmlinkage long long __muldi3 (long long, long long); + +/* The following are special because they're not called + explicitly (the C compiler generates them). Fortunately, + their interface isn't gonna change any time soon now, so + it's OK to leave it out of version control. */ +EXPORT_SYMBOL(__ashldi3); +EXPORT_SYMBOL(__ashrdi3); +EXPORT_SYMBOL(__lshrdi3); +EXPORT_SYMBOL(__muldi3); + +#if !defined(__mc68020__) && !defined(__mc68030__) && \ + !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcpu32__) +/* + * Simpler 68k and ColdFire parts also need a few other gcc functions. + */ +extern long long __divsi3(long long, long long); +extern long long __modsi3(long long, long long); +extern long long __mulsi3(long long, long long); +extern long long __udivsi3(long long, long long); +extern long long __umodsi3(long long, long long); + +EXPORT_SYMBOL(__divsi3); +EXPORT_SYMBOL(__modsi3); +EXPORT_SYMBOL(__mulsi3); +EXPORT_SYMBOL(__udivsi3); +EXPORT_SYMBOL(__umodsi3); #endif diff --git a/arch/m68k/kernel/m68k_ksyms_mm.c b/arch/m68k/kernel/m68k_ksyms_mm.c deleted file mode 100644 index d900e77e5363..000000000000 --- a/arch/m68k/kernel/m68k_ksyms_mm.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - -asmlinkage long long __ashldi3 (long long, int); -asmlinkage long long __ashrdi3 (long long, int); -asmlinkage long long __lshrdi3 (long long, int); -asmlinkage long long __muldi3 (long long, long long); - -/* The following are special because they're not called - explicitly (the C compiler generates them). Fortunately, - their interface isn't gonna change any time soon now, so - it's OK to leave it out of version control. */ -EXPORT_SYMBOL(__ashldi3); -EXPORT_SYMBOL(__ashrdi3); -EXPORT_SYMBOL(__lshrdi3); -EXPORT_SYMBOL(__muldi3); - diff --git a/arch/m68k/kernel/m68k_ksyms_no.c b/arch/m68k/kernel/m68k_ksyms_no.c deleted file mode 100644 index db6f87aa0a7f..000000000000 --- a/arch/m68k/kernel/m68k_ksyms_no.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * libgcc functions - functions that are used internally by the - * compiler... (prototypes are not correct though, but that - * doesn't really matter since they're not versioned). - */ -extern void __ashldi3(void); -extern void __ashrdi3(void); -extern void __divsi3(void); -extern void __lshrdi3(void); -extern void __modsi3(void); -extern void __muldi3(void); -extern void __mulsi3(void); -extern void __udivsi3(void); -extern void __umodsi3(void); - - /* gcc lib functions */ -EXPORT_SYMBOL(__ashldi3); -EXPORT_SYMBOL(__ashrdi3); -EXPORT_SYMBOL(__divsi3); -EXPORT_SYMBOL(__lshrdi3); -EXPORT_SYMBOL(__modsi3); -EXPORT_SYMBOL(__muldi3); -EXPORT_SYMBOL(__mulsi3); -EXPORT_SYMBOL(__udivsi3); -EXPORT_SYMBOL(__umodsi3); - From aa4d1f897f6a7ffdb3654a2152b60d9d832951a3 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 29 Mar 2011 15:55:36 +1000 Subject: [PATCH 17/22] m68k: merge mmu and non-mmu versions of asm-offsets.c It is strait forward to merge the mmu and non-mmu versions of asm-offstes.c. Some name changes are required for the preempt and thread_info.flags in the non-mmu entry.S assembler to make them consistent for both setups. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/asm-offsets.c | 106 +++++++++++++++++++++++++++- arch/m68k/kernel/asm-offsets_mm.c | 100 -------------------------- arch/m68k/kernel/asm-offsets_no.c | 76 -------------------- arch/m68k/platform/68328/entry.S | 6 +- arch/m68k/platform/68360/entry.S | 6 +- arch/m68k/platform/coldfire/entry.S | 10 +-- 6 files changed, 114 insertions(+), 190 deletions(-) delete mode 100644 arch/m68k/kernel/asm-offsets_mm.c delete mode 100644 arch/m68k/kernel/asm-offsets_no.c diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c index 59a69a5c62f2..983fed9d469b 100644 --- a/arch/m68k/kernel/asm-offsets.c +++ b/arch/m68k/kernel/asm-offsets.c @@ -1,5 +1,105 @@ -#ifdef CONFIG_MMU -#include "asm-offsets_mm.c" +/* + * This program is used to generate definitions needed by + * assembly language modules. + * + * We use the technique used in the OSF Mach kernel code: + * generate asm statements containing #defines, + * compile this file to assembler, and then extract the + * #defines from the assembly-language output. + */ + +#define ASM_OFFSETS_C + +#include +#include +#include +#include +#include +#include +#include +#include + +int main(void) +{ + /* offsets into the task struct */ + DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); + DEFINE(TASK_MM, offsetof(struct task_struct, mm)); + DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); + DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); + + /* offsets into the thread struct */ + DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); + DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); + DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); + DEFINE(THREAD_FS, offsetof(struct thread_struct, fs)); + DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp)); + DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); + DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp)); + DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); + DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); + + /* offsets into the thread_info struct */ + DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count)); + DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); + + /* offsets into the pt_regs */ + DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); + DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); + DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); + DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); + DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); + DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); + DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); + DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); + DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); + DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); + DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); + DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); + + /* bitfields are a bit difficult */ +#ifdef CONFIG_COLDFIRE + DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2); #else -#include "asm-offsets_no.c" + DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4); #endif + + /* offsets into the irq_cpustat_t struct */ + DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); + + /* signal defines */ + DEFINE(LSIGSEGV, SIGSEGV); + DEFINE(LSEGV_MAPERR, SEGV_MAPERR); + DEFINE(LSIGTRAP, SIGTRAP); + DEFINE(LTRAP_TRACE, TRAP_TRACE); + +#ifdef CONFIG_MMU + /* offsets into the bi_record struct */ + DEFINE(BIR_TAG, offsetof(struct bi_record, tag)); + DEFINE(BIR_SIZE, offsetof(struct bi_record, size)); + DEFINE(BIR_DATA, offsetof(struct bi_record, data)); + + /* offsets into font_desc (drivers/video/console/font.h) */ + DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx)); + DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name)); + DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width)); + DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height)); + DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data)); + DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); + + /* offsets into the custom struct */ + DEFINE(CUSTOMBASE, &amiga_custom); + DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar)); + DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr)); + DEFINE(C_INTENA, offsetof(struct CUSTOM, intena)); + DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq)); + DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr)); + DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat)); + DEFINE(C_SERPER, offsetof(struct CUSTOM, serper)); + DEFINE(CIAABASE, &ciaa); + DEFINE(CIABBASE, &ciab); + DEFINE(C_PRA, offsetof(struct CIA, pra)); + DEFINE(ZTWOBASE, zTwoBase); +#endif + + return 0; +} diff --git a/arch/m68k/kernel/asm-offsets_mm.c b/arch/m68k/kernel/asm-offsets_mm.c deleted file mode 100644 index 78e59b82ebc3..000000000000 --- a/arch/m68k/kernel/asm-offsets_mm.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This program is used to generate definitions needed by - * assembly language modules. - * - * We use the technique used in the OSF Mach kernel code: - * generate asm statements containing #defines, - * compile this file to assembler, and then extract the - * #defines from the assembly-language output. - */ - -#define ASM_OFFSETS_C - -#include -#include -#include -#include -#include -#include -#include -#include - -int main(void) -{ - /* offsets into the task struct */ - DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); - DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); - DEFINE(TASK_MM, offsetof(struct task_struct, mm)); -#ifdef CONFIG_MMU - DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); -#endif - - /* offsets into the thread struct */ - DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); - DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); - DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); - DEFINE(THREAD_FS, offsetof(struct thread_struct, fs)); - DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp)); - DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); - DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp)); - DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); - DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); - - /* offsets into the thread_info struct */ - DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count)); - DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); - - /* offsets into the pt_regs */ - DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); - DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); - DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); - DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); - DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); - DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); - DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); - DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); - DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); - DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); - DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); - DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); - /* bitfields are a bit difficult */ - DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4); - - /* offsets into the irq_cpustat_t struct */ - DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); - - /* offsets into the bi_record struct */ - DEFINE(BIR_TAG, offsetof(struct bi_record, tag)); - DEFINE(BIR_SIZE, offsetof(struct bi_record, size)); - DEFINE(BIR_DATA, offsetof(struct bi_record, data)); - - /* offsets into font_desc (drivers/video/console/font.h) */ - DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx)); - DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name)); - DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width)); - DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height)); - DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data)); - DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); - - /* signal defines */ - DEFINE(LSIGSEGV, SIGSEGV); - DEFINE(LSEGV_MAPERR, SEGV_MAPERR); - DEFINE(LSIGTRAP, SIGTRAP); - DEFINE(LTRAP_TRACE, TRAP_TRACE); - - /* offsets into the custom struct */ - DEFINE(CUSTOMBASE, &amiga_custom); - DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar)); - DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr)); - DEFINE(C_INTENA, offsetof(struct CUSTOM, intena)); - DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq)); - DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr)); - DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat)); - DEFINE(C_SERPER, offsetof(struct CUSTOM, serper)); - DEFINE(CIAABASE, &ciaa); - DEFINE(CIABBASE, &ciab); - DEFINE(C_PRA, offsetof(struct CIA, pra)); - DEFINE(ZTWOBASE, zTwoBase); - - return 0; -} diff --git a/arch/m68k/kernel/asm-offsets_no.c b/arch/m68k/kernel/asm-offsets_no.c deleted file mode 100644 index ffe02f41ad46..000000000000 --- a/arch/m68k/kernel/asm-offsets_no.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This program is used to generate definitions needed by - * assembly language modules. - * - * We use the technique used in the OSF Mach kernel code: - * generate asm statements containing #defines, - * compile this file to assembler, and then extract the - * #defines from the assembly-language output. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(void) -{ - /* offsets into the task struct */ - DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); - DEFINE(TASK_MM, offsetof(struct task_struct, mm)); - - /* offsets into the irq_cpustat_t struct */ - DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); - - /* offsets into the thread struct */ - DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); - DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); - DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); - DEFINE(THREAD_FS, offsetof(struct thread_struct, fs)); - DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp)); - DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); - DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp)); - DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); - DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); - - /* offsets into the pt_regs */ - DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); - DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); - DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); - DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); - DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); - DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); - DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); - DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); - DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); - DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); - DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); - DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); - -#ifdef CONFIG_COLDFIRE - /* bitfields are a bit difficult */ - DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2); -#else - /* bitfields are a bit difficult */ - DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4); -#endif - - /* signal defines */ - DEFINE(SIGSEGV, SIGSEGV); - DEFINE(SEGV_MAPERR, SEGV_MAPERR); - DEFINE(SIGTRAP, SIGTRAP); - DEFINE(TRAP_TRACE, TRAP_TRACE); - - DEFINE(PT_PTRACED, PT_PTRACED); - - /* Offsets in thread_info structure */ - DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count)); - - return 0; -} diff --git a/arch/m68k/platform/68328/entry.S b/arch/m68k/platform/68328/entry.S index 676960cf022a..3e4675996a71 100644 --- a/arch/m68k/platform/68328/entry.S +++ b/arch/m68k/platform/68328/entry.S @@ -80,7 +80,7 @@ ENTRY(system_call) movel %sp,%d1 /* get thread_info pointer */ andl #-THREAD_SIZE,%d1 movel %d1,%a2 - btst #(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) + btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) jne do_trace cmpl #NR_syscalls,%d0 jcc badsys @@ -107,12 +107,12 @@ Luser_return: andl #-THREAD_SIZE,%d1 movel %d1,%a2 1: - move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ + move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ jne Lwork_to_do RESTORE_ALL Lwork_to_do: - movel %a2@(TI_FLAGS),%d1 /* thread_info->flags */ + movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ btst #TIF_NEED_RESCHED,%d1 jne reschedule diff --git a/arch/m68k/platform/68360/entry.S b/arch/m68k/platform/68360/entry.S index 46c1b18c9dcb..50dcae66f6cd 100644 --- a/arch/m68k/platform/68360/entry.S +++ b/arch/m68k/platform/68360/entry.S @@ -76,7 +76,7 @@ ENTRY(system_call) movel %sp,%d1 /* get thread_info pointer */ andl #-THREAD_SIZE,%d1 movel %d1,%a2 - btst #(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) + btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) jne do_trace cmpl #NR_syscalls,%d0 jcc badsys @@ -103,12 +103,12 @@ Luser_return: andl #-THREAD_SIZE,%d1 movel %d1,%a2 1: - move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ + move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ jne Lwork_to_do RESTORE_ALL Lwork_to_do: - movel %a2@(TI_FLAGS),%d1 /* thread_info->flags */ + movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ btst #TIF_NEED_RESCHED,%d1 jne reschedule diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S index eab63f09965b..eee9a06aa265 100644 --- a/arch/m68k/platform/coldfire/entry.S +++ b/arch/m68k/platform/coldfire/entry.S @@ -78,7 +78,7 @@ ENTRY(system_call) movel %d2,%a0 movel %a0@,%a1 /* save top of frame */ movel %sp,%a1@(TASK_THREAD+THREAD_ESP0) - btst #(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8) + btst #(TIF_SYSCALL_TRACE%8),%a0@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) bnes 1f movel %d3,%a0 @@ -113,11 +113,11 @@ ret_from_exception: movel %sp,%d1 /* get thread_info pointer */ andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ movel %d1,%a0 - movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ + movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */ andl #(1<flags */ + movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */ jne Lwork_to_do /* still work to do */ Lreturn: RESTORE_USER Lwork_to_do: - movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ + movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */ move #0x2000,%sr /* enable intrs again */ btst #TIF_NEED_RESCHED,%d1 jne reschedule From b60de9f5142ffc677e4e1bf0d1e8ad177d21095f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Apr 2011 21:43:19 +0200 Subject: [PATCH 18/22] m68knommu: Remove obsolete #include Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Ungerer --- arch/m68k/kernel/entry_no.S | 1 - arch/m68k/kernel/syscalltable.S | 1 - arch/m68k/platform/68328/entry.S | 1 - arch/m68k/platform/68360/entry.S | 1 - arch/m68k/platform/coldfire/entry.S | 1 - arch/m68k/platform/coldfire/head.S | 1 - 6 files changed, 6 deletions(-) diff --git a/arch/m68k/kernel/entry_no.S b/arch/m68k/kernel/entry_no.S index 2783f25e38bd..5f0f6b598b5a 100644 --- a/arch/m68k/kernel/entry_no.S +++ b/arch/m68k/kernel/entry_no.S @@ -24,7 +24,6 @@ * linux 2.4 support David McCullough */ -#include #include #include #include diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 5909e392cb1e..6f7b09122a00 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -11,7 +11,6 @@ * Linux/m68k support by Hamish Macdonald */ -#include #include #ifndef CONFIG_MMU diff --git a/arch/m68k/platform/68328/entry.S b/arch/m68k/platform/68328/entry.S index 3e4675996a71..f68dce766c0a 100644 --- a/arch/m68k/platform/68328/entry.S +++ b/arch/m68k/platform/68328/entry.S @@ -10,7 +10,6 @@ * Linux/m68k support by Hamish Macdonald */ -#include #include #include #include diff --git a/arch/m68k/platform/68360/entry.S b/arch/m68k/platform/68360/entry.S index 50dcae66f6cd..a07b14feed92 100644 --- a/arch/m68k/platform/68360/entry.S +++ b/arch/m68k/platform/68360/entry.S @@ -12,7 +12,6 @@ * M68360 Port by SED Systems, and Lineo. */ -#include #include #include #include diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S index eee9a06aa265..27c2b001161e 100644 --- a/arch/m68k/platform/coldfire/entry.S +++ b/arch/m68k/platform/coldfire/entry.S @@ -26,7 +26,6 @@ * Bug, speed and maintainability fixes by Philippe De Muyter */ -#include #include #include #include diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S index 6ae91a499184..c33483824a2e 100644 --- a/arch/m68k/platform/coldfire/head.S +++ b/arch/m68k/platform/coldfire/head.S @@ -8,7 +8,6 @@ /*****************************************************************************/ -#include #include #include #include From 48e1328e06dd9bd7a4932ee47428475963ea55b0 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 17 Apr 2011 22:57:29 +0900 Subject: [PATCH 19/22] m68knommu: use asm-generic/bitops/ext2-atomic.h m68knommu can use generic implementation of ext2 atomic bitops. Signed-off-by: Akinobu Mita Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/bitops_no.h | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/arch/m68k/include/asm/bitops_no.h b/arch/m68k/include/asm/bitops_no.h index 7d3779fdc5b6..6b0e2d349f0e 100644 --- a/arch/m68k/include/asm/bitops_no.h +++ b/arch/m68k/include/asm/bitops_no.h @@ -246,23 +246,7 @@ static inline int __test_and_clear_bit_le(int nr, volatile void *addr) return retval; } -#define ext2_set_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = __test_and_set_bit_le((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -#define ext2_clear_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = __test_and_clear_bit_le((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) +#include static inline int test_bit_le(int nr, const volatile void *addr) { From cae2e6cc002d6fdee7d8a230736fa7c685e54b35 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Thu, 21 Apr 2011 12:48:07 +1000 Subject: [PATCH 20/22] m68k: merge the mmu and non-mmu versions of sys_m68k.c There is a lot of common code in the sys_m68k.c files. The mmu and non-mmu versions can easily be merged into a single file. There is really only 2 functions that differ in the 2 cases. A single ifdef on CONFIG_MMU can take care of this. Alternatively we could break those 2 functions out and maintain sys_m68k_no.c and sys_m68k_mm.c with just this code in it (Makefile could then just build the right one). Does anyone have strong feelings on which way they want this done? Signed-off-by: Greg Ungerer --- arch/m68k/kernel/sys_m68k.c | 581 ++++++++++++++++++++++++++++++++- arch/m68k/kernel/sys_m68k_mm.c | 546 ------------------------------- arch/m68k/kernel/sys_m68k_no.c | 94 ------ 3 files changed, 578 insertions(+), 643 deletions(-) delete mode 100644 arch/m68k/kernel/sys_m68k_mm.c delete mode 100644 arch/m68k/kernel/sys_m68k_no.c diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 63013df33584..8623f8dc16f8 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -1,5 +1,580 @@ +/* + * linux/arch/m68k/kernel/sys_m68k.c + * + * This file contains various random system calls that + * have a non-standard calling sequence on the Linux/m68k + * platform. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + #ifdef CONFIG_MMU -#include "sys_m68k_mm.c" + +#include + +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code); + +asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + /* + * This is wrong for sun3 - there PAGE_SIZE is 8Kb, + * so we need to shift the argument down by 1; m68k mmap64(3) + * (in libc) expects the last argument of mmap2 in 4Kb units. + */ + return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); +} + +/* Convert virtual (user) 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" \ + "movec %%mmusr,%0\n\t" \ + ".chip 68k" \ + : "=r" (_mmusr) \ + : "a" (vaddr)); \ + _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, i; + + switch (scope) + { + case FLUSH_SCOPE_ALL: + switch (cache) + { + case FLUSH_CACHE_DATA: + /* This nop is needed for some broken versions of the 68040. */ + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpusha %dc\n\t" + ".chip 68k"); + break; + case FLUSH_CACHE_INSN: + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpusha %ic\n\t" + ".chip 68k"); + break; + default: + case FLUSH_CACHE_BOTH: + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpusha %bc\n\t" + ".chip 68k"); + break; + } + break; + + case FLUSH_SCOPE_LINE: + /* Find the physical address of the first mapped page in the + address range. */ + 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) + { + case FLUSH_CACHE_DATA: + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushl %%dc,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + case FLUSH_CACHE_INSN: + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushl %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + default: + case FLUSH_CACHE_BOTH: + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushl %%bc,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + } + if (!--i && len) + { + /* + * No need to page align here since it is done by + * virt_to_phys_040(). + */ + addr += PAGE_SIZE; + i = PAGE_SIZE / 16; + /* Recompute physical address when crossing a page + boundary. */ + for (;;) + { + if ((paddr = virt_to_phys_040(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); + for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) + { + if (!(paddr = virt_to_phys_040(addr))) + continue; + switch (cache) + { + case FLUSH_CACHE_DATA: + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushp %%dc,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + case FLUSH_CACHE_INSN: + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushp %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + default: + case FLUSH_CACHE_BOTH: + __asm__ __volatile__ ("nop\n\t" + ".chip 68040\n\t" + "cpushp %%bc,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + } + } + break; + } + return 0; +} + +#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)); \ + (paddr); /* XXX */ \ +}) + +static inline int +cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len) +{ + unsigned long paddr, i; + + /* + * 68060 manual says: + * cpush %dc : flush DC, remains valid (with our %cacr setup) + * cpush %ic : invalidate IC + * cpush %bc : flush DC + invalidate IC + */ + switch (scope) + { + case FLUSH_SCOPE_ALL: + switch (cache) + { + case FLUSH_CACHE_DATA: + __asm__ __volatile__ (".chip 68060\n\t" + "cpusha %dc\n\t" + ".chip 68k"); + break; + case FLUSH_CACHE_INSN: + __asm__ __volatile__ (".chip 68060\n\t" + "cpusha %ic\n\t" + ".chip 68k"); + break; + default: + case FLUSH_CACHE_BOTH: + __asm__ __volatile__ (".chip 68060\n\t" + "cpusha %bc\n\t" + ".chip 68k"); + break; + } + break; + + case FLUSH_SCOPE_LINE: + /* Find the physical address of the first mapped page in the + address range. */ + 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) + { + case FLUSH_CACHE_DATA: + __asm__ __volatile__ (".chip 68060\n\t" + "cpushl %%dc,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + case FLUSH_CACHE_INSN: + __asm__ __volatile__ (".chip 68060\n\t" + "cpushl %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + default: + case FLUSH_CACHE_BOTH: + __asm__ __volatile__ (".chip 68060\n\t" + "cpushl %%bc,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + } + if (!--i && len) + { + + /* + * We just want to jump to the first cache line + * in the next page. + */ + addr += PAGE_SIZE; + addr &= PAGE_MASK; + + 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) + { + if (!(paddr = virt_to_phys_060(addr))) + continue; + switch (cache) + { + case FLUSH_CACHE_DATA: + __asm__ __volatile__ (".chip 68060\n\t" + "cpushp %%dc,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + case FLUSH_CACHE_INSN: + __asm__ __volatile__ (".chip 68060\n\t" + "cpushp %%ic,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + default: + case FLUSH_CACHE_BOTH: + __asm__ __volatile__ (".chip 68060\n\t" + "cpushp %%bc,(%0)\n\t" + ".chip 68k" + : : "a" (paddr)); + break; + } + } + break; + } + return 0; +} + +/* sys_cacheflush -- flush (part of) the processor cache. */ +asmlinkage int +sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) +{ + struct vm_area_struct *vma; + int ret = -EINVAL; + + if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL || + cache & ~FLUSH_CACHE_BOTH) + goto out; + + if (scope == FLUSH_SCOPE_ALL) { + /* Only the superuser may explicitly flush the whole cache. */ + ret = -EPERM; + if (!capable(CAP_SYS_ADMIN)) + goto out; + } else { + /* + * Verify that the specified address region actually belongs + * to this process. + */ + vma = find_vma (current->mm, addr); + ret = -EINVAL; + /* Check for overflow. */ + if (addr + len < addr) + goto out; + if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) + goto out; + } + + if (CPU_IS_020_OR_030) { + if (scope == FLUSH_SCOPE_LINE && len < 256) { + unsigned long cacr; + __asm__ ("movec %%cacr, %0" : "=r" (cacr)); + if (cache & FLUSH_CACHE_INSN) + cacr |= 4; + if (cache & FLUSH_CACHE_DATA) + cacr |= 0x400; + len >>= 2; + while (len--) { + __asm__ __volatile__ ("movec %1, %%caar\n\t" + "movec %0, %%cacr" + : /* no outputs */ + : "r" (cacr), "r" (addr)); + addr += 4; + } + } else { + /* Flush the whole cache, even if page granularity requested. */ + unsigned long cacr; + __asm__ ("movec %%cacr, %0" : "=r" (cacr)); + if (cache & FLUSH_CACHE_INSN) + cacr |= 8; + if (cache & FLUSH_CACHE_DATA) + cacr |= 0x800; + __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr)); + } + ret = 0; + goto out; + } else { + /* + * 040 or 060: don't blindly trust 'scope', someone could + * try to flush a few megs of memory. + */ + + if (len>=3*PAGE_SIZE && scope=10*PAGE_SIZE && scopemm; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + spinlock_t *ptl; + unsigned long mem_value; + + down_read(&mm->mmap_sem); + pgd = pgd_offset(mm, (unsigned long)mem); + if (!pgd_present(*pgd)) + goto bad_access; + pmd = pmd_offset(pgd, (unsigned long)mem); + if (!pmd_present(*pmd)) + goto bad_access; + pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); + if (!pte_present(*pte) || !pte_dirty(*pte) + || !pte_write(*pte)) { + pte_unmap_unlock(pte, ptl); + goto bad_access; + } + + mem_value = *mem; + if (mem_value == oldval) + *mem = newval; + + pte_unmap_unlock(pte, ptl); + up_read(&mm->mmap_sem); + return mem_value; + + bad_access: + up_read(&mm->mmap_sem); + /* This is not necessarily a bad access, we can get here if + a memory we're trying to write to should be copied-on-write. + Make the kernel do the necessary page stuff, then re-iterate. + Simulate a write access fault to do that. */ + { + /* The first argument of the function corresponds to + D1, which is the first field of struct pt_regs. */ + struct pt_regs *fp = (struct pt_regs *)&newval; + + /* '3' is an RMW flag. */ + if (do_page_fault(fp, (unsigned long)mem, 3)) + /* If the do_page_fault() failed, we don't + have anything meaningful to return. + There should be a SIGSEGV pending for + the process. */ + return 0xdeadbeef; + } + } +} + #else -#include "sys_m68k_no.c" -#endif + +/* sys_cacheflush -- flush (part of) the processor cache. */ +asmlinkage int +sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) +{ + flush_cache_all(); + return 0; +} + +/* This syscall gets its arguments in A0 (mem), D2 (oldval) and + D1 (newval). */ +asmlinkage int +sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, + unsigned long __user * mem) +{ + struct mm_struct *mm = current->mm; + unsigned long mem_value; + + down_read(&mm->mmap_sem); + + mem_value = *mem; + if (mem_value == oldval) + *mem = newval; + + up_read(&mm->mmap_sem); + return mem_value; +} + +#endif /* CONFIG_MMU */ + +asmlinkage int sys_getpagesize(void) +{ + return PAGE_SIZE; +} + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, + const char *const argv[], + const char *const envp[]) +{ + register long __res asm ("%d0") = __NR_execve; + register long __a asm ("%d1") = (long)(filename); + register long __b asm ("%d2") = (long)(argv); + register long __c asm ("%d3") = (long)(envp); + asm volatile ("trap #0" : "+d" (__res) + : "d" (__a), "d" (__b), "d" (__c)); + return __res; +} + +asmlinkage unsigned long sys_get_thread_area(void) +{ + return current_thread_info()->tp_value; +} + +asmlinkage int sys_set_thread_area(unsigned long tp) +{ + current_thread_info()->tp_value = tp; + return 0; +} + +asmlinkage int sys_atomic_barrier(void) +{ + /* no code needed for uniprocs */ + return 0; +} diff --git a/arch/m68k/kernel/sys_m68k_mm.c b/arch/m68k/kernel/sys_m68k_mm.c deleted file mode 100644 index 3db2e7f902aa..000000000000 --- a/arch/m68k/kernel/sys_m68k_mm.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * linux/arch/m68k/kernel/sys_m68k.c - * - * This file contains various random system calls that - * have a non-standard calling sequence on the Linux/m68k - * platform. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code); - -asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff) -{ - /* - * This is wrong for sun3 - there PAGE_SIZE is 8Kb, - * so we need to shift the argument down by 1; m68k mmap64(3) - * (in libc) expects the last argument of mmap2 in 4Kb units. - */ - return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); -} - -/* Convert virtual (user) 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" \ - "movec %%mmusr,%0\n\t" \ - ".chip 68k" \ - : "=r" (_mmusr) \ - : "a" (vaddr)); \ - _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, i; - - switch (scope) - { - case FLUSH_SCOPE_ALL: - switch (cache) - { - case FLUSH_CACHE_DATA: - /* This nop is needed for some broken versions of the 68040. */ - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpusha %dc\n\t" - ".chip 68k"); - break; - case FLUSH_CACHE_INSN: - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpusha %ic\n\t" - ".chip 68k"); - break; - default: - case FLUSH_CACHE_BOTH: - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpusha %bc\n\t" - ".chip 68k"); - break; - } - break; - - case FLUSH_SCOPE_LINE: - /* Find the physical address of the first mapped page in the - address range. */ - 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) - { - case FLUSH_CACHE_DATA: - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushl %%dc,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - case FLUSH_CACHE_INSN: - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushl %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - default: - case FLUSH_CACHE_BOTH: - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushl %%bc,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - } - if (!--i && len) - { - /* - * No need to page align here since it is done by - * virt_to_phys_040(). - */ - addr += PAGE_SIZE; - i = PAGE_SIZE / 16; - /* Recompute physical address when crossing a page - boundary. */ - for (;;) - { - if ((paddr = virt_to_phys_040(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); - for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) - { - if (!(paddr = virt_to_phys_040(addr))) - continue; - switch (cache) - { - case FLUSH_CACHE_DATA: - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%dc,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - case FLUSH_CACHE_INSN: - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - default: - case FLUSH_CACHE_BOTH: - __asm__ __volatile__ ("nop\n\t" - ".chip 68040\n\t" - "cpushp %%bc,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - } - } - break; - } - return 0; -} - -#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)); \ - (paddr); /* XXX */ \ -}) - -static inline int -cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len) -{ - unsigned long paddr, i; - - /* - * 68060 manual says: - * cpush %dc : flush DC, remains valid (with our %cacr setup) - * cpush %ic : invalidate IC - * cpush %bc : flush DC + invalidate IC - */ - switch (scope) - { - case FLUSH_SCOPE_ALL: - switch (cache) - { - case FLUSH_CACHE_DATA: - __asm__ __volatile__ (".chip 68060\n\t" - "cpusha %dc\n\t" - ".chip 68k"); - break; - case FLUSH_CACHE_INSN: - __asm__ __volatile__ (".chip 68060\n\t" - "cpusha %ic\n\t" - ".chip 68k"); - break; - default: - case FLUSH_CACHE_BOTH: - __asm__ __volatile__ (".chip 68060\n\t" - "cpusha %bc\n\t" - ".chip 68k"); - break; - } - break; - - case FLUSH_SCOPE_LINE: - /* Find the physical address of the first mapped page in the - address range. */ - 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) - { - case FLUSH_CACHE_DATA: - __asm__ __volatile__ (".chip 68060\n\t" - "cpushl %%dc,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - case FLUSH_CACHE_INSN: - __asm__ __volatile__ (".chip 68060\n\t" - "cpushl %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - default: - case FLUSH_CACHE_BOTH: - __asm__ __volatile__ (".chip 68060\n\t" - "cpushl %%bc,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - } - if (!--i && len) - { - - /* - * We just want to jump to the first cache line - * in the next page. - */ - addr += PAGE_SIZE; - addr &= PAGE_MASK; - - 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) - { - if (!(paddr = virt_to_phys_060(addr))) - continue; - switch (cache) - { - case FLUSH_CACHE_DATA: - __asm__ __volatile__ (".chip 68060\n\t" - "cpushp %%dc,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - case FLUSH_CACHE_INSN: - __asm__ __volatile__ (".chip 68060\n\t" - "cpushp %%ic,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - default: - case FLUSH_CACHE_BOTH: - __asm__ __volatile__ (".chip 68060\n\t" - "cpushp %%bc,(%0)\n\t" - ".chip 68k" - : : "a" (paddr)); - break; - } - } - break; - } - return 0; -} - -/* sys_cacheflush -- flush (part of) the processor cache. */ -asmlinkage int -sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) -{ - struct vm_area_struct *vma; - int ret = -EINVAL; - - if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL || - cache & ~FLUSH_CACHE_BOTH) - goto out; - - if (scope == FLUSH_SCOPE_ALL) { - /* Only the superuser may explicitly flush the whole cache. */ - ret = -EPERM; - if (!capable(CAP_SYS_ADMIN)) - goto out; - } else { - /* - * Verify that the specified address region actually belongs - * to this process. - */ - vma = find_vma (current->mm, addr); - ret = -EINVAL; - /* Check for overflow. */ - if (addr + len < addr) - goto out; - if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) - goto out; - } - - if (CPU_IS_020_OR_030) { - if (scope == FLUSH_SCOPE_LINE && len < 256) { - unsigned long cacr; - __asm__ ("movec %%cacr, %0" : "=r" (cacr)); - if (cache & FLUSH_CACHE_INSN) - cacr |= 4; - if (cache & FLUSH_CACHE_DATA) - cacr |= 0x400; - len >>= 2; - while (len--) { - __asm__ __volatile__ ("movec %1, %%caar\n\t" - "movec %0, %%cacr" - : /* no outputs */ - : "r" (cacr), "r" (addr)); - addr += 4; - } - } else { - /* Flush the whole cache, even if page granularity requested. */ - unsigned long cacr; - __asm__ ("movec %%cacr, %0" : "=r" (cacr)); - if (cache & FLUSH_CACHE_INSN) - cacr |= 8; - if (cache & FLUSH_CACHE_DATA) - cacr |= 0x800; - __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr)); - } - ret = 0; - goto out; - } else { - /* - * 040 or 060: don't blindly trust 'scope', someone could - * try to flush a few megs of memory. - */ - - if (len>=3*PAGE_SIZE && scope=10*PAGE_SIZE && scopetp_value; -} - -asmlinkage int sys_set_thread_area(unsigned long tp) -{ - current_thread_info()->tp_value = tp; - return 0; -} - -/* This syscall gets its arguments in A0 (mem), D2 (oldval) and - D1 (newval). */ -asmlinkage int -sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, - unsigned long __user * mem) -{ - /* This was borrowed from ARM's implementation. */ - for (;;) { - struct mm_struct *mm = current->mm; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - spinlock_t *ptl; - unsigned long mem_value; - - down_read(&mm->mmap_sem); - pgd = pgd_offset(mm, (unsigned long)mem); - if (!pgd_present(*pgd)) - goto bad_access; - pmd = pmd_offset(pgd, (unsigned long)mem); - if (!pmd_present(*pmd)) - goto bad_access; - pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); - if (!pte_present(*pte) || !pte_dirty(*pte) - || !pte_write(*pte)) { - pte_unmap_unlock(pte, ptl); - goto bad_access; - } - - mem_value = *mem; - if (mem_value == oldval) - *mem = newval; - - pte_unmap_unlock(pte, ptl); - up_read(&mm->mmap_sem); - return mem_value; - - bad_access: - up_read(&mm->mmap_sem); - /* This is not necessarily a bad access, we can get here if - a memory we're trying to write to should be copied-on-write. - Make the kernel do the necessary page stuff, then re-iterate. - Simulate a write access fault to do that. */ - { - /* The first argument of the function corresponds to - D1, which is the first field of struct pt_regs. */ - struct pt_regs *fp = (struct pt_regs *)&newval; - - /* '3' is an RMW flag. */ - if (do_page_fault(fp, (unsigned long)mem, 3)) - /* If the do_page_fault() failed, we don't - have anything meaningful to return. - There should be a SIGSEGV pending for - the process. */ - return 0xdeadbeef; - } - } -} - -asmlinkage int sys_atomic_barrier(void) -{ - /* no code needed for uniprocs */ - return 0; -} diff --git a/arch/m68k/kernel/sys_m68k_no.c b/arch/m68k/kernel/sys_m68k_no.c deleted file mode 100644 index 68488ae47f0a..000000000000 --- a/arch/m68k/kernel/sys_m68k_no.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * linux/arch/m68knommu/kernel/sys_m68k.c - * - * This file contains various random system calls that - * have a non-standard calling sequence on the Linux/m68k - * platform. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* sys_cacheflush -- flush (part of) the processor cache. */ -asmlinkage int -sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) -{ - flush_cache_all(); - return(0); -} - -asmlinkage int sys_getpagesize(void) -{ - return PAGE_SIZE; -} - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, - const char *const argv[], - const char *const envp[]) -{ - register long __res asm ("%d0") = __NR_execve; - register long __a asm ("%d1") = (long)(filename); - register long __b asm ("%d2") = (long)(argv); - register long __c asm ("%d3") = (long)(envp); - asm volatile ("trap #0" : "+d" (__res) - : "d" (__a), "d" (__b), "d" (__c)); - return __res; -} - -asmlinkage unsigned long sys_get_thread_area(void) -{ - return current_thread_info()->tp_value; -} - -asmlinkage int sys_set_thread_area(unsigned long tp) -{ - current_thread_info()->tp_value = tp; - return 0; -} - -/* This syscall gets its arguments in A0 (mem), D2 (oldval) and - D1 (newval). */ -asmlinkage int -sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, - unsigned long __user * mem) -{ - struct mm_struct *mm = current->mm; - unsigned long mem_value; - - down_read(&mm->mmap_sem); - - mem_value = *mem; - if (mem_value == oldval) - *mem = newval; - - up_read(&mm->mmap_sem); - return mem_value; -} - -asmlinkage int sys_atomic_barrier(void) -{ - /* no code needed for uniprocs */ - return 0; -} From 0b4bf78214efcdadbbe5b09c5dff35dcc9bcb3df Mon Sep 17 00:00:00 2001 From: Steven King Date: Sun, 24 Apr 2011 10:48:07 -0700 Subject: [PATCH 21/22] coldfire_qspi compile fix The m68k/m68knommu merge broke the qspi build. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- drivers/spi/coldfire_qspi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/coldfire_qspi.c b/drivers/spi/coldfire_qspi.c index 8856bcca9d29..ae2cd1c1fda8 100644 --- a/drivers/spi/coldfire_qspi.c +++ b/drivers/spi/coldfire_qspi.c @@ -33,6 +33,7 @@ #include #include +#include #include #define DRIVER_NAME "mcfqspi" From 531d2895917566ab0d82faa0696d0576569f1053 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 30 Apr 2011 23:15:07 +0200 Subject: [PATCH 22/22] m68knommu: Use generic show_interrupts() Apart from whitespace differences, /proc/interrupts doesn't change by enabling GENERIC_IRQ_SHOW. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig | 1 + arch/m68k/kernel/irq.c | 28 ---------------------------- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 75531da02a40..d66e34c718d0 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -5,6 +5,7 @@ config M68K select HAVE_AOUT if MMU select GENERIC_ATOMIC64 if MMU select HAVE_GENERIC_HARDIRQS if !MMU + select GENERIC_IRQ_SHOW if !MMU config RWSEM_GENERIC_SPINLOCK bool diff --git a/arch/m68k/kernel/irq.c b/arch/m68k/kernel/irq.c index 15dbc3e9d20c..544b8717d499 100644 --- a/arch/m68k/kernel/irq.c +++ b/arch/m68k/kernel/irq.c @@ -28,31 +28,3 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) set_irq_regs(oldregs); } - -int show_interrupts(struct seq_file *p, void *v) -{ - struct irqaction *ap; - int irq = *((loff_t *) v); - - if (irq == 0) - seq_puts(p, " CPU0\n"); - - if (irq < NR_IRQS) { - struct irq_desc *desc = irq_to_desc(irq); - - ap = desc->action; - if (ap) { - seq_printf(p, "%3d: ", irq); - seq_printf(p, "%10u ", kstat_irqs(irq)); - seq_printf(p, "%14s ", irq_desc_get_chip(desc)->name); - - seq_printf(p, "%s", ap->name); - for (ap = ap->next; ap; ap = ap->next) - seq_printf(p, ", %s", ap->name); - seq_putc(p, '\n'); - } - } - - return 0; -} -