From gino at heusdens-ulenaers.be Wed Nov 2 03:18:08 2011 From: gino at heusdens-ulenaers.be (Gino Heusdens) Date: Wed, 02 Nov 2011 08:18:08 +0100 Subject: [uClinux-dev] bFLT binary: applet not found Message-ID: <4EB0EEB0.40202@heusdens-ulenaers.be> Hi, I'm having some troubles building uClinux with my self compiled toolkit. Normaly I use an precompiled (uclinux-tools-20050221, binaries are distributed by wago), but there is none for my x64 architecture. I used these sources, http://www.develer.com/uclinux/uclinux-tools-20050221/ I've finaly builded the sources, but when I execute an user program compiled with the new compilers, I get the error message applet not found. I thintk the bFLT binary headers are incorrect (see below) file output: leds: BFLT executable - version 0 flthdr output: leds Magic: bFLT Rev: 4 Build Date: Mon Oct 31 23:35:17 2011 Entry: 0x50 Data Start: 0x4d20 Data End: 0x5a00 BSS End: 0x7a40 Stack Size: 0x1000 Reloc Start: 0x5a00 Reloc Count: 0x7f Flags: 0x0 ( Output from a binary I compiled earlier with the compilers distributed by wago file output: luac: BFLT executable - version 4 ram flthdr output: luac Magic: bFLT Rev: 80 Build Date: Fri May 15 00:25:23 1970 Entry: 0x2a6a0 Data Start: 0x1000 Data End: 0x3a7 BSS End: 0x4e3c65ee Stack Size: 0x0 Reloc Start: 0x0 Reloc Count: 0x0 Flags: 0x0 ( The file output is realy weird, BFLT version 0? Can someone give me some help with this? Gino From gerg at snapgear.com Thu Nov 3 01:58:27 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Thu, 3 Nov 2011 15:58:27 +1000 Subject: [uClinux-dev] [PATCH] m68k: make fp register stores consistent for m68k and ColdFire Message-ID: <1320299907-11410-1-git-send-email-gerg@snapgear.com> From: Greg Ungerer There is no reason we can't make the saved fp registers the same for all m68k types and ColdFire. There is a little wasted space, but the code consistentcy and cleanliness is a big win. sigcontext.h is an exported header, but currently there is no in-mainline users of the !__uClinux__ and __mcoldfire__ case that this change effects. Even better this change actually makes this structure consistent with the out-of-mainline ColdFire/MMU code. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/sigcontext.h | 4 ---- arch/m68k/include/asm/ucontext.h | 4 ---- 2 files changed, 0 insertions(+), 8 deletions(-) diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h index a29dd74..523db2a 100644 --- a/arch/m68k/include/asm/sigcontext.h +++ b/arch/m68k/include/asm/sigcontext.h @@ -15,11 +15,7 @@ struct sigcontext { unsigned long sc_pc; unsigned short sc_formatvec; #ifndef __uClinux__ -# ifdef __mcoldfire__ - unsigned long sc_fpregs[2][2]; /* room for two fp registers */ -# else unsigned long sc_fpregs[2*3]; /* room for two fp registers */ -# endif unsigned long sc_fpcntl[3]; unsigned char sc_fpstate[216]; #endif diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h index 00dcc51..e4e2266 100644 --- a/arch/m68k/include/asm/ucontext.h +++ b/arch/m68k/include/asm/ucontext.h @@ -7,11 +7,7 @@ typedef greg_t gregset_t[NGREG]; typedef struct fpregset { int f_fpcntl[3]; -#ifdef __mcoldfire__ - int f_fpregs[8][2]; -#else int f_fpregs[8*3]; -#endif } fpregset_t; struct mcontext { -- 1.7.0.4 From geert at linux-m68k.org Thu Nov 3 04:23:05 2011 From: geert at linux-m68k.org (Geert Uytterhoeven) Date: Thu, 3 Nov 2011 09:23:05 +0100 Subject: [uClinux-dev] Re: [PATCH] m68k: make fp register stores consistent for m68k and ColdFire In-Reply-To: <1320299907-11410-1-git-send-email-gerg@snapgear.com> References: <1320299907-11410-1-git-send-email-gerg@snapgear.com> Message-ID: On Thu, Nov 3, 2011 at 06:58, wrote: > From: Greg Ungerer > > There is no reason we can't make the saved fp registers the same for all > m68k types and ColdFire. There is a little wasted space, but the code > consistentcy and cleanliness is a big win. consistency > sigcontext.h is an exported header, but currently there is no in-mainline > users of the !__uClinux__ and __mcoldfire__ case that this change effects. > Even better this change actually makes this structure consistent with > the out-of-mainline ColdFire/MMU code. > > Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven Gr{oetje,eeting}s, ? ? ? ? ? ? ? ? ? ? ? ? Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ?? -- Linus Torvalds From gerg at snapgear.com Thu Nov 3 21:14:50 2011 From: gerg at snapgear.com (Greg Ungerer) Date: Fri, 4 Nov 2011 11:14:50 +1000 Subject: [uClinux-dev] Re: [PATCH] m68k: make fp register stores consistent for m68k and ColdFire In-Reply-To: References: <1320299907-11410-1-git-send-email-gerg@snapgear.com> Message-ID: <4EB33C8A.5020000@snapgear.com> Hi Geert, On 03/11/11 18:23, Geert Uytterhoeven wrote: > On Thu, Nov 3, 2011 at 06:58, wrote: >> From: Greg Ungerer >> >> There is no reason we can't make the saved fp registers the same for all >> m68k types and ColdFire. There is a little wasted space, but the code >> consistentcy and cleanliness is a big win. > > consistency I really need to spell check these :-) >> sigcontext.h is an exported header, but currently there is no in-mainline >> users of the !__uClinux__ and __mcoldfire__ case that this change effects. >> Even better this change actually makes this structure consistent with >> the out-of-mainline ColdFire/MMU code. >> >> Signed-off-by: Greg Ungerer > > Acked-by: Geert Uytterhoeven Thanks! Regards Greg ------------------------------------------------------------------------ Greg Ungerer -- Principal Engineer EMAIL: gerg at snapgear.com SnapGear Group, McAfee PHONE: +61 7 3435 2888 8 Gardner Close FAX: +61 7 3217 5323 Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com From gino at heusdens-ulenaers.be Sat Nov 5 07:08:51 2011 From: gino at heusdens-ulenaers.be (Gino Heusdens) Date: Sat, 05 Nov 2011 12:08:51 +0100 Subject: [uClinux-dev] Re: bFLT binary: applet not found In-Reply-To: <1320449040.7163.247.camel@xyzzy.cam.corp.google.com> References: <4EB0EF01.9020507@heusdens-ulenaers.be> <1320449040.7163.247.camel@xyzzy.cam.corp.google.com> Message-ID: <4EB51943.4060700@heusdens-ulenaers.be> On 11/05/2011 12:24 AM, Bernie Innocenti wrote: > Hello, > > On Wed, 2011-11-02 at 08:19 +0100, Gino Heusdens wrote: >> Hi, >> >> I'm having some troubles building uClinux with my self compiled toolkit. >> Normaly I use an precompiled (uclinux-tools-20050221, binaries are >> distributed by wago), but there is none for my x64 architecture. >> I used these sources, http://www.develer.com/uclinux/uclinux-tools-20050221/ > > > My uClinux toolchain is outrageously outdated (2005). The latest version > (2008) is here: > > http://www.uclinux.org/pub/uClinux/m68k-elf-tools/ > I know its outdated, but it was distributed with the device. So I used that old version. I don't know if I simple can use a newer toolkit without any compatibility issues? In the meanwhile I discoverd there where some incompatibilities in the elf2flt sources on x64 hosts. unsigned long is 8-bit on 64-bit linux, so the bFLT header was written incorrect. I backported the commits 62d6b3b0 and 223a4dab of the recent sources of elf2flt. (Patch included for the 20041205 sources of elf2flt) After that everything is working fine on x64 Archlinux, bFLT binaries are build with the correct header and are executing fine on the device. Gino From gino at heusdens-ulenaers.be Fri Nov 4 18:03:53 2011 From: gino at heusdens-ulenaers.be (Gino Heusdens) Date: Fri, 4 Nov 2011 23:03:53 +0100 Subject: [PATCH] fixed x64 alignment, so x64 hosts can build a correct elf2flt binary unsigned long is 8-bit on 64-bit linux Message-ID: --- elf2flt.c | 70 ++++++++++++++++++++++++++++++------------------------------ flat.h | 36 +++++++++++++++--------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/elf2flt.c b/elf2flt.c index ea4b3fa..06fb1e5 100644 --- a/elf2flt.c +++ b/elf2flt.c @@ -198,7 +198,7 @@ einfo (int type, const char *format, ...) { asymbol** get_symbols (bfd *abfd, long *num) { - long storage_needed; + int32_t storage_needed; asymbol **symbol_table; long number_of_symbols; @@ -254,11 +254,11 @@ get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number -long -add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len) +int32_t +add_com_to_bss(asymbol **symbol_table, int32_t number_of_symbols, int32_t bss_len) { - long i, comsize; - long offset; + int32_t i, comsize; + int32_t offset; comsize = 0; for (i=0; i GOT_LIMIT) { fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n", @@ -654,7 +654,7 @@ dump_symbols(symbols, number_of_symbols); sym_vma, (*(q->sym_ptr_ptr))->value, q->address, sym_addr, (*p)->howto->rightshift, - *(unsigned long *)r_mem); + *(uint32_t *)r_mem); sym_vma = bfd_section_vma(abs_bfd, sym_section); sym_addr += sym_vma + q->addend; break; @@ -671,7 +671,7 @@ dump_symbols(symbols, number_of_symbols); sym_vma, (*(q->sym_ptr_ptr))->value, q->address, sym_addr, (*p)->howto->rightshift, - *(unsigned long *)r_mem); + *(uint32_t *)r_mem); case R_ARM_PC24: sym_vma = 0; sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift; @@ -779,7 +779,7 @@ dump_symbols(symbols, number_of_symbols); /* create a new reloc entry */ flat_relocs = realloc(flat_relocs, - (flat_reloc_count + 1) * sizeof(unsigned long)); + (flat_reloc_count + 1) * sizeof(uint32_t)); flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address); flat_reloc_count++; relocation_needed = 0; @@ -854,7 +854,7 @@ dump_symbols(symbols, number_of_symbols); sym_addr = (((*(q->sym_ptr_ptr))->value- q->address) >> 2) & 0x3fffffff; sym_addr |= ( - ntohl(*(unsigned long *)r_mem) + ntohl(*(uint32_t *)r_mem) & 0xc0000000 ); break; @@ -864,7 +864,7 @@ dump_symbols(symbols, number_of_symbols); sym_vma = bfd_section_vma(abs_bfd, sym_section); sym_addr += sym_vma + q->addend; sym_addr |= ( - htonl(*(unsigned long *)r_mem) + htonl(*(uint32_t *)r_mem) & 0xffc00000 ); break; @@ -875,7 +875,7 @@ dump_symbols(symbols, number_of_symbols); sym_addr += sym_vma + q->addend; sym_addr &= 0x000003ff; sym_addr |= ( - htonl(*(unsigned long *)r_mem) + htonl(*(uint32_t *)r_mem) & 0xfffffc00 ); break; @@ -1108,7 +1108,7 @@ DIS29_RELOCATION: i3 = 0; } - tmp.l = *(unsigned long *)r_mem; + tmp.l = *(uint32_t *)r_mem; hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16); if (((*p)->howto->type != R_ARM_PC24) && ((*p)->howto->type != R_ARM_PLT32)) @@ -1123,9 +1123,9 @@ DIS29_RELOCATION: ((*p)->howto->type != R_ARM_PLT32)) tmp.c[i3] = (hl >> 24) & 0xff; if ((*p)->howto->type == R_ARM_ABS32) - *(unsigned long *)r_mem = htonl(hl); + *(uint32_t *)r_mem = htonl(hl); else - *(unsigned long *)r_mem = tmp.l; + *(uint32_t *)r_mem = tmp.l; #elif defined(TARGET_e1) #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/ @@ -1197,7 +1197,7 @@ DIS29_RELOCATION: */ if (relocation_needed) { flat_relocs = realloc(flat_relocs, - (flat_reloc_count + 1) * sizeof(unsigned long)); + (flat_reloc_count + 1) * sizeof(uint32_t)); #ifndef TARGET_e1 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address); @@ -1401,20 +1401,20 @@ int main(int argc, char *argv[]) asymbol **symbol_table; long number_of_symbols; - unsigned long data_len = 0; - unsigned long bss_len = 0; - unsigned long text_len = 0; - unsigned long reloc_len; + uint32_t data_len = 0; + uint32_t bss_len = 0; + uint32_t text_len = 0; + uint32_t reloc_len; - unsigned long data_vma = ~0; - unsigned long bss_vma = ~0; - unsigned long text_vma = ~0; + uint32_t data_vma = ~0; + uint32_t bss_vma = ~0; + uint32_t text_vma = ~0; unsigned long text_offs; void *text; void *data; - unsigned long *reloc; + uint32_t *reloc; struct flat_hdr hdr; @@ -1487,7 +1487,7 @@ int main(int argc, char *argv[]) if (! rel_file) rel_file = fname; - + if (!(rel_bfd = bfd_openr(rel_file, 0))) { fprintf(stderr, "Can't open %s\n", rel_file); exit(1); @@ -1530,7 +1530,7 @@ int main(int argc, char *argv[]) /* Group output sections into text, data, and bss, and calc their sizes. */ for (s = abs_bfd->sections; s != NULL; s = s->next) { - unsigned long *vma, *len; + uint32_t *vma, *len; bfd_size_type sec_size; bfd_vma sec_vma; @@ -1629,7 +1629,7 @@ int main(int argc, char *argv[]) data_len = bss_vma - data_vma; } - reloc = (unsigned long *) + reloc = (uint32_t *) output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len, text, text_len, text_vma, data, data_len, data_vma, rel_bfd); @@ -1654,7 +1654,7 @@ int main(int argc, char *argv[]) | (pic_with_got ? FLAT_FLAG_GOTPIC : 0) | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0) ); - hdr.build_date = htonl((unsigned long)time(NULL)); + hdr.build_date = htonl((uint32_t)time(NULL)); bzero(hdr.filler, sizeof(hdr.filler)); for (i=0; i References: <4EB0EF01.9020507@heusdens-ulenaers.be> <1320449040.7163.247.camel@xyzzy.cam.corp.google.com> <4EB51943.4060700@heusdens-ulenaers.be> <1320517473.13783.10.camel@giskard> Message-ID: <4EB5C181.90308@heusdens-ulenaers.be> On 11/05/2011 07:24 PM, Bernie Innocenti wrote: > On Sat, 2011-11-05 at 12:08 +0100, Gino Heusdens wrote: >>> My uClinux toolchain is outrageously outdated (2005). The latest version >>> (2008) is here: >>> >>> http://www.uclinux.org/pub/uClinux/m68k-elf-tools/ >>> >> I know its outdated, but it was distributed with the device. > > Nice to hear that. What device is this? It's a WAGO 750-860 PLC. I used it to do some automation in our home. > > >> So I used >> that old version. I don't know if I simple can use a newer toolkit >> without any compatibility issues? > > It depends: are you going to replace the whole uClinux image with yours, > or just add one executable? In the latter case, you should use the same > toolchain that was used to compile the rest of the OS. Currently its for compiling userspace programs. > > If instead you're rebuilding the whole system from sources, I recommend > trying the very latest toolchain with the very latest stable release of > uClinux. Newer code may contain bugfixes and enhancements that will save > you time later on. Of course, the latest release might have dropped > support for your platform... embedded processors have a very short > lifespan! That's not gonna work for me. I can't rebuild the wago kernel modules because I don't have the source code.So recompiling with another kernel and/or other toolchain is not an option I think, unless I rewrite the drivers myself. Recompiling/patching the current kernel sources with the old toolchain is no problem, I already did that an it works fine. The processor is an ARM7TDMI, don't know if its still supported. >> In the meanwhile I discoverd there where some incompatibilities in the >> elf2flt sources on x64 hosts. unsigned long is 8-bit on 64-bit linux, so >> the bFLT header was written incorrect. I backported the commits 62d6b3b0 >> and 223a4dab of the recent sources of elf2flt. (Patch included for the >> 20041205 sources of elf2flt) >> After that everything is working fine on x64 Archlinux, bFLT binaries >> are build with the correct header and are executing fine on the device. > > Ah, I remember fixing some 64bit issues in elf2flt! I thought I had > nailed them all, but... > > If you send me the patch, I'll publish it on my old toolchain page. I no > longer maintain it, but this would save time to people like you who are > still using it. Patch included as text and attachment diff --git a/elf2flt.c b/elf2flt.c index ea4b3fa..06fb1e5 100644 --- a/elf2flt.c +++ b/elf2flt.c @@ -198,7 +198,7 @@ einfo (int type, const char *format, ...) { asymbol** get_symbols (bfd *abfd, long *num) { - long storage_needed; + int32_t storage_needed; asymbol **symbol_table; long number_of_symbols; @@ -254,11 +254,11 @@ get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number -long -add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len) +int32_t +add_com_to_bss(asymbol **symbol_table, int32_t number_of_symbols, int32_t bss_len) { - long i, comsize; - long offset; + int32_t i, comsize; + int32_t offset; comsize = 0; for (i=0; i GOT_LIMIT) { fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n", @@ -654,7 +654,7 @@ dump_symbols(symbols, number_of_symbols); sym_vma, (*(q->sym_ptr_ptr))->value, q->address, sym_addr, (*p)->howto->rightshift, - *(unsigned long *)r_mem); + *(uint32_t *)r_mem); sym_vma = bfd_section_vma(abs_bfd, sym_section); sym_addr += sym_vma + q->addend; break; @@ -671,7 +671,7 @@ dump_symbols(symbols, number_of_symbols); sym_vma, (*(q->sym_ptr_ptr))->value, q->address, sym_addr, (*p)->howto->rightshift, - *(unsigned long *)r_mem); + *(uint32_t *)r_mem); case R_ARM_PC24: sym_vma = 0; sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift; @@ -779,7 +779,7 @@ dump_symbols(symbols, number_of_symbols); /* create a new reloc entry */ flat_relocs = realloc(flat_relocs, - (flat_reloc_count + 1) * sizeof(unsigned long)); + (flat_reloc_count + 1) * sizeof(uint32_t)); flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address); flat_reloc_count++; relocation_needed = 0; @@ -854,7 +854,7 @@ dump_symbols(symbols, number_of_symbols); sym_addr = (((*(q->sym_ptr_ptr))->value- q->address)>> 2)& 0x3fffffff; sym_addr |= ( - ntohl(*(unsigned long *)r_mem) + ntohl(*(uint32_t *)r_mem) & 0xc0000000 ); break; @@ -864,7 +864,7 @@ dump_symbols(symbols, number_of_symbols); sym_vma = bfd_section_vma(abs_bfd, sym_section); sym_addr += sym_vma + q->addend; sym_addr |= ( - htonl(*(unsigned long *)r_mem) + htonl(*(uint32_t *)r_mem) & 0xffc00000 ); break; @@ -875,7 +875,7 @@ dump_symbols(symbols, number_of_symbols); sym_addr += sym_vma + q->addend; sym_addr&= 0x000003ff; sym_addr |= ( - htonl(*(unsigned long *)r_mem) + htonl(*(uint32_t *)r_mem) & 0xfffffc00 ); break; @@ -1108,7 +1108,7 @@ DIS29_RELOCATION: i3 = 0; } - tmp.l = *(unsigned long *)r_mem; + tmp.l = *(uint32_t *)r_mem; hl = tmp.c[i0] | (tmp.c[i1]<< 8) | (tmp.c[i2]<< 16); if (((*p)->howto->type != R_ARM_PC24)&& ((*p)->howto->type != R_ARM_PLT32)) @@ -1123,9 +1123,9 @@ DIS29_RELOCATION: ((*p)->howto->type != R_ARM_PLT32)) tmp.c[i3] = (hl>> 24)& 0xff; if ((*p)->howto->type == R_ARM_ABS32) - *(unsigned long *)r_mem = htonl(hl); + *(uint32_t *)r_mem = htonl(hl); else - *(unsigned long *)r_mem = tmp.l; + *(uint32_t *)r_mem = tmp.l; #elif defined(TARGET_e1) #define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/ @@ -1197,7 +1197,7 @@ DIS29_RELOCATION: */ if (relocation_needed) { flat_relocs = realloc(flat_relocs, - (flat_reloc_count + 1) * sizeof(unsigned long)); + (flat_reloc_count + 1) * sizeof(uint32_t)); #ifndef TARGET_e1 flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address); @@ -1401,20 +1401,20 @@ int main(int argc, char *argv[]) asymbol **symbol_table; long number_of_symbols; - unsigned long data_len = 0; - unsigned long bss_len = 0; - unsigned long text_len = 0; - unsigned long reloc_len; + uint32_t data_len = 0; + uint32_t bss_len = 0; + uint32_t text_len = 0; + uint32_t reloc_len; - unsigned long data_vma = ~0; - unsigned long bss_vma = ~0; - unsigned long text_vma = ~0; + uint32_t data_vma = ~0; + uint32_t bss_vma = ~0; + uint32_t text_vma = ~0; unsigned long text_offs; void *text; void *data; - unsigned long *reloc; + uint32_t *reloc; struct flat_hdr hdr; @@ -1487,7 +1487,7 @@ int main(int argc, char *argv[]) if (! rel_file) rel_file = fname; - + if (!(rel_bfd = bfd_openr(rel_file, 0))) { fprintf(stderr, "Can't open %s\n", rel_file); exit(1); @@ -1530,7 +1530,7 @@ int main(int argc, char *argv[]) /* Group output sections into text, data, and bss, and calc their sizes. */ for (s = abs_bfd->sections; s != NULL; s = s->next) { - unsigned long *vma, *len; + uint32_t *vma, *len; bfd_size_type sec_size; bfd_vma sec_vma; @@ -1629,7 +1629,7 @@ int main(int argc, char *argv[]) data_len = bss_vma - data_vma; } - reloc = (unsigned long *) + reloc = (uint32_t *) output_relocs(abs_bfd, symbol_table, number_of_symbols,&reloc_len, text, text_len, text_vma, data, data_len, data_vma, rel_bfd); @@ -1654,7 +1654,7 @@ int main(int argc, char *argv[]) | (pic_with_got ? FLAT_FLAG_GOTPIC : 0) | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0) ); - hdr.build_date = htonl((unsigned long)time(NULL)); + hdr.build_date = htonl((uint32_t)time(NULL)); bzero(hdr.filler, sizeof(hdr.filler)); for (i=0; i From b.buettner at mkc-gmbh.de Mon Nov 7 05:41:12 2011 From: b.buettner at mkc-gmbh.de (=?ISO-8859-15?Q?MKC_GmbH_-_Bernd_B=FCttner?=) Date: Mon, 07 Nov 2011 11:41:12 +0100 Subject: [uClinux-dev] No more mails from the list Message-ID: <4EB7B5C8.20001@mkc-gmbh.de> Since mid september I don't receive mails from the list anymore. By looking at the archives I see that I am not the only one, but there is no solution for this. Looking at my membership configuration I see a bounce score of 2.0. But the only problems with my email account are with uclinux. As the membership remainder says, I sent this message to mailman-owner at uclinux.org first. This one was returned to me as undelivered. Is there something I can/must do? Bernd From gerg at snapgear.com Mon Nov 14 01:04:53 2011 From: gerg at snapgear.com (Greg Ungerer) Date: Mon, 14 Nov 2011 16:04:53 +1000 Subject: [uClinux-dev] change of m68knommu git tree back to kernel.org Message-ID: <4EC0AF85.8060206@snapgear.com> Hi Stephen, The m68knommu git tree has now moved back onto kernel.org. Could you please pull the for-next branch of the m68knommu git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git for-next for the linux-next tree. Thanks Greg -- ------------------------------------------------------------------------ Greg Ungerer -- Principal Engineer EMAIL: gerg at snapgear.com SnapGear Group, McAfee PHONE: +61 7 3435 2888 8 Gardner Close FAX: +61 7 3217 5323 Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com From gerg at snapgear.com Fri Nov 18 01:19:16 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 18 Nov 2011 16:19:16 +1000 Subject: [uClinux-dev] [PATCH] m68knommu: no need to set register marker on traps Message-ID: <1321597156-23570-1-git-send-email-gerg@snapgear.com> From: Greg Ungerer Commit 61619b12078dc8b85a3d4cbfa16f650daa341bd1 ("m68k: merge mmu and non-mmu include/asm/entry.h files") made the trap entry code basically the same for mmu and non-mmu builds. This means we no longer need code to mark the stack frame as "system-call" type or other in the non-mmu trap handling entry points. This is done in the SAVE_ALL_INT macro now. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/entry_no.S | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/arch/m68k/kernel/entry_no.S b/arch/m68k/kernel/entry_no.S index 1b42890..ac86a9f 100644 --- a/arch/m68k/kernel/entry_no.S +++ b/arch/m68k/kernel/entry_no.S @@ -44,8 +44,6 @@ ENTRY(buserr) SAVE_ALL_INT - moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) movel %sp,%sp at - /* stack frame pointer argument */ jsr buserr_c addql #4,%sp @@ -53,8 +51,6 @@ ENTRY(buserr) ENTRY(trap) SAVE_ALL_INT - moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) movel %sp,%sp at - /* stack frame pointer argument */ jsr trap_c addql #4,%sp @@ -65,8 +61,6 @@ ENTRY(trap) .globl dbginterrupt ENTRY(dbginterrupt) SAVE_ALL_INT - moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) movel %sp,%sp at - /* stack frame pointer argument */ jsr dbginterrupt_c addql #4,%sp -- 1.7.0.4 From gerg at snapgear.com Fri Nov 18 01:32:12 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 18 Nov 2011 16:32:12 +1000 Subject: [uClinux-dev] [PATCH] m68knommu: disable cache early in startup for ColdFire Message-ID: <1321597932-23734-1-git-send-email-gerg@snapgear.com> From: Greg Ungerer Disbale the CPU cache really early in the ColdFire startup code. We set up some variables for RAM sizing and we want to make they stick in RAM. Signed-off-by: Alexander Stein Signed-off-by: Greg Ungerer --- arch/m68k/platform/coldfire/head.S | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S index c334838..49666b4 100644 --- a/arch/m68k/platform/coldfire/head.S +++ b/arch/m68k/platform/coldfire/head.S @@ -143,6 +143,9 @@ __HEAD _start: nop /* filler */ movew #0x2700, %sr /* no interrupts */ + movel #CACHE_INIT,%d0 /* disable cache */ + movec %d0,%CACR + nop #if defined(CONFIG_UBOOT) movel %sp,_init_sp /* save initial stack pointer */ #endif @@ -176,9 +179,6 @@ _start: * it is very similar. Define the exact settings in the headers * then the code here is the same for all. */ - movel #CACHE_INIT,%d0 /* invalidate whole cache */ - movec %d0,%CACR - nop movel #ACR0_MODE,%d0 /* set RAM region for caching */ movec %d0,%ACR0 movel #ACR1_MODE,%d0 /* anything else to cache? */ -- 1.7.0.4 From gerg at snapgear.com Fri Nov 18 01:32:40 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 18 Nov 2011 16:32:40 +1000 Subject: [uClinux-dev] [PATCH] m68k: handle presence of 64bit mul/div instructions cleanly Message-ID: <1321597960-23782-1-git-send-email-gerg@snapgear.com> From: Greg Ungerer The traditional 68000 processors and the newer reduced instruction set ColdFire processors do not support the 32*32->64 multiply or the 64/32->32 divide instructions. This is not a difference based on the presence of a hardware MMU or not. Create a new config symbol to mark that a CPU type doesn't support the longer multiply/divide instructions. Use this then as a basis for using the fast 64bit based divide (in div64.h) and for linking in the extra libgcc functions that may be required (mulsi3, divsi3, etc). Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig | 3 +++ arch/m68k/Kconfig.cpu | 2 ++ arch/m68k/include/asm/div64.h | 8 ++++---- arch/m68k/kernel/m68k_ksyms.c | 2 +- arch/m68k/lib/Makefile | 8 +++----- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 2fe2d63..32fd364 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -63,6 +63,9 @@ config ZONE_DMA config CPU_HAS_NO_BITFIELDS bool +config CPU_HAS_NO_MULDIV64 + bool + config HZ int default 1000 if CLEOPATRA diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 17d37ed..017f4fc 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -3,6 +3,7 @@ comment "Processor Type" config M68000 bool select CPU_HAS_NO_BITFIELDS + select CPU_HAS_NO_MULDIV64 select GENERIC_CSUM help The Freescale (was Motorola) 68000 CPU is the first generation of @@ -24,6 +25,7 @@ config COLDFIRE select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select CPU_HAS_NO_BITFIELDS + select CPU_HAS_NO_MULDIV64 select GENERIC_CSUM help The Freescale ColdFire family of processors is a modern derivitive diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h index edb6614..444ea8a 100644 --- a/arch/m68k/include/asm/div64.h +++ b/arch/m68k/include/asm/div64.h @@ -1,7 +1,9 @@ #ifndef _M68K_DIV64_H #define _M68K_DIV64_H -#ifdef CONFIG_MMU +#ifdef CONFIG_CPU_HAS_NO_MULDIV64 +#include +#else #include @@ -27,8 +29,6 @@ __rem; \ }) -#else -#include -#endif /* CONFIG_MMU */ +#endif /* CONFIG_CPU_HAS_NO_MULDIV64 */ #endif /* _M68K_DIV64_H */ diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index 1b7a14d..774c1bd 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c @@ -14,7 +14,7 @@ EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__muldi3); -#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) +#if defined(CONFIG_CPU_HAS_NO_MULDIV64) /* * Simpler 68k and ColdFire parts also need a few other gcc functions. */ diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index b3b40e4..a9d782d 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -6,11 +6,9 @@ lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ memcpy.o memset.o memmove.o -ifdef CONFIG_MMU -lib-y += string.o uaccess.o -else -lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o -endif +lib-$(CONFIG_MMU) += string.o uaccess.o +lib-$(CONFIG_CPU_HAS_NO_MULDIV64) += mulsi3.o divsi3.o udivsi3.o +lib-$(CONFIG_CPU_HAS_NO_MULDIV64) += modsi3.o umodsi3.o ifndef CONFIG_GENERIC_CSUM lib-y += checksum.o -- 1.7.0.4 From gerg at snapgear.com Fri Nov 18 01:32:27 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 18 Nov 2011 16:32:27 +1000 Subject: [uClinux-dev] [PATCH] m68knommu: fix ColdFire slice timer to handle clock counter wrapping Message-ID: <1321597947-23758-1-git-send-email-gerg@snapgear.com> From: Greg Ungerer The read function for the ColdFire slice timer doesn't deal with the hardware timer count register wrapping while we are reading it to get an accurate snapshot of the time. Re-read the timer a second time and see if it has wrapped, adjust the total count as required. Signed-off-by: Greg Ungerer --- arch/m68k/platform/coldfire/sltimers.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/m68k/platform/coldfire/sltimers.c b/arch/m68k/platform/coldfire/sltimers.c index b7f822b..1249367 100644 --- a/arch/m68k/platform/coldfire/sltimers.c +++ b/arch/m68k/platform/coldfire/sltimers.c @@ -98,16 +98,17 @@ static struct irqaction mcfslt_timer_irq = { static cycle_t mcfslt_read_clk(struct clocksource *cs) { unsigned long flags; - u32 cycles; - u16 scnt; + u32 cycles, scnt; local_irq_save(flags); scnt = __raw_readl(TA(MCFSLT_SCNT)); cycles = mcfslt_cnt; + if (scnt < __raw_readl(TA(MCFSLT_SCNT))) + cycles += mcfslt_cycles_per_jiffy; local_irq_restore(flags); /* subtract because slice timers count down */ - return cycles - scnt; + return cycles + ((mcfslt_cycles_per_jiffy - 1) - scnt); } static struct clocksource mcfslt_clk = { -- 1.7.0.4 From gerg at snapgear.com Fri Nov 18 01:32:50 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 18 Nov 2011 16:32:50 +1000 Subject: [uClinux-dev] [PATCH] m68k: simpler m68k and ColdFire CPU's can use generic csum code Message-ID: <1321597970-23806-1-git-send-email-gerg@snapgear.com> From: Greg Ungerer We have two implementations of the IP checksuming code for the m68k arch. One uses the more advanced instructions available in 68020 and above processors, the other uses the simpler instructions available on the original 68000 processors and the modern ColdFire processors. This simpler code is pretty much the same as the generic lib implementation of the IP csum functions. So lets just switch over to using that. That means we can completely remove the checksum_no.c file, and only have the local fast code used for the more complex 68k CPU family members. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/Kconfig | 3 + arch/m68k/Kconfig.cpu | 2 + arch/m68k/include/asm/checksum.h | 31 +--- arch/m68k/lib/Makefile | 8 +- arch/m68k/lib/checksum.c | 425 ++++++++++++++++++++++++++++++++++++++ arch/m68k/lib/checksum_mm.c | 425 -------------------------------------- arch/m68k/lib/checksum_no.c | 156 -------------- 7 files changed, 441 insertions(+), 609 deletions(-) create mode 100644 arch/m68k/lib/checksum.c delete mode 100644 arch/m68k/lib/checksum_mm.c delete mode 100644 arch/m68k/lib/checksum_no.c diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 2914b03..2fe2d63 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -40,6 +40,9 @@ config GENERIC_CALIBRATE_DELAY config GENERIC_IOMAP def_bool MMU +config GENERIC_CSUM + bool + config TIME_LOW_RES bool default y diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 9af9e68..17d37ed 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -3,6 +3,7 @@ comment "Processor Type" config M68000 bool select CPU_HAS_NO_BITFIELDS + select GENERIC_CSUM help The Freescale (was Motorola) 68000 CPU is the first generation of the well known M68K family of processors. The CPU core as well as @@ -23,6 +24,7 @@ config COLDFIRE select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select CPU_HAS_NO_BITFIELDS + select GENERIC_CSUM help The Freescale ColdFire family of processors is a modern derivitive of the 68000 processor family. They are mainly targeted at embedded diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index ec51448..2f88d86 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -3,6 +3,10 @@ #include +#ifdef CONFIG_GENERIC_CSUM +#include +#else + /* * computes the checksum of a memory block at buff, length len, * and adds in "sum" (32-bit) @@ -34,30 +38,6 @@ extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); - -#ifdef CONFIG_COLDFIRE - -/* - * The ColdFire cores don't support all the 68k instructions used - * in the optimized checksum code below. So it reverts back to using - * more standard C coded checksums. The fast checksum code is - * significantly larger than the optimized version, so it is not - * inlined here. - */ -__sum16 ip_fast_csum(const void *iph, unsigned int ihl); - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp = (__force u32)sum; - - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - - return (__force __sum16)~tmp; -} - -#else - /* * This is a version of ip_fast_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -97,8 +77,6 @@ static inline __sum16 csum_fold(__wsum sum) return (__force __sum16)~sum; } -#endif /* CONFIG_COLDFIRE */ - static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, __wsum sum) @@ -167,4 +145,5 @@ csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, return csum_fold(sum); } +#endif /* CONFIG_GENERIC_CSUM */ #endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index 1a1bd90..b3b40e4 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -7,8 +7,12 @@ lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ memcpy.o memset.o memmove.o ifdef CONFIG_MMU -lib-y += string.o uaccess.o checksum_mm.o +lib-y += string.o uaccess.o else -lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o checksum_no.o +lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o +endif + +ifndef CONFIG_GENERIC_CSUM +lib-y += checksum.o endif diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c new file mode 100644 index 0000000..6216f12 --- /dev/null +++ b/arch/m68k/lib/checksum.c @@ -0,0 +1,425 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * IP/TCP/UDP checksumming routines + * + * Authors: Jorge Cwik, + * Arnt Gulbrandsen, + * Tom May, + * Andreas Schwab, + * Lots of code moved from tcp.c and ip.c; see those files + * for more names. + * + * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: + * Fixed some nasty bugs, causing some horrible crashes. + * A: At some points, the sum (%0) was used as + * length-counter instead of the length counter + * (%1). Thanks to Roman Hodek for pointing this out. + * B: GCC seems to mess up if one uses too many + * data-registers to hold input values and one tries to + * specify d0 and d1 as scratch registers. Letting gcc + * choose these registers itself solves the problem. + * + * This program 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 of the License, or (at your option) any later version. + * + * 1998/8/31 Andreas Schwab: + * Zero out rest of buffer on exception in + * csum_partial_copy_from_user. + */ + +#include +#include + +/* + * computes a partial checksum, e.g. for TCP/UDP fragments + */ + +__wsum csum_partial(const void *buff, int len, __wsum sum) +{ + unsigned long tmp1, tmp2; + /* + * Experiments with ethernet and slip connections show that buff + * is aligned on either a 2-byte or 4-byte boundary. + */ + __asm__("movel %2,%3\n\t" + "btst #1,%3\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\t" + "addw %2 at +,%0\n\t" /* add first word to sum */ + "clrl %3\n\t" + "addxl %3,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%3\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\t" + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "dbra %1,1b\n\t" + "clrl %4\n\t" + "addxl %4,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %3,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%3\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%3\n\t" + "subqw #1,%3\n" + "3:\t" + /* loop for rest longs */ + "movel %2 at +,%4\n\t" + "addxl %4,%0\n\t" + "dbra %3,3b\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %4\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "movew %2 at +,%4\n\t" /* have rest >= 2: get word */ + "swap %4\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\t" + "moveb %2@,%4\n\t" /* have odd rest: get byte */ + "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %4,%0\n\t" /* now add rest long to sum */ + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "7:\t" + : "=d" (sum), "=d" (len), "=a" (buff), + "=&d" (tmp1), "=&d" (tmp2) + : "0" (sum), "1" (len), "2" (buff) + ); + return(sum); +} + +EXPORT_SYMBOL(csum_partial); + + +/* + * copy from user space while checksumming, with exception handling. + */ + +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *csum_err) +{ + /* + * GCC doesn't like more than 10 operands for the asm + * statements so we have to use tmp2 for the error + * code. + */ + unsigned long tmp1, tmp2; + + __asm__("movel %2,%4\n\t" + "btst #1,%4\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\n" + "10:\t" + "movesw %2 at +,%4\n\t" /* add first word to sum */ + "addw %4,%0\n\t" + "movew %4,%3 at +\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%4\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\n" + "11:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "12:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "13:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "14:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "15:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "16:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "17:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "18:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "dbra %1,1b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %4,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%4\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "3:\n" + /* loop for rest longs */ + "19:\t" + "movesl %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "dbra %4,3b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %5\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "20:\t" + "movesw %2 at +,%5\n\t" /* have rest >= 2: get word */ + "movew %5,%3 at +\n\t" + "swap %5\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\n" + "21:\t" + "movesb %2@,%5\n\t" /* have odd rest: get byte */ + "moveb %5,%3 at +\n\t" + "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %5,%0\n\t" /* now add rest long to sum */ + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "7:\t" + "clrl %5\n" /* no error - clear return value */ + "8:\n" + ".section .fixup,\"ax\"\n" + ".even\n" + /* If any exception occurs zero out the rest. + Similarities with the code above are intentional :-) */ + "90:\t" + "clrw %3 at +\n\t" + "movel %1,%4\n\t" + "lsrl #5,%1\n\t" + "jeq 1f\n\t" + "subql #1,%1\n" + "91:\t" + "clrl %3 at +\n" + "92:\t" + "clrl %3 at +\n" + "93:\t" + "clrl %3 at +\n" + "94:\t" + "clrl %3 at +\n" + "95:\t" + "clrl %3 at +\n" + "96:\t" + "clrl %3 at +\n" + "97:\t" + "clrl %3 at +\n" + "98:\t" + "clrl %3 at +\n\t" + "dbra %1,91b\n\t" + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 91b\n" + "1:\t" + "movel %4,%1\n\t" + "andw #0x1c,%4\n\t" + "jeq 1f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "99:\t" + "clrl %3 at +\n\t" + "dbra %4,99b\n\t" + "1:\t" + "andw #3,%1\n\t" + "jeq 9f\n" + "100:\t" + "clrw %3 at +\n\t" + "tstw %1\n\t" + "jeq 9f\n" + "101:\t" + "clrb %3 at +\n" + "9:\t" +#define STR(X) STR1(X) +#define STR1(X) #X + "moveq #-" STR(EFAULT) ",%5\n\t" + "jra 8b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + ".long 10b,90b\n" + ".long 11b,91b\n" + ".long 12b,92b\n" + ".long 13b,93b\n" + ".long 14b,94b\n" + ".long 15b,95b\n" + ".long 16b,96b\n" + ".long 17b,97b\n" + ".long 18b,98b\n" + ".long 19b,99b\n" + ".long 20b,100b\n" + ".long 21b,101b\n" + ".previous" + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), + "=&d" (tmp1), "=d" (tmp2) + : "0" (sum), "1" (len), "2" (src), "3" (dst) + ); + + *csum_err = tmp2; + + return(sum); +} + +EXPORT_SYMBOL(csum_partial_copy_from_user); + + +/* + * copy from kernel space while checksumming, otherwise like csum_partial + */ + +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) +{ + unsigned long tmp1, tmp2; + __asm__("movel %2,%4\n\t" + "btst #1,%4\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\t" + "movew %2 at +,%4\n\t" /* add first word to sum */ + "addw %4,%0\n\t" + "movew %4,%3 at +\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%4\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\t" + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "dbra %1,1b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %4,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%4\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "3:\t" + /* loop for rest longs */ + "movel %2 at +,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3 at +\n\t" + "dbra %4,3b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %5\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "movew %2 at +,%5\n\t" /* have rest >= 2: get word */ + "movew %5,%3 at +\n\t" + "swap %5\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\t" + "moveb %2@,%5\n\t" /* have odd rest: get byte */ + "moveb %5,%3 at +\n\t" + "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %5,%0\n\t" /* now add rest long to sum */ + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "7:\t" + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), + "=&d" (tmp1), "=&d" (tmp2) + : "0" (sum), "1" (len), "2" (src), "3" (dst) + ); + return(sum); +} +EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/m68k/lib/checksum_mm.c b/arch/m68k/lib/checksum_mm.c deleted file mode 100644 index 6216f12..0000000 --- a/arch/m68k/lib/checksum_mm.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, - * Arnt Gulbrandsen, - * Tom May, - * Andreas Schwab, - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: - * Fixed some nasty bugs, causing some horrible crashes. - * A: At some points, the sum (%0) was used as - * length-counter instead of the length counter - * (%1). Thanks to Roman Hodek for pointing this out. - * B: GCC seems to mess up if one uses too many - * data-registers to hold input values and one tries to - * specify d0 and d1 as scratch registers. Letting gcc - * choose these registers itself solves the problem. - * - * This program 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 of the License, or (at your option) any later version. - * - * 1998/8/31 Andreas Schwab: - * Zero out rest of buffer on exception in - * csum_partial_copy_from_user. - */ - -#include -#include - -/* - * computes a partial checksum, e.g. for TCP/UDP fragments - */ - -__wsum csum_partial(const void *buff, int len, __wsum sum) -{ - unsigned long tmp1, tmp2; - /* - * Experiments with ethernet and slip connections show that buff - * is aligned on either a 2-byte or 4-byte boundary. - */ - __asm__("movel %2,%3\n\t" - "btst #1,%3\n\t" /* Check alignment */ - "jeq 2f\n\t" - "subql #2,%1\n\t" /* buff%4==2: treat first word */ - "jgt 1f\n\t" - "addql #2,%1\n\t" /* len was == 2, treat only rest */ - "jra 4f\n" - "1:\t" - "addw %2 at +,%0\n\t" /* add first word to sum */ - "clrl %3\n\t" - "addxl %3,%0\n" /* add X bit */ - "2:\t" - /* unrolled loop for the main part: do 8 longs at once */ - "movel %1,%3\n\t" /* save len in tmp1 */ - "lsrl #5,%1\n\t" /* len/32 */ - "jeq 2f\n\t" /* not enough... */ - "subql #1,%1\n" - "1:\t" - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "dbra %1,1b\n\t" - "clrl %4\n\t" - "addxl %4,%0\n\t" /* add X bit */ - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 1b\n" - "2:\t" - "movel %3,%1\n\t" /* restore len from tmp1 */ - "andw #0x1c,%3\n\t" /* number of rest longs */ - "jeq 4f\n\t" - "lsrw #2,%3\n\t" - "subqw #1,%3\n" - "3:\t" - /* loop for rest longs */ - "movel %2 at +,%4\n\t" - "addxl %4,%0\n\t" - "dbra %3,3b\n\t" - "clrl %4\n\t" - "addxl %4,%0\n" /* add X bit */ - "4:\t" - /* now check for rest bytes that do not fit into longs */ - "andw #3,%1\n\t" - "jeq 7f\n\t" - "clrl %4\n\t" /* clear tmp2 for rest bytes */ - "subqw #2,%1\n\t" - "jlt 5f\n\t" - "movew %2 at +,%4\n\t" /* have rest >= 2: get word */ - "swap %4\n\t" /* into bits 16..31 */ - "tstw %1\n\t" /* another byte? */ - "jeq 6f\n" - "5:\t" - "moveb %2@,%4\n\t" /* have odd rest: get byte */ - "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ - "6:\t" - "addl %4,%0\n\t" /* now add rest long to sum */ - "clrl %4\n\t" - "addxl %4,%0\n" /* add X bit */ - "7:\t" - : "=d" (sum), "=d" (len), "=a" (buff), - "=&d" (tmp1), "=&d" (tmp2) - : "0" (sum), "1" (len), "2" (buff) - ); - return(sum); -} - -EXPORT_SYMBOL(csum_partial); - - -/* - * copy from user space while checksumming, with exception handling. - */ - -__wsum -csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *csum_err) -{ - /* - * GCC doesn't like more than 10 operands for the asm - * statements so we have to use tmp2 for the error - * code. - */ - unsigned long tmp1, tmp2; - - __asm__("movel %2,%4\n\t" - "btst #1,%4\n\t" /* Check alignment */ - "jeq 2f\n\t" - "subql #2,%1\n\t" /* buff%4==2: treat first word */ - "jgt 1f\n\t" - "addql #2,%1\n\t" /* len was == 2, treat only rest */ - "jra 4f\n" - "1:\n" - "10:\t" - "movesw %2 at +,%4\n\t" /* add first word to sum */ - "addw %4,%0\n\t" - "movew %4,%3 at +\n\t" - "clrl %4\n\t" - "addxl %4,%0\n" /* add X bit */ - "2:\t" - /* unrolled loop for the main part: do 8 longs at once */ - "movel %1,%4\n\t" /* save len in tmp1 */ - "lsrl #5,%1\n\t" /* len/32 */ - "jeq 2f\n\t" /* not enough... */ - "subql #1,%1\n" - "1:\n" - "11:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "12:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "13:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "14:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "15:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "16:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "17:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "18:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "dbra %1,1b\n\t" - "clrl %5\n\t" - "addxl %5,%0\n\t" /* add X bit */ - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 1b\n" - "2:\t" - "movel %4,%1\n\t" /* restore len from tmp1 */ - "andw #0x1c,%4\n\t" /* number of rest longs */ - "jeq 4f\n\t" - "lsrw #2,%4\n\t" - "subqw #1,%4\n" - "3:\n" - /* loop for rest longs */ - "19:\t" - "movesl %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "dbra %4,3b\n\t" - "clrl %5\n\t" - "addxl %5,%0\n" /* add X bit */ - "4:\t" - /* now check for rest bytes that do not fit into longs */ - "andw #3,%1\n\t" - "jeq 7f\n\t" - "clrl %5\n\t" /* clear tmp2 for rest bytes */ - "subqw #2,%1\n\t" - "jlt 5f\n\t" - "20:\t" - "movesw %2 at +,%5\n\t" /* have rest >= 2: get word */ - "movew %5,%3 at +\n\t" - "swap %5\n\t" /* into bits 16..31 */ - "tstw %1\n\t" /* another byte? */ - "jeq 6f\n" - "5:\n" - "21:\t" - "movesb %2@,%5\n\t" /* have odd rest: get byte */ - "moveb %5,%3 at +\n\t" - "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ - "6:\t" - "addl %5,%0\n\t" /* now add rest long to sum */ - "clrl %5\n\t" - "addxl %5,%0\n\t" /* add X bit */ - "7:\t" - "clrl %5\n" /* no error - clear return value */ - "8:\n" - ".section .fixup,\"ax\"\n" - ".even\n" - /* If any exception occurs zero out the rest. - Similarities with the code above are intentional :-) */ - "90:\t" - "clrw %3 at +\n\t" - "movel %1,%4\n\t" - "lsrl #5,%1\n\t" - "jeq 1f\n\t" - "subql #1,%1\n" - "91:\t" - "clrl %3 at +\n" - "92:\t" - "clrl %3 at +\n" - "93:\t" - "clrl %3 at +\n" - "94:\t" - "clrl %3 at +\n" - "95:\t" - "clrl %3 at +\n" - "96:\t" - "clrl %3 at +\n" - "97:\t" - "clrl %3 at +\n" - "98:\t" - "clrl %3 at +\n\t" - "dbra %1,91b\n\t" - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 91b\n" - "1:\t" - "movel %4,%1\n\t" - "andw #0x1c,%4\n\t" - "jeq 1f\n\t" - "lsrw #2,%4\n\t" - "subqw #1,%4\n" - "99:\t" - "clrl %3 at +\n\t" - "dbra %4,99b\n\t" - "1:\t" - "andw #3,%1\n\t" - "jeq 9f\n" - "100:\t" - "clrw %3 at +\n\t" - "tstw %1\n\t" - "jeq 9f\n" - "101:\t" - "clrb %3 at +\n" - "9:\t" -#define STR(X) STR1(X) -#define STR1(X) #X - "moveq #-" STR(EFAULT) ",%5\n\t" - "jra 8b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - ".long 10b,90b\n" - ".long 11b,91b\n" - ".long 12b,92b\n" - ".long 13b,93b\n" - ".long 14b,94b\n" - ".long 15b,95b\n" - ".long 16b,96b\n" - ".long 17b,97b\n" - ".long 18b,98b\n" - ".long 19b,99b\n" - ".long 20b,100b\n" - ".long 21b,101b\n" - ".previous" - : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), - "=&d" (tmp1), "=d" (tmp2) - : "0" (sum), "1" (len), "2" (src), "3" (dst) - ); - - *csum_err = tmp2; - - return(sum); -} - -EXPORT_SYMBOL(csum_partial_copy_from_user); - - -/* - * copy from kernel space while checksumming, otherwise like csum_partial - */ - -__wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) -{ - unsigned long tmp1, tmp2; - __asm__("movel %2,%4\n\t" - "btst #1,%4\n\t" /* Check alignment */ - "jeq 2f\n\t" - "subql #2,%1\n\t" /* buff%4==2: treat first word */ - "jgt 1f\n\t" - "addql #2,%1\n\t" /* len was == 2, treat only rest */ - "jra 4f\n" - "1:\t" - "movew %2 at +,%4\n\t" /* add first word to sum */ - "addw %4,%0\n\t" - "movew %4,%3 at +\n\t" - "clrl %4\n\t" - "addxl %4,%0\n" /* add X bit */ - "2:\t" - /* unrolled loop for the main part: do 8 longs at once */ - "movel %1,%4\n\t" /* save len in tmp1 */ - "lsrl #5,%1\n\t" /* len/32 */ - "jeq 2f\n\t" /* not enough... */ - "subql #1,%1\n" - "1:\t" - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "dbra %1,1b\n\t" - "clrl %5\n\t" - "addxl %5,%0\n\t" /* add X bit */ - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 1b\n" - "2:\t" - "movel %4,%1\n\t" /* restore len from tmp1 */ - "andw #0x1c,%4\n\t" /* number of rest longs */ - "jeq 4f\n\t" - "lsrw #2,%4\n\t" - "subqw #1,%4\n" - "3:\t" - /* loop for rest longs */ - "movel %2 at +,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3 at +\n\t" - "dbra %4,3b\n\t" - "clrl %5\n\t" - "addxl %5,%0\n" /* add X bit */ - "4:\t" - /* now check for rest bytes that do not fit into longs */ - "andw #3,%1\n\t" - "jeq 7f\n\t" - "clrl %5\n\t" /* clear tmp2 for rest bytes */ - "subqw #2,%1\n\t" - "jlt 5f\n\t" - "movew %2 at +,%5\n\t" /* have rest >= 2: get word */ - "movew %5,%3 at +\n\t" - "swap %5\n\t" /* into bits 16..31 */ - "tstw %1\n\t" /* another byte? */ - "jeq 6f\n" - "5:\t" - "moveb %2@,%5\n\t" /* have odd rest: get byte */ - "moveb %5,%3 at +\n\t" - "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ - "6:\t" - "addl %5,%0\n\t" /* now add rest long to sum */ - "clrl %5\n\t" - "addxl %5,%0\n" /* add X bit */ - "7:\t" - : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), - "=&d" (tmp1), "=&d" (tmp2) - : "0" (sum), "1" (len), "2" (src), "3" (dst) - ); - return(sum); -} -EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/m68k/lib/checksum_no.c b/arch/m68k/lib/checksum_no.c deleted file mode 100644 index e4c6354..0000000 --- a/arch/m68k/lib/checksum_no.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, - * Arnt Gulbrandsen, - * Tom May, - * Andreas Schwab, - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: - * Fixed some nasty bugs, causing some horrible crashes. - * A: At some points, the sum (%0) was used as - * length-counter instead of the length counter - * (%1). Thanks to Roman Hodek for pointing this out. - * B: GCC seems to mess up if one uses too many - * data-registers to hold input values and one tries to - * specify d0 and d1 as scratch registers. Letting gcc choose these - * registers itself solves the problem. - * - * This program 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 of the License, or (at your option) any later version. - */ - -/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most - of the assembly has to go. */ - -#include -#include - -static inline unsigned short from32to16(unsigned long x) -{ - /* add up 16-bit and 16-bit for 16+c bit */ - x = (x & 0xffff) + (x >> 16); - /* add up carry.. */ - x = (x & 0xffff) + (x >> 16); - return x; -} - -static unsigned long do_csum(const unsigned char * buff, int len) -{ - int odd, count; - unsigned long result = 0; - - if (len <= 0) - goto out; - odd = 1 & (unsigned long) buff; - if (odd) { - result = *buff; - len--; - buff++; - } - count = len >> 1; /* nr of 16-bit words.. */ - if (count) { - if (2 & (unsigned long) buff) { - result += *(unsigned short *) buff; - count--; - len -= 2; - buff += 2; - } - count >>= 1; /* nr of 32-bit words.. */ - if (count) { - unsigned long carry = 0; - do { - unsigned long w = *(unsigned long *) buff; - count--; - buff += 4; - result += carry; - result += w; - carry = (w > result); - } while (count); - result += carry; - result = (result & 0xffff) + (result >> 16); - } - if (len & 2) { - result += *(unsigned short *) buff; - buff += 2; - } - } - if (len & 1) - result += (*buff << 8); - result = from32to16(result); - if (odd) - result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); -out: - return result; -} - -#ifdef CONFIG_COLDFIRE -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - */ -__sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - return (__force __sum16)~do_csum(iph,ihl*4); -} -EXPORT_SYMBOL(ip_fast_csum); -#endif - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum) -{ - unsigned int result = do_csum(buff, len); - - /* add in old sum, and carry.. */ - result += (__force u32)sum; - if ((__force u32)sum > result) - result += 1; - return (__force __wsum)result; -} - -EXPORT_SYMBOL(csum_partial); - -/* - * copy from fs while checksumming, otherwise like csum_partial - */ - -__wsum -csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *csum_err) -{ - if (csum_err) *csum_err = 0; - 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 - */ - -__wsum -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); -- 1.7.0.4 From geert at linux-m68k.org Sat Nov 19 16:19:43 2011 From: geert at linux-m68k.org (Geert Uytterhoeven) Date: Sat, 19 Nov 2011 22:19:43 +0100 Subject: [uClinux-dev] Re: [PATCH] m68k: handle presence of 64bit mul/div instructions cleanly In-Reply-To: <1321597960-23782-1-git-send-email-gerg@snapgear.com> References: <1321597960-23782-1-git-send-email-gerg@snapgear.com> Message-ID: On Fri, Nov 18, 2011 at 07:32, wrote: > From: Greg Ungerer > > The traditional 68000 processors and the newer reduced instruction set > ColdFire processors do not support the 32*32->64 multiply or the 64/32->32 > divide instructions. This is not a difference based on the presence of > a hardware MMU or not. > > Create a new config symbol to mark that a CPU type doesn't support the > longer multiply/divide instructions. Use this then as a basis for using > the fast 64bit based divide (in div64.h) and for linking in the extra > libgcc functions that may be required (mulsi3, divsi3, etc). > > Signed-off-by: Greg Ungerer Looks fine. Acked-by: Geert Uytterhoeven Gr{oetje,eeting}s, ? ? ? ? ? ? ? ? ? ? ? ? Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ?? -- Linus Torvalds From richardcochran at gmail.com Sun Nov 20 08:42:12 2011 From: richardcochran at gmail.com (Richard Cochran) Date: Sun, 20 Nov 2011 14:42:12 +0100 Subject: [uClinux-dev] bootloader for MCF5234BCC Message-ID: <20111120134212.GA24165@netboy.at.omicron.at> I am working with the very latest mainstream Linux kernel on the Freescale MCF5234BCC. The kernel boots file (if I hack the root device in drivers/mtd/maps/uclinux.c). However, I am getting really tired of the dBUG thing. It only can fetch an image via TFTP if I force the host NIC into 10 megabit mode. I would really like to use a "real" bootloader, able to sent the kernel command line, and working at 100 mbit Ethernet. What can you recommend? (It looks like u-boot does not directly support this CPU.) Thanks, Richard From gerg at snapgear.com Thu Nov 24 18:36:38 2011 From: gerg at snapgear.com (Greg Ungerer) Date: Fri, 25 Nov 2011 09:36:38 +1000 Subject: [uClinux-dev] Re: [PATCH] m68k: simpler m68k and ColdFire CPU's can use generic csum code In-Reply-To: <1321597970-23806-1-git-send-email-gerg@snapgear.com> References: <1321597970-23806-1-git-send-email-gerg@snapgear.com> Message-ID: <4ECED506.6030201@snapgear.com> Hi Geert, On 18/11/11 16:32, gerg at snapgear.com wrote: > From: Greg Ungerer > > We have two implementations of the IP checksuming code for the m68k arch. > One uses the more advanced instructions available in 68020 and above > processors, the other uses the simpler instructions available on the > original 68000 processors and the modern ColdFire processors. > > This simpler code is pretty much the same as the generic lib implementation > of the IP csum functions. So lets just switch over to using that. That > means we can completely remove the checksum_no.c file, and only have the > local fast code used for the more complex 68k CPU family members. > > Signed-off-by: Greg Ungerer > Acked-by: Geert Uytterhoeven This is a reworked version of the original patch (http://www.spinics.net/lists/linux-m68k/msg04271.html), so I probably should have removed your "Acked-by" here, since you haven't really acked this version of it at all :-) Sorry about that. This version goes a bit further than the original, and actually switches to use the generic csum for the non-mmu and ColdFire cases. Regards Greg > --- > arch/m68k/Kconfig | 3 + > arch/m68k/Kconfig.cpu | 2 + > arch/m68k/include/asm/checksum.h | 31 +--- > arch/m68k/lib/Makefile | 8 +- > arch/m68k/lib/checksum.c | 425 ++++++++++++++++++++++++++++++++++++++ > arch/m68k/lib/checksum_mm.c | 425 -------------------------------------- > arch/m68k/lib/checksum_no.c | 156 -------------- > 7 files changed, 441 insertions(+), 609 deletions(-) > create mode 100644 arch/m68k/lib/checksum.c > delete mode 100644 arch/m68k/lib/checksum_mm.c > delete mode 100644 arch/m68k/lib/checksum_no.c > > diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig > index 2914b03..2fe2d63 100644 > --- a/arch/m68k/Kconfig > +++ b/arch/m68k/Kconfig > @@ -40,6 +40,9 @@ config GENERIC_CALIBRATE_DELAY > config GENERIC_IOMAP > def_bool MMU > > +config GENERIC_CSUM > + bool > + > config TIME_LOW_RES > bool > default y > diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu > index 9af9e68..17d37ed 100644 > --- a/arch/m68k/Kconfig.cpu > +++ b/arch/m68k/Kconfig.cpu > @@ -3,6 +3,7 @@ comment "Processor Type" > config M68000 > bool > select CPU_HAS_NO_BITFIELDS > + select GENERIC_CSUM > help > The Freescale (was Motorola) 68000 CPU is the first generation of > the well known M68K family of processors. The CPU core as well as > @@ -23,6 +24,7 @@ config COLDFIRE > select GENERIC_GPIO > select ARCH_REQUIRE_GPIOLIB > select CPU_HAS_NO_BITFIELDS > + select GENERIC_CSUM > help > The Freescale ColdFire family of processors is a modern derivitive > of the 68000 processor family. They are mainly targeted at embedded > diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h > index ec51448..2f88d86 100644 > --- a/arch/m68k/include/asm/checksum.h > +++ b/arch/m68k/include/asm/checksum.h > @@ -3,6 +3,10 @@ > > #include > > +#ifdef CONFIG_GENERIC_CSUM > +#include > +#else > + > /* > * computes the checksum of a memory block at buff, length len, > * and adds in "sum" (32-bit) > @@ -34,30 +38,6 @@ extern __wsum csum_partial_copy_nocheck(const void *src, > void *dst, int len, > __wsum sum); > > - > -#ifdef CONFIG_COLDFIRE > - > -/* > - * The ColdFire cores don't support all the 68k instructions used > - * in the optimized checksum code below. So it reverts back to using > - * more standard C coded checksums. The fast checksum code is > - * significantly larger than the optimized version, so it is not > - * inlined here. > - */ > -__sum16 ip_fast_csum(const void *iph, unsigned int ihl); > - > -static inline __sum16 csum_fold(__wsum sum) > -{ > - unsigned int tmp = (__force u32)sum; > - > - tmp = (tmp& 0xffff) + (tmp>> 16); > - tmp = (tmp& 0xffff) + (tmp>> 16); > - > - return (__force __sum16)~tmp; > -} > - > -#else > - > /* > * This is a version of ip_fast_csum() optimized for IP headers, > * which always checksum on 4 octet boundaries. > @@ -97,8 +77,6 @@ static inline __sum16 csum_fold(__wsum sum) > return (__force __sum16)~sum; > } > > -#endif /* CONFIG_COLDFIRE */ > - > static inline __wsum > csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, > unsigned short proto, __wsum sum) > @@ -167,4 +145,5 @@ csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, > return csum_fold(sum); > } > > +#endif /* CONFIG_GENERIC_CSUM */ > #endif /* _M68K_CHECKSUM_H */ > diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile > index 1a1bd90..b3b40e4 100644 > --- a/arch/m68k/lib/Makefile > +++ b/arch/m68k/lib/Makefile > @@ -7,8 +7,12 @@ lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ > memcpy.o memset.o memmove.o > > ifdef CONFIG_MMU > -lib-y += string.o uaccess.o checksum_mm.o > +lib-y += string.o uaccess.o > else > -lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o checksum_no.o > +lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o > +endif > + > +ifndef CONFIG_GENERIC_CSUM > +lib-y += checksum.o > endif > > diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c > new file mode 100644 > index 0000000..6216f12 > --- /dev/null > +++ b/arch/m68k/lib/checksum.c > @@ -0,0 +1,425 @@ > +/* > + * INET An implementation of the TCP/IP protocol suite for the LINUX > + * operating system. INET is implemented using the BSD Socket > + * interface as the means of communication with the user level. > + * > + * IP/TCP/UDP checksumming routines > + * > + * Authors: Jorge Cwik, > + * Arnt Gulbrandsen, > + * Tom May, > + * Andreas Schwab, > + * Lots of code moved from tcp.c and ip.c; see those files > + * for more names. > + * > + * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: > + * Fixed some nasty bugs, causing some horrible crashes. > + * A: At some points, the sum (%0) was used as > + * length-counter instead of the length counter > + * (%1). Thanks to Roman Hodek for pointing this out. > + * B: GCC seems to mess up if one uses too many > + * data-registers to hold input values and one tries to > + * specify d0 and d1 as scratch registers. Letting gcc > + * choose these registers itself solves the problem. > + * > + * This program 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 of the License, or (at your option) any later version. > + * > + * 1998/8/31 Andreas Schwab: > + * Zero out rest of buffer on exception in > + * csum_partial_copy_from_user. > + */ > + > +#include > +#include > + > +/* > + * computes a partial checksum, e.g. for TCP/UDP fragments > + */ > + > +__wsum csum_partial(const void *buff, int len, __wsum sum) > +{ > + unsigned long tmp1, tmp2; > + /* > + * Experiments with ethernet and slip connections show that buff > + * is aligned on either a 2-byte or 4-byte boundary. > + */ > + __asm__("movel %2,%3\n\t" > + "btst #1,%3\n\t" /* Check alignment */ > + "jeq 2f\n\t" > + "subql #2,%1\n\t" /* buff%4==2: treat first word */ > + "jgt 1f\n\t" > + "addql #2,%1\n\t" /* len was == 2, treat only rest */ > + "jra 4f\n" > + "1:\t" > + "addw %2 at +,%0\n\t" /* add first word to sum */ > + "clrl %3\n\t" > + "addxl %3,%0\n" /* add X bit */ > + "2:\t" > + /* unrolled loop for the main part: do 8 longs at once */ > + "movel %1,%3\n\t" /* save len in tmp1 */ > + "lsrl #5,%1\n\t" /* len/32 */ > + "jeq 2f\n\t" /* not enough... */ > + "subql #1,%1\n" > + "1:\t" > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "dbra %1,1b\n\t" > + "clrl %4\n\t" > + "addxl %4,%0\n\t" /* add X bit */ > + "clrw %1\n\t" > + "subql #1,%1\n\t" > + "jcc 1b\n" > + "2:\t" > + "movel %3,%1\n\t" /* restore len from tmp1 */ > + "andw #0x1c,%3\n\t" /* number of rest longs */ > + "jeq 4f\n\t" > + "lsrw #2,%3\n\t" > + "subqw #1,%3\n" > + "3:\t" > + /* loop for rest longs */ > + "movel %2 at +,%4\n\t" > + "addxl %4,%0\n\t" > + "dbra %3,3b\n\t" > + "clrl %4\n\t" > + "addxl %4,%0\n" /* add X bit */ > + "4:\t" > + /* now check for rest bytes that do not fit into longs */ > + "andw #3,%1\n\t" > + "jeq 7f\n\t" > + "clrl %4\n\t" /* clear tmp2 for rest bytes */ > + "subqw #2,%1\n\t" > + "jlt 5f\n\t" > + "movew %2 at +,%4\n\t" /* have rest>= 2: get word */ > + "swap %4\n\t" /* into bits 16..31 */ > + "tstw %1\n\t" /* another byte? */ > + "jeq 6f\n" > + "5:\t" > + "moveb %2@,%4\n\t" /* have odd rest: get byte */ > + "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ > + "6:\t" > + "addl %4,%0\n\t" /* now add rest long to sum */ > + "clrl %4\n\t" > + "addxl %4,%0\n" /* add X bit */ > + "7:\t" > + : "=d" (sum), "=d" (len), "=a" (buff), > + "=&d" (tmp1), "=&d" (tmp2) > + : "0" (sum), "1" (len), "2" (buff) > + ); > + return(sum); > +} > + > +EXPORT_SYMBOL(csum_partial); > + > + > +/* > + * copy from user space while checksumming, with exception handling. > + */ > + > +__wsum > +csum_partial_copy_from_user(const void __user *src, void *dst, > + int len, __wsum sum, int *csum_err) > +{ > + /* > + * GCC doesn't like more than 10 operands for the asm > + * statements so we have to use tmp2 for the error > + * code. > + */ > + unsigned long tmp1, tmp2; > + > + __asm__("movel %2,%4\n\t" > + "btst #1,%4\n\t" /* Check alignment */ > + "jeq 2f\n\t" > + "subql #2,%1\n\t" /* buff%4==2: treat first word */ > + "jgt 1f\n\t" > + "addql #2,%1\n\t" /* len was == 2, treat only rest */ > + "jra 4f\n" > + "1:\n" > + "10:\t" > + "movesw %2 at +,%4\n\t" /* add first word to sum */ > + "addw %4,%0\n\t" > + "movew %4,%3 at +\n\t" > + "clrl %4\n\t" > + "addxl %4,%0\n" /* add X bit */ > + "2:\t" > + /* unrolled loop for the main part: do 8 longs at once */ > + "movel %1,%4\n\t" /* save len in tmp1 */ > + "lsrl #5,%1\n\t" /* len/32 */ > + "jeq 2f\n\t" /* not enough... */ > + "subql #1,%1\n" > + "1:\n" > + "11:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "12:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "13:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "14:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "15:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "16:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "17:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "18:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "dbra %1,1b\n\t" > + "clrl %5\n\t" > + "addxl %5,%0\n\t" /* add X bit */ > + "clrw %1\n\t" > + "subql #1,%1\n\t" > + "jcc 1b\n" > + "2:\t" > + "movel %4,%1\n\t" /* restore len from tmp1 */ > + "andw #0x1c,%4\n\t" /* number of rest longs */ > + "jeq 4f\n\t" > + "lsrw #2,%4\n\t" > + "subqw #1,%4\n" > + "3:\n" > + /* loop for rest longs */ > + "19:\t" > + "movesl %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "dbra %4,3b\n\t" > + "clrl %5\n\t" > + "addxl %5,%0\n" /* add X bit */ > + "4:\t" > + /* now check for rest bytes that do not fit into longs */ > + "andw #3,%1\n\t" > + "jeq 7f\n\t" > + "clrl %5\n\t" /* clear tmp2 for rest bytes */ > + "subqw #2,%1\n\t" > + "jlt 5f\n\t" > + "20:\t" > + "movesw %2 at +,%5\n\t" /* have rest>= 2: get word */ > + "movew %5,%3 at +\n\t" > + "swap %5\n\t" /* into bits 16..31 */ > + "tstw %1\n\t" /* another byte? */ > + "jeq 6f\n" > + "5:\n" > + "21:\t" > + "movesb %2@,%5\n\t" /* have odd rest: get byte */ > + "moveb %5,%3 at +\n\t" > + "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ > + "6:\t" > + "addl %5,%0\n\t" /* now add rest long to sum */ > + "clrl %5\n\t" > + "addxl %5,%0\n\t" /* add X bit */ > + "7:\t" > + "clrl %5\n" /* no error - clear return value */ > + "8:\n" > + ".section .fixup,\"ax\"\n" > + ".even\n" > + /* If any exception occurs zero out the rest. > + Similarities with the code above are intentional :-) */ > + "90:\t" > + "clrw %3 at +\n\t" > + "movel %1,%4\n\t" > + "lsrl #5,%1\n\t" > + "jeq 1f\n\t" > + "subql #1,%1\n" > + "91:\t" > + "clrl %3 at +\n" > + "92:\t" > + "clrl %3 at +\n" > + "93:\t" > + "clrl %3 at +\n" > + "94:\t" > + "clrl %3 at +\n" > + "95:\t" > + "clrl %3 at +\n" > + "96:\t" > + "clrl %3 at +\n" > + "97:\t" > + "clrl %3 at +\n" > + "98:\t" > + "clrl %3 at +\n\t" > + "dbra %1,91b\n\t" > + "clrw %1\n\t" > + "subql #1,%1\n\t" > + "jcc 91b\n" > + "1:\t" > + "movel %4,%1\n\t" > + "andw #0x1c,%4\n\t" > + "jeq 1f\n\t" > + "lsrw #2,%4\n\t" > + "subqw #1,%4\n" > + "99:\t" > + "clrl %3 at +\n\t" > + "dbra %4,99b\n\t" > + "1:\t" > + "andw #3,%1\n\t" > + "jeq 9f\n" > + "100:\t" > + "clrw %3 at +\n\t" > + "tstw %1\n\t" > + "jeq 9f\n" > + "101:\t" > + "clrb %3 at +\n" > + "9:\t" > +#define STR(X) STR1(X) > +#define STR1(X) #X > + "moveq #-" STR(EFAULT) ",%5\n\t" > + "jra 8b\n" > + ".previous\n" > + ".section __ex_table,\"a\"\n" > + ".long 10b,90b\n" > + ".long 11b,91b\n" > + ".long 12b,92b\n" > + ".long 13b,93b\n" > + ".long 14b,94b\n" > + ".long 15b,95b\n" > + ".long 16b,96b\n" > + ".long 17b,97b\n" > + ".long 18b,98b\n" > + ".long 19b,99b\n" > + ".long 20b,100b\n" > + ".long 21b,101b\n" > + ".previous" > + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), > + "=&d" (tmp1), "=d" (tmp2) > + : "0" (sum), "1" (len), "2" (src), "3" (dst) > + ); > + > + *csum_err = tmp2; > + > + return(sum); > +} > + > +EXPORT_SYMBOL(csum_partial_copy_from_user); > + > + > +/* > + * copy from kernel space while checksumming, otherwise like csum_partial > + */ > + > +__wsum > +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) > +{ > + unsigned long tmp1, tmp2; > + __asm__("movel %2,%4\n\t" > + "btst #1,%4\n\t" /* Check alignment */ > + "jeq 2f\n\t" > + "subql #2,%1\n\t" /* buff%4==2: treat first word */ > + "jgt 1f\n\t" > + "addql #2,%1\n\t" /* len was == 2, treat only rest */ > + "jra 4f\n" > + "1:\t" > + "movew %2 at +,%4\n\t" /* add first word to sum */ > + "addw %4,%0\n\t" > + "movew %4,%3 at +\n\t" > + "clrl %4\n\t" > + "addxl %4,%0\n" /* add X bit */ > + "2:\t" > + /* unrolled loop for the main part: do 8 longs at once */ > + "movel %1,%4\n\t" /* save len in tmp1 */ > + "lsrl #5,%1\n\t" /* len/32 */ > + "jeq 2f\n\t" /* not enough... */ > + "subql #1,%1\n" > + "1:\t" > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "dbra %1,1b\n\t" > + "clrl %5\n\t" > + "addxl %5,%0\n\t" /* add X bit */ > + "clrw %1\n\t" > + "subql #1,%1\n\t" > + "jcc 1b\n" > + "2:\t" > + "movel %4,%1\n\t" /* restore len from tmp1 */ > + "andw #0x1c,%4\n\t" /* number of rest longs */ > + "jeq 4f\n\t" > + "lsrw #2,%4\n\t" > + "subqw #1,%4\n" > + "3:\t" > + /* loop for rest longs */ > + "movel %2 at +,%5\n\t" > + "addxl %5,%0\n\t" > + "movel %5,%3 at +\n\t" > + "dbra %4,3b\n\t" > + "clrl %5\n\t" > + "addxl %5,%0\n" /* add X bit */ > + "4:\t" > + /* now check for rest bytes that do not fit into longs */ > + "andw #3,%1\n\t" > + "jeq 7f\n\t" > + "clrl %5\n\t" /* clear tmp2 for rest bytes */ > + "subqw #2,%1\n\t" > + "jlt 5f\n\t" > + "movew %2 at +,%5\n\t" /* have rest>= 2: get word */ > + "movew %5,%3 at +\n\t" > + "swap %5\n\t" /* into bits 16..31 */ > + "tstw %1\n\t" /* another byte? */ > + "jeq 6f\n" > + "5:\t" > + "moveb %2@,%5\n\t" /* have odd rest: get byte */ > + "moveb %5,%3 at +\n\t" > + "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ > + "6:\t" > + "addl %5,%0\n\t" /* now add rest long to sum */ > + "clrl %5\n\t" > + "addxl %5,%0\n" /* add X bit */ > + "7:\t" > + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), > + "=&d" (tmp1), "=&d" (tmp2) > + : "0" (sum), "1" (len), "2" (src), "3" (dst) > + ); > + return(sum); > +} > +EXPORT_SYMBOL(csum_partial_copy_nocheck); > diff --git a/arch/m68k/lib/checksum_mm.c b/arch/m68k/lib/checksum_mm.c > deleted file mode 100644 > index 6216f12..0000000 > --- a/arch/m68k/lib/checksum_mm.c > +++ /dev/null > @@ -1,425 +0,0 @@ > -/* > - * INET An implementation of the TCP/IP protocol suite for the LINUX > - * operating system. INET is implemented using the BSD Socket > - * interface as the means of communication with the user level. > - * > - * IP/TCP/UDP checksumming routines > - * > - * Authors: Jorge Cwik, > - * Arnt Gulbrandsen, > - * Tom May, > - * Andreas Schwab, > - * Lots of code moved from tcp.c and ip.c; see those files > - * for more names. > - * > - * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: > - * Fixed some nasty bugs, causing some horrible crashes. > - * A: At some points, the sum (%0) was used as > - * length-counter instead of the length counter > - * (%1). Thanks to Roman Hodek for pointing this out. > - * B: GCC seems to mess up if one uses too many > - * data-registers to hold input values and one tries to > - * specify d0 and d1 as scratch registers. Letting gcc > - * choose these registers itself solves the problem. > - * > - * This program 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 of the License, or (at your option) any later version. > - * > - * 1998/8/31 Andreas Schwab: > - * Zero out rest of buffer on exception in > - * csum_partial_copy_from_user. > - */ > - > -#include > -#include > - > -/* > - * computes a partial checksum, e.g. for TCP/UDP fragments > - */ > - > -__wsum csum_partial(const void *buff, int len, __wsum sum) > -{ > - unsigned long tmp1, tmp2; > - /* > - * Experiments with ethernet and slip connections show that buff > - * is aligned on either a 2-byte or 4-byte boundary. > - */ > - __asm__("movel %2,%3\n\t" > - "btst #1,%3\n\t" /* Check alignment */ > - "jeq 2f\n\t" > - "subql #2,%1\n\t" /* buff%4==2: treat first word */ > - "jgt 1f\n\t" > - "addql #2,%1\n\t" /* len was == 2, treat only rest */ > - "jra 4f\n" > - "1:\t" > - "addw %2 at +,%0\n\t" /* add first word to sum */ > - "clrl %3\n\t" > - "addxl %3,%0\n" /* add X bit */ > - "2:\t" > - /* unrolled loop for the main part: do 8 longs at once */ > - "movel %1,%3\n\t" /* save len in tmp1 */ > - "lsrl #5,%1\n\t" /* len/32 */ > - "jeq 2f\n\t" /* not enough... */ > - "subql #1,%1\n" > - "1:\t" > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "dbra %1,1b\n\t" > - "clrl %4\n\t" > - "addxl %4,%0\n\t" /* add X bit */ > - "clrw %1\n\t" > - "subql #1,%1\n\t" > - "jcc 1b\n" > - "2:\t" > - "movel %3,%1\n\t" /* restore len from tmp1 */ > - "andw #0x1c,%3\n\t" /* number of rest longs */ > - "jeq 4f\n\t" > - "lsrw #2,%3\n\t" > - "subqw #1,%3\n" > - "3:\t" > - /* loop for rest longs */ > - "movel %2 at +,%4\n\t" > - "addxl %4,%0\n\t" > - "dbra %3,3b\n\t" > - "clrl %4\n\t" > - "addxl %4,%0\n" /* add X bit */ > - "4:\t" > - /* now check for rest bytes that do not fit into longs */ > - "andw #3,%1\n\t" > - "jeq 7f\n\t" > - "clrl %4\n\t" /* clear tmp2 for rest bytes */ > - "subqw #2,%1\n\t" > - "jlt 5f\n\t" > - "movew %2 at +,%4\n\t" /* have rest>= 2: get word */ > - "swap %4\n\t" /* into bits 16..31 */ > - "tstw %1\n\t" /* another byte? */ > - "jeq 6f\n" > - "5:\t" > - "moveb %2@,%4\n\t" /* have odd rest: get byte */ > - "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ > - "6:\t" > - "addl %4,%0\n\t" /* now add rest long to sum */ > - "clrl %4\n\t" > - "addxl %4,%0\n" /* add X bit */ > - "7:\t" > - : "=d" (sum), "=d" (len), "=a" (buff), > - "=&d" (tmp1), "=&d" (tmp2) > - : "0" (sum), "1" (len), "2" (buff) > - ); > - return(sum); > -} > - > -EXPORT_SYMBOL(csum_partial); > - > - > -/* > - * copy from user space while checksumming, with exception handling. > - */ > - > -__wsum > -csum_partial_copy_from_user(const void __user *src, void *dst, > - int len, __wsum sum, int *csum_err) > -{ > - /* > - * GCC doesn't like more than 10 operands for the asm > - * statements so we have to use tmp2 for the error > - * code. > - */ > - unsigned long tmp1, tmp2; > - > - __asm__("movel %2,%4\n\t" > - "btst #1,%4\n\t" /* Check alignment */ > - "jeq 2f\n\t" > - "subql #2,%1\n\t" /* buff%4==2: treat first word */ > - "jgt 1f\n\t" > - "addql #2,%1\n\t" /* len was == 2, treat only rest */ > - "jra 4f\n" > - "1:\n" > - "10:\t" > - "movesw %2 at +,%4\n\t" /* add first word to sum */ > - "addw %4,%0\n\t" > - "movew %4,%3 at +\n\t" > - "clrl %4\n\t" > - "addxl %4,%0\n" /* add X bit */ > - "2:\t" > - /* unrolled loop for the main part: do 8 longs at once */ > - "movel %1,%4\n\t" /* save len in tmp1 */ > - "lsrl #5,%1\n\t" /* len/32 */ > - "jeq 2f\n\t" /* not enough... */ > - "subql #1,%1\n" > - "1:\n" > - "11:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "12:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "13:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "14:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "15:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "16:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "17:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "18:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "dbra %1,1b\n\t" > - "clrl %5\n\t" > - "addxl %5,%0\n\t" /* add X bit */ > - "clrw %1\n\t" > - "subql #1,%1\n\t" > - "jcc 1b\n" > - "2:\t" > - "movel %4,%1\n\t" /* restore len from tmp1 */ > - "andw #0x1c,%4\n\t" /* number of rest longs */ > - "jeq 4f\n\t" > - "lsrw #2,%4\n\t" > - "subqw #1,%4\n" > - "3:\n" > - /* loop for rest longs */ > - "19:\t" > - "movesl %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "dbra %4,3b\n\t" > - "clrl %5\n\t" > - "addxl %5,%0\n" /* add X bit */ > - "4:\t" > - /* now check for rest bytes that do not fit into longs */ > - "andw #3,%1\n\t" > - "jeq 7f\n\t" > - "clrl %5\n\t" /* clear tmp2 for rest bytes */ > - "subqw #2,%1\n\t" > - "jlt 5f\n\t" > - "20:\t" > - "movesw %2 at +,%5\n\t" /* have rest>= 2: get word */ > - "movew %5,%3 at +\n\t" > - "swap %5\n\t" /* into bits 16..31 */ > - "tstw %1\n\t" /* another byte? */ > - "jeq 6f\n" > - "5:\n" > - "21:\t" > - "movesb %2@,%5\n\t" /* have odd rest: get byte */ > - "moveb %5,%3 at +\n\t" > - "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ > - "6:\t" > - "addl %5,%0\n\t" /* now add rest long to sum */ > - "clrl %5\n\t" > - "addxl %5,%0\n\t" /* add X bit */ > - "7:\t" > - "clrl %5\n" /* no error - clear return value */ > - "8:\n" > - ".section .fixup,\"ax\"\n" > - ".even\n" > - /* If any exception occurs zero out the rest. > - Similarities with the code above are intentional :-) */ > - "90:\t" > - "clrw %3 at +\n\t" > - "movel %1,%4\n\t" > - "lsrl #5,%1\n\t" > - "jeq 1f\n\t" > - "subql #1,%1\n" > - "91:\t" > - "clrl %3 at +\n" > - "92:\t" > - "clrl %3 at +\n" > - "93:\t" > - "clrl %3 at +\n" > - "94:\t" > - "clrl %3 at +\n" > - "95:\t" > - "clrl %3 at +\n" > - "96:\t" > - "clrl %3 at +\n" > - "97:\t" > - "clrl %3 at +\n" > - "98:\t" > - "clrl %3 at +\n\t" > - "dbra %1,91b\n\t" > - "clrw %1\n\t" > - "subql #1,%1\n\t" > - "jcc 91b\n" > - "1:\t" > - "movel %4,%1\n\t" > - "andw #0x1c,%4\n\t" > - "jeq 1f\n\t" > - "lsrw #2,%4\n\t" > - "subqw #1,%4\n" > - "99:\t" > - "clrl %3 at +\n\t" > - "dbra %4,99b\n\t" > - "1:\t" > - "andw #3,%1\n\t" > - "jeq 9f\n" > - "100:\t" > - "clrw %3 at +\n\t" > - "tstw %1\n\t" > - "jeq 9f\n" > - "101:\t" > - "clrb %3 at +\n" > - "9:\t" > -#define STR(X) STR1(X) > -#define STR1(X) #X > - "moveq #-" STR(EFAULT) ",%5\n\t" > - "jra 8b\n" > - ".previous\n" > - ".section __ex_table,\"a\"\n" > - ".long 10b,90b\n" > - ".long 11b,91b\n" > - ".long 12b,92b\n" > - ".long 13b,93b\n" > - ".long 14b,94b\n" > - ".long 15b,95b\n" > - ".long 16b,96b\n" > - ".long 17b,97b\n" > - ".long 18b,98b\n" > - ".long 19b,99b\n" > - ".long 20b,100b\n" > - ".long 21b,101b\n" > - ".previous" > - : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), > - "=&d" (tmp1), "=d" (tmp2) > - : "0" (sum), "1" (len), "2" (src), "3" (dst) > - ); > - > - *csum_err = tmp2; > - > - return(sum); > -} > - > -EXPORT_SYMBOL(csum_partial_copy_from_user); > - > - > -/* > - * copy from kernel space while checksumming, otherwise like csum_partial > - */ > - > -__wsum > -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) > -{ > - unsigned long tmp1, tmp2; > - __asm__("movel %2,%4\n\t" > - "btst #1,%4\n\t" /* Check alignment */ > - "jeq 2f\n\t" > - "subql #2,%1\n\t" /* buff%4==2: treat first word */ > - "jgt 1f\n\t" > - "addql #2,%1\n\t" /* len was == 2, treat only rest */ > - "jra 4f\n" > - "1:\t" > - "movew %2 at +,%4\n\t" /* add first word to sum */ > - "addw %4,%0\n\t" > - "movew %4,%3 at +\n\t" > - "clrl %4\n\t" > - "addxl %4,%0\n" /* add X bit */ > - "2:\t" > - /* unrolled loop for the main part: do 8 longs at once */ > - "movel %1,%4\n\t" /* save len in tmp1 */ > - "lsrl #5,%1\n\t" /* len/32 */ > - "jeq 2f\n\t" /* not enough... */ > - "subql #1,%1\n" > - "1:\t" > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "dbra %1,1b\n\t" > - "clrl %5\n\t" > - "addxl %5,%0\n\t" /* add X bit */ > - "clrw %1\n\t" > - "subql #1,%1\n\t" > - "jcc 1b\n" > - "2:\t" > - "movel %4,%1\n\t" /* restore len from tmp1 */ > - "andw #0x1c,%4\n\t" /* number of rest longs */ > - "jeq 4f\n\t" > - "lsrw #2,%4\n\t" > - "subqw #1,%4\n" > - "3:\t" > - /* loop for rest longs */ > - "movel %2 at +,%5\n\t" > - "addxl %5,%0\n\t" > - "movel %5,%3 at +\n\t" > - "dbra %4,3b\n\t" > - "clrl %5\n\t" > - "addxl %5,%0\n" /* add X bit */ > - "4:\t" > - /* now check for rest bytes that do not fit into longs */ > - "andw #3,%1\n\t" > - "jeq 7f\n\t" > - "clrl %5\n\t" /* clear tmp2 for rest bytes */ > - "subqw #2,%1\n\t" > - "jlt 5f\n\t" > - "movew %2 at +,%5\n\t" /* have rest>= 2: get word */ > - "movew %5,%3 at +\n\t" > - "swap %5\n\t" /* into bits 16..31 */ > - "tstw %1\n\t" /* another byte? */ > - "jeq 6f\n" > - "5:\t" > - "moveb %2@,%5\n\t" /* have odd rest: get byte */ > - "moveb %5,%3 at +\n\t" > - "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ > - "6:\t" > - "addl %5,%0\n\t" /* now add rest long to sum */ > - "clrl %5\n\t" > - "addxl %5,%0\n" /* add X bit */ > - "7:\t" > - : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), > - "=&d" (tmp1), "=&d" (tmp2) > - : "0" (sum), "1" (len), "2" (src), "3" (dst) > - ); > - return(sum); > -} > -EXPORT_SYMBOL(csum_partial_copy_nocheck); > diff --git a/arch/m68k/lib/checksum_no.c b/arch/m68k/lib/checksum_no.c > deleted file mode 100644 > index e4c6354..0000000 > --- a/arch/m68k/lib/checksum_no.c > +++ /dev/null > @@ -1,156 +0,0 @@ > -/* > - * INET An implementation of the TCP/IP protocol suite for the LINUX > - * operating system. INET is implemented using the BSD Socket > - * interface as the means of communication with the user level. > - * > - * IP/TCP/UDP checksumming routines > - * > - * Authors: Jorge Cwik, > - * Arnt Gulbrandsen, > - * Tom May, > - * Andreas Schwab, > - * Lots of code moved from tcp.c and ip.c; see those files > - * for more names. > - * > - * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: > - * Fixed some nasty bugs, causing some horrible crashes. > - * A: At some points, the sum (%0) was used as > - * length-counter instead of the length counter > - * (%1). Thanks to Roman Hodek for pointing this out. > - * B: GCC seems to mess up if one uses too many > - * data-registers to hold input values and one tries to > - * specify d0 and d1 as scratch registers. Letting gcc choose these > - * registers itself solves the problem. > - * > - * This program 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 of the License, or (at your option) any later version. > - */ > - > -/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most > - of the assembly has to go. */ > - > -#include > -#include > - > -static inline unsigned short from32to16(unsigned long x) > -{ > - /* add up 16-bit and 16-bit for 16+c bit */ > - x = (x& 0xffff) + (x>> 16); > - /* add up carry.. */ > - x = (x& 0xffff) + (x>> 16); > - return x; > -} > - > -static unsigned long do_csum(const unsigned char * buff, int len) > -{ > - int odd, count; > - unsigned long result = 0; > - > - if (len<= 0) > - goto out; > - odd = 1& (unsigned long) buff; > - if (odd) { > - result = *buff; > - len--; > - buff++; > - } > - count = len>> 1; /* nr of 16-bit words.. */ > - if (count) { > - if (2& (unsigned long) buff) { > - result += *(unsigned short *) buff; > - count--; > - len -= 2; > - buff += 2; > - } > - count>>= 1; /* nr of 32-bit words.. */ > - if (count) { > - unsigned long carry = 0; > - do { > - unsigned long w = *(unsigned long *) buff; > - count--; > - buff += 4; > - result += carry; > - result += w; > - carry = (w> result); > - } while (count); > - result += carry; > - result = (result& 0xffff) + (result>> 16); > - } > - if (len& 2) { > - result += *(unsigned short *) buff; > - buff += 2; > - } > - } > - if (len& 1) > - result += (*buff<< 8); > - result = from32to16(result); > - if (odd) > - result = ((result>> 8)& 0xff) | ((result& 0xff)<< 8); > -out: > - return result; > -} > - > -#ifdef CONFIG_COLDFIRE > -/* > - * This is a version of ip_compute_csum() optimized for IP headers, > - * which always checksum on 4 octet boundaries. > - */ > -__sum16 ip_fast_csum(const void *iph, unsigned int ihl) > -{ > - return (__force __sum16)~do_csum(iph,ihl*4); > -} > -EXPORT_SYMBOL(ip_fast_csum); > -#endif > - > -/* > - * computes the checksum of a memory block at buff, length len, > - * and adds in "sum" (32-bit) > - * > - * returns a 32-bit number suitable for feeding into itself > - * or csum_tcpudp_magic > - * > - * this function must be called with even lengths, except > - * for the last fragment, which may be odd > - * > - * it's best to have buff aligned on a 32-bit boundary > - */ > -__wsum csum_partial(const void *buff, int len, __wsum sum) > -{ > - unsigned int result = do_csum(buff, len); > - > - /* add in old sum, and carry.. */ > - result += (__force u32)sum; > - if ((__force u32)sum> result) > - result += 1; > - return (__force __wsum)result; > -} > - > -EXPORT_SYMBOL(csum_partial); > - > -/* > - * copy from fs while checksumming, otherwise like csum_partial > - */ > - > -__wsum > -csum_partial_copy_from_user(const void __user *src, void *dst, > - int len, __wsum sum, int *csum_err) > -{ > - if (csum_err) *csum_err = 0; > - 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 > - */ > - > -__wsum > -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); -- ------------------------------------------------------------------------ Greg Ungerer -- Principal Engineer EMAIL: gerg at snapgear.com SnapGear Group, McAfee PHONE: +61 7 3435 2888 8 Gardner Close FAX: +61 7 3217 5323 Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com From gerg at snapgear.com Thu Nov 24 20:36:46 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 11:36:46 +1000 Subject: [uClinux-dev] [PATCH] m68knommu: hard set the ColdFire MBAR register on startup Message-ID: <1322185006-21546-1-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire MBAR register that holds the mapping of the peripheral region on some ColdFire CPUs is configurable. It can be configured at some address different to that of the bootloader that loaded the kernel. So hard set the MBAR register mapping at kernel startup time. Signed-off-by: Alexander Stein Signed-off-by: Greg Ungerer --- arch/m68k/platform/coldfire/head.S | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S index 49666b4..0ed41ed 100644 --- a/arch/m68k/platform/coldfire/head.S +++ b/arch/m68k/platform/coldfire/head.S @@ -149,6 +149,10 @@ _start: #if defined(CONFIG_UBOOT) movel %sp,_init_sp /* save initial stack pointer */ #endif +#ifdef CONFIG_MBAR + movel #CONFIG_MBAR+1,%d0 /* configured MBAR address */ + movec %d0,%MBAR /* set it */ +#endif /* * Do any platform or board specific setup now. Most boards -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:46 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:46 +1000 Subject: [uClinux-dev] [PATCH 01/35] m68k: add machine and CPU definitions for ColdFire cores In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-2-git-send-email-gerg@snapgear.com> From: Greg Ungerer Create machine and CPU definitions to support the ColdFire CPU family members that have a virtual memory management unit. The ColdFire V4e core contains an MMU, and it is quite different to any other 68k family members. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/setup.h | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/m68k/include/asm/setup.h b/arch/m68k/include/asm/setup.h index 4dfb395..00c2c53 100644 --- a/arch/m68k/include/asm/setup.h +++ b/arch/m68k/include/asm/setup.h @@ -40,6 +40,7 @@ #define MACH_HP300 9 #define MACH_Q40 10 #define MACH_SUN3X 11 +#define MACH_M54XX 12 #define COMMAND_LINE_SIZE 256 @@ -211,23 +212,27 @@ extern unsigned long m68k_machtype; #define CPUB_68030 1 #define CPUB_68040 2 #define CPUB_68060 3 +#define CPUB_COLDFIRE 4 #define CPU_68020 (1< References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-5-git-send-email-gerg@snapgear.com> From: Greg Ungerer The interrupt handling support defines and code is not so much conditional on an MMU being present (CONFIG_MMU), as it is on which type of CPU we are building for. So make the code conditional on the CPU types instead. The current irq.h is mostly specific to the interrupt code for the 680x0 CPUs, so it should only be used for them. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/irq.h | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index 6198df5..0e89fa0 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -25,7 +25,8 @@ #define NR_IRQS 0 #endif -#ifdef CONFIG_MMU +#if defined(CONFIG_M68020) || defined(CONFIG_M68030) || \ + defined(CONFIG_M68040) || defined(CONFIG_M68060) /* * Interrupt source definitions @@ -80,7 +81,7 @@ extern unsigned int irq_canonicalize(unsigned int irq); #else #define irq_canonicalize(irq) (irq) -#endif /* CONFIG_MMU */ +#endif /* !(CONFIG_M68020 || CONFIG_M68030 || CONFIG_M68040 || CONFIG_M68060) */ asmlinkage void do_IRQ(int irq, struct pt_regs *regs); extern atomic_t irq_err_count; -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:45 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:45 +1000 Subject: [uClinux-dev] [PATCH 00/35 v2] m68k: ColdFire MMU support Message-ID: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Hi All, This is version 2 of a patch set that adds support for running the V4e ColdFire cores with their MMU enabled. A bit of cleanup and some fixes over the first version. In particular the following changes: . rebased onto 3.2-rc3 . fixed FPU support . fixed running with shared libraries . fixed running at non-0 based RAM (thanks to Alexander Stein) . many random small cleanups . spelling and comment fixes This patch set is based on 3.2-rc3 with all the recent patches I have sent here applied first. It is available as a git tree for easier testing, just pull this tree, with the cfmmu branch: git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git cfmmu Some of the code in this set is taken from Freescales 2.6.25 kernel support of MMU ColdFire. Specifically I am testing this on a ColdFire 5475 (on a FireBee board). I have test compiled and run this patch set on ARAnyM as well, I didn't have any problems there. Also test compiled and run on MMU-less ColdFire. Geert, any patches that changed in any significant way I dropped your "Acked-by". Regards Greg --- arch/m68k/Kconfig | 10 +- arch/m68k/Kconfig.cpu | 8 +- arch/m68k/include/asm/atomic.h | 10 + arch/m68k/include/asm/cacheflush_mm.h | 88 +++++++- arch/m68k/include/asm/elf.h | 6 +- arch/m68k/include/asm/entry.h | 10 +- arch/m68k/include/asm/fpu.h | 2 + arch/m68k/include/asm/irq.h | 5 +- arch/m68k/include/asm/m54xxacr.h | 32 +++- arch/m68k/include/asm/mcf_pgalloc.h | 102 ++++++++ arch/m68k/include/asm/mcf_pgtable.h | 422 +++++++++++++++++++++++++++++++++ arch/m68k/include/asm/mcfmmu.h | 119 +++++++++ arch/m68k/include/asm/mmu_context.h | 250 ++++++++++++++++---- arch/m68k/include/asm/page.h | 6 +- arch/m68k/include/asm/page_offset.h | 8 +- arch/m68k/include/asm/pgalloc.h | 4 +- arch/m68k/include/asm/pgtable_mm.h | 30 ++- arch/m68k/include/asm/processor.h | 16 +- arch/m68k/include/asm/segment.h | 30 ++- arch/m68k/include/asm/setup.h | 14 + arch/m68k/include/asm/thread_info.h | 3 + arch/m68k/include/asm/tlbflush.h | 23 ++- arch/m68k/include/asm/uaccess_mm.h | 42 +++- arch/m68k/kernel/Makefile | 4 +- arch/m68k/kernel/entry.S | 2 +- arch/m68k/kernel/entry_no.S | 3 + arch/m68k/kernel/process_mm.c | 59 ++++- arch/m68k/kernel/ptrace_mm.c | 18 ++ arch/m68k/kernel/setup_mm.c | 18 ++- arch/m68k/kernel/signal_mm.c | 173 ++++++++++---- arch/m68k/kernel/time.c | 2 +- arch/m68k/kernel/traps.c | 104 ++++++++ arch/m68k/kernel/vmlinux.lds.S | 2 +- arch/m68k/kernel/vmlinux.lds_no.S | 8 + arch/m68k/lib/uaccess.c | 22 +- arch/m68k/mm/Makefile | 8 +- arch/m68k/mm/cache.c | 24 ++- arch/m68k/mm/init_mm.c | 2 +- arch/m68k/mm/kmap.c | 4 + arch/m68k/mm/mcfmmu.c | 219 +++++++++++++++++ arch/m68k/mm/memory.c | 8 +- arch/m68k/platform/54xx/config.c | 48 ++++ arch/m68k/platform/coldfire/entry.S | 6 +- arch/m68k/platform/coldfire/head.S | 47 ++++- 44 files changed, 1808 insertions(+), 213 deletions(-) create mode 100644 arch/m68k/include/asm/mcf_pgalloc.h create mode 100644 arch/m68k/include/asm/mcf_pgtable.h create mode 100644 arch/m68k/include/asm/mcfmmu.h create mode 100644 arch/m68k/mm/mcfmmu.c From gerg at snapgear.com Thu Nov 24 22:40:47 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:47 +1000 Subject: [uClinux-dev] [PATCH 02/35] m68k: show ColdFire CPU/FPU/MMU type In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-3-git-send-email-gerg@snapgear.com> From: Greg Ungerer Update the show_cpuinfo() code to display info about ColdFire cores. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/setup_mm.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c index 55f8f50..52e17d1 100644 --- a/arch/m68k/kernel/setup_mm.c +++ b/arch/m68k/kernel/setup_mm.c @@ -388,6 +388,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) #define LOOP_CYCLES_68030 (8) #define LOOP_CYCLES_68040 (3) #define LOOP_CYCLES_68060 (1) +#define LOOP_CYCLES_COLDFIRE (2) if (CPU_IS_020) { cpu = "68020"; @@ -401,6 +402,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) } else if (CPU_IS_060) { cpu = "68060"; clockfactor = LOOP_CYCLES_68060; + } else if (CPU_IS_COLDFIRE) { + cpu = "ColdFire"; + clockfactor = LOOP_CYCLES_COLDFIRE; } else { cpu = "680x0"; clockfactor = 0; @@ -419,6 +423,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) fpu = "68060"; else if (m68k_fputype & FPU_SUNFPA) fpu = "Sun FPA"; + else if (m68k_fputype & FPU_COLDFIRE) + fpu = "ColdFire"; else fpu = "none"; #endif @@ -435,6 +441,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) mmu = "Sun-3"; else if (m68k_mmutype & MMU_APOLLO) mmu = "Apollo"; + else if (m68k_mmutype & MMU_COLDFIRE) + mmu = "ColdFire"; else mmu = "unknown"; -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:48 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:48 +1000 Subject: [uClinux-dev] [PATCH 03/35] m68k: definitions for the ColdFire V4e MMU hardware In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-4-git-send-email-gerg@snapgear.com> From: Greg Ungerer Basic register level definitions to support the internal MMU of the V4e ColdFire cores. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/mcfmmu.h | 117 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 117 insertions(+), 0 deletions(-) create mode 100644 arch/m68k/include/asm/mcfmmu.h diff --git a/arch/m68k/include/asm/mcfmmu.h b/arch/m68k/include/asm/mcfmmu.h new file mode 100644 index 0000000..84b4c28 --- /dev/null +++ b/arch/m68k/include/asm/mcfmmu.h @@ -0,0 +1,117 @@ +/****************************************************************************/ + +/* + * mcfmmu.h -- definitions for the ColdFire v4e MMU + * + * (C) Copyright 2011, Greg Ungerer + * + * 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. + */ + +/****************************************************************************/ +#ifndef MCFMMU_H +#define MCFMMU_H +/****************************************************************************/ + +/* + * The MMU support registers are mapped into the address space using + * the processor MMUBASE register. We used a fixed address for mapping, + * there doesn't seem any need to make this configurable yet. + */ +#define MMUBASE 0xfe000000 + +/* + * The support registers of the MMU. Names are the sames as those + * used in the Freescale v4e documentation. + */ +#define MMUCR (MMUBASE + 0x00) /* Control register */ +#define MMUOR (MMUBASE + 0x04) /* Operation register */ +#define MMUSR (MMUBASE + 0x08) /* Status register */ +#define MMUAR (MMUBASE + 0x10) /* TLB Address register */ +#define MMUTR (MMUBASE + 0x14) /* TLB Tag register */ +#define MMUDR (MMUBASE + 0x18) /* TLB Data register */ + +/* + * MMU Control register bit flags + */ +#define MMUCR_EN 0x00000001 /* Virtual mode enable */ +#define MMUCR_ASM 0x00000002 /* Address space mode */ + +/* + * MMU Operation register. + */ +#define MMUOR_UAA 0x00000001 /* Update allocatiom address */ +#define MMUOR_ACC 0x00000002 /* TLB access */ +#define MMUOR_RD 0x00000004 /* TLB access read */ +#define MMUOR_WR 0x00000000 /* TLB access write */ +#define MMUOR_ADR 0x00000008 /* TLB address select */ +#define MMUOR_ITLB 0x00000010 /* ITLB operation */ +#define MMUOR_CAS 0x00000020 /* Clear non-locked ASID TLBs */ +#define MMUOR_CNL 0x00000040 /* Clear non-locked TLBs */ +#define MMUOR_CA 0x00000080 /* Clear all TLBs */ +#define MMUOR_STLB 0x00000100 /* Search TLBs */ +#define MMUOR_AAN 16 /* TLB allocation address */ +#define MMUOR_AAMASK 0xffff0000 /* AA mask */ + +/* + * MMU Status register. + */ +#define MMUSR_HIT 0x00000002 /* Search TLB hit */ +#define MMUSR_WF 0x00000008 /* Write access fault */ +#define MMUSR_RF 0x00000010 /* Read access fault */ +#define MMUSR_SPF 0x00000020 /* Supervisor protect fault */ + +/* + * MMU Read/Write Tag register. + */ +#define MMUTR_V 0x00000001 /* Valid */ +#define MMUTR_SG 0x00000002 /* Shared global */ +#define MMUTR_IDN 2 /* Address Space ID */ +#define MMUTR_IDMASK 0x000003fc /* ASID mask */ +#define MMUTR_VAN 10 /* Virtual Address */ +#define MMUTR_VAMASK 0xfffffc00 /* VA mask */ + +/* + * MMU Read/Write Data register. + */ +#define MMUDR_LK 0x00000002 /* Lock entry */ +#define MMUDR_X 0x00000004 /* Execute access enable */ +#define MMUDR_W 0x00000008 /* Write access enable */ +#define MMUDR_R 0x00000010 /* Read access enable */ +#define MMUDR_SP 0x00000020 /* Supervisor access enable */ +#define MMUDR_CM_CWT 0x00000000 /* Cachable write thru */ +#define MMUDR_CM_CCB 0x00000040 /* Cachable copy back */ +#define MMUDR_CM_NCP 0x00000080 /* Non-cachable precise */ +#define MMUDR_CM_NCI 0x000000c0 /* Non-cachable imprecise */ +#define MMUDR_SZ_1MB 0x00000000 /* 1MB page size */ +#define MMUDR_SZ_4KB 0x00000100 /* 4kB page size */ +#define MMUDR_SZ_8KB 0x00000200 /* 8kB page size */ +#define MMUDR_SZ_1KB 0x00000300 /* 1kB page size */ +#define MMUDR_PAN 10 /* Physical address */ +#define MMUDR_PAMASK 0xfffffc00 /* PA mask */ + +/* + * Simple access functions for the MMU registers. Nothing fancy + * currently required, just simple 32bit access. + */ +#ifndef __ASSEMBLY__ + +#define CF_PAGE_PGNUM_MASK (PAGE_MASK) + +static inline u32 mmu_read(u32 a) +{ + return *((volatile u32 *) a); +} + +static inline void mmu_write(u32 a, u32 v) +{ + *((volatile u32 *) a) = v; + __asm__ __volatile__ ("nop"); +} + +#endif + +/****************************************************************************/ +#endif /* MCFMMU_H */ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:54 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:54 +1000 Subject: [uClinux-dev] [PATCH 09/35] m68k: add ColdFire 54xx CPU MMU memory init code In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-10-git-send-email-gerg@snapgear.com> From: Greg Ungerer Add code to the 54xx ColdFire CPU init to setup memory ready for the m68k paged memory start up. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/platform/54xx/config.c | 48 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/arch/m68k/platform/54xx/config.c b/arch/m68k/platform/54xx/config.c index 7813098..09be59c 100644 --- a/arch/m68k/platform/54xx/config.c +++ b/arch/m68k/platform/54xx/config.c @@ -13,11 +13,17 @@ #include #include #include +#include +#include +#include #include #include #include #include #include +#ifdef CONFIG_MMU +#include +#endif /***************************************************************************/ @@ -95,8 +101,50 @@ static void mcf54xx_reset(void) /***************************************************************************/ +#ifdef CONFIG_MMU + +unsigned long num_pages; + +static void __init mcf54xx_bootmem_alloc(void) +{ + extern unsigned int _rambase, _ramstart, _ramend; + unsigned long start_pfn; + unsigned long memstart; + + /* _rambase and _ramend will be naturally page aligned */ + m68k_memory[0].addr = _rambase; + m68k_memory[0].size = _ramend - _rambase; + + /* compute total pages in system */ + num_pages = (_ramend - _rambase) >> PAGE_SHIFT; + + /* page numbers */ + memstart = PAGE_ALIGN(_ramstart); + min_low_pfn = _rambase >> PAGE_SHIFT; + start_pfn = memstart >> PAGE_SHIFT; + max_low_pfn = _ramend >> PAGE_SHIFT; + high_memory = (void *)_ramend; + + m68k_virt_to_node_shift = fls(_ramend - _rambase - 1) - 6; + module_fixup(NULL, __start_fixup, __stop_fixup); + + /* setup bootmem data */ + m68k_setup_node(0); + memstart += init_bootmem_node(NODE_DATA(0), start_pfn, + min_low_pfn, max_low_pfn); + free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart); +} + +#endif /* CONFIG_MMU */ + +/***************************************************************************/ + void __init config_BSP(char *commandp, int size) { +#ifdef CONFIG_MMU + mcf54xx_bootmem_alloc(); + mmu_context_init(); +#endif mach_reset = mcf54xx_reset; m54xx_uarts_init(); } -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:51 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:51 +1000 Subject: [uClinux-dev] [PATCH 06/35] m68k: modify user space access functions to support ColdFire CPUs In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-7-git-send-email-gerg@snapgear.com> From: Greg Ungerer Modify the user space access functions to support the ColdFire V4e cores running with MMU enabled. The ColdFire processors do not support the "moves" instruction used by the traditional 680x0 processors for moving data into and out of another address space. They only support the notion of a single address space, and you use the usual "move" instruction to access that. Create a new config symbol (CONFIG_CPU_HAS_ADDRESS_SPACES) to mark the CPU types that support separate address spaces, and thus also support the sfc/dfc registers and the "moves" instruction that go along with that. The code is almost identical for user space access, so lets just use a define to choose either the "move" or "moves" in the assembler code. Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig | 3 ++ arch/m68k/Kconfig.cpu | 4 +++ arch/m68k/include/asm/segment.h | 4 +- arch/m68k/include/asm/uaccess_mm.h | 42 ++++++++++++++++++++++++----------- arch/m68k/lib/uaccess.c | 22 +++++++++--------- 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 32fd364..5f860cf 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -66,6 +66,9 @@ config CPU_HAS_NO_BITFIELDS config CPU_HAS_NO_MULDIV64 bool +config CPU_HAS_ADDRESS_SPACES + bool + config HZ int default 1000 if CLEOPATRA diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 017f4fc..5ae1d63 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -38,6 +38,7 @@ config M68020 bool "68020 support" depends on MMU select GENERIC_ATOMIC64 + select CPU_HAS_ADDRESS_SPACES help If you anticipate running this kernel on a computer with a MC68020 processor, say Y. Otherwise, say N. Note that the 68020 requires a @@ -48,6 +49,7 @@ config M68030 bool "68030 support" depends on MMU && !MMU_SUN3 select GENERIC_ATOMIC64 + select CPU_HAS_ADDRESS_SPACES help If you anticipate running this kernel on a computer with a MC68030 processor, say Y. Otherwise, say N. Note that a MC68EC030 will not @@ -57,6 +59,7 @@ config M68040 bool "68040 support" depends on MMU && !MMU_SUN3 select GENERIC_ATOMIC64 + select CPU_HAS_ADDRESS_SPACES help If you anticipate running this kernel on a computer with a MC68LC040 or MC68040 processor, say Y. Otherwise, say N. Note that an @@ -67,6 +70,7 @@ config M68060 bool "68060 support" depends on MMU && !MMU_SUN3 select GENERIC_ATOMIC64 + select CPU_HAS_ADDRESS_SPACES help If you anticipate running this kernel on a computer with a MC68060 processor, say Y. Otherwise, say N. diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h index ee95921..1a142e9 100644 --- a/arch/m68k/include/asm/segment.h +++ b/arch/m68k/include/asm/segment.h @@ -31,7 +31,7 @@ typedef struct { static inline mm_segment_t get_fs(void) { -#ifdef CONFIG_MMU +#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES mm_segment_t _v; __asm__ ("movec %/dfc,%0":"=r" (_v.seg):); @@ -49,7 +49,7 @@ static inline mm_segment_t get_ds(void) static inline void set_fs(mm_segment_t val) { -#ifdef CONFIG_MMU +#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES __asm__ __volatile__ ("movec %0,%/sfc\n\t" "movec %0,%/dfc\n\t" : /* no outputs */ : "r" (val.seg) : "memory"); diff --git a/arch/m68k/include/asm/uaccess_mm.h b/arch/m68k/include/asm/uaccess_mm.h index 7107f3f..9c80cd5 100644 --- a/arch/m68k/include/asm/uaccess_mm.h +++ b/arch/m68k/include/asm/uaccess_mm.h @@ -21,6 +21,22 @@ static inline int access_ok(int type, const void __user *addr, } /* + * Not all varients of the 68k family support the notion of address spaces. + * The traditional 680x0 parts do, and they use the sfc/dfc registers and + * the "moves" instruction to access user space from kernel space. Other + * family members like ColdFire don't support this, and only have a single + * address space, and use the usual "move" instruction for user space access. + * + * Outside of this difference the user space access functions are the same. + * So lets keep the code simple and just define in what we need to use. + */ +#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES +#define MOVES "moves" +#else +#define MOVES "move" +#endif + +/* * The exception table consists of pairs of addresses: the first is the * address of an instruction that is allowed to fault, and the second is * the address at which the program should continue. No registers are @@ -43,7 +59,7 @@ extern int __get_user_bad(void); #define __put_user_asm(res, x, ptr, bwl, reg, err) \ asm volatile ("\n" \ - "1: moves."#bwl" %2,%1\n" \ + "1: "MOVES"."#bwl" %2,%1\n" \ "2:\n" \ " .section .fixup,\"ax\"\n" \ " .even\n" \ @@ -83,8 +99,8 @@ asm volatile ("\n" \ { \ const void __user *__pu_ptr = (ptr); \ asm volatile ("\n" \ - "1: moves.l %2,(%1)+\n" \ - "2: moves.l %R2,(%1)\n" \ + "1: "MOVES".l %2,(%1)+\n" \ + "2: "MOVES".l %R2,(%1)\n" \ "3:\n" \ " .section .fixup,\"ax\"\n" \ " .even\n" \ @@ -115,12 +131,12 @@ asm volatile ("\n" \ #define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \ type __gu_val; \ asm volatile ("\n" \ - "1: moves."#bwl" %2,%1\n" \ + "1: "MOVES"."#bwl" %2,%1\n" \ "2:\n" \ " .section .fixup,\"ax\"\n" \ " .even\n" \ "10: move.l %3,%0\n" \ - " sub."#bwl" %1,%1\n" \ + " sub.l %1,%1\n" \ " jra 2b\n" \ " .previous\n" \ "\n" \ @@ -152,8 +168,8 @@ asm volatile ("\n" \ const void *__gu_ptr = (ptr); \ u64 __gu_val; \ asm volatile ("\n" \ - "1: moves.l (%2)+,%1\n" \ - "2: moves.l (%2),%R1\n" \ + "1: "MOVES".l (%2)+,%1\n" \ + "2: "MOVES".l (%2),%R1\n" \ "3:\n" \ " .section .fixup,\"ax\"\n" \ " .even\n" \ @@ -188,12 +204,12 @@ unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned #define __constant_copy_from_user_asm(res, to, from, tmp, n, s1, s2, s3)\ asm volatile ("\n" \ - "1: moves."#s1" (%2)+,%3\n" \ + "1: "MOVES"."#s1" (%2)+,%3\n" \ " move."#s1" %3,(%1)+\n" \ - "2: moves."#s2" (%2)+,%3\n" \ + "2: "MOVES"."#s2" (%2)+,%3\n" \ " move."#s2" %3,(%1)+\n" \ " .ifnc \""#s3"\",\"\"\n" \ - "3: moves."#s3" (%2)+,%3\n" \ + "3: "MOVES"."#s3" (%2)+,%3\n" \ " move."#s3" %3,(%1)+\n" \ " .endif\n" \ "4:\n" \ @@ -269,13 +285,13 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n) #define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \ asm volatile ("\n" \ " move."#s1" (%2)+,%3\n" \ - "11: moves."#s1" %3,(%1)+\n" \ + "11: "MOVES"."#s1" %3,(%1)+\n" \ "12: move."#s2" (%2)+,%3\n" \ - "21: moves."#s2" %3,(%1)+\n" \ + "21: "MOVES"."#s2" %3,(%1)+\n" \ "22:\n" \ " .ifnc \""#s3"\",\"\"\n" \ " move."#s3" (%2)+,%3\n" \ - "31: moves."#s3" %3,(%1)+\n" \ + "31: "MOVES"."#s3" %3,(%1)+\n" \ "32:\n" \ " .endif\n" \ "4:\n" \ diff --git a/arch/m68k/lib/uaccess.c b/arch/m68k/lib/uaccess.c index 13854ed..5664386 100644 --- a/arch/m68k/lib/uaccess.c +++ b/arch/m68k/lib/uaccess.c @@ -15,17 +15,17 @@ unsigned long __generic_copy_from_user(void *to, const void __user *from, asm volatile ("\n" " tst.l %0\n" " jeq 2f\n" - "1: moves.l (%1)+,%3\n" + "1: "MOVES".l (%1)+,%3\n" " move.l %3,(%2)+\n" " subq.l #1,%0\n" " jne 1b\n" "2: btst #1,%5\n" " jeq 4f\n" - "3: moves.w (%1)+,%3\n" + "3: "MOVES".w (%1)+,%3\n" " move.w %3,(%2)+\n" "4: btst #0,%5\n" " jeq 6f\n" - "5: moves.b (%1)+,%3\n" + "5: "MOVES".b (%1)+,%3\n" " move.b %3,(%2)+\n" "6:\n" " .section .fixup,\"ax\"\n" @@ -68,17 +68,17 @@ unsigned long __generic_copy_to_user(void __user *to, const void *from, " tst.l %0\n" " jeq 4f\n" "1: move.l (%1)+,%3\n" - "2: moves.l %3,(%2)+\n" + "2: "MOVES".l %3,(%2)+\n" "3: subq.l #1,%0\n" " jne 1b\n" "4: btst #1,%5\n" " jeq 6f\n" " move.w (%1)+,%3\n" - "5: moves.w %3,(%2)+\n" + "5: "MOVES".w %3,(%2)+\n" "6: btst #0,%5\n" " jeq 8f\n" " move.b (%1)+,%3\n" - "7: moves.b %3,(%2)+\n" + "7: "MOVES".b %3,(%2)+\n" "8:\n" " .section .fixup,\"ax\"\n" " .even\n" @@ -115,7 +115,7 @@ long strncpy_from_user(char *dst, const char __user *src, long count) return count; asm volatile ("\n" - "1: moves.b (%2)+,%4\n" + "1: "MOVES".b (%2)+,%4\n" " move.b %4,(%1)+\n" " jeq 2f\n" " subq.l #1,%3\n" @@ -152,7 +152,7 @@ long strnlen_user(const char __user *src, long n) asm volatile ("\n" "1: subq.l #1,%1\n" " jmi 3f\n" - "2: moves.b (%0)+,%2\n" + "2: "MOVES".b (%0)+,%2\n" " tst.b %2\n" " jne 1b\n" " jra 4f\n" @@ -188,15 +188,15 @@ unsigned long __clear_user(void __user *to, unsigned long n) asm volatile ("\n" " tst.l %0\n" " jeq 3f\n" - "1: moves.l %2,(%1)+\n" + "1: "MOVES".l %2,(%1)+\n" "2: subq.l #1,%0\n" " jne 1b\n" "3: btst #1,%4\n" " jeq 5f\n" - "4: moves.w %2,(%1)+\n" + "4: "MOVES".w %2,(%1)+\n" "5: btst #0,%4\n" " jeq 7f\n" - "6: moves.b %2,(%1)\n" + "6: "MOVES".b %2,(%1)\n" "7:\n" " .section .fixup,\"ax\"\n" " .even\n" -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:50 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:50 +1000 Subject: [uClinux-dev] [PATCH 05/35] m68k: add TASK definitions for ColdFires running with MMU In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-6-git-send-email-gerg@snapgear.com> From: Greg Ungerer Add appropriate TASK_SIZE and TASK_UNMAPPED_BASE definitions for running on ColdFire V4e cores with MMU enabled. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/processor.h | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index 7ec0609..0a84b79 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -48,10 +48,12 @@ static inline void wrusp(unsigned long usp) * so don't change it unless you know what you are doing. */ #ifdef CONFIG_MMU -#ifndef CONFIG_SUN3 -#define TASK_SIZE (0xF0000000UL) -#else +#if defined(CONFIG_COLDFIRE) +#define TASK_SIZE (0xC0000000UL) +#elif defined(CONFIG_SUN3) #define TASK_SIZE (0x0E000000UL) +#else +#define TASK_SIZE (0xF0000000UL) #endif #else #define TASK_SIZE (0xFFFFFFFFUL) @@ -66,10 +68,12 @@ static inline void wrusp(unsigned long usp) * space during mmap's. */ #ifdef CONFIG_MMU -#ifndef CONFIG_SUN3 -#define TASK_UNMAPPED_BASE 0xC0000000UL -#else +#if defined(CONFIG_COLDFIRE) +#define TASK_UNMAPPED_BASE 0x80000000UL +#elif defined(CONFIG_SUN3) #define TASK_UNMAPPED_BASE 0x0A000000UL +#else +#define TASK_UNMAPPED_BASE 0xC0000000UL #endif #define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) #else -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:52 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:52 +1000 Subject: [uClinux-dev] [PATCH 07/35] m68k: use addr_limit checking for m68k CPUs that do no support address spaces In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-8-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire CPU family, and the original 68000, do not support separate address spaces like the other 680x0 CPU types. Modify the set_fs()/get_fs() functions and macros to use a thread_info addr_limit for address space checking. This is pretty much what all other architectures that do not support separate setable address spaces do. Signed-off-by: Alexander Stein Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/segment.h | 30 ++++++++++++++++-------------- arch/m68k/include/asm/thread_info.h | 3 +++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h index 1a142e9..0fa80e9 100644 --- a/arch/m68k/include/asm/segment.h +++ b/arch/m68k/include/asm/segment.h @@ -22,23 +22,26 @@ typedef struct { } mm_segment_t; #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define USER_DS MAKE_MM_SEG(__USER_DS) -#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) +#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES /* * Get/set the SFC/DFC registers for MOVES instructions */ +#define USER_DS MAKE_MM_SEG(__USER_DS) +#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) static inline mm_segment_t get_fs(void) { -#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES mm_segment_t _v; __asm__ ("movec %/dfc,%0":"=r" (_v.seg):); - return _v; -#else - return USER_DS; -#endif +} + +static inline void set_fs(mm_segment_t val) +{ + __asm__ __volatile__ ("movec %0,%/sfc\n\t" + "movec %0,%/dfc\n\t" + : /* no outputs */ : "r" (val.seg) : "memory"); } static inline mm_segment_t get_ds(void) @@ -47,14 +50,13 @@ static inline mm_segment_t get_ds(void) return KERNEL_DS; } -static inline void set_fs(mm_segment_t val) -{ -#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES - __asm__ __volatile__ ("movec %0,%/sfc\n\t" - "movec %0,%/dfc\n\t" - : /* no outputs */ : "r" (val.seg) : "memory"); +#else +#define USER_DS MAKE_MM_SEG(TASK_SIZE) +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) +#define get_ds() (KERNEL_DS) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) #endif -} #define segment_eq(a,b) ((a).seg == (b).seg) diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h index 01cef3c..29fa6da 100644 --- a/arch/m68k/include/asm/thread_info.h +++ b/arch/m68k/include/asm/thread_info.h @@ -3,6 +3,7 @@ #include #include +#include /* * On machines with 4k pages we default to an 8k thread size, though we @@ -26,6 +27,7 @@ struct thread_info { struct task_struct *task; /* main task structure */ unsigned long flags; struct exec_domain *exec_domain; /* execution domain */ + mm_segment_t addr_limit; /* thread address space */ int preempt_count; /* 0 => preemptable, <0 => BUG */ __u32 cpu; /* should always be 0 on m68k */ unsigned long tp_value; /* thread pointer */ @@ -39,6 +41,7 @@ struct thread_info { { \ .task = &tsk, \ .exec_domain = &default_exec_domain, \ + .addr_limit = KERNEL_DS, \ .preempt_count = INIT_PREEMPT_COUNT, \ .restart_block = { \ .fn = do_no_restart_syscall, \ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:56 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:56 +1000 Subject: [uClinux-dev] [PATCH 11/35] m68k: page table support definitions and code for ColdFire MMU In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-12-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire V4e MMU is nothing like any of the other m68k MMU's. So we need to create a set of definitions and support routines for the kernels paging functions. This is largely taken from Freescales BSP code for this (though it was a 2.6.25 kernel). I have cleaned it up alot from the original. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/mcf_pgtable.h | 422 +++++++++++++++++++++++++++++++++++ 1 files changed, 422 insertions(+), 0 deletions(-) create mode 100644 arch/m68k/include/asm/mcf_pgtable.h diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h new file mode 100644 index 0000000..37ebaa2 --- /dev/null +++ b/arch/m68k/include/asm/mcf_pgtable.h @@ -0,0 +1,422 @@ +#ifndef _MCF_PGTABLE_H +#define _MCF_PGTABLE_H + +#include +#include + +/* + * MMUDR bits, in proper place. We write these directly into the MMUDR + * after masking from the pte. + */ +#define CF_PAGE_LOCKED MMUDR_LK /* 0x00000002 */ +#define CF_PAGE_EXEC MMUDR_X /* 0x00000004 */ +#define CF_PAGE_WRITABLE MMUDR_W /* 0x00000008 */ +#define CF_PAGE_READABLE MMUDR_R /* 0x00000010 */ +#define CF_PAGE_SYSTEM MMUDR_SP /* 0x00000020 */ +#define CF_PAGE_COPYBACK MMUDR_CM_CCB /* 0x00000040 */ +#define CF_PAGE_NOCACHE MMUDR_CM_NCP /* 0x00000080 */ + +#define CF_CACHEMASK (~MMUDR_CM_CCB) +#define CF_PAGE_MMUDR_MASK 0x000000fe + +#define _PAGE_NOCACHE030 CF_PAGE_NOCACHE + +/* + * MMUTR bits, need shifting down. + */ +#define CF_PAGE_MMUTR_MASK 0x00000c00 +#define CF_PAGE_MMUTR_SHIFT 10 + +#define CF_PAGE_VALID (MMUTR_V << CF_PAGE_MMUTR_SHIFT) +#define CF_PAGE_SHARED (MMUTR_SG << CF_PAGE_MMUTR_SHIFT) + +/* + * Fake bits, not implemented in CF, will get masked out before + * hitting hardware. + */ +#define CF_PAGE_DIRTY 0x00000001 +#define CF_PAGE_FILE 0x00000200 +#define CF_PAGE_ACCESSED 0x00001000 + +#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ +#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ +#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ +#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ +#define _DESCTYPE_MASK 0x003 +#define _CACHEMASK040 (~0x060) +#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ + +/* + * Externally used page protection values. + */ +#define _PAGE_PRESENT (CF_PAGE_VALID) +#define _PAGE_ACCESSED (CF_PAGE_ACCESSED) +#define _PAGE_DIRTY (CF_PAGE_DIRTY) +#define _PAGE_READWRITE (CF_PAGE_READABLE | CF_PAGE_WRITABLE | CF_PAGE_SYSTEM) + +/* + * Compound page protection values. + */ +#define PAGE_NONE __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED) + +#define PAGE_SHARED __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_SHARED) + +#define PAGE_INIT __pgprot(CF_PAGE_VALID \ + | CF_PAGE_READABLE \ + | CF_PAGE_WRITABLE \ + | CF_PAGE_EXEC \ + | CF_PAGE_SYSTEM) + +#define PAGE_KERNEL __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_READABLE \ + | CF_PAGE_WRITABLE \ + | CF_PAGE_EXEC \ + | CF_PAGE_SYSTEM) + +#define PAGE_COPY __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_READABLE \ + | CF_PAGE_DIRTY) + +/* + * Page protections for initialising protection_map. See mm/mmap.c + * for use. In general, the bit positions are xwr, and P-items are + * private, the S-items are shared. + */ +#define __P000 PAGE_NONE +#define __P001 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_READABLE) +#define __P010 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_WRITABLE) +#define __P011 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_READABLE \ + | CF_PAGE_WRITABLE) +#define __P100 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_EXEC) +#define __P101 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_READABLE \ + | CF_PAGE_EXEC) +#define __P110 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_WRITABLE \ + | CF_PAGE_EXEC) +#define __P111 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_READABLE \ + | CF_PAGE_WRITABLE \ + | CF_PAGE_EXEC) + +#define __S000 PAGE_NONE +#define __S001 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_READABLE) +#define __S010 PAGE_SHARED +#define __S011 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_SHARED \ + | CF_PAGE_READABLE) +#define __S100 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_EXEC) +#define __S101 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_READABLE \ + | CF_PAGE_EXEC) +#define __S110 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_SHARED \ + | CF_PAGE_EXEC) +#define __S111 __pgprot(CF_PAGE_VALID \ + | CF_PAGE_ACCESSED \ + | CF_PAGE_SHARED \ + | CF_PAGE_READABLE \ + | CF_PAGE_EXEC) + +#define PTE_MASK PAGE_MASK +#define CF_PAGE_CHG_MASK (PTE_MASK | CF_PAGE_ACCESSED | CF_PAGE_DIRTY) + +#ifndef __ASSEMBLY__ + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & CF_PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + +#define pmd_set(pmdp, ptep) do {} while (0) + +static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) +{ + pgd_val(*pgdp) = virt_to_phys(pmdp); +} + +#define __pte_page(pte) ((unsigned long) (pte_val(pte) & CF_PAGE_PGNUM_MASK)) +#define __pmd_page(pmd) ((unsigned long) (pmd_val(pmd))) + +static inline int pte_none(pte_t pte) +{ + return !pte_val(pte); +} + +static inline int pte_present(pte_t pte) +{ + return pte_val(pte) & CF_PAGE_VALID; +} + +static inline void pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + pte_val(*ptep) = 0; +} + +#define pte_pagenr(pte) ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT) +#define pte_page(pte) virt_to_page(__pte_page(pte)) + +static inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); } +#define pmd_none(pmd) pmd_none2(&(pmd)) +static inline int pmd_bad2(pmd_t *pmd) { return 0; } +#define pmd_bad(pmd) pmd_bad2(&(pmd)) +#define pmd_present(pmd) (!pmd_none2(&(pmd))) +static inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; } + +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } +static inline void pgd_clear(pgd_t *pgdp) {} + +#define pte_ERROR(e) \ + printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \ + __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk(KERN_ERR "%s:%d: bad pmd %08lx.\n", \ + __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \ + __FILE__, __LINE__, pgd_val(e)) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not... + * [we have the full set here even if they don't change from m68k] + */ +static inline int pte_read(pte_t pte) +{ + return pte_val(pte) & CF_PAGE_READABLE; +} + +static inline int pte_write(pte_t pte) +{ + return pte_val(pte) & CF_PAGE_WRITABLE; +} + +static inline int pte_exec(pte_t pte) +{ + return pte_val(pte) & CF_PAGE_EXEC; +} + +static inline int pte_dirty(pte_t pte) +{ + return pte_val(pte) & CF_PAGE_DIRTY; +} + +static inline int pte_young(pte_t pte) +{ + return pte_val(pte) & CF_PAGE_ACCESSED; +} + +static inline int pte_file(pte_t pte) +{ + return pte_val(pte) & CF_PAGE_FILE; +} + +static inline int pte_special(pte_t pte) +{ + return 0; +} + +static inline pte_t pte_wrprotect(pte_t pte) +{ + pte_val(pte) &= ~CF_PAGE_WRITABLE; + return pte; +} + +static inline pte_t pte_rdprotect(pte_t pte) +{ + pte_val(pte) &= ~CF_PAGE_READABLE; + return pte; +} + +static inline pte_t pte_exprotect(pte_t pte) +{ + pte_val(pte) &= ~CF_PAGE_EXEC; + return pte; +} + +static inline pte_t pte_mkclean(pte_t pte) +{ + pte_val(pte) &= ~CF_PAGE_DIRTY; + return pte; +} + +static inline pte_t pte_mkold(pte_t pte) +{ + pte_val(pte) &= ~CF_PAGE_ACCESSED; + return pte; +} + +static inline pte_t pte_mkwrite(pte_t pte) +{ + pte_val(pte) |= CF_PAGE_WRITABLE; + return pte; +} + +static inline pte_t pte_mkread(pte_t pte) +{ + pte_val(pte) |= CF_PAGE_READABLE; + return pte; +} + +static inline pte_t pte_mkexec(pte_t pte) +{ + pte_val(pte) |= CF_PAGE_EXEC; + return pte; +} + +static inline pte_t pte_mkdirty(pte_t pte) +{ + pte_val(pte) |= CF_PAGE_DIRTY; + return pte; +} + +static inline pte_t pte_mkyoung(pte_t pte) +{ + pte_val(pte) |= CF_PAGE_ACCESSED; + return pte; +} + +static inline pte_t pte_mknocache(pte_t pte) +{ + pte_val(pte) |= 0x80 | (pte_val(pte) & ~0x40); + return pte; +} + +static inline pte_t pte_mkcache(pte_t pte) +{ + pte_val(pte) &= ~CF_PAGE_NOCACHE; + return pte; +} + +static inline pte_t pte_mkspecial(pte_t pte) +{ + return pte; +} + +#define swapper_pg_dir kernel_pg_dir +extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; + +/* + * Find an entry in a pagetable directory. + */ +#define pgd_index(address) ((address) >> PGDIR_SHIFT) +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) + +/* + * Find an entry in a kernel pagetable directory. + */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* + * Find an entry in the second-level pagetable. + */ +static inline pmd_t *pmd_offset(pgd_t *pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +/* + * Find an entry in the third-level pagetable. + */ +#define __pte_offset(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) __pmd_page(*(dir)) + __pte_offset(address)) + +/* + * Disable caching for page at given kernel virtual address. + */ +static inline void nocache_page(void *vaddr) +{ + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + unsigned long addr = (unsigned long) vaddr; + + dir = pgd_offset_k(addr); + pmdp = pmd_offset(dir, addr); + ptep = pte_offset_kernel(pmdp, addr); + *ptep = pte_mknocache(*ptep); +} + +/* + * Enable caching for page at given kernel virtual address. + */ +static inline void cache_page(void *vaddr) +{ + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + unsigned long addr = (unsigned long) vaddr; + + dir = pgd_offset_k(addr); + pmdp = pmd_offset(dir, addr); + ptep = pte_offset_kernel(pmdp, addr); + *ptep = pte_mkcache(*ptep); +} + +#define PTE_FILE_MAX_BITS 21 +#define PTE_FILE_SHIFT 11 + +static inline unsigned long pte_to_pgoff(pte_t pte) +{ + return pte_val(pte) >> PTE_FILE_SHIFT; +} + +static inline pte_t pgoff_to_pte(unsigned pgoff) +{ + return __pte((pgoff << PTE_FILE_SHIFT) + CF_PAGE_FILE); +} + +/* + * Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) + */ +#define __swp_type(x) ((x).val & 0xFF) +#define __swp_offset(x) ((x).val >> PTE_FILE_SHIFT) +#define __swp_entry(typ, off) ((swp_entry_t) { (typ) | \ + (off << PTE_FILE_SHIFT) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) (__pte((x).val)) + +#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) + +#define pte_offset_map(pmdp, addr) ((pte_t *)__pmd_page(*pmdp) + \ + __pte_offset(addr)) +#define pte_unmap(pte) ((void) 0) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) + +#endif /* !__ASSEMBLY__ */ +#endif /* _MCF_PGTABLE_H */ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:01 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:01 +1000 Subject: [uClinux-dev] [PATCH 16/35] m68k: add TLB flush support for the ColdFire V4e MMU hardware In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-17-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire V4e MMU is unlike any of the other m68k MMU hardware. It needs its own TLB flush support code. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/tlbflush.h | 23 +++++++++++++++++------ 1 files changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/m68k/include/asm/tlbflush.h b/arch/m68k/include/asm/tlbflush.h index a6b4ed4..965ea35 100644 --- a/arch/m68k/include/asm/tlbflush.h +++ b/arch/m68k/include/asm/tlbflush.h @@ -5,10 +5,13 @@ #ifndef CONFIG_SUN3 #include +#include static inline void flush_tlb_kernel_page(void *addr) { - if (CPU_IS_040_OR_060) { + if (CPU_IS_COLDFIRE) { + mmu_write(MMUOR, MMUOR_CNL); + } else if (CPU_IS_040_OR_060) { mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); __asm__ __volatile__(".chip 68040\n\t" @@ -25,12 +28,15 @@ static inline void flush_tlb_kernel_page(void *addr) */ static inline void __flush_tlb(void) { - if (CPU_IS_040_OR_060) + if (CPU_IS_COLDFIRE) { + mmu_write(MMUOR, MMUOR_CNL); + } else if (CPU_IS_040_OR_060) { __asm__ __volatile__(".chip 68040\n\t" "pflushan\n\t" ".chip 68k"); - else if (CPU_IS_020_OR_030) + } else if (CPU_IS_020_OR_030) { __asm__ __volatile__("pflush #0,#4"); + } } static inline void __flush_tlb040_one(unsigned long addr) @@ -43,7 +49,9 @@ static inline void __flush_tlb040_one(unsigned long addr) static inline void __flush_tlb_one(unsigned long addr) { - if (CPU_IS_040_OR_060) + if (CPU_IS_COLDFIRE) + mmu_write(MMUOR, MMUOR_CNL); + else if (CPU_IS_040_OR_060) __flush_tlb040_one(addr); else if (CPU_IS_020_OR_030) __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); @@ -56,12 +64,15 @@ static inline void __flush_tlb_one(unsigned long addr) */ static inline void flush_tlb_all(void) { - if (CPU_IS_040_OR_060) + if (CPU_IS_COLDFIRE) { + mmu_write(MMUOR, MMUOR_CNL); + } else if (CPU_IS_040_OR_060) { __asm__ __volatile__(".chip 68040\n\t" "pflusha\n\t" ".chip 68k"); - else if (CPU_IS_020_OR_030) + } else if (CPU_IS_020_OR_030) { __asm__ __volatile__("pflusha"); + } } static inline void flush_tlb_mm(struct mm_struct *mm) -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:58 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:58 +1000 Subject: [uClinux-dev] [PATCH 13/35] m68k: add ColdFire paging exception handling code In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-14-git-send-email-gerg@snapgear.com> From: Greg Ungerer Add code to traps.c to handle MMU exceptions for the ColdFire. Most of this code is from the 2.6.25 kernel BSP code released by Freescale. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/traps.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 104 insertions(+), 0 deletions(-) diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index 89362f2..a76452c 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -706,6 +706,88 @@ create_atc_entry: #endif /* CPU_M68020_OR_M68030 */ #endif /* !CONFIG_SUN3 */ +#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU) +#include + +/* + * The following table converts the FS encoding of a ColdFire + * exception stack frame into the error_code value needed by + * do_fault. +*/ +static const unsigned char fs_err_code[] = { + 0, /* 0000 */ + 0, /* 0001 */ + 0, /* 0010 */ + 0, /* 0011 */ + 1, /* 0100 */ + 0, /* 0101 */ + 0, /* 0110 */ + 0, /* 0111 */ + 2, /* 1000 */ + 3, /* 1001 */ + 2, /* 1010 */ + 0, /* 1011 */ + 1, /* 1100 */ + 1, /* 1101 */ + 0, /* 1110 */ + 0 /* 1111 */ +}; + +static inline void access_errorcf(unsigned int fs, struct frame *fp) +{ + unsigned long mmusr, addr; + unsigned int err_code; + int need_page_fault; + + mmusr = mmu_read(MMUSR); + addr = mmu_read(MMUAR); + + /* + * error_code: + * bit 0 == 0 means no page found, 1 means protection fault + * bit 1 == 0 means read, 1 means write + */ + switch (fs) { + case 5: /* 0101 TLB opword X miss */ + need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 0); + addr = fp->ptregs.pc; + break; + case 6: /* 0110 TLB extension word X miss */ + need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 1); + addr = fp->ptregs.pc + sizeof(long); + break; + case 10: /* 1010 TLB W miss */ + need_page_fault = cf_tlb_miss(&fp->ptregs, 1, 1, 0); + break; + case 14: /* 1110 TLB R miss */ + need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 1, 0); + break; + default: + /* 0000 Normal */ + /* 0001 Reserved */ + /* 0010 Interrupt during debug service routine */ + /* 0011 Reserved */ + /* 0100 X Protection */ + /* 0111 IFP in emulator mode */ + /* 1000 W Protection*/ + /* 1001 Write error*/ + /* 1011 Reserved*/ + /* 1100 R Protection*/ + /* 1101 R Protection*/ + /* 1111 OEP in emulator mode*/ + need_page_fault = 1; + break; + } + + if (need_page_fault) { + err_code = fs_err_code[fs]; + if ((fs == 13) && (mmusr & MMUSR_WF)) /* rd-mod-wr access */ + err_code |= 2; /* bit1 - write, bit0 - protection */ + do_page_fault(&fp->ptregs, addr, err_code); + } +} +#endif /* CONFIG_COLDFIRE CONFIG_MMU */ + asmlinkage void buserr_c(struct frame *fp) { /* Only set esp0 if coming from user mode */ @@ -716,6 +798,28 @@ asmlinkage void buserr_c(struct frame *fp) printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format); #endif +#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU) + if (CPU_IS_COLDFIRE) { + unsigned int fs; + fs = (fp->ptregs.vector & 0x3) | + ((fp->ptregs.vector & 0xc00) >> 8); + switch (fs) { + case 0x5: + case 0x6: + case 0x7: + case 0x9: + case 0xa: + case 0xd: + case 0xe: + case 0xf: + access_errorcf(fs, fp); + return; + default: + break; + } + } +#endif /* CONFIG_COLDFIRE && CONFIG_MMU */ + switch (fp->ptregs.format) { #if defined (CONFIG_M68060) case 4: /* 68060 access error */ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:05 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:05 +1000 Subject: [uClinux-dev] [PATCH 20/35] m68k: ColdFire V4e MMU context support code In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-21-git-send-email-gerg@snapgear.com> From: Greg Ungerer Add code to manage the context's of the ColdFire V4e MMU. This code is mostly taken from the Freescale 2.6.35 kernel BSP for MMU enabled ColdFire. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/atomic.h | 10 ++ arch/m68k/include/asm/mmu_context.h | 250 ++++++++++++++++++++++++++++------- 2 files changed, 211 insertions(+), 49 deletions(-) diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h index 65c6be6..4eba796 100644 --- a/arch/m68k/include/asm/atomic.h +++ b/arch/m68k/include/asm/atomic.h @@ -55,6 +55,16 @@ static inline int atomic_dec_and_test(atomic_t *v) return c != 0; } +static inline int atomic_dec_and_test_lt(atomic_t *v) +{ + char c; + __asm__ __volatile__( + "subql #1,%1; slt %0" + : "=d" (c), "=m" (*v) + : "m" (*v)); + return c != 0; +} + static inline int atomic_inc_and_test(atomic_t *v) { char c; diff --git a/arch/m68k/include/asm/mmu_context.h b/arch/m68k/include/asm/mmu_context.h index 7d4341e..dc3be99 100644 --- a/arch/m68k/include/asm/mmu_context.h +++ b/arch/m68k/include/asm/mmu_context.h @@ -8,7 +8,206 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) } #ifdef CONFIG_MMU -#ifndef CONFIG_SUN3 + +#if defined(CONFIG_COLDFIRE) + +#include +#include +#include +#include + +#define NO_CONTEXT 256 +#define LAST_CONTEXT 255 +#define FIRST_CONTEXT 1 + +extern unsigned long context_map[]; +extern mm_context_t next_mmu_context; + +extern atomic_t nr_free_contexts; +extern struct mm_struct *context_mm[LAST_CONTEXT+1]; +extern void steal_context(void); + +static inline void get_mmu_context(struct mm_struct *mm) +{ + mm_context_t ctx; + + if (mm->context != NO_CONTEXT) + return; + while (atomic_dec_and_test_lt(&nr_free_contexts)) { + atomic_inc(&nr_free_contexts); + steal_context(); + } + ctx = next_mmu_context; + while (test_and_set_bit(ctx, context_map)) { + ctx = find_next_zero_bit(context_map, LAST_CONTEXT+1, ctx); + if (ctx > LAST_CONTEXT) + ctx = 0; + } + next_mmu_context = (ctx + 1) & LAST_CONTEXT; + mm->context = ctx; + context_mm[ctx] = mm; +} + +/* + * Set up the context for a new address space. + */ +#define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0) + +/* + * We're finished using the context for an address space. + */ +static inline void destroy_context(struct mm_struct *mm) +{ + if (mm->context != NO_CONTEXT) { + clear_bit(mm->context, context_map); + mm->context = NO_CONTEXT; + atomic_inc(&nr_free_contexts); + } +} + +static inline void set_context(mm_context_t context, pgd_t *pgd) +{ + __asm__ __volatile__ ("movec %0,%%asid" : : "d" (context)); +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + get_mmu_context(tsk->mm); + set_context(tsk->mm->context, next->pgd); +} + +/* + * After we have set current->mm to a new value, this activates + * the context for the new mm so we see the new mappings. + */ +static inline void activate_mm(struct mm_struct *active_mm, + struct mm_struct *mm) +{ + get_mmu_context(mm); + set_context(mm->context, mm->pgd); +} + +#define deactivate_mm(tsk, mm) do { } while (0) + +extern void mmu_context_init(void); +#define prepare_arch_switch(next) load_ksp_mmu(next) + +static inline void load_ksp_mmu(struct task_struct *task) +{ + unsigned long flags; + struct mm_struct *mm; + int asid; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + unsigned long mmuar; + + local_irq_save(flags); + mmuar = task->thread.ksp; + + /* Search for a valid TLB entry, if one is found, don't remap */ + mmu_write(MMUAR, mmuar); + mmu_write(MMUOR, MMUOR_STLB | MMUOR_ADR); + if (mmu_read(MMUSR) & MMUSR_HIT) + goto end; + + if (mmuar >= PAGE_OFFSET) { + mm = &init_mm; + } else { + pr_info("load_ksp_mmu: non-kernel mm found: 0x%p\n", task->mm); + mm = task->mm; + } + + if (!mm) + goto bug; + + pgd = pgd_offset(mm, mmuar); + if (pgd_none(*pgd)) + goto bug; + + pmd = pmd_offset(pgd, mmuar); + if (pmd_none(*pmd)) + goto bug; + + pte = (mmuar >= PAGE_OFFSET) ? pte_offset_kernel(pmd, mmuar) + : pte_offset_map(pmd, mmuar); + if (pte_none(*pte) || !pte_present(*pte)) + goto bug; + + set_pte(pte, pte_mkyoung(*pte)); + asid = mm->context & 0xff; + if (!pte_dirty(*pte) && mmuar <= PAGE_OFFSET) + set_pte(pte, pte_wrprotect(*pte)); + + mmu_write(MMUTR, (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) | + (((int)(pte->pte) & (int)CF_PAGE_MMUTR_MASK) + >> CF_PAGE_MMUTR_SHIFT) | MMUTR_V); + + mmu_write(MMUDR, (pte_val(*pte) & PAGE_MASK) | + ((pte->pte) & CF_PAGE_MMUDR_MASK) | MMUDR_SZ_8KB | MMUDR_X); + + mmu_write(MMUOR, MMUOR_ACC | MMUOR_UAA); + + goto end; + +bug: + pr_info("ksp load failed: mm=0x%p ksp=0x08%lx\n", mm, mmuar); +end: + local_irq_restore(flags); +} + +#elif defined(CONFIG_SUN3) +#include +#include + +extern unsigned long get_free_context(struct mm_struct *mm); +extern void clear_context(unsigned long context); + +/* set the context for a new task to unmapped */ +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + mm->context = SUN3_INVALID_CONTEXT; + return 0; +} + +/* find the context given to this process, and if it hasn't already + got one, go get one for it. */ +static inline void get_mmu_context(struct mm_struct *mm) +{ + if (mm->context == SUN3_INVALID_CONTEXT) + mm->context = get_free_context(mm); +} + +/* flush context if allocated... */ +static inline void destroy_context(struct mm_struct *mm) +{ + if (mm->context != SUN3_INVALID_CONTEXT) + clear_context(mm->context); +} + +static inline void activate_context(struct mm_struct *mm) +{ + get_mmu_context(mm); + sun3_put_context(mm->context); +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + activate_context(tsk->mm); +} + +#define deactivate_mm(tsk, mm) do { } while (0) + +static inline void activate_mm(struct mm_struct *prev_mm, + struct mm_struct *next_mm) +{ + activate_context(next_mm); +} + +#else #include #include @@ -103,55 +302,8 @@ static inline void activate_mm(struct mm_struct *prev_mm, switch_mm_0460(next_mm); } -#else /* CONFIG_SUN3 */ -#include -#include - -extern unsigned long get_free_context(struct mm_struct *mm); -extern void clear_context(unsigned long context); - -/* set the context for a new task to unmapped */ -static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - mm->context = SUN3_INVALID_CONTEXT; - return 0; -} - -/* find the context given to this process, and if it hasn't already - got one, go get one for it. */ -static inline void get_mmu_context(struct mm_struct *mm) -{ - if(mm->context == SUN3_INVALID_CONTEXT) - mm->context = get_free_context(mm); -} - -/* flush context if allocated... */ -static inline void destroy_context(struct mm_struct *mm) -{ - if(mm->context != SUN3_INVALID_CONTEXT) - clear_context(mm->context); -} - -static inline void activate_context(struct mm_struct *mm) -{ - get_mmu_context(mm); - sun3_put_context(mm->context); -} - -static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) -{ - activate_context(tsk->mm); -} - -#define deactivate_mm(tsk,mm) do { } while (0) - -static inline void activate_mm(struct mm_struct *prev_mm, - struct mm_struct *next_mm) -{ - activate_context(next_mm); -} - #endif + #else /* !CONFIG_MMU */ static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:53 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:53 +1000 Subject: [uClinux-dev] [PATCH 08/35] m68k: init the MMU hardware for the 54xx ColdFire In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-9-git-send-email-gerg@snapgear.com> From: Greg Ungerer The 54xx ColdFire CPU family has an internal MMU. Up to now though we have only supported running on them with the MMU disabled. Add code to the 54xx ColdFire init sequence to initialize the bootmem used by the usual MMU m68k code for paging init. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/platform/coldfire/head.S | 47 +++++++++++++++++++++++++++++++++++- 1 files changed, 46 insertions(+), 1 deletions(-) diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S index 0ed41ed..c3db70e 100644 --- a/arch/m68k/platform/coldfire/head.S +++ b/arch/m68k/platform/coldfire/head.S @@ -3,7 +3,7 @@ /* * head.S -- common startup code for ColdFire CPUs. * - * (C) Copyright 1999-2010, Greg Ungerer . + * (C) Copyright 1999-2011, Greg Ungerer . */ /*****************************************************************************/ @@ -13,6 +13,7 @@ #include #include #include +#include #include /*****************************************************************************/ @@ -135,6 +136,14 @@ _init_sp: __HEAD +#ifdef CONFIG_MMU +_start0: + jmp _start +.global kernel_pg_dir +.equ kernel_pg_dir,_start0 +.equ .,_start0+0x1000 +#endif + /* * This is the codes first entry point. This is where it all * begins... @@ -197,6 +206,26 @@ _start: movec %d0,%CACR nop +#ifdef CONFIG_MMU + /* + * Identity mapping for the kernel region. + */ + movel #(MMUBASE+1),%d0 /* enable MMUBAR registers */ + movec %d0,%MMUBAR + movel #MMUOR_CA,%d0 /* clear TLB entries */ + movel %d0,MMUOR + movel #0,%d0 /* set ASID to 0 */ + movec %d0,%asid + + movel #MMUCR_EN,%d0 /* Enable the identity map */ + movel %d0,MMUCR + nop /* sync i-pipeline */ + + movel #_vstart,%a0 /* jump to "virtual" space */ + jmp %a0@ +_vstart: +#endif /* CONFIG_MMU */ + #ifdef CONFIG_ROMFS_FS /* * Move ROM filesystem above bss :-) @@ -242,6 +271,22 @@ _clear_bss: lea init_thread_union,%a0 lea THREAD_SIZE(%a0),%sp +#ifdef CONFIG_MMU +.global m68k_cputype +.global m68k_mmutype +.global m68k_fputype +.global m68k_machtype + movel #CPU_COLDFIRE,%d0 + movel %d0,m68k_cputype /* Mark us as a ColdFire */ + movel #MMU_COLDFIRE,%d0 + movel %d0,m68k_mmutype + movel #FPU_COLDFIRE,%d0 + movel %d0,m68k_fputype + movel #MACH_M54XX,%d0 + movel %d0,m68k_machtype /* Mark us as a 54xx machine */ + lea init_task,%a2 /* Set "current" init task */ +#endif + /* * Assember start up done, start code proper. */ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:03 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:03 +1000 Subject: [uClinux-dev] [PATCH 18/35] m68k: set ColdFire MMU page size In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-19-git-send-email-gerg@snapgear.com> From: Greg Ungerer We use the ColdFire V4e MMU page size of 8KiB. Define PAGE_SHIFT appropriately. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/page.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h index dfebb7c..e8aef81 100644 --- a/arch/m68k/include/asm/page.h +++ b/arch/m68k/include/asm/page.h @@ -6,10 +6,10 @@ #include /* PAGE_SHIFT determines the page size */ -#ifndef CONFIG_SUN3 -#define PAGE_SHIFT (12) +#if defined(CONFIG_SUN3) || defined(CONFIG_COLDFIRE) +#define PAGE_SHIFT 13 #else -#define PAGE_SHIFT (13) +#define PAGE_SHIFT 12 #endif #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:57 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:57 +1000 Subject: [uClinux-dev] [PATCH 12/35] m68k: add page table size definitions for ColdFire V4e MMU In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-13-git-send-email-gerg@snapgear.com> From: Greg Ungerer Define the page table size and attributes for the ColdFire V4e MMU. Also setup the vmalloc and kmap regions we will use. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/pgtable_mm.h | 30 ++++++++++++++++++++++++------ 1 files changed, 24 insertions(+), 6 deletions(-) diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h index 87174c9..d76d596 100644 --- a/arch/m68k/include/asm/pgtable_mm.h +++ b/arch/m68k/include/asm/pgtable_mm.h @@ -40,6 +40,8 @@ /* PGDIR_SHIFT determines what a third-level page table entry can map */ #ifdef CONFIG_SUN3 #define PGDIR_SHIFT 17 +#elif defined(CONFIG_COLDFIRE) +#define PGDIR_SHIFT 22 #else #define PGDIR_SHIFT 25 #endif @@ -54,6 +56,10 @@ #define PTRS_PER_PTE 16 #define PTRS_PER_PMD 1 #define PTRS_PER_PGD 2048 +#elif defined(CONFIG_COLDFIRE) +#define PTRS_PER_PTE 512 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 1024 #else #define PTRS_PER_PTE 1024 #define PTRS_PER_PMD 8 @@ -66,12 +72,22 @@ #ifdef CONFIG_SUN3 #define KMAP_START 0x0DC00000 #define KMAP_END 0x0E000000 +#elif defined(CONFIG_COLDFIRE) +#define KMAP_START 0xd8000000 +#define KMAP_END 0xe0000000 #else #define KMAP_START 0xd0000000 #define KMAP_END 0xf0000000 #endif -#ifndef CONFIG_SUN3 +#ifdef CONFIG_SUN3 +extern unsigned long m68k_vmalloc_end; +#define VMALLOC_START 0x0f800000 +#define VMALLOC_END m68k_vmalloc_end +#elif defined(CONFIG_COLDFIRE) +#define VMALLOC_START 0xd0000000 +#define VMALLOC_END 0xd8000000 +#else /* Just any arbitrary offset to the start of the vmalloc VM area: the * current 8MB value just means that there will be a 8MB "hole" after the * physical memory until the kernel virtual memory starts. That means that @@ -82,11 +98,7 @@ #define VMALLOC_OFFSET (8*1024*1024) #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) #define VMALLOC_END KMAP_START -#else -extern unsigned long m68k_vmalloc_end; -#define VMALLOC_START 0x0f800000 -#define VMALLOC_END m68k_vmalloc_end -#endif /* CONFIG_SUN3 */ +#endif /* zero page used for uninitialized stuff */ extern void *empty_zero_page; @@ -130,6 +142,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, #ifdef CONFIG_SUN3 #include +#elif defined(CONFIG_COLDFIRE) +#include #else #include #endif @@ -138,6 +152,9 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, /* * Macro to mark a page protection value as "uncacheable". */ +#ifdef CONFIG_COLDFIRE +# define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | CF_PAGE_NOCACHE)) +#else #ifdef SUN3_PAGE_NOCACHE # define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE #else @@ -152,6 +169,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ : (prot))) +#endif /* CONFIG_COLDFIRE */ #include #endif /* !__ASSEMBLY__ */ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:55 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:55 +1000 Subject: [uClinux-dev] [PATCH 10/35] m68k: set register a2 to current if MMU enabled on ColdFire In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-11-git-send-email-gerg@snapgear.com> From: Greg Ungerer Virtual memory m68k systems build with register a2 dedicated to being the current proc pointer (non-MMU don't do this). Add code to the ColdFire interrupt and exception processing to set this on entry, and at context switch time. We use the same GET_CURRENT() macro that MMU enabled code uses - modifying it so that the assembler is ColdFire clean. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/entry.h | 10 +++++++++- arch/m68k/kernel/entry_no.S | 3 +++ arch/m68k/platform/coldfire/entry.S | 6 +++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/m68k/include/asm/entry.h b/arch/m68k/include/asm/entry.h index c3c5a86..c717f57 100644 --- a/arch/m68k/include/asm/entry.h +++ b/arch/m68k/include/asm/entry.h @@ -222,16 +222,24 @@ * Non-MMU systems do not reserve %a2 in this way, and this definition is * not used for them. */ +#ifdef CONFIG_MMU + #define curptr a2 #define GET_CURRENT(tmp) get_current tmp .macro get_current reg=%d0 movel %sp,\reg - andw #-THREAD_SIZE,\reg + andl #-THREAD_SIZE,\reg movel \reg,%curptr movel %curptr@,%curptr .endm +#else + +#define GET_CURRENT(tmp) + +#endif /* CONFIG_MMU */ + #else /* C source */ #define STR(X) STR1(X) diff --git a/arch/m68k/kernel/entry_no.S b/arch/m68k/kernel/entry_no.S index ac86a9f..d80cba4 100644 --- a/arch/m68k/kernel/entry_no.S +++ b/arch/m68k/kernel/entry_no.S @@ -44,6 +44,7 @@ ENTRY(buserr) SAVE_ALL_INT + GET_CURRENT(%d0) movel %sp,%sp at - /* stack frame pointer argument */ jsr buserr_c addql #4,%sp @@ -51,6 +52,7 @@ ENTRY(buserr) ENTRY(trap) SAVE_ALL_INT + GET_CURRENT(%d0) movel %sp,%sp at - /* stack frame pointer argument */ jsr trap_c addql #4,%sp @@ -61,6 +63,7 @@ ENTRY(trap) .globl dbginterrupt ENTRY(dbginterrupt) SAVE_ALL_INT + GET_CURRENT(%d0) movel %sp,%sp at - /* stack frame pointer argument */ jsr dbginterrupt_c addql #4,%sp diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S index f567a16..863889f 100644 --- a/arch/m68k/platform/coldfire/entry.S +++ b/arch/m68k/platform/coldfire/entry.S @@ -62,6 +62,7 @@ enosys: ENTRY(system_call) SAVE_ALL_SYS move #0x2000,%sr /* enable intrs again */ + GET_CURRENT(%d2) cmpl #NR_syscalls,%d0 jcc enosys @@ -165,6 +166,7 @@ Lsignal_return: */ ENTRY(inthandler) SAVE_ALL_INT + GET_CURRENT(%d2) movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */ andl #0x03fc,%d0 /* mask out vector only */ @@ -190,7 +192,9 @@ ENTRY(resume) movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */ RDUSP /* movel %usp,%a3 */ movel %a3,%a0@(TASK_THREAD+THREAD_USP) /* save thread user stack */ - +#ifdef CONFIG_MMU + movel %a1,%a2 /* set new current */ +#endif movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore thread user stack */ WRUSP /* movel %a3,%usp */ movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new kernel stack */ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:40:59 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:40:59 +1000 Subject: [uClinux-dev] [PATCH 14/35] m68k: add cache support for V4e ColdFire cores running with MMU enabled In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-15-git-send-email-gerg@snapgear.com> From: Greg Ungerer Add code to deal with instruction, data and branch caches of the V4e ColdFire cores when they are running with the MMU enabled. This code is loosely based on Freescales changes for the caches of the V4e ColdFire in the 2.6.25 kernel BSP. That code is listed as being by Kurt Mahan . Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/cacheflush_mm.h | 88 +++++++++++++++++++++++++++++++-- arch/m68k/mm/cache.c | 24 ++++++++- 2 files changed, 104 insertions(+), 8 deletions(-) diff --git a/arch/m68k/include/asm/cacheflush_mm.h b/arch/m68k/include/asm/cacheflush_mm.h index 73de7c8..8104bd8 100644 --- a/arch/m68k/include/asm/cacheflush_mm.h +++ b/arch/m68k/include/asm/cacheflush_mm.h @@ -2,23 +2,89 @@ #define _M68K_CACHEFLUSH_H #include +#ifdef CONFIG_COLDFIRE +#include +#endif /* cache code */ #define FLUSH_I_AND_D (0x00000808) #define FLUSH_I (0x00000008) +#ifndef ICACHE_MAX_ADDR +#define ICACHE_MAX_ADDR 0 +#define ICACHE_SET_MASK 0 +#define DCACHE_MAX_ADDR 0 +#define DCACHE_SETMASK 0 +#endif + +static inline void flush_cf_icache(unsigned long start, unsigned long end) +{ + unsigned long set; + + for (set = start; set <= end; set += (0x10 - 3)) { + __asm__ __volatile__ ( + "cpushl %%ic,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%ic,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%ic,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%ic,(%0)" + : "=a" (set) + : "a" (set)); + } +} + +static inline void flush_cf_dcache(unsigned long start, unsigned long end) +{ + unsigned long set; + + for (set = start; set <= end; set += (0x10 - 3)) { + __asm__ __volatile__ ( + "cpushl %%dc,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%dc,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%dc,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%dc,(%0)" + : "=a" (set) + : "a" (set)); + } +} + +static inline void flush_cf_bcache(unsigned long start, unsigned long end) +{ + unsigned long set; + + for (set = start; set <= end; set += (0x10 - 3)) { + __asm__ __volatile__ ( + "cpushl %%bc,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%bc,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%bc,(%0)\n\t" + "addq%.l #1,%0\n\t" + "cpushl %%bc,(%0)" + : "=a" (set) + : "a" (set)); + } +} + /* * Cache handling functions */ static inline void flush_icache(void) { - if (CPU_IS_040_OR_060) + if (CPU_IS_COLDFIRE) { + flush_cf_icache(0, ICACHE_MAX_ADDR); + } else if (CPU_IS_040_OR_060) { asm volatile ( "nop\n" " .chip 68040\n" " cpusha %bc\n" " .chip 68k"); - else { + } else { unsigned long tmp; asm volatile ( "movec %%cacr,%0\n" " or.w %1,%0\n" @@ -51,12 +117,14 @@ extern void cache_push_v(unsigned long vaddr, int len); process changes. */ #define __flush_cache_all() \ ({ \ - if (CPU_IS_040_OR_060) \ + if (CPU_IS_COLDFIRE) { \ + flush_cf_dcache(0, DCACHE_MAX_ADDR); \ + } else if (CPU_IS_040_OR_060) { \ __asm__ __volatile__("nop\n\t" \ ".chip 68040\n\t" \ "cpusha %dc\n\t" \ ".chip 68k"); \ - else { \ + } else { \ unsigned long _tmp; \ __asm__ __volatile__("movec %%cacr,%0\n\t" \ "orw %1,%0\n\t" \ @@ -112,7 +180,17 @@ static inline void flush_cache_page(struct vm_area_struct *vma, unsigned long vm /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ static inline void __flush_page_to_ram(void *vaddr) { - if (CPU_IS_040_OR_060) { + if (CPU_IS_COLDFIRE) { + unsigned long addr, start, end; + addr = ((unsigned long) vaddr) & ~(PAGE_SIZE - 1); + start = addr & ICACHE_SET_MASK; + end = (addr + PAGE_SIZE - 1) & ICACHE_SET_MASK; + if (start > end) { + flush_cf_bcache(0, end); + end = ICACHE_MAX_ADDR; + } + flush_cf_bcache(start, end); + } else if (CPU_IS_040_OR_060) { __asm__ __volatile__("nop\n\t" ".chip 68040\n\t" "cpushp %%bc,(%0)\n\t" diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c index 5437fff..95d0bf6 100644 --- a/arch/m68k/mm/cache.c +++ b/arch/m68k/mm/cache.c @@ -74,8 +74,16 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr) /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ void flush_icache_range(unsigned long address, unsigned long endaddr) { - - if (CPU_IS_040_OR_060) { + if (CPU_IS_COLDFIRE) { + unsigned long start, end; + start = address & ICACHE_SET_MASK; + end = endaddr & ICACHE_SET_MASK; + if (start > end) { + flush_cf_icache(0, end); + end = ICACHE_MAX_ADDR; + } + flush_cf_icache(start, end); + } else if (CPU_IS_040_OR_060) { address &= PAGE_MASK; do { @@ -100,7 +108,17 @@ EXPORT_SYMBOL(flush_icache_range); void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, int len) { - if (CPU_IS_040_OR_060) { + if (CPU_IS_COLDFIRE) { + unsigned long start, end; + start = addr & ICACHE_SET_MASK; + end = (addr + len) & ICACHE_SET_MASK; + if (start > end) { + flush_cf_icache(0, end); + end = ICACHE_MAX_ADDR; + } + flush_cf_icache(start, end); + + } else if (CPU_IS_040_OR_060) { asm volatile ("nop\n\t" ".chip 68040\n\t" "cpushp %%bc,(%0)\n\t" -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:00 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:00 +1000 Subject: [uClinux-dev] [PATCH 15/35] m68k: modify ColdFire 54xx cache support for MMU enabled In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-16-git-send-email-gerg@snapgear.com> From: Greg Ungerer Modify the cache setup for the ColdFire 54xx parts when running with the MMU enabled. We want to map the peripheral register space (MBAR region) as non cacheable. And create an identity mapping for all of RAM for the kernel. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/m54xxacr.h | 32 +++++++++++++++++++++++++++++++- 1 files changed, 31 insertions(+), 1 deletions(-) diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h index 16a1835..47906aa 100644 --- a/arch/m68k/include/asm/m54xxacr.h +++ b/arch/m68k/include/asm/m54xxacr.h @@ -39,8 +39,12 @@ #define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */ #define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */ #define ACR_CM 0x00000060 /* Cache mode mask */ +#define ACR_SP 0x00000008 /* Supervisor protect */ #define ACR_WPROTECT 0x00000004 /* Write protect */ +#define ACR_BA(x) ((x) & 0xff000000) +#define ACR_ADMSK(x) ((((x) - 1) & 0xff000000) >> 8) + #if defined(CONFIG_M5407) #define ICACHE_SIZE 0x4000 /* instruction - 16k */ @@ -56,6 +60,11 @@ #define CACHE_LINE_SIZE 0x0010 /* 16 bytes */ #define CACHE_WAYS 4 /* 4 ways */ +#define ICACHE_SET_MASK ((ICACHE_SIZE / 64 - 1) << CACHE_WAYS) +#define DCACHE_SET_MASK ((DCACHE_SIZE / 64 - 1) << CACHE_WAYS) +#define ICACHE_MAX_ADDR ICACHE_SET_MASK +#define DCACHE_MAX_ADDR DCACHE_SET_MASK + /* * Version 4 cores have a true harvard style separate instruction * and data cache. Enable data and instruction caches, also enable write @@ -73,6 +82,27 @@ #else #define CACHE_MODE (CACR_DEC+CACR_DESB+CACR_DDCM_P+CACR_BEC+CACR_IEC+CACR_EUSP) #endif +#define CACHE_INIT (CACR_DCINVA+CACR_BCINVA+CACR_ICINVA) + +#if defined(CONFIG_MMU) +/* + * If running with the MMU enabled then we need to map the internal + * register region as non-cacheable. And then we map all our RAM as + * cacheable and supervisor access only. + */ +#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \ + ACR_ENABLE+ACR_SUPER+ACR_CM_OFF_PRE+ACR_SP) +#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \ + ACR_ENABLE+ACR_SUPER+ACR_SP) +#define ACR2_MODE 0 +#define ACR3_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \ + ACR_ENABLE+ACR_SUPER+ACR_SP) + +#else + +/* + * For the non-MMU enabled case we map all of RAM as cacheable. + */ #if defined(CONFIG_CACHE_COPYBACK) #define DATA_CACHE_MODE (ACR_ENABLE+ACR_ANY+ACR_CM_CP) #else @@ -80,7 +110,6 @@ #endif #define INSN_CACHE_MODE (ACR_ENABLE+ACR_ANY) -#define CACHE_INIT (CACR_DCINVA+CACR_BCINVA+CACR_ICINVA) #define CACHE_INVALIDATE (CACHE_MODE+CACR_DCINVA+CACR_BCINVA+CACR_ICINVA) #define CACHE_INVALIDATEI (CACHE_MODE+CACR_BCINVA+CACR_ICINVA) #define CACHE_INVALIDATED (CACHE_MODE+CACR_DCINVA) @@ -94,4 +123,5 @@ #define CACHE_PUSH #endif +#endif /* CONFIG_MMU */ #endif /* m54xxacr_h */ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:02 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:02 +1000 Subject: [uClinux-dev] [PATCH 17/35] m68k: define PAGE_OFFSET_RAW for ColdFire CPU with MMU enabled In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-18-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire CPU configurations need PAGE_OFFSET_RAW set to the base of their RAM. It doesn't matter if they are running with the MMU enabled or disabled, it is always set to the base of RAM. We can keep the choices simple here and key of CONFIG_RAMBASE. If it is defined we are on a plaftorm (ColdFire or other non-MMU systems) which have a configurable RAM base, just use it. Reported-by: Alexander Stein Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/page_offset.h | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/m68k/include/asm/page_offset.h b/arch/m68k/include/asm/page_offset.h index 1780152..a53d7f1 100644 --- a/arch/m68k/include/asm/page_offset.h +++ b/arch/m68k/include/asm/page_offset.h @@ -1,11 +1,9 @@ /* This handles the memory map.. */ -#ifdef CONFIG_MMU -#ifndef CONFIG_SUN3 +#if defined(CONFIG_RAMBASE) +#define PAGE_OFFSET_RAW CONFIG_RAMBASE +#elif !defined(CONFIG_SUN3) #define PAGE_OFFSET_RAW 0x00000000 #else #define PAGE_OFFSET_RAW 0x0E000000 #endif -#else -#define PAGE_OFFSET_RAW CONFIG_RAMBASE -#endif -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:09 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:09 +1000 Subject: [uClinux-dev] [PATCH 24/35] m68k: ColdFire V4e MMU paging init code and miss handler In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-25-git-send-email-gerg@snapgear.com> From: Greg Ungerer The different ColdFire V4e MMU requires its own dedicated paging init code, and a TLB miss handler for its software driven TLB. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/mcfmmu.h | 10 +- arch/m68k/mm/mcfmmu.c | 219 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 4 deletions(-) create mode 100644 arch/m68k/mm/mcfmmu.c diff --git a/arch/m68k/include/asm/mcfmmu.h b/arch/m68k/include/asm/mcfmmu.h index 84b4c28..34c4240 100644 --- a/arch/m68k/include/asm/mcfmmu.h +++ b/arch/m68k/include/asm/mcfmmu.h @@ -92,14 +92,14 @@ #define MMUDR_PAN 10 /* Physical address */ #define MMUDR_PAMASK 0xfffffc00 /* PA mask */ -/* - * Simple access functions for the MMU registers. Nothing fancy - * currently required, just simple 32bit access. - */ #ifndef __ASSEMBLY__ #define CF_PAGE_PGNUM_MASK (PAGE_MASK) +/* + * Simple access functions for the MMU registers. Nothing fancy + * currently required, just simple 32bit access. + */ static inline u32 mmu_read(u32 a) { return *((volatile u32 *) a); @@ -111,6 +111,8 @@ static inline void mmu_write(u32 a, u32 v) __asm__ __volatile__ ("nop"); } +int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word); + #endif /****************************************************************************/ diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c new file mode 100644 index 0000000..7e7130b --- /dev/null +++ b/arch/m68k/mm/mcfmmu.c @@ -0,0 +1,219 @@ +/* + * Based upon linux/arch/m68k/mm/sun3mmu.c + * Based upon linux/arch/ppc/mm/mmu_context.c + * + * Implementations of mm routines specific to the Coldfire MMU. + * + * Copyright (c) 2008 Freescale Semiconductor, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_BLK_DEV_RAM +#include +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KMAPAREA(x) ((x >= VMALLOC_START) && (x < KMAP_END)) + +mm_context_t next_mmu_context; +unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1]; +atomic_t nr_free_contexts; +struct mm_struct *context_mm[LAST_CONTEXT+1]; +extern unsigned long num_pages; + +void free_initmem(void) +{ +} + +/* + * ColdFire paging_init derived from sun3. + */ +void __init paging_init(void) +{ + pgd_t *pg_dir; + pte_t *pg_table; + unsigned long address; + unsigned long next_pgtable; + unsigned long bootmem_end; + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long size; + enum zone_type zone; + int i; + + empty_zero_page = (void *)alloc_bootmem_pages(PAGE_SIZE); + memset((void *)empty_zero_page, 0, PAGE_SIZE); + + pg_dir = swapper_pg_dir; + memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir)); + + size = num_pages * sizeof(pte_t); + size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1); + next_pgtable = (unsigned long)alloc_bootmem_pages(size); + + bootmem_end = (next_pgtable + size + PAGE_SIZE) & PAGE_MASK; + pg_dir += PAGE_OFFSET >> PGDIR_SHIFT; + + address = PAGE_OFFSET; + while (address < (unsigned long)high_memory) { + pg_table = (pte_t *)next_pgtable; + next_pgtable += PTRS_PER_PTE * sizeof(pte_t); + pgd_val(*pg_dir) = (unsigned long) pg_table; + pg_dir++; + + /* now change pg_table to kernel virtual addresses */ + for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) { + pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT); + if (address >= (unsigned long)high_memory) + pte_val(pte) = 0; + + set_pte(pg_table, pte); + address += PAGE_SIZE; + } + } + + current->mm = NULL; + + /* clear zones */ + for (zone = 0; zone < MAX_NR_ZONES; zone++) + zones_size[zone] = 0x0; + + zones_size[ZONE_DMA] = (32*1024*1024) >> PAGE_SHIFT; + + /* allocate the rest to NORMAL - head.S marks them CACHE */ + zones_size[ZONE_NORMAL] = + (((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT) - + zones_size[0]; + + free_area_init(zones_size); +} + +int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word) +{ + unsigned long flags; + unsigned long mmuar; + struct mm_struct *mm; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + int asid; + + local_irq_save(flags); + + mmuar = (dtlb) ? mmu_read(MMUAR) : + regs->pc + (extension_word * sizeof(long)); + + mm = (!user_mode(regs) && KMAPAREA(mmuar)) ? &init_mm : current->mm; + if (!mm) { + local_irq_restore(flags); + return -1; + } + + pgd = pgd_offset(mm, mmuar); + if (pgd_none(*pgd)) { + local_irq_restore(flags); + return -1; + } + + pmd = pmd_offset(pgd, mmuar); + if (pmd_none(*pmd)) { + local_irq_restore(flags); + return -1; + } + + pte = (KMAPAREA(mmuar)) ? pte_offset_kernel(pmd, mmuar) + : pte_offset_map(pmd, mmuar); + if (pte_none(*pte) || !pte_present(*pte)) { + local_irq_restore(flags); + return -1; + } + + if (write) { + if (!pte_write(*pte)) { + local_irq_restore(flags); + return -1; + } + set_pte(pte, pte_mkdirty(*pte)); + } + + set_pte(pte, pte_mkyoung(*pte)); + asid = mm->context & 0xff; + if (!pte_dirty(*pte) && !KMAPAREA(mmuar)) + set_pte(pte, pte_wrprotect(*pte)); + + mmu_write(MMUTR, (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) | + (((int)(pte->pte) & (int)CF_PAGE_MMUTR_MASK) + >> CF_PAGE_MMUTR_SHIFT) | MMUTR_V); + + mmu_write(MMUDR, (pte_val(*pte) & PAGE_MASK) | + ((pte->pte) & CF_PAGE_MMUDR_MASK) | MMUDR_SZ_8KB | MMUDR_X); + + if (dtlb) + mmu_write(MMUOR, MMUOR_ACC | MMUOR_UAA); + else + mmu_write(MMUOR, MMUOR_ITLB | MMUOR_ACC | MMUOR_UAA); + + local_irq_restore(flags); + return 0; +} + + +/* + * Initialize the context management stuff. + * The following was taken from arch/ppc/mmu_context.c + */ +void __init mmu_context_init(void) +{ + /* + * Some processors have too few contexts to reserve one for + * init_mm, and require using context 0 for a normal task. + * Other processors reserve the use of context zero for the kernel. + * This code assumes FIRST_CONTEXT < 32. + */ + context_map[0] = (1 << FIRST_CONTEXT) - 1; + next_mmu_context = FIRST_CONTEXT; + atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1); +} + +/* + * Steal a context from a task that has one at the moment. + * This is only used on 8xx and 4xx and we presently assume that + * they don't do SMP. If they do then thicfpgalloc.hs will have to check + * whether the MM we steal is in use. + * We also assume that this is only used on systems that don't + * use an MMU hash table - this is true for 8xx and 4xx. + * This isn't an LRU system, it just frees up each context in + * turn (sort-of pseudo-random replacement :). This would be the + * place to implement an LRU scheme if anyone was motivated to do it. + * -- paulus + */ +void steal_context(void) +{ + struct mm_struct *mm; + /* free up context `next_mmu_context' */ + /* if we shouldn't free context 0, don't... */ + if (next_mmu_context < FIRST_CONTEXT) + next_mmu_context = FIRST_CONTEXT; + mm = context_mm[next_mmu_context]; + flush_tlb_mm(mm); + destroy_context(mm); +} + -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:04 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:04 +1000 Subject: [uClinux-dev] [PATCH 19/35] m68k: MMU enabled ColdFire needs 8k ELF alignment In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-20-git-send-email-gerg@snapgear.com> From: Greg Ungerer Like the SUN3 hardware MMU the ColdFire MMU uses 8k pages. So we want our ELF page size alingment to also be 8k. Modify the ELF alignment setting. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/elf.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h index 01c193d..e9b7cda 100644 --- a/arch/m68k/include/asm/elf.h +++ b/arch/m68k/include/asm/elf.h @@ -59,10 +59,10 @@ typedef struct user_m68kfp_struct elf_fpregset_t; is actually used on ASV. */ #define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0 -#ifndef CONFIG_SUN3 -#define ELF_EXEC_PAGESIZE 4096 -#else +#if defined(CONFIG_SUN3) || defined(CONFIG_COLDFIRE) #define ELF_EXEC_PAGESIZE 8192 +#else +#define ELF_EXEC_PAGESIZE 4096 #endif /* This is the location that an ET_DYN program is loaded if exec'ed. Typical -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:07 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:07 +1000 Subject: [uClinux-dev] [PATCH 22/35] m68k: modify cache push and clear code for ColdFire with MMU enable In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-23-git-send-email-gerg@snapgear.com> From: Greg Ungerer The cache push and clear code only need to flush the branch cache on the write-through cache setup of the ColdFire V4e with MMU enabled. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/mm/memory.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index 34c77ce..a5dbb74 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c @@ -203,7 +203,9 @@ static inline void pushcl040(unsigned long paddr) void cache_clear (unsigned long paddr, int len) { - if (CPU_IS_040_OR_060) { + if (CPU_IS_COLDFIRE) { + flush_cf_bcache(0, DCACHE_MAX_ADDR); + } else if (CPU_IS_040_OR_060) { int tmp; /* @@ -250,7 +252,9 @@ EXPORT_SYMBOL(cache_clear); void cache_push (unsigned long paddr, int len) { - if (CPU_IS_040_OR_060) { + if (CPU_IS_COLDFIRE) { + flush_cf_bcache(0, DCACHE_MAX_ADDR); + } else if (CPU_IS_040_OR_060) { int tmp = PAGE_SIZE; /* -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:06 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:06 +1000 Subject: [uClinux-dev] [PATCH 21/35] m68k: use tracehook_report_syscall_entry/exit for ColdFire MMU ptrace path In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-22-git-send-email-gerg@snapgear.com> From: Greg Ungerer The existing ColdFire code (which is all non-mmu) for system call entry and exit uses the more modern tracehook_report_syscall_entry()/exit() into the ptrace code. Now that we are supporting ColdFire with MMU we need the same hooks for these. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/ptrace_mm.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/arch/m68k/kernel/ptrace_mm.c b/arch/m68k/kernel/ptrace_mm.c index 0b25268..7bc999b 100644 --- a/arch/m68k/kernel/ptrace_mm.c +++ b/arch/m68k/kernel/ptrace_mm.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -275,3 +276,20 @@ asmlinkage void syscall_trace(void) current->exit_code = 0; } } + +#ifdef CONFIG_COLDFIRE +asmlinkage int syscall_trace_enter(void) +{ + int ret = 0; + + if (test_thread_flag(TIF_SYSCALL_TRACE)) + ret = tracehook_report_syscall_entry(task_pt_regs(current)); + return ret; +} + +asmlinkage void syscall_trace_leave(void) +{ + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(task_pt_regs(current), 0); +} +#endif /* CONFIG_COLDFIRE */ -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:11 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:11 +1000 Subject: [uClinux-dev] [PATCH 26/35] m68k: create ColdFire MMU pgalloc code In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-27-git-send-email-gerg@snapgear.com> From: Greg Ungerer Add code to support the ColdFire V4e MMU pgalloc functions. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/mcf_pgalloc.h | 102 +++++++++++++++++++++++++++++++++++ arch/m68k/include/asm/pgalloc.h | 4 +- 2 files changed, 105 insertions(+), 1 deletions(-) create mode 100644 arch/m68k/include/asm/mcf_pgalloc.h diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h new file mode 100644 index 0000000..313f3dd --- /dev/null +++ b/arch/m68k/include/asm/mcf_pgalloc.h @@ -0,0 +1,102 @@ +#ifndef M68K_MCF_PGALLOC_H +#define M68K_MCF_PGALLOC_H + +#include +#include + +extern inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + free_page((unsigned long) pte); +} + +extern const char bad_pmd_string[]; + +extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, + unsigned long address) +{ + unsigned long page = __get_free_page(GFP_DMA|__GFP_REPEAT); + + if (!page) + return NULL; + + memset((void *)page, 0, PAGE_SIZE); + return (pte_t *) (page); +} + +extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +#define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); }) +#define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); }) + +#define pte_alloc_one_fast(mm, addr) pte_alloc_one(mm, addr) + +#define pmd_populate(mm, pmd, page) (pmd_val(*pmd) = \ + (unsigned long)(page_address(page))) + +#define pmd_populate_kernel(mm, pmd, pte) (pmd_val(*pmd) = (unsigned long)(pte)) + +#define pmd_pgtable(pmd) pmd_page(pmd) + +static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page, + unsigned long address) +{ + __free_page(page); +} + +#define __pmd_free_tlb(tlb, pmd, address) do { } while (0) + +static inline struct page *pte_alloc_one(struct mm_struct *mm, + unsigned long address) +{ + struct page *page = alloc_pages(GFP_DMA|__GFP_REPEAT, 0); + pte_t *pte; + + if (!page) + return NULL; + + pte = kmap(page); + if (pte) { + clear_page(pte); + __flush_page_to_ram(pte); + flush_tlb_kernel_page(pte); + nocache_page(pte); + } + kunmap(page); + + return page; +} + +extern inline void pte_free(struct mm_struct *mm, struct page *page) +{ + __free_page(page); +} + +/* + * In our implementation, each pgd entry contains 1 pmd that is never allocated + * or freed. pgd_present is always 1, so this should never be called. -NL + */ +#define pmd_free(mm, pmd) BUG() + +static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) +{ + free_page((unsigned long) pgd); +} + +static inline pgd_t *pgd_alloc(struct mm_struct *mm) +{ + pgd_t *new_pgd; + + new_pgd = (pgd_t *)__get_free_page(GFP_DMA | __GFP_NOWARN); + if (!new_pgd) + return NULL; + memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE); + memset(new_pgd, 0, PAGE_OFFSET >> PGDIR_SHIFT); + return new_pgd; +} + +#define pgd_populate(mm, pmd, pte) BUG() + +#endif /* M68K_MCF_PGALLOC_H */ diff --git a/arch/m68k/include/asm/pgalloc.h b/arch/m68k/include/asm/pgalloc.h index c294aad..37bee7e 100644 --- a/arch/m68k/include/asm/pgalloc.h +++ b/arch/m68k/include/asm/pgalloc.h @@ -7,7 +7,9 @@ #ifdef CONFIG_MMU #include -#ifdef CONFIG_SUN3 +#if defined(CONFIG_COLDFIRE) +#include +#elif defined(CONFIG_SUN3) #include #else #include -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:12 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:12 +1000 Subject: [uClinux-dev] [PATCH 27/35] m68k: use non-MMU entry.S code when compiling for ColdFire CPU In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-28-git-send-email-gerg@snapgear.com> From: Greg Ungerer No matter whether we are configured for non-MMU or MMU enabled if we are compiling for ColdFire CPU we always use the entry_no.S code. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/entry.S | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 081cf96..b8daf64 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -1,4 +1,4 @@ -#ifdef CONFIG_MMU +#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) #include "entry_mm.S" #else #include "entry_no.S" -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:10 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:10 +1000 Subject: [uClinux-dev] [PATCH 25/35] m68k: compile appropriate mm arch files for ColdFire MMU support In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-26-git-send-email-gerg@snapgear.com> From: Greg Ungerer Create a config symbol to enable when using a ColdFire MMU. We then use that to only compile the necessary arch mm files. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/Kconfig | 5 ++++- arch/m68k/mm/Makefile | 8 +++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 5f860cf..330eb88 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -88,9 +88,12 @@ config MMU config MMU_MOTOROLA bool +config MMU_COLDFIRE + bool + config MMU_SUN3 bool - depends on MMU && !MMU_MOTOROLA + depends on MMU && !MMU_MOTOROLA && !MMU_COLDFIRE menu "Platform setup" diff --git a/arch/m68k/mm/Makefile b/arch/m68k/mm/Makefile index 09cadf1..cfbf320 100644 --- a/arch/m68k/mm/Makefile +++ b/arch/m68k/mm/Makefile @@ -4,6 +4,8 @@ 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 +obj-$(CONFIG_MMU) += cache.o fault.o +obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o hwtest.o +obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o hwtest.o +obj-$(CONFIG_MMU_COLDFIRE) += kmap.o memory.o mcfmmu.o + -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:08 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:08 +1000 Subject: [uClinux-dev] [PATCH 23/35] m68k: use ColdFire MMU read/write bit flags when ioremapping In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-24-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire MMU has separate read and write bits, unlike the m68k MMU's which have a single read-only bit. We need to make sure we have the read and write bits in the page table entry for ioremapped pages for ColdFire targets. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/mm/kmap.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index 6934584..4d08f98 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c @@ -172,6 +172,10 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla } } else { physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); +#ifdef CONFIG_COLDFIRE + /* ColdFire has separate read/write bits, not on by default */ + physaddr |= _PAGE_READWRITE; +#endif switch (cacheflag) { case IOMAP_NOCACHE_SER: case IOMAP_NOCACHE_NONSER: -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:13 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:13 +1000 Subject: [uClinux-dev] [PATCH 28/35] m68k: add code to setup a ColdFire 54xx platform when MMU enabled In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-29-git-send-email-gerg@snapgear.com> From: Greg Ungerer We use the same setup code for ColdFire MMU enabled platforms as standard m68k. So add support for it to setup our 54xx ColdFire platforms. They do not support the same bootinfo parsing as other m68k platforms. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/setup_mm.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c index 52e17d1..b3938ad 100644 --- a/arch/m68k/kernel/setup_mm.c +++ b/arch/m68k/kernel/setup_mm.c @@ -221,7 +221,8 @@ void __init setup_arch(char **cmdline_p) #endif /* The bootinfo is located right after the kernel bss */ - m68k_parse_bootinfo((const struct bi_record *)_end); + if (!CPU_IS_COLDFIRE) + m68k_parse_bootinfo((const struct bi_record *)_end); if (CPU_IS_040) m68k_is040or060 = 4; @@ -327,6 +328,11 @@ void __init setup_arch(char **cmdline_p) config_sun3x(); break; #endif +#ifdef CONFIG_COLDFIRE + case MACH_M54XX: + config_BSP(NULL, 0); + break; +#endif default: panic("No configuration setup"); } -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:16 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:16 +1000 Subject: [uClinux-dev] [PATCH 31/35] m68k: adjustments to stack frame for ColdFire with MMU enabled In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-32-git-send-email-gerg@snapgear.com> From: Greg Ungerer The exception return stack adjustment required by ColdFire when running with the MMU enabled is not completely identical to 680x0 processors. Specifically the format type 4 stack frame doesn't need any stack adjustment on exception return. And the ColdFire always must return with a frame type of 4, not 0. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/signal_mm.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c index a0afc23..5f6b3d0 100644 --- a/arch/m68k/kernel/signal_mm.c +++ b/arch/m68k/kernel/signal_mm.c @@ -56,7 +56,11 @@ static const int frame_extra_sizes[16] = { [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ [2] = sizeof(((struct frame *)0)->un.fmt2), [3] = sizeof(((struct frame *)0)->un.fmt3), +#ifdef CONFIG_COLDFIRE + [4] = 0, +#else [4] = sizeof(((struct frame *)0)->un.fmt4), +#endif [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ [7] = sizeof(((struct frame *)0)->un.fmt7), @@ -84,7 +88,11 @@ int handle_kernel_fault(struct pt_regs *regs) regs->stkadj = frame_extra_sizes[regs->format]; tregs = (struct pt_regs *)((long)regs + regs->stkadj); tregs->vector = regs->vector; +#ifdef CONFIG_COLDFIRE + tregs->format = 4; +#else tregs->format = 0; +#endif tregs->pc = fixup->fixup; tregs->sr = regs->sr; @@ -336,8 +344,12 @@ static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, regs->format = formatvec >> 12; regs->vector = formatvec & 0xfff; #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) - __asm__ __volatile__ - (" movel %0,%/a0\n\t" + __asm__ __volatile__ ( +#ifdef CONFIG_COLDFIRE + " movel %0,%/sp\n\t" + " bra ret_from_signal\n" +#else + " movel %0,%/a0\n\t" " subl %1,%/a0\n\t" /* make room on stack */ " movel %/a0,%/sp\n\t" /* set stack pointer */ /* move switch_stack and pt_regs */ @@ -350,6 +362,7 @@ static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, "2: movel %4 at +,%/a0 at +\n\t" " dbra %1,2b\n\t" " bral ret_from_signal\n" +#endif : /* no outputs, it doesn't ever return */ : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), "n" (frame_offset), "a" (buf + fsize/4) -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:15 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:15 +1000 Subject: [uClinux-dev] [PATCH 30/35] m68k: use non-MMU linker script for ColdFire MMU builds In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-31-git-send-email-gerg@snapgear.com> From: Greg Ungerer Use the non-MMU linker script for ColdFire builds when we are building for MMU enabled. The image layout is correct for loading on existing ColdFire dev boards. The only addition required to the current non-MMU linker script is to add support for the fixup section. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/vmlinux.lds.S | 2 +- arch/m68k/kernel/vmlinux.lds_no.S | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletions(-) diff --git a/arch/m68k/kernel/vmlinux.lds.S b/arch/m68k/kernel/vmlinux.lds.S index 030dabf..8405c58 100644 --- a/arch/m68k/kernel/vmlinux.lds.S +++ b/arch/m68k/kernel/vmlinux.lds.S @@ -1,4 +1,4 @@ -#ifdef CONFIG_MMU +#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) #include "vmlinux.lds_mm.S" #else #include "vmlinux.lds_no.S" diff --git a/arch/m68k/kernel/vmlinux.lds_no.S b/arch/m68k/kernel/vmlinux.lds_no.S index 4e23893..8e66ccb 100644 --- a/arch/m68k/kernel/vmlinux.lds_no.S +++ b/arch/m68k/kernel/vmlinux.lds_no.S @@ -69,6 +69,7 @@ SECTIONS { SCHED_TEXT LOCK_TEXT *(.text..lock) + *(.fixup) . = ALIGN(16); /* Exception table */ __start___ex_table = .; @@ -161,6 +162,13 @@ SECTIONS { _edata = . ; } > DATA + .m68k_fixup : { + __start_fixup = .; + *(.m68k_fixup) + __stop_fixup = .; + } > DATA + NOTES > DATA + .init.text : { . = ALIGN(PAGE_SIZE); __init_begin = .; -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:14 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:14 +1000 Subject: [uClinux-dev] [PATCH 29/35] m68k: ColdFire with MMU enabled uses same clocking code as non-MMU In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-30-git-send-email-gerg@snapgear.com> From: Greg Ungerer We want to use the same timer support code for ColdFire CPU's when running with MMU enabled or not. So use the same time_no.c code even when the MMU is enabled for ColdFire. This also means we do not want CONFIG_ARCH_USES_GETTIMEOFFSET set, since that code is only in time_mm.c. Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig | 2 +- arch/m68k/kernel/time.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 330eb88..81fdaa7 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -48,7 +48,7 @@ config TIME_LOW_RES default y config ARCH_USES_GETTIMEOFFSET - def_bool MMU + def_bool MMU && !COLDFIRE config NO_IOPORT def_bool y diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index a5cf40c..75ab79b 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c @@ -1,4 +1,4 @@ -#ifdef CONFIG_MMU +#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) #include "time_mm.c" #else #include "time_no.c" -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:18 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:18 +1000 Subject: [uClinux-dev] [PATCH 33/35] m68k: do not use m68k startup or interrupt code for ColdFire CPU's In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-34-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire CPUs have their own startup and interrupt code (in the platform/coldfire directory), and do not use the general m68k startup and interrupt code. So if CONFIG_COLDFIRE is true do not compile the general code for them. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/Makefile | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index ea0a396..a327816 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -4,13 +4,15 @@ extra-$(CONFIG_MMU) := head.o extra-$(CONFIG_SUN3) := sun3-head.o +extra-$(CONFIG_COLDFIRE):= extra-y += vmlinux.lds obj-y := entry.o init_task.o irq.o m68k_ksyms.o module.o process.o ptrace.o obj-y += setup.o signal.o sys_m68k.o syscalltable.o time.o traps.o +ifndef CONFIG_COLDFIRE obj-$(CONFIG_MMU) += ints.o vectors.o - +endif ifndef CONFIG_MMU_SUN3 obj-y += dma.o endif -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:17 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:17 +1000 Subject: [uClinux-dev] [PATCH 32/35] m68k: add ColdFire FPU support for the V4e ColdFire CPU's In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-33-git-send-email-gerg@snapgear.com> From: Greg Ungerer The V4e ColdFire CPU family also has an integrated FPU (as well as the MMU). So add code to support this hardware along side the existing m68k FPU code. The ColdFire FPU is of course different to all previous 68k FP units. It is close in operation to the 68060, but not completely compatible. The biggest issue to deal with is that the ColdFire FPU multi-move instructions are different. It does not support multi-moving the FP control registers, and the multi-move of the FP data registers uses a different instruction mnemonic. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/fpu.h | 2 + arch/m68k/kernel/process_mm.c | 59 ++++++++++++---- arch/m68k/kernel/setup_mm.c | 2 +- arch/m68k/kernel/signal_mm.c | 156 ++++++++++++++++++++++++++++------------- 4 files changed, 154 insertions(+), 65 deletions(-) diff --git a/arch/m68k/include/asm/fpu.h b/arch/m68k/include/asm/fpu.h index ffb6b8c..526db9d 100644 --- a/arch/m68k/include/asm/fpu.h +++ b/arch/m68k/include/asm/fpu.h @@ -12,6 +12,8 @@ #define FPSTATESIZE (96) #elif defined(CONFIG_M68KFPU_EMU) #define FPSTATESIZE (28) +#elif defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU) +#define FPSTATESIZE (16) #elif defined(CONFIG_M68060) #define FPSTATESIZE (12) #else diff --git a/arch/m68k/kernel/process_mm.c b/arch/m68k/kernel/process_mm.c index 58a3253..125f34e 100644 --- a/arch/m68k/kernel/process_mm.c +++ b/arch/m68k/kernel/process_mm.c @@ -172,9 +172,7 @@ void flush_thread(void) current->thread.fs = __USER_DS; if (!FPU_IS_EMU) - asm volatile (".chip 68k/68881\n\t" - "frestore %0@\n\t" - ".chip 68k" : : "a" (&zero)); + asm volatile ("frestore %0@" : : "a" (&zero) : "memory"); } /* @@ -248,11 +246,28 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, /* Copy the current fpu state */ asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory"); - if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) - asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t" - "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" - : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0]) - : "memory"); + if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) { + if (CPU_IS_COLDFIRE) { + asm volatile ("fmovemd %/fp0-%/fp7,%0\n\t" + "fmovel %/fpiar,%1\n\t" + "fmovel %/fpcr,%2\n\t" + "fmovel %/fpsr,%3" + : + : "m" (p->thread.fp[0]), + "m" (p->thread.fpcntl[0]), + "m" (p->thread.fpcntl[1]), + "m" (p->thread.fpcntl[2]) + : "memory"); + } else { + asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t" + "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" + : + : "m" (p->thread.fp[0]), + "m" (p->thread.fpcntl[0]) + : "memory"); + } + } + /* Restore the state in case the fpu was busy */ asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); } @@ -285,12 +300,28 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) return 0; - asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0" - :: "m" (fpu->fpcntl[0]) - : "memory"); - asm volatile ("fmovemx %/fp0-%/fp7,%0" - :: "m" (fpu->fpregs[0]) - : "memory"); + if (CPU_IS_COLDFIRE) { + asm volatile ("fmovel %/fpiar,%0\n\t" + "fmovel %/fpcr,%1\n\t" + "fmovel %/fpsr,%2\n\t" + "fmovemd %/fp0-%/fp7,%3" + : + : "m" (fpu->fpcntl[0]), + "m" (fpu->fpcntl[1]), + "m" (fpu->fpcntl[2]), + "m" (fpu->fpregs[0]) + : "memory"); + } else { + asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0" + : + : "m" (fpu->fpcntl[0]) + : "memory"); + asm volatile ("fmovemx %/fp0-%/fp7,%0" + : + : "m" (fpu->fpregs[0]) + : "memory"); + } + return 1; } EXPORT_SYMBOL(dump_fpu); diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c index b3938ad..d872ce4 100644 --- a/arch/m68k/kernel/setup_mm.c +++ b/arch/m68k/kernel/setup_mm.c @@ -236,7 +236,7 @@ void __init setup_arch(char **cmdline_p) * with them, we should add a test to check_bugs() below] */ #ifndef CONFIG_M68KFPU_EMU_ONLY /* clear the fpu if we have one */ - if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { + if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060|FPU_COLDFIRE)) { volatile int zero = 0; asm volatile ("frestore %0" : : "m" (zero)); } diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c index 5f6b3d0..9a827a5 100644 --- a/arch/m68k/kernel/signal_mm.c +++ b/arch/m68k/kernel/signal_mm.c @@ -203,7 +203,8 @@ static inline int restore_fpu_state(struct sigcontext *sc) if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { /* Verify the frame format. */ - if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version)) + if (!(CPU_IS_060 || CPU_IS_COLDFIRE) && + (sc->sc_fpstate[0] != fpu_version)) goto out; if (CPU_IS_020_OR_030) { if (m68k_fputype & FPU_68881 && @@ -222,19 +223,36 @@ static inline int restore_fpu_state(struct sigcontext *sc) sc->sc_fpstate[3] == 0x60 || sc->sc_fpstate[3] == 0xe0)) goto out; + } else if (CPU_IS_COLDFIRE) { + if (!(sc->sc_fpstate[0] == 0x00 || + sc->sc_fpstate[0] == 0x05 || + sc->sc_fpstate[0] == 0xe5)) + goto out; } else goto out; - __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %0,%%fp0-%%fp1\n\t" - "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" - ".chip 68k" - : /* no outputs */ - : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t" + "fmovel %1,%%fpcr\n\t" + "fmovel %2,%%fpsr\n\t" + "fmovel %3,%%fpiar" + : /* no outputs */ + : "m" (sc->sc_fpregs[0]), + "m" (sc->sc_fpcntl[0]), + "m" (sc->sc_fpcntl[1]), + "m" (sc->sc_fpcntl[2])); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %0,%%fp0-%%fp1\n\t" + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" + ".chip 68k" + : /* no outputs */ + : "m" (*sc->sc_fpregs), + "m" (*sc->sc_fpcntl)); + } } - __asm__ volatile (".chip 68k/68881\n\t" - "frestore %0\n\t" - ".chip 68k" : : "m" (*sc->sc_fpstate)); + + __asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate)); err = 0; out: @@ -249,7 +267,7 @@ out: static inline int rt_restore_fpu_state(struct ucontext __user *uc) { unsigned char fpstate[FPCONTEXT_SIZE]; - int context_size = CPU_IS_060 ? 8 : 0; + int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0); fpregset_t fpregs; int err = 1; @@ -268,10 +286,11 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc) if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) goto out; if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { - if (!CPU_IS_060) + if (!(CPU_IS_060 || CPU_IS_COLDFIRE)) context_size = fpstate[1]; /* Verify the frame format. */ - if (!CPU_IS_060 && (fpstate[0] != fpu_version)) + if (!(CPU_IS_060 || CPU_IS_COLDFIRE) && + (fpstate[0] != fpu_version)) goto out; if (CPU_IS_020_OR_030) { if (m68k_fputype & FPU_68881 && @@ -290,26 +309,42 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc) fpstate[3] == 0x60 || fpstate[3] == 0xe0)) goto out; + } else if (CPU_IS_COLDFIRE) { + if (!(fpstate[3] == 0x00 || + fpstate[3] == 0x05 || + fpstate[3] == 0xe5)) + goto out; } else goto out; if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, sizeof(fpregs))) goto out; - __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %0,%%fp0-%%fp7\n\t" - "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" - ".chip 68k" - : /* no outputs */ - : "m" (*fpregs.f_fpregs), - "m" (*fpregs.f_fpcntl)); + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fmovemd %0,%%fp0-%%fp7\n\t" + "fmovel %1,%%fpcr\n\t" + "fmovel %2,%%fpsr\n\t" + "fmovel %3,%%fpiar" + : /* no outputs */ + : "m" (fpregs.f_fpregs[0]), + "m" (fpregs.f_fpcntl[0]), + "m" (fpregs.f_fpcntl[1]), + "m" (fpregs.f_fpcntl[2])); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %0,%%fp0-%%fp7\n\t" + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" + ".chip 68k" + : /* no outputs */ + : "m" (*fpregs.f_fpregs), + "m" (*fpregs.f_fpcntl)); + } } if (context_size && __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, context_size)) goto out; - __asm__ volatile (".chip 68k/68881\n\t" - "frestore %0\n\t" - ".chip 68k" : : "m" (*fpstate)); + __asm__ volatile ("frestore %0" : : "m" (*fpstate)); err = 0; out: @@ -529,10 +564,7 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) return; } - __asm__ volatile (".chip 68k/68881\n\t" - "fsave %0\n\t" - ".chip 68k" - : : "m" (*sc->sc_fpstate) : "memory"); + __asm__ volatile ("fsave %0" : : "m" (*sc->sc_fpstate) : "memory"); if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { fpu_version = sc->sc_fpstate[0]; @@ -543,21 +575,35 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) if (*(unsigned short *) sc->sc_fpstate == 0x1f38) sc->sc_fpstate[0x38] |= 1 << 3; } - __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %%fp0-%%fp1,%0\n\t" - "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" - ".chip 68k" - : "=m" (*sc->sc_fpregs), - "=m" (*sc->sc_fpcntl) - : /* no inputs */ - : "memory"); + + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fmovemd %%fp0-%%fp1,%0\n\t" + "fmovel %%fpcr,%1\n\t" + "fmovel %%fpsr,%2\n\t" + "fmovel %%fpiar,%3" + : "=m" (sc->sc_fpregs[0]), + "=m" (sc->sc_fpcntl[0]), + "=m" (sc->sc_fpcntl[1]), + "=m" (sc->sc_fpcntl[2]) + : /* no inputs */ + : "memory"); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %%fp0-%%fp1,%0\n\t" + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" + ".chip 68k" + : "=m" (*sc->sc_fpregs), + "=m" (*sc->sc_fpcntl) + : /* no inputs */ + : "memory"); + } } } static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) { unsigned char fpstate[FPCONTEXT_SIZE]; - int context_size = CPU_IS_060 ? 8 : 0; + int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0); int err = 0; if (FPU_IS_EMU) { @@ -570,15 +616,12 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs * return err; } - __asm__ volatile (".chip 68k/68881\n\t" - "fsave %0\n\t" - ".chip 68k" - : : "m" (*fpstate) : "memory"); + __asm__ volatile ("fsave %0" : : "m" (*fpstate) : "memory"); err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { fpregset_t fpregs; - if (!CPU_IS_060) + if (!(CPU_IS_060 || CPU_IS_COLDFIRE)) context_size = fpstate[1]; fpu_version = fpstate[0]; if (CPU_IS_020_OR_030 && @@ -588,14 +631,27 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs * if (*(unsigned short *) fpstate == 0x1f38) fpstate[0x38] |= 1 << 3; } - __asm__ volatile (".chip 68k/68881\n\t" - "fmovemx %%fp0-%%fp7,%0\n\t" - "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" - ".chip 68k" - : "=m" (*fpregs.f_fpregs), - "=m" (*fpregs.f_fpcntl) - : /* no inputs */ - : "memory"); + if (CPU_IS_COLDFIRE) { + __asm__ volatile ("fmovemd %%fp0-%%fp7,%0\n\t" + "fmovel %%fpcr,%1\n\t" + "fmovel %%fpsr,%2\n\t" + "fmovel %%fpiar,%3" + : "=m" (fpregs.f_fpregs[0]), + "=m" (fpregs.f_fpcntl[0]), + "=m" (fpregs.f_fpcntl[1]), + "=m" (fpregs.f_fpcntl[2]) + : /* no inputs */ + : "memory"); + } else { + __asm__ volatile (".chip 68k/68881\n\t" + "fmovemx %%fp0-%%fp7,%0\n\t" + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" + ".chip 68k" + : "=m" (*fpregs.f_fpregs), + "=m" (*fpregs.f_fpcntl) + : /* no inputs */ + : "memory"); + } err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, sizeof(fpregs)); } @@ -693,7 +749,7 @@ static inline void push_cache (unsigned long vaddr) ".chip 68k" : : "a" (temp)); } - else { + else if (!CPU_IS_COLDFIRE) { /* * 68030/68020 have no writeback cache; * still need to clear icache. -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:20 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:20 +1000 Subject: [uClinux-dev] [PATCH 35/35] m68k: allow ColdFire 547x and 548x CPUs to be built with MMU enabled In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-36-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire 547x and 548x CPUs have internal MMU hardware. All code to support this is now in, so we can build kernels with it enabled. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/Kconfig.cpu | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 5ae1d63..a4c75ad 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -226,8 +226,8 @@ config M54xx config M547x bool "MCF547x" - depends on !MMU select COLDFIRE + select MMU_COLDFIRE if MMU select M54xx select HAVE_CACHE_CB select HAVE_MBAR @@ -236,8 +236,8 @@ config M547x config M548x bool "MCF548x" - depends on !MMU select COLDFIRE + select MMU_COLDFIRE if MMU select M54xx select HAVE_CACHE_CB select HAVE_MBAR -- 1.7.0.4 From gerg at snapgear.com Thu Nov 24 22:41:19 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 13:41:19 +1000 Subject: [uClinux-dev] [PATCH 34/35] m68k: add ColdFire with MMU enabled support to the m68k mem init code In-Reply-To: <1322192480-22822-1-git-send-email-gerg@snapgear.com> References: <1322192480-22822-1-git-send-email-gerg@snapgear.com> Message-ID: <1322192480-22822-35-git-send-email-gerg@snapgear.com> From: Greg Ungerer The ColdFire has similar setup requirements to the SUN3 code, so we use that. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/mm/init_mm.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/m68k/mm/init_mm.c b/arch/m68k/mm/init_mm.c index 85c5f0e..89f3b20 100644 --- a/arch/m68k/mm/init_mm.c +++ b/arch/m68k/mm/init_mm.c @@ -139,7 +139,7 @@ void __init mem_init(void) } } -#ifndef CONFIG_SUN3 +#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) /* insert pointer tables allocated so far into the tablelist */ init_pointer_table((unsigned long)kernel_pg_dir); for (i = 0; i < PTRS_PER_PGD; i++) { -- 1.7.0.4 From gerg at snapgear.com Fri Nov 25 01:47:55 2011 From: gerg at snapgear.com (gerg at snapgear.com) Date: Fri, 25 Nov 2011 16:47:55 +1000 Subject: [uClinux-dev] [PATCH] m68knommu: remove unused anchor.h include file Message-ID: <1322203675-26458-1-git-send-email-gerg@snapgear.com> From: Greg Ungerer The code that used the anchor.h include file has long been removed from the kernel. Remove it too. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/anchor.h | 112 ---------------------------------------- 1 files changed, 0 insertions(+), 112 deletions(-) delete mode 100644 arch/m68k/include/asm/anchor.h diff --git a/arch/m68k/include/asm/anchor.h b/arch/m68k/include/asm/anchor.h deleted file mode 100644 index 871c0d5..0000000 --- a/arch/m68k/include/asm/anchor.h +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************/ - -/* - * anchor.h -- Anchor CO-MEM Lite PCI host bridge part. - * - * (C) Copyright 2000, Moreton Bay (www.moreton.com.au) - */ - -/****************************************************************************/ -#ifndef anchor_h -#define anchor_h -/****************************************************************************/ - -/* - * Define basic addressing info. - */ -#if defined(CONFIG_M5407C3) -#define COMEM_BASE 0xFFFF0000 /* Base of CO-MEM address space */ -#define COMEM_IRQ 25 /* IRQ of anchor part */ -#else -#define COMEM_BASE 0x80000000 /* Base of CO-MEM address space */ -#define COMEM_IRQ 25 /* IRQ of anchor part */ -#endif - -/****************************************************************************/ - -/* - * 4-byte registers of CO-MEM, so adjust register addresses for - * easy access. Handy macro for word access too. - */ -#define LREG(a) ((a) >> 2) -#define WREG(a) ((a) >> 1) - - -/* - * Define base addresses within CO-MEM Lite register address space. - */ -#define COMEM_I2O 0x0000 /* I2O registers */ -#define COMEM_OPREGS 0x0400 /* Operation registers */ -#define COMEM_PCIBUS 0x2000 /* Direct access to PCI bus */ -#define COMEM_SHMEM 0x4000 /* Shared memory region */ - -#define COMEM_SHMEMSIZE 0x4000 /* Size of shared memory */ - - -/* - * Define CO-MEM Registers. - */ -#define COMEM_I2OHISR 0x0030 /* I2O host interrupt status */ -#define COMEM_I2OHIMR 0x0034 /* I2O host interrupt mask */ -#define COMEM_I2OLISR 0x0038 /* I2O local interrupt status */ -#define COMEM_I2OLIMR 0x003c /* I2O local interrupt mask */ -#define COMEM_IBFPFIFO 0x0040 /* I2O inbound free/post FIFO */ -#define COMEM_OBPFFIFO 0x0044 /* I2O outbound post/free FIFO */ -#define COMEM_IBPFFIFO 0x0048 /* I2O inbound post/free FIFO */ -#define COMEM_OBFPFIFO 0x004c /* I2O outbound free/post FIFO */ - -#define COMEM_DAHBASE 0x0460 /* Direct access base address */ - -#define COMEM_NVCMD 0x04a0 /* I2C serial command */ -#define COMEM_NVREAD 0x04a4 /* I2C serial read */ -#define COMEM_NVSTAT 0x04a8 /* I2C status */ - -#define COMEM_DMALBASE 0x04b0 /* DMA local base address */ -#define COMEM_DMAHBASE 0x04b4 /* DMA host base address */ -#define COMEM_DMASIZE 0x04b8 /* DMA size */ -#define COMEM_DMACTL 0x04bc /* DMA control */ - -#define COMEM_HCTL 0x04e0 /* Host control */ -#define COMEM_HINT 0x04e4 /* Host interrupt control/status */ -#define COMEM_HLDATA 0x04e8 /* Host to local data mailbox */ -#define COMEM_LINT 0x04f4 /* Local interrupt contole status */ -#define COMEM_LHDATA 0x04f8 /* Local to host data mailbox */ - -#define COMEM_LBUSCFG 0x04fc /* Local bus configuration */ - - -/* - * Commands and flags for use with Direct Access Register. - */ -#define COMEM_DA_IACK 0x00000000 /* Interrupt acknowledge (read) */ -#define COMEM_DA_SPCL 0x00000010 /* Special cycle (write) */ -#define COMEM_DA_MEMRD 0x00000004 /* Memory read cycle */ -#define COMEM_DA_MEMWR 0x00000004 /* Memory write cycle */ -#define COMEM_DA_IORD 0x00000002 /* I/O read cycle */ -#define COMEM_DA_IOWR 0x00000002 /* I/O write cycle */ -#define COMEM_DA_CFGRD 0x00000006 /* Configuration read cycle */ -#define COMEM_DA_CFGWR 0x00000006 /* Configuration write cycle */ - -#define COMEM_DA_ADDR(a) ((a) & 0xffffe000) - -#define COMEM_DA_OFFSET(a) ((a) & 0x00001fff) - - -/* - * The PCI bus will be limited in what slots will actually be used. - * Define valid device numbers for different boards. - */ -#if defined(CONFIG_M5407C3) -#define COMEM_MINDEV 14 /* Minimum valid DEVICE */ -#define COMEM_MAXDEV 14 /* Maximum valid DEVICE */ -#define COMEM_BRIDGEDEV 15 /* Slot bridge is in */ -#else -#define COMEM_MINDEV 0 /* Minimum valid DEVICE */ -#define COMEM_MAXDEV 3 /* Maximum valid DEVICE */ -#endif - -#define COMEM_MAXPCI (COMEM_MAXDEV+1) /* Maximum PCI devices */ - - -/****************************************************************************/ -#endif /* anchor_h */ -- 1.7.0.4 From richardcochran at gmail.com Fri Nov 25 03:09:11 2011 From: richardcochran at gmail.com (Richard Cochran) Date: Fri, 25 Nov 2011 09:09:11 +0100 Subject: [uClinux-dev] Re: bootloader for MCF5234BCC In-Reply-To: <20111120134212.GA24165@netboy.at.omicron.at> References: <20111120134212.GA24165@netboy.at.omicron.at> Message-ID: <20111125080911.GA1816@cherladcori01> On Sun, Nov 20, 2011 at 02:42:12PM +0100, Richard Cochran wrote: > I am working with the very latest mainstream Linux kernel on the > Freescale MCF5234BCC. The kernel boots file (if I hack the root device > in drivers/mtd/maps/uclinux.c). > > However, I am getting really tired of the dBUG thing. It only can > fetch an image via TFTP if I force the host NIC into 10 megabit mode. > I would really like to use a "real" bootloader, able to sent the > kernel command line, and working at 100 mbit Ethernet. > > What can you recommend? > > (It looks like u-boot does not directly support this CPU.) To answer my own question, u-boot does in fact support this board with M5235EVB_config. However, it did not compile at first because I was using the compiler from the uClinux website, namely m68k-uclinux-tools-20080626.sh. This compiler is too old to compile the current u-boot, but the latest Code Sourcery release does work fine. Thanks, Richard From phdm at macqel.be Fri Nov 25 11:58:21 2011 From: phdm at macqel.be (Philippe De Muyter) Date: Fri, 25 Nov 2011 17:58:21 +0100 Subject: [uClinux-dev] what do I need to do to get again the mails from the list ? Message-ID: <1322240301.7391.16.camel@frolo> Hello, As others, I do not receive any mails from the uclinux-dev at uclinux.org list. I am still subscribed: I have verified that by using the interface at http://mailman.uclinux.org/mailman/listinfo/uclinux-dev. What do I need to do to get again the mails from the list (I do already wait, but that's maybe not enough :)) Philippe From b.buettner at mkc-gmbh.de Tue Nov 29 07:45:34 2011 From: b.buettner at mkc-gmbh.de (=?ISO-8859-15?Q?MKC_GmbH_-_Bernd_B=FCttner?=) Date: Tue, 29 Nov 2011 13:45:34 +0100 Subject: [uClinux-dev] what do I need to do to get again the mails from the list ? Message-ID: <4ED4D3EE.1000801@mkc-gmbh.de> As Philippe mentioned before, there are a few people who don't receive mails anymore (like me). Is there a specific reason why these questions are never answered on the list? Are we on a blacklist? Even if the answer doesn't reach the questioner directly, it can be read through the archive. Bernd