You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
(12) |
May
(82) |
Jun
(72) |
Jul
(39) |
Aug
(104) |
Sep
(61) |
Oct
(55) |
Nov
(101) |
Dec
(48) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(52) |
Feb
(67) |
Mar
(18) |
Apr
(16) |
May
(33) |
Jun
(12) |
Jul
(102) |
Aug
(168) |
Sep
(65) |
Oct
(60) |
Nov
(43) |
Dec
(121) |
2002 |
Jan
(69) |
Feb
(32) |
Mar
(90) |
Apr
(59) |
May
(45) |
Jun
(43) |
Jul
(33) |
Aug
(21) |
Sep
(11) |
Oct
(20) |
Nov
(26) |
Dec
(3) |
2003 |
Jan
(12) |
Feb
(18) |
Mar
(11) |
Apr
(11) |
May
(41) |
Jun
(76) |
Jul
(77) |
Aug
(15) |
Sep
(38) |
Oct
(56) |
Nov
(19) |
Dec
(39) |
2004 |
Jan
(17) |
Feb
(52) |
Mar
(36) |
Apr
(34) |
May
(48) |
Jun
(85) |
Jul
(38) |
Aug
(42) |
Sep
(41) |
Oct
(77) |
Nov
(27) |
Dec
(19) |
2005 |
Jan
(32) |
Feb
(35) |
Mar
(29) |
Apr
(8) |
May
(7) |
Jun
(31) |
Jul
(46) |
Aug
(93) |
Sep
(65) |
Oct
(85) |
Nov
(219) |
Dec
(47) |
2006 |
Jan
(170) |
Feb
(103) |
Mar
(49) |
Apr
(43) |
May
(45) |
Jun
(29) |
Jul
(77) |
Aug
(82) |
Sep
(43) |
Oct
(45) |
Nov
(26) |
Dec
(85) |
2007 |
Jan
(42) |
Feb
(48) |
Mar
(64) |
Apr
(31) |
May
(88) |
Jun
(53) |
Jul
(175) |
Aug
(212) |
Sep
(91) |
Oct
(103) |
Nov
(110) |
Dec
(5) |
2008 |
Jan
(20) |
Feb
(11) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(5) |
Sep
(3) |
Oct
(12) |
Nov
|
Dec
|
From: Mitch D. <mj...@au...> - 2000-05-09 02:47:47
|
Hello, I'm sorry to ask such a stupid question, but I'm having trouble getting GDB to talk to my Hitachi MS7750SE01 SolutionEngine. When Greg and I did our work with the SH3 Hitachi Evaluation board, we found that gdb talked to the board by sending the HIMON monitor commands it understood. From memory, this is in gdb/sh-rom.c. It seems that the monitor on the SolutionEngine is different, or at least, the commands are different, and as a consequence, GDB does not want to talk to it. Can someone advise me on how I can get GDB to talk to the SolutionEngine, for loading images, setting memory and starting execution please? Any help most gratefully received. Thanks, Mitch. -- | mailto:mj...@au... | Not the official view of: | | mailto:mj...@al... | Australian Calculator Opn | | Certified Linux Evangelist! | Hewlett Packard Australia | |
From: kaz K. <kk...@rr...> - 2000-05-09 00:29:44
|
NIIBE Yutaka wrote: > And I'll add Kaz' network driver to CVS repository. I import it > almost "as is", to avoid confusion. But I think that it's better > to follow the coding standard of Linux community here. Specifically, > indentation and such. > > It's just a matter of taste, I don't care much, but this is the > co-operation, where some compromise is needed, I think. I agree. Some people are very sensitive about this matter. I hope it will be reformated so to follow the standard. > I don't have strong opinion about coding standard. When I wrote for > GNU Project, I follow the one of GNU, while I follow the Linux one, > when write to the kernel. I also have no strong opinion about it. When I write a file from the scratch, I follow my editor. I follow the way of the existing file when I modify it. Too stupid :-) kaz |
From: NIIBE Y. <gn...@ch...> - 2000-05-08 23:40:48
|
Toshinobu Sugioka found that checksum routine is broken in case of bigendian. I got the patch from him, still investigating. Partly, it is merged. More will follows this week. And I'll add Kaz' network driver to CVS repository. I import it almost "as is", to avoid confusion. But I think that it's better to follow the coding standard of Linux community here. Specifically, indentation and such. It's just a matter of taste, I don't care much, but this is the co-operation, where some compromise is needed, I think. I don't have strong opinion about coding standard. When I wrote for GNU Project, I follow the one of GNU, while I follow the Linux one, when write to the kernel. I'll commit this and stnic.c soon. -------------------------- 2000-05-08 NIIBE Yutaka <gn...@m1...> * drivers/net/stnic.c: New file by Kazmoto Kojima. (stnic_probe): Changed the prototype. (stnic_probe): Use new style probing API. * include/asm-sh/hitachi_se.h (IRQ_STNIC): Added. * arch/sh/kernel/time.c (time_init): New variable `bus_clock'. 2000-05-08 Toshinobu Sugioka <su...@it...> * include/asm-sh/checksum.h (csum_fold): Change the implementation for readability and in case it is used with no cast to ushort. * arch/sh/lib/checksum.S: Shift 8-bit when it's big endian. Index: arch/sh/kernel/time.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/time.c,v retrieving revision 1.7 diff -u -r1.7 time.c --- arch/sh/kernel/time.c 2000/05/03 01:34:46 1.7 +++ arch/sh/kernel/time.c 2000/05/08 23:29:25 @@ -383,14 +383,16 @@ void __init time_init(void) { - unsigned int cpu_clock, master_clock, module_clock; - unsigned short ifc, pfc; + unsigned int cpu_clock, master_clock, bus_clock, module_clock; + unsigned short frqcr, ifc, pfc; unsigned long interval; #if defined(__sh3__) static int ifc_table[] = { 1, 2, 4, 1, 3, 1, 1, 1 }; static int pfc_table[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; + static int sfc_table[] = { 1, 2, 3, 4, 6, 8, 1, 1 }; #elif defined(__SH4__) static int ifc_table[] = { 1, 2, 3, 4, 6, 8, 1, 1 }; +#define bfc_table ifc_table /* Same */ static int pfc_table[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; #endif @@ -408,19 +410,33 @@ (cpu_clock / 1000000), (cpu_clock % 1000000)/10000); #if defined(__sh3__) { - unsigned short tmp; - tmp = (ctrl_inw(FRQCR) & 0x000c) >> 2; - tmp |= (ctrl_inw(FRQCR) & 0x4000) >> 12; - ifc = ifc_table[tmp & 0x0007]; - tmp = ctrl_inw(FRQCR) & 0x0003; - tmp |= (ctrl_inw(FRQCR) & 0x2000) >> 11; - pfc = pfc_table[ctrl_inw(FRQCR) & 0x0007]; + unsigned short tmp, stc; + frqcr = ctrl_inw(FRQCR); + tmp = (frqcr & 0x8000) >> 13; + tmp |= (frqcr & 0x0030) >> 4; + stc = stc_table[tmp]; + tmp = (frqcr & 0x4000) >> 12; + tmp |= (frqcr & 0x000c) >> 2; + ifc = ifc_table[tmp]; + tmp = (frqcr & 0x2000) >> 11; + tmp |= frqcr & 0x0003; + pfc = pfc_table[tmp]; + master_clock = cpu_clock * ifc; + bus_clock = master_clock/sfc; } #elif defined(__SH4__) - ifc = ifc_table[(ctrl_inw(FRQCR)>> 6) & 0x0007]; - pfc = pfc_table[ctrl_inw(FRQCR) & 0x0007]; + { + unsigned short bfc; + frqcr = ctrl_inw(FRQCR); + ifc = ifc_table[(frqcr>> 6) & 0x0007]; + bfc = bfc_table[(frqcr>> 3) & 0x0007]; + pfc = pfc_table[frqcr & 0x0007]; + master_clock = cpu_clock * ifc; + bus_clock = master_clock/bfc; + } #endif - master_clock = cpu_clock * ifc; + printk("Bus clock: %d.%02dMHz\n", + (bus_clock/1000000), (bus_clock % 1000000)/10000); module_clock = master_clock/pfc; printk("Module clock: %d.%02dMHz\n", (module_clock/1000000), (module_clock % 1000000)/10000); Index: arch/sh/lib/checksum.S =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/lib/checksum.S,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 checksum.S --- arch/sh/lib/checksum.S 2000/04/14 16:49:01 1.1.1.1 +++ arch/sh/lib/checksum.S 2000/05/08 23:29:25 @@ -131,6 +131,9 @@ 7: mov.b @r4+,r0 extu.b r0,r0 +#ifndef __LITTLE_ENDIAN__ + shll8 r0 +#endif 8: addc r0,r6 mov #0,r0 @@ -167,6 +170,16 @@ .long 9999b, 6002f ; \ .previous +! +! r4: const char *SRC +! r5: char *DST +! r6: int LEN +! r7: int SUM +! +! on stack: +! int *SRC_ERR_PTR +! int *DST_ERR_PTR +! ENTRY(csum_partial_copy_generic) mov.l r5,@-r15 mov.l r6,@-r15 @@ -179,7 +192,7 @@ bt/s 1f clrt bra 4f - add #2,r6 ! ecx was < 2. Deal with it. + add #2,r6 ! $r6 was < 2. Deal with it. SRC(1: mov.w @r4+,r0 ) DST( mov.w r0,@r5 ) add #2,r5 Index: drivers/net/Config.in =================================================================== RCS file: /cvsroot/linuxsh/kernel/drivers/net/Config.in,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 Config.in --- drivers/net/Config.in 2000/04/14 17:36:02 1.1.1.2 +++ drivers/net/Config.in 2000/05/08 23:29:26 @@ -51,6 +51,9 @@ if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH fi + if [ "$CONFIG_SUPERH" = "y" -a "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then + tristate ' National DP83902AV support' CONFIG_STNIC + fi bool ' 3COM cards' CONFIG_NET_VENDOR_3COM if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then tristate ' 3c501 support' CONFIG_EL1 Index: drivers/net/Makefile =================================================================== RCS file: /cvsroot/linuxsh/kernel/drivers/net/Makefile,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 Makefile --- drivers/net/Makefile 2000/04/14 17:36:01 1.1.1.2 +++ drivers/net/Makefile 2000/05/08 23:29:26 @@ -146,6 +146,8 @@ obj-$(CONFIG_YELLOWFIN) += yellowfin.o obj-$(CONFIG_ACENIC) += acenic.o +obj-$(CONFIG_STNIC) += stnic.o 8390.o + ifeq ($(CONFIG_SK98LIN),y) SUB_DIRS += sk98lin obj-y += sk98lin/sk98lin.o Index: include/asm-sh/checksum.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/include/asm-sh/checksum.h,v retrieving revision 1.2 diff -u -r1.2 checksum.h --- include/asm-sh/checksum.h 2000/04/14 17:25:44 1.2 +++ include/asm-sh/checksum.h 2000/05/08 23:29:26 @@ -72,16 +72,17 @@ static __inline__ unsigned int csum_fold(unsigned int sum) { unsigned int __dummy; - __asm__("clrt\n\t" - "mov %0, %1\n\t" - "shll16 %0\n\t" - "addc %0, %1\n\t" - "movt %0\n\t" - "shlr16 %1\n\t" - "add %1, %0" + __asm__("swap.w %0, %1\n\t" + "extu.w %0, %0\n\t" + "extu.w %1, %1\n\t" + "add %1, %0\n\t" + "swap.w %0, %1\n\t" + "add %1, %0\n\t" + "not %0, %0\n\t" + "extu.w %0, %0" : "=r" (sum), "=&r" (__dummy) : "0" (sum)); - return ~sum; + return sum; } /* Index: include/asm-sh/hitachi_se.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/include/asm-sh/hitachi_se.h,v retrieving revision 1.1 diff -u -r1.1 hitachi_se.h --- include/asm-sh/hitachi_se.h 2000/05/03 02:24:42 1.1 +++ include/asm-sh/hitachi_se.h 2000/05/08 23:29:27 @@ -48,4 +48,6 @@ #define BCR_ILCRF (PA_BCR + 10) #define BCR_ILCRG (PA_BCR + 12) +#define IRQ_STNIC 10 + #endif /* __ASM_SH_HITACHI_SE_H */ |
From: NIIBE Y. <gn...@ch...> - 2000-05-06 07:31:33
|
With following change, integration of I/O handling is finished. For the type of PORT, it is intentionaly changed (from unsigned long to unsigned int) to detect the changes. I'll commit this soon. -------------------------- 2000-05-06 NIIBE Yutaka <gn...@m1...> * include/asm/io.h (outb, outb_p, outw, outl): Fix the prototype. * arch/sh/kernel/io_se.c (outb, outb_p, outw, outl): Follow the change of io.h. * arch/sh/kernel/io_generic.c (inb, inb_p, inw, inl, insb, insw, insl, outb, outb_p, outw, outl, outsb, outsw, outsl): Fix the prototype. * arch/sh/kernel/setup_se.c (init_smsc): Removed setting of POWER_CONTROL, since it is done by ACTIVATE. Index: arch/sh/kernel/io_generic.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/io_generic.c,v retrieving revision 1.2 diff -u -r1.2 io_generic.c --- arch/sh/kernel/io_generic.c 2000/05/03 08:13:34 1.2 +++ arch/sh/kernel/io_generic.c 2000/05/06 07:23:26 @@ -18,12 +18,12 @@ ctrl_inw(0xa0000000); } -unsigned long inb(unsigned long port) +unsigned long inb(unsigned int port) { return *(volatile unsigned char*)PORT2ADDR(port); } -unsigned long inb_p(unsigned long port) +unsigned long inb_p(unsigned int port) { unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); @@ -31,68 +31,68 @@ return v; } -unsigned long inw(unsigned long port) +unsigned long inw(unsigned int port) { return *(volatile unsigned short*)PORT2ADDR(port); } -unsigned long inl(unsigned long port) +unsigned long inl(unsigned int port) { return *(volatile unsigned long*)PORT2ADDR(port); } -void insb(unsigned long port, void *buffer, int count) +void insb(unsigned int port, void *buffer, unsigned long count) { unsigned char *buf=buffer; while(count--) *buf++=inb(port); } -void insw(unsigned long port, void *buffer, int count) +void insw(unsigned int port, void *buffer, unsigned long count) { unsigned short *buf=buffer; while(count--) *buf++=inw(port); } -void insl(unsigned long port, void *buffer, int count) +void insl(unsigned int port, void *buffer, unsigned long count) { unsigned long *buf=buffer; while(count--) *buf++=inl(port); } -void outb(unsigned char b, unsigned long port) +void outb(unsigned long b, unsigned int port) { *(volatile unsigned char*)PORT2ADDR(port) = b; } -void outb_p(unsigned char b, unsigned long port) +void outb_p(unsigned long b, unsigned int port) { *(volatile unsigned char*)PORT2ADDR(port) = b; delay(); } -void outw(unsigned short b, unsigned long port) +void outw(unsigned long b, unsigned int port) { *(volatile unsigned short*)PORT2ADDR(port) = b; } -void outl(unsigned int b, unsigned long port) +void outl(unsigned long b, unsigned int port) { *(volatile unsigned long*)PORT2ADDR(port) = b; } -void outsb(unsigned long port, const void *buffer, int count) +void outsb(unsigned int port, const void *buffer, unsigned long count) { const unsigned char *buf=buffer; while(count--) outb(*buf++, port); } -void outsw(unsigned long port, const void *buffer, int count) +void outsw(unsigned int port, const void *buffer, unsigned long count) { const unsigned short *buf=buffer; while(count--) outw(*buf++, port); } -void outsl(unsigned long port, const void *buffer, int count) +void outsl(unsigned int port, const void *buffer, unsigned long count) { const unsigned long *buf=buffer; while(count--) outl(*buf++, port); Index: arch/sh/kernel/io_se.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/io_se.c,v retrieving revision 1.3 diff -u -r1.3 io_se.c --- arch/sh/kernel/io_se.c 2000/05/03 08:49:58 1.3 +++ arch/sh/kernel/io_se.c 2000/05/06 07:23:26 @@ -97,7 +97,7 @@ return 0; } -void outb(unsigned int value, unsigned int port) +void outb(unsigned long value, unsigned int port) { if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) *(__u8 *)(sh_pcic_io_wbase + port) = value; @@ -107,7 +107,7 @@ *(port2adr(port)) = value; } -void outb_p(unsigned int value, unsigned int port) +void outb_p(unsigned long value, unsigned int port) { if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) *(__u8 *)(sh_pcic_io_wbase + port) = value; @@ -118,7 +118,7 @@ delay(); } -void outw(unsigned int value, unsigned int port) +void outw(unsigned long value, unsigned int port) { if (port >= 0x2000 || (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) @@ -127,7 +127,7 @@ maybebadio(outw, port); } -void outl(unsigned int value, unsigned int port) +void outl(unsigned long value, unsigned int port) { maybebadio(outl, port); } Index: arch/sh/kernel/setup_se.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/setup_se.c,v retrieving revision 1.4 diff -u -r1.4 setup_se.c --- arch/sh/kernel/setup_se.c 2000/05/05 03:46:03 1.4 +++ arch/sh/kernel/setup_se.c 2000/05/06 07:23:26 @@ -32,22 +32,6 @@ outb_p(CONFIG_ENTER, CONFIG_PORT); outb_p(CONFIG_ENTER, CONFIG_PORT); -#if defined(__sh3__) - /* SolutionEngine SH7709A has power control feature */ - /* It reads "FDC37C935APM" */ - /* - * b0: FDC - * b1: IDE1 - * b2: IDE2 - * b3: Parallel port - * b4: Serial port 1 - * b5: Serial port 2 - * b6: ACCESS.bus - * b7: ---- - */ - smsc_config(POWER_CONTROL_INDEX, 0x13); /* Power on! */ -#endif - /* FDC */ smsc_config(CURRENT_LDN_INDEX, LDN_FDC); smsc_config(ACTIVATE_INDEX, 0x01); @@ -70,7 +54,7 @@ smsc_config(ACTIVATE_INDEX, 0x01); smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */ - /* XXX: COM2, PARPORT, KBD, and MOUSE come here... */ + /* XXX: COM2, PARPORT, KBD, and MOUSE will come here... */ outb_p(CONFIG_EXIT, CONFIG_PORT); } @@ -103,7 +87,7 @@ set_ipr_data(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ - set_ipr_data( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ + set_ipr_data( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ set_ipr_data(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ set_ipr_data( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ set_ipr_data( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ Index: include/asm-sh/io.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/include/asm-sh/io.h,v retrieving revision 1.3 diff -u -r1.3 io.h --- include/asm-sh/io.h 2000/05/03 08:13:34 1.3 +++ include/asm-sh/io.h 2000/05/06 07:23:28 @@ -58,10 +58,10 @@ extern void insw(unsigned int port, void *addr, unsigned long count); extern void insl(unsigned int port, void *addr, unsigned long count); -extern void outb(unsigned int value, unsigned int port); -extern void outb_p(unsigned int value, unsigned int port); -extern void outw(unsigned int value, unsigned int port); -extern void outl(unsigned int value, unsigned int port); +extern void outb(unsigned long value, unsigned int port); +extern void outb_p(unsigned long value, unsigned int port); +extern void outw(unsigned long value, unsigned int port); +extern void outl(unsigned long value, unsigned int port); extern void outsb(unsigned int port, const void *addr, unsigned long count); extern void outsw(unsigned int port, const void *addr, unsigned long count); extern void outsl(unsigned int port, const void *addr, unsigned long count); |
From: kaz K. <kk...@rr...> - 2000-05-04 23:40:46
|
Hi Mitch, > Tomorrow Greg and I will (finally) put binutils/gcc/gdb etc > under CVS like we've done with the Linux kernel source. I > hope this makes it easier for new users, and smooths the way > to have the SuperH changes folded back into the official > versions. > > For this, we need to know the recommended base versions, patches, > procedure for building, etc. Please use the most recent versions. Currently you can get gcc: gcc-2.95.2 + gcc-2.95.2-000228.diff.gz gdb: gdb-4.18 + gdb-4.18-sh-linux-000110.diff.gz libc: glibc-2.1.3 + glibc-2.1.3-000427.diff.gz from my junkyard. About binutils, the combination binutils-000218.tar.bz2 + binutils-000218-000219.diff.gz + binutils-more-patch-000305 which can be get from Niibe-san's ftp machine, is recommended. There is a problem of the visibility of the symbols in libgcc.a at the bootstrap of ld.so and Niibe-san's gcc-patch for the symbol visibility ftp://ftp.m17n.org/pub/linux-sh/gcc-symbol-vis-000501.diff.gz solves it. Notice that it may be temporary since there is no rigid specification of the symbol visibility and its ABI. Now gcc guys discuss about the shared libgcc library. I think it will also solve the above problem. Anyway, we should wait a while. kaz |
From: <joh...@pr...> - 2000-05-04 18:42:07
|
OK - I downloaded gcc-core-2.95.1, binutils-991010, linux-2.2.3.99-pre3, and linux-sh-2000-03-25.diff. I installed, patched and built (used --target=sh-linux-elf) All built correctly except for the kernel, I get when compiling init/main.c - ..../include/asm/unistd.h:346: invalid register name "$r0" for register variable... I get a whole bunch like that. It is like the compiler is built/configured wrong, but...? I have tried target=sh-elf and sh-linux and sh-linux-gnu and same problems. I have read the howto and the readme's but they all refer to different versions of everything and the patches referred to seem dated. What am I screwing up here? Johnny ---------------------------------------------------------------- Get your free email from AltaVista at http://altavista.iname.com |
From: Mitch D. <mj...@hp...> - 2000-05-04 13:33:00
|
Dear Kaz (and others), Tomorrow Greg and I will (finally) put binutils/gcc/gdb etc under CVS like we've done with the Linux kernel source. I hope this makes it easier for new users, and smooths the way to have the SuperH changes folded back into the official versions. For this, we need to know the recommended base versions, patches, procedure for building, etc. If we don't hear anything, we will use the procedure and versions as outlined in the 7-Feb-2000 edition of Ludovic's FAQ. If you (or anyone else) thinks we should use some other version, patch, feature, aardvark, you name it, please let us know as soon as possible. Thanks, Mitch. -- | mailto:mj...@au... | Not the official view of: | | mailto:mj...@al... | Australian Calculator Opn | | Certified Linux Evangelist! | Hewlett Packard Australia | |
From: Mitch D. <mj...@au...> - 2000-05-03 05:10:38
|
Hello, At long last, here is my patch which add help for the SuperH kernel configuration options. This is probably going to clash with the most recent option changes such as the SolutionEngine options and the IPR stuff. https://sourceforge.net/patch/?func=detailpatch&patch_id=100343&group_id=2682 Note there are a couple of FIXMEs in the help. If people want to make the descriptions clearer (either before or after I check it in) please feel free. I think after checking this in, that resolving the conflicts for the new options won't be so hard. And in future if people change the available options, also keeping Configure.help up to date might be a good idea. If no-one objects, I'll check this in tomorrow. Regards, Mitch. -- | mailto:mj...@au... | Not the official view of: | | mailto:mj...@al... | Australian Calculator Opn | | Certified Linux Evangelist! | Hewlett Packard Australia | |
From: NIIBE Y. <gn...@ch...> - 2000-05-03 02:19:38
|
Here is new I/O support. I'm about to connect IDE disk to SolutionEngine on my desk. I'll commit this soon. 2000-05-03 NIIBE Yutaka <gn...@m1...> * arch/sh/config.in (CONFIG_IOPORT_START): New CONFIG variable. (CONFIG_CF_ENABLER): Conditionalize it (Not for SolutionEngine). * include/asm-sh/ide.h (ide_default_irq, ide_default_io_base): Use PORT, instead of ADDR. * include/asm-sh/io.h (inb_local, outb_local): Removed. (inb,inw,inl,insb,insw,insl,outb,outw,outl,outsb,outsw,outsl): Make them real function. (sh_isa_slot,isa_readb,isa_readw,isa_readl,isa_writeb, isa_writew,isa_writel,isa_memset_io,isa_memcpy_fromio): Added. SolutionEngine support. * include/asm-sh/smc37c93x.h: New file by Kazumoto Kojima. * arch/sh/kernel/setup_se.c: New file by Kazumoto Kojima. * include/asm-sh/hitachi_se.h: Ditto. * arch/sh/kernel/Makefile (O_OBJS): Added irq_ipr.o, removing irq_onchip.c. Added setup_se.c. Index: arch/sh/config.in =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/config.in,v retrieving revision 1.3 diff -u -r1.3 config.in --- arch/sh/config.in 2000/04/14 17:56:34 1.3 +++ arch/sh/config.in 2000/05/03 02:01:51 @@ -15,6 +15,10 @@ mainmenu_option next_comment comment 'Processor type and features' +choice 'SuperH system type' \ + "Generic CONFIG_SH_GENERIC \ + SolutionEngine CONFIG_SH_SOLUTION_ENGINE" Generic + choice 'Processor type' \ "SH7708 CONFIG_CPU_SUBTYPE_SH7708 \ SH7709 CONFIG_CPU_SUBTYPE_SH7709 \ @@ -32,7 +36,12 @@ define_bool CONFIG_CPU_SH4 y fi bool 'Little Endian' CONFIG_LITTLE_ENDIAN -hex 'Physical memory start address' CONFIG_MEMORY_START 08000000 +if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then + define_hex CONFIG_MEMORY_START 0c000000 +else + hex 'Physical memory start address' CONFIG_MEMORY_START 08000000 + hex 'I/O port offset address' CONFIG_IOPORT_START ba000000 +fi endmenu mainmenu_option next_comment @@ -52,7 +61,9 @@ bool 'Networking support' CONFIG_NET -bool 'Directy Connected Compact Flash support' CONFIG_CF_ENABLER +if [ "$CONFIG_SH_SOLUTION_ENGINE" != "y" ]; then + bool 'Directy Connected Compact Flash support' CONFIG_CF_ENABLER +fi bool 'PCI support' CONFIG_PCI if [ "$CONFIG_PCI" = "y" ]; then Index: arch/sh/kernel/Makefile =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/Makefile,v retrieving revision 1.2 diff -u -r1.2 Makefile --- arch/sh/kernel/Makefile 2000/04/14 19:14:01 1.2 +++ arch/sh/kernel/Makefile 2000/05/03 02:01:51 @@ -10,7 +10,7 @@ $(CC) $(AFLAGS) -traditional -c $< -o $*.o O_TARGET := kernel.o -O_OBJS := process.o signal.o entry.o traps.o irq.o irq_onchip.o \ +O_OBJS := process.o signal.o entry.o traps.o irq.o irq_ipr.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o pci-sh.o \ irq_imask.o OX_OBJS := sh_ksyms.o @@ -18,6 +18,14 @@ ifdef CONFIG_CF_ENABLER O_OBJS += cf-enabler.o +endif + +ifdef CONFIG_SH_GENERIC +O_OBJS += io_generic.o +endif + +ifdef CONFIG_SH_SOLUTION_ENGINE +O_OBJS += setup_se.o io_se.o endif ifdef CONFIG_CPU_SH4 Index: arch/sh/kernel/io_generic.c =================================================================== RCS file: io_generic.c diff -N io_generic.c --- /dev/null Tue May 5 13:32:27 1998 +++ io_generic.c Tue May 2 19:01:51 2000 @@ -0,0 +1,77 @@ +/* $Id$ + * + * linux/arch/sh/kernel/io_generic.c + * + * Copyright (C) 2000 Niibe Yutaka + * + * Generic I/O routine. + * + */ + +#define PORT2ADDR(x) (CONFIG_IOPORT_START+(x)) + +unsigned long inb(unsigned long port) +{ + return *(volatile unsigned char*)PORT2ADDR(port); +} + +unsigned long inw(unsigned long port) +{ + return *(volatile unsigned short*)PORT2ADDR(port); +} + +unsigned long inl(unsigned long port) +{ + return *(volatile unsigned long*)PORT2ADDR(port); +} + +void insb(unsigned long port, void *buffer, int count) +{ + unsigned char *buf=buffer; + while(count--) *buf++=inb(port); +} + +void insw(unsigned long port, void *buffer, int count) +{ + unsigned short *buf=buffer; + while(count--) *buf++=inw(port); +} + +void insl(unsigned long port, void *buffer, int count) +{ + unsigned long *buf=buffer; + while(count--) *buf++=inl(port); +} + +void outb(unsigned char b, unsigned long port) +{ + *(volatile unsigned char*)PORT2ADDR(port) = b; +} + +void outw(unsigned short b, unsigned long port) +{ + *(volatile unsigned short*)PORT2ADDR(port) = b; +} + +void outl(unsigned int b, unsigned long port) +{ + *(volatile unsigned long*)PORT2ADDR(port) = b; +} + +void outsb(unsigned long port, const void *buffer, int count) +{ + const unsigned char *buf=buffer; + while(count--) outb(*buf++, port); +} + +void outsw(unsigned long port, const void *buffer, int count) +{ + const unsigned short *buf=buffer; + while(count--) outw(*buf++, port); +} + +void outsl(unsigned long port, const void *buffer, int count) +{ + const unsigned long *buf=buffer; + while(count--) outl(*buf++, port); +} Index: arch/sh/kernel/io_se.c =================================================================== RCS file: io_se.c diff -N io_se.c --- /dev/null Tue May 5 13:32:27 1998 +++ io_se.c Tue May 2 19:01:51 2000 @@ -0,0 +1,194 @@ +/* $Id$ + * + * linux/arch/sh/kernel/io_se.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * I/O routine for Hitachi SolutionEngine. + * + */ +#include <linux/config.h> + +#include <linux/kernel.h> +#include <linux/types.h> +#include <asm/hitachi_se.h> + +/* SH pcmcia io window base, start and end. */ +int sh_pcic_io_wbase = 0xb8400000; +int sh_pcic_io_start; +int sh_pcic_io_stop; +int sh_pcic_io_type; +int sh_pcic_io_dummy; + +/* MS7750 requires special versions of __in*, __out* routines, since + PC-like io ports are located at upper half byte of 16-bit word which + can be accessed only with 16-bit wide. */ + +static inline volatile __u16 * +port2adr(unsigned int port) +{ + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); + else if (port >= 0x1000) + return (volatile __u16 *) (PA_83902 + (port << 1)); + else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) + return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1)); + else + return (volatile __u16 *) (PA_SUPERIO + (port << 1)); +} + +static inline int +shifted_port(unsigned int port) +{ + if (0x1f0 <= port && port < 0x1f8) + return 0; + else if (port == 0x3f6) + return 0; + else + return 1; +} + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%x at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +unsigned long inb(unsigned int port) +{ + if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) + return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); + else if (shifted_port(port)) + return (*port2adr(port) >> 8); + else + return (*port2adr(port))&0xff; +} + +unsigned long inw(unsigned int port) +{ + if (port >= 0x2000 || + (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) + return *port2adr(port); + else + maybebadio(inw, port); + return 0; +} + +unsigned long inl(unsigned int port) +{ + maybebadio(inl, port); + return 0; +} + +void outb(unsigned int value, unsigned int port) +{ + if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) + *(__u8 *)(sh_pcic_io_wbase + port) = value; + else if (shifted_port(port)) + *(port2adr(port)) = value << 8; + else + *(port2adr(port)) = value; +} + +void outw(unsigned int value, unsigned int port) +{ + if (port >= 0x2000 || + (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) + *port2adr(port) = value; + else + maybebadio(outw, port); +} + +void outl(unsigned int value, unsigned int port) +{ + maybebadio(outl, port); +} + +void insb(unsigned int port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + + if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) { + volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port); + while (count--) + *((__u8 *) addr)++ = *bp; + } + else if (shifted_port(port)) { + while (count--) + *((__u8 *) addr)++ = *p >> 8; + } else { + while (count--) + *((__u8 *) addr)++ = *p; + } +} + +void insw(unsigned int port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + while (count--) + *((__u16 *) addr)++ = *p; +} + +void insl(unsigned int port, void *addr, unsigned long count) +{ + maybebadio(insl, port); +} + +void outsb(unsigned int port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + + if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) { + volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port); + while (count--) + *bp = *((__u8 *) addr)++; + } else if (shifted_port(port)) { + while (count--) + *p = *((__u8 *) addr)++ << 8; + } else { + while (count--) + *p = *((__u8 *) addr)++; + } +} + +void outsw(unsigned int port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + while (count--) + *p = *((__u16 *) addr)++; +} + +void outsl(unsigned int port, const void *addr, unsigned long count) +{ + maybebadio(outsw, port); +} + +/* Map ISA bus address to the real address. Only for PCMCIA. */ + +/* ISA page descriptor. */ +static __u32 sh_isa_memmap[256]; + +int +sh_isa_mmap(__u32 start, __u32 length, __u32 offset) +{ + int idx; + + if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) + return -1; + + idx = start >> 12; + sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); +#if 0 + printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", + start, length, offset, idx, sh_isa_memmap[idx]); +#endif + return 0; +} + +unsigned long +sh_isa_slot(unsigned long offset) +{ + int idx; + + idx = (offset >> 12) & 0xff; + offset &= 0xfff; + return sh_isa_memmap[idx] + offset; +} Index: arch/sh/kernel/setup_se.c =================================================================== RCS file: setup_se.c diff -N setup_se.c --- /dev/null Tue May 5 13:32:27 1998 +++ setup_se.c Tue May 2 19:01:51 2000 @@ -0,0 +1,120 @@ +/* $Id$ + * + * linux/arch/sh/kernel/setup_se.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Hitachi SolutionEngine Support. + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> + +#include <linux/hdreg.h> +#include <linux/ide.h> +#include <asm/io.h> +#include <asm/hitachi_se.h> +#include <asm/smc37c93x.h> + +/* + * Configure the Super I/O chip + */ +static void __init smsc_config(int index, int data) +{ + outb(index, INDEX_PORT); + outb(data, DATA_PORT); +} + +static void __init init_smsc(void) +{ + outb(CONFIG_ENTER, CONFIG_PORT); + outb(CONFIG_ENTER, CONFIG_PORT); + + /* FDC */ + smsc_config(CURRENT_LDN_INDEX, LDN_FDC); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 0x06); /* IRQ6 */ + + /* IDE1 */ + smsc_config(CURRENT_LDN_INDEX, LDN_IDE1); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 0x0E); /* IRQ14 */ + +#if 0 + smsc_config(0x24, 0x04); /* XXX: What's that? */ +#endif + + /* COM1 */ + smsc_config(CURRENT_LDN_INDEX, LDN_COM1); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IO_BASE_HI_INDEX, 0x03); + smsc_config(IO_BASE_LO_INDEX, 0xf8); + smsc_config(IRQ_SELECT_INDEX, 0x03); /* IRQ3 */ + + /* RTC */ + smsc_config(CURRENT_LDN_INDEX, LDN_RTC); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 0x08); /* XXX: needed? IRQ8 */ + + /* XXX: COM2, PARPORT, KBD, and MOUSE come here... */ + outb(CONFIG_EXIT, CONFIG_PORT); +} + +/* + * Initialize IRQ setting + */ +static void __init init_se_IRQ(void) +{ + int i; + + /* + * Super I/O (Just mimic PC): + * 1: keyboard + * 3: serial 0 + * 4: serial 1 + * 5: printer + * 6: floppy + * 8: rtc + * 12: mouse + * 14: ide0 + */ + set_ipr_data(14, BCR_ILCRA, 2, 14); + set_ipr_data(12, BCR_ILCRA, 1, 12); + set_ipr_data( 8, BCR_ILCRB, 1, 8); + set_ipr_data( 6, BCR_ILCRC, 3, 6); + set_ipr_data( 5, BCR_ILCRC, 2, 5); + set_ipr_data( 4, BCR_ILCRC, 1, 4); + set_ipr_data( 3, BCR_ILCRC, 0, 3); + set_ipr_data( 1, BCR_ILCRD, 3, 1); + + set_ipr_data(10, BCR_ILCRD, 1, 10); /* LAN */ + + set_ipr_data(15, BCR_ILCRE, 3, 13); /* PCIRQ3 */ + set_ipr_data(11, BCR_ILCRE, 2, 11); /* PCIRQ2 */ + set_ipr_data( 9, BCR_ILCRE, 1, 9); /* PCIRQ1 */ + set_ipr_data( 7, BCR_ILCRE, 0, 7); /* PCIRQ0 */ + + /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ + /* NOTE: #2 and #13 are not used on PC */ + set_ipr_data(13, BCR_ILCRG, 1, 13); /* SLOTIRQ2 */ + set_ipr_data( 2, BCR_ILCRG, 0, 2); /* SLOTIRQ1 */ + + for (i = 1; i < 16; i++) { + make_ipr_irq(i); + } +} + +/* + * Initialize the board + */ +int __init setup_se(void) +{ + init_se_IRQ(); + init_smsc(); + /* XXX: RTC setting comes here */ + return 0; +} + +module_init(setup_se); Index: include/asm-sh/ide.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/include/asm-sh/ide.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 ide.h --- include/asm-sh/ide.h 2000/04/14 16:48:21 1.1.1.1 +++ include/asm-sh/ide.h 2000/05/03 02:01:52 @@ -25,8 +25,8 @@ static __inline__ int ide_default_irq(ide_ioreg_t base) { switch (base) { - case 0xba0001f0: return 14; - case 0xba000170: return 14; + case 0x01f0: return 14; + case 0x0170: return 14; default: return 0; } @@ -36,9 +36,9 @@ { switch (index) { case 0: - return 0xba0001f0; + return 0x01f0; case 1: - return 0xba000170; + return 0x0170; default: return 0; } Index: include/asm-sh/io.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/include/asm-sh/io.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 io.h --- include/asm-sh/io.h 2000/04/14 16:48:21 1.1.1.1 +++ include/asm-sh/io.h 2000/05/03 02:01:52 @@ -53,103 +53,60 @@ *(volatile unsigned long*)addr = b; } -extern __inline__ unsigned long inb_local(unsigned long addr) -{ - return readb(addr); -} - -extern __inline__ void outb_local(unsigned char b, unsigned long addr) -{ - return writeb(b,addr); -} - -extern __inline__ unsigned long inb(unsigned long addr) -{ - return readb(addr); -} - -extern __inline__ unsigned long inw(unsigned long addr) -{ - return readw(addr); -} - -extern __inline__ unsigned long inl(unsigned long addr) -{ - return readl(addr); -} - -extern __inline__ void insb(unsigned long addr, void *buffer, int count) -{ - unsigned char *buf=buffer; - while(count--) *buf++=inb(addr); -} - -extern __inline__ void insw(unsigned long addr, void *buffer, int count) -{ - unsigned short *buf=buffer; - while(count--) *buf++=inw(addr); -} - -extern __inline__ void insl(unsigned long addr, void *buffer, int count) -{ - unsigned long *buf=buffer; - while(count--) *buf++=inl(addr); -} - -extern __inline__ void outb(unsigned char b, unsigned long addr) -{ - return writeb(b,addr); -} - -extern __inline__ void outw(unsigned short b, unsigned long addr) -{ - return writew(b,addr); -} - -extern __inline__ void outl(unsigned int b, unsigned long addr) -{ - return writel(b,addr); -} - -extern __inline__ void outsb(unsigned long addr, const void *buffer, int count) -{ - const unsigned char *buf=buffer; - while(count--) outb(*buf++, addr); -} - -extern __inline__ void outsw(unsigned long addr, const void *buffer, int count) -{ - const unsigned short *buf=buffer; - while(count--) outw(*buf++, addr); -} - -extern __inline__ void outsl(unsigned long addr, const void *buffer, int count) -{ - const unsigned long *buf=buffer; - while(count--) outl(*buf++, addr); -} +extern unsigned char inb(unsigned int port); +extern unsigned short inw(unsigned int port); +extern unsigned int inl(unsigned int port); +extern void insb(unsigned int port, void *addr, unsigned long count); +extern void insw(unsigned int port, void *addr, unsigned long count); +extern void insl(unsigned int port, void *addr, unsigned long count); + +extern void outb(unsigned int value, unsigned int port); +extern void outw(unsigned int value, unsigned int port); +extern void outl(unsigned int value, unsigned int port); +extern void outsb(unsigned int port, const void *addr, unsigned long count); +extern void outsw(unsigned int port, const void *addr, unsigned long count); +extern void outsl(unsigned int port, const void *addr, unsigned long count); + +/* + * If the platform has PC-like I/O, this function gives us the address + * from the offset. + */ +extern unsigned long sh_isa_slot(unsigned long offset); + +#define isa_readb(a) readb(sh_isa_slot(a)) +#define isa_readw(a) readw(sh_isa_slot(a)) +#define isa_readl(a) readl(sh_isa_slot(a)) +#define isa_writeb(b,a) writeb(b,sh_isa_slot(a)) +#define isa_writew(w,a) writew(w,sh_isa_slot(a)) +#define isa_writel(l,a) writel(l,sh_isa_slot(a)) +#define isa_memset_io(a,b,c) \ + memset((void *)(sh_isa_slot((unsigned long)a)),(b),(c)) +#define isa_memcpy_fromio(a,b,c) \ + memcpy((a),(void *)(sh_isa_slot((unsigned long)(b))),(c)) +#define isa_memcpy_toio(a,b,c) \ + memcpy((void *)(sh_isa_slot((unsigned long)(a))),(b),(c)) #define ctrl_in(addr) *(addr) #define ctrl_out(data,addr) *(addr) = (data) extern __inline__ unsigned long ctrl_inb(unsigned long addr) { - return *(volatile unsigned char*)addr; + return *(volatile unsigned char*)addr; } extern __inline__ unsigned long ctrl_inw(unsigned long addr) { - return *(volatile unsigned short*)addr; + return *(volatile unsigned short*)addr; } extern __inline__ unsigned long ctrl_inl(unsigned long addr) { - return *(volatile unsigned long*)addr; + return *(volatile unsigned long*)addr; } extern __inline__ void ctrl_outb(unsigned char b, unsigned long addr) { - *(volatile unsigned char*)addr = b; + *(volatile unsigned char*)addr = b; } extern __inline__ void ctrl_outw(unsigned short b, unsigned long addr) |
From: Mitch D. <mj...@au...> - 2000-05-03 02:15:50
|
gn...@ch... wrote: > > So, I've replaced on-chip support into generalized one called "IPR > (Interrupt Priority Register) based IRQ" support. A Totally Excellent Idea. > I think that it's the job of boot loader, and wanna remove > the code from the kernel. How do you think? I agree. Each type of hardware needs to be initialised in a certain (unique) way. It's really not feasible for the kernel to autoprobe to find out how to do the correct initialisation. And hard-coding the choices means it's not possible to make a basic binary people can download and try. The bootloaders I'm working with do the initialisation, then vector to the kernel. IMHO that's the correct place for initialisation. We could provide people with sample bootloader code, documenting what to change and why, and distribute this either separately, or in the arch/sh directory. Regards, Mitch. -- | mailto:mj...@au... | Not the official view of: | | mailto:mj...@al... | Australian Calculator Opn | | Certified Linux Evangelist! | Hewlett Packard Australia | |
From: <pi...@li...> - 2000-05-02 15:47:34
|
Hello Niibe, NIIBE Yutaka wrote: --8<--8<--SNIP-SNIP--8<--8<-- > functions. Please get the patch from: > ftp://ftp.m17n.org/pub/super-h/gcc-symbol-vis-000501.diff.gz > > It's agains the Kaz' patch of gcc-2.95.2-000228. > > WARNING: This is just a experimental hack. This may not included > standard distribution of GCC, since I did this hack without seeing the > proposed-but-not-yet-released gABI, guess(and expect)ing the feature. > > With this patch, you don't see the entries on ld.so. Again, this may > be work around, not the solution. We have to think hard, more... > > Please let me know how this works (or not) for you, if you will try. It works ! ld.so compiles and runs fine now. Unfortunately, the new visibility patch seems to break the linking of some other parts of glibc, but now that I know what to look for, I can play around to fix the problem :-) Thanks a lot to you and Kaz, Take care --- Pierre-Philippe Coupard <pi...@li...> Software Engineer, Lineo, Inc. 801-426-5001 x 208 --- |
From: <gn...@ch...> - 2000-05-02 11:28:34
|
Hello all, I'm hacking for supporting SolutionEngine. Actually, hacking part has already been done by Kaz and Takashi Yoshii. Now is the time of integration. Integrating interrupt handling of SolutionEngine, I've noticed that almost all of the code is SAME between on-chip support, on-chip2 support by Takashi, and SolutionEngine. So, I've replaced on-chip support into generalized one called "IPR (Interrupt Priority Register) based IRQ" support. Then, supporting SolutionEngine with this scheme. I'll commit this tomorrow. Next comes setup routine of SolutionEngine. Thanks Kaz for the implementation and discussion. I'd like to listen your comment. And Takeshi, As I added the comment, I think that initializing all of INTC registers is not relevant. I think that it's the job of boot loader, and wanna remove the code from the kernel. How do you think? -------------------------- 2000-05-02 NIIBE Yutaka <gn...@ch...> * arch/sh/mm/fault.c (do_page_fault): Bug fix. When "Oops", we don't try to follow the page handling data when PGDIR==0. * arch/sh/kernel/Makefile (O_OBJS): Added irq_ipr.o, removing irq_onchip.c. Added irq_se.c. * arch/sh/kernel/irq_se.c: New file for SolutionEngine support. * arch/sh/kernel/time.c (time_init): Removed IPR setting. * arch/sh/kernel/irq_ipr.c (init_IRQ): ... moved to here. * drivers/char/sh-sci.c (sci_init): Use new calling of set_ipr_data. * drivers/char/sh-sci.h (SCI_IPR_POS, SCI_IPR_ADDR): New macros. (SCI_IPR_OFFSET): Removed. * arch/sh/kernel/irq_ipr.c (startup_ipr_irq, ipr_irq_type, disable_ipr_irq, enable_ipr_irq, make_ipr_irq, mask_and_ack_ipr, end_ipr_irq): Renamed from *_onChip_*. (struct ipr_data): Added member POS. Remove OFFSET, and added ADDR. (startup_onChip2_irq, onChip2_irq_type, disable_onChip2_irq, enable_onChip2_irq, mask_and_ack_onChip2, end_onChip2_irq): Removed. * include/asm-sh/irq.h (make_ipr_irq): Renamed from make_onChip_irq. (set_ipr_data): Change the prototype for address. * arch/sh/kernel/irq_ipr.c: Renamed from irq_onchip.c. Index: arch/sh/config.in =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/config.in,v retrieving revision 1.3 diff -u -r1.3 config.in --- arch/sh/config.in 2000/04/14 17:56:34 1.3 +++ arch/sh/config.in 2000/05/02 10:56:42 @@ -15,6 +15,10 @@ mainmenu_option next_comment comment 'Processor type and features' +choice 'SuperH system type' \ + "Generic CONFIG_SH_GENERIC \ + SolutionEngine CONFIG_SH_SOLUTION_ENGINE" Generic + choice 'Processor type' \ "SH7708 CONFIG_CPU_SUBTYPE_SH7708 \ SH7709 CONFIG_CPU_SUBTYPE_SH7709 \ Index: arch/sh/kernel/Makefile =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/Makefile,v retrieving revision 1.2 diff -u -r1.2 Makefile --- arch/sh/kernel/Makefile 2000/04/14 19:14:01 1.2 +++ arch/sh/kernel/Makefile 2000/05/02 10:56:42 @@ -10,7 +10,7 @@ $(CC) $(AFLAGS) -traditional -c $< -o $*.o O_TARGET := kernel.o -O_OBJS := process.o signal.o entry.o traps.o irq.o irq_onchip.o \ +O_OBJS := process.o signal.o entry.o traps.o irq.o irq_ipr.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o pci-sh.o \ irq_imask.o OX_OBJS := sh_ksyms.o @@ -18,6 +18,10 @@ ifdef CONFIG_CF_ENABLER O_OBJS += cf-enabler.o +endif + +ifdef CONFIG_SH_SOLUTION_ENGINE +O_OBJS += irq_se.o endif ifdef CONFIG_CPU_SH4 Index: arch/sh/kernel/irq_ipr.c =================================================================== RCS file: irq_ipr.c diff -N irq_ipr.c --- /dev/null Tue May 5 13:32:27 1998 +++ irq_ipr.c Tue May 2 03:56:42 2000 @@ -0,0 +1,167 @@ +/* $Id$ + * + * linux/arch/sh/kernel/irq_ipr.c + * + * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi + * Copyright (C) 2000 Kazumoto Kojima + * + * Interrupt handling for IPR-based IRQ. + * + * Supported system: + * On-chip supporting modules (TMU, RTC, etc.). + * On-chip supporting modules for SH7709/SH7709A/SH7729. + * Hitachi SolutionEngine external I/O: + * MS7709SE01, MS7709ASE01, and MS7750SE01 + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> + +#include <asm/system.h> +#include <asm/io.h> + +struct ipr_data { + unsigned int addr; /* Address of Interrupt Priority Register */ + int shift; /* Shifts of the 16-bit data */ + int priority; /* The priority */ +}; +static struct ipr_data ipr_data[NR_IRQS]; + +void set_ipr_data(unsigned int irq, unsigned int addr, int pos, int priority) +{ + ipr_data[irq].addr = addr; + ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ + ipr_data[irq].priority = priority; +} + +static void enable_ipr_irq(unsigned int irq); +void disable_ipr_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_ipr_irq disable_ipr_irq + +static void mask_and_ack_ipr(unsigned int); +static void end_ipr_irq(unsigned int irq); + +static unsigned int startup_ipr_irq(unsigned int irq) +{ + enable_ipr_irq(irq); + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type ipr_irq_type = { + "IPR-based-IRQ", + startup_ipr_irq, + shutdown_ipr_irq, + enable_ipr_irq, + disable_ipr_irq, + mask_and_ack_ipr, + end_ipr_irq +}; + +void disable_ipr_irq(unsigned int irq) +{ + unsigned long val, flags; + unsigned int addr = ipr_data[irq].addr; + unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift); + + /* Set the priority in IPR to 0 */ + save_and_cli(flags); + val = ctrl_inw(addr); + val &= mask; + ctrl_outw(val, addr); + restore_flags(flags); +} + +static void enable_ipr_irq(unsigned int irq) +{ + unsigned long val, flags; + unsigned int addr = ipr_data[irq].addr; + int priority = ipr_data[irq].priority; + unsigned short value = (priority << ipr_data[irq].shift); + + /* Set priority in IPR back to original value */ + save_and_cli(flags); + val = ctrl_inw(addr); + val |= value; + ctrl_outw(val, addr); + restore_flags(flags); +} + +void make_ipr_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &ipr_irq_type; + enable_irq(irq); +} + +static void mask_and_ack_ipr(unsigned int irq) +{ + disable_ipr_irq(irq); + + /* This is needed when we use edge triggered setting */ + /* XXX: Is it really needed? */ + if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { + /* Clear external interrupt request */ + int a = ctrl_inb(INTC_IRR0); + a &= ~(1 << (irq - IRQ0_IRQ)); + ctrl_outb(a, INTC_IRR0); + } +} + +static void end_ipr_irq(unsigned int irq) +{ + enable_ipr_irq(irq); +} + +void __init init_IRQ(void) +{ + int i; + + for (i = TIMER_IRQ; i < NR_IRQS; i++) { + irq_desc[i].handler = &ipr_irq_type; + } + + set_ipr_data(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); + set_ipr_data(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); + +#ifdef CONFIG_CPU_SUBTYPE_SH7709 + /* + * Initialize the Interrupt Controller (INTC) + * registers to their power on values + */ + /* + * XXX: I think that this is the job of boot loader. -- gniibe + * + * When Takeshi released new boot loader following setting + * will be removed shortly. + */ + ctrl_outb(0, INTC_IRR0); + ctrl_outb(0, INTC_IRR1); + ctrl_outb(0, INTC_IRR2); + + ctrl_outw(0, INTC_ICR0); + ctrl_outw(0, INTC_ICR1); + ctrl_outw(0, INTC_ICR2); + ctrl_outw(0, INTC_INTER); + ctrl_outw(0, INTC_IPRA); + ctrl_outw(0, INTC_IPRB); + ctrl_outw(0, INTC_IPRC); + ctrl_outw(0, INTC_IPRD); + ctrl_outw(0, INTC_IPRE); + + /* + * Enable external irq (INTC IRQ mode). + * You should set corresponding bits of PFC to "00" + * to enable these interrupts. + */ + set_ipr_data(IRQ0_IRQ, IRQ0_IRP_ADDR, IRQ0_IRP_POS, IRQ0_PRIORITY); + set_ipr_data(IRQ1_IRQ, IRQ1_IRP_ADDR, IRQ1_IRP_POS, IRQ1_PRIORITY); + set_ipr_data(IRQ2_IRQ, IRQ2_IRP_ADDR, IRQ2_IRP_POS, IRQ2_PRIORITY); + set_ipr_data(IRQ3_IRQ, IRQ3_IRP_ADDR, IRQ3_IRP_POS, IRQ3_PRIORITY); + set_ipr_data(IRQ4_IRQ, IRQ4_IRP_ADDR, IRQ4_IRP_POS, IRQ4_PRIORITY); + set_ipr_data(IRQ5_IRQ, IRQ5_IRP_ADDR, IRQ5_IRP_POS, IRQ5_PRIORITY); +#endif /* CONFIG_CPU_SUBTYPE_SH7709 */ +} Index: arch/sh/kernel/irq_onchip.c =================================================================== RCS file: irq_onchip.c diff -N irq_onchip.c --- /tmp/cvsLlt0mr Tue May 2 03:57:16 2000 +++ /dev/null Tue May 5 13:32:27 1998 @@ -1,298 +0,0 @@ -/* $Id: irq_onchip.c,v 1.3 2000/04/28 17:58:50 mjd Exp $ - * - * linux/arch/sh/kernel/irq_onchip.c - * - * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi - * - * Interrupt handling for on-chip supporting modules (TMU, RTC, etc.). - * - */ - -#include <linux/config.h> -#include <linux/ptrace.h> -#include <linux/errno.h> -#include <linux/kernel_stat.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/ioport.h> -#include <linux/interrupt.h> -#include <linux/timex.h> -#include <linux/malloc.h> -#include <linux/random.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/init.h> - -#include <asm/system.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/bitops.h> -#include <asm/smp.h> -#include <asm/pgtable.h> -#include <asm/delay.h> - -#include <linux/irq.h> - -struct ipr_data { - int offset; - int priority; -}; -static struct ipr_data ipr_data[NR_IRQS-TIMER_IRQ]; - -void set_ipr_data(unsigned int irq, int offset, int priority) -{ - ipr_data[irq-TIMER_IRQ].offset = offset; - ipr_data[irq-TIMER_IRQ].priority = priority; -} - -static void enable_onChip_irq(unsigned int irq); -void disable_onChip_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_onChip_irq disable_onChip_irq - -static void mask_and_ack_onChip(unsigned int); -static void end_onChip_irq(unsigned int irq); - -static unsigned int startup_onChip_irq(unsigned int irq) -{ - enable_onChip_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type onChip_irq_type = { - "On-Chip-IPR", - startup_onChip_irq, - shutdown_onChip_irq, - enable_onChip_irq, - disable_onChip_irq, - mask_and_ack_onChip, - end_onChip_irq -}; - -/* - * These have to be protected by the irq controller spinlock - * before being called. - * - * - * IPRA 15-12 11-8 7-4 3-0 - * IPRB 15-12 11-8 7-4 3-0 - * IPRC 15-12 11-8 7-4 3-0 - * - */ -#if defined(__sh3__) -#define INTC_IPR 0xfffffee2UL /* Word access */ -#define INTC_SIZE 0x2 -#elif defined(__SH4__) -#define INTC_IPR 0xffd00004UL /* Word access */ -#define INTC_SIZE 0x4 -#endif - -void disable_onChip_irq(unsigned int irq) -{ - unsigned long val, flags; - /* Set priority in IPR to 0 */ - int offset = ipr_data[irq-TIMER_IRQ].offset; - unsigned long intc_ipr_address = INTC_IPR + (offset/16*INTC_SIZE); - unsigned short mask = 0xffff ^ (0xf << (offset%16)); - - save_and_cli(flags); - val = ctrl_inw(intc_ipr_address); - val &= mask; - ctrl_outw(val, intc_ipr_address); - restore_flags(flags); -} - -static void enable_onChip_irq(unsigned int irq) -{ - unsigned long val, flags; - /* Set priority in IPR back to original value */ - int offset = ipr_data[irq-TIMER_IRQ].offset; - int priority = ipr_data[irq-TIMER_IRQ].priority; - unsigned long intc_ipr_address = INTC_IPR + (offset/16*INTC_SIZE); - unsigned short value = (priority << (offset%16)); - - save_and_cli(flags); - val = ctrl_inw(intc_ipr_address); - val |= value; - ctrl_outw(val, intc_ipr_address); - restore_flags(flags); -} - -void make_onChip_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].handler = &onChip_irq_type; - enable_irq(irq); -} - -static void mask_and_ack_onChip(unsigned int irq) -{ - disable_onChip_irq(irq); -} - -static void end_onChip_irq(unsigned int irq) -{ - enable_onChip_irq(irq); -} - - -#ifdef CONFIG_CPU_SUBTYPE_SH7709 -/* - * SH7707/SH7709/SH7709A/SH7729 Extended on-chip I/O - */ - -#define INTC_IRR0 0xa4000004UL -#define INTC_IRR1 0xa4000006UL -#define INTC_IRR2 0xa4000008UL - -#define INTC_ICR0 0xfffffee0 -#define INTC_ICR1 0xa4000010 -#define INTC_ICR2 0xa4000012 -#define INTC_INTER 0xa4000014 -#define INTC_IPRA 0xfffffee2 -#define INTC_IPRB 0xfffffee4 -#define INTC_IPRC 0xa4000016 -#define INTC_IPRD 0xa4000018 -#define INTC_IPRE 0xa400001a - -#define IRQ0_IRQ 32 -#define IRQ1_IRQ 33 -#define IRQ2_IRQ 34 -#define IRQ3_IRQ 35 -#define IRQ4_IRQ 36 -#define IRQ5_IRQ 37 - -#define IRQ0_IRP_OFFSET 32 -#define IRQ1_IRP_OFFSET 36 -#define IRQ2_IRP_OFFSET 40 -#define IRQ3_IRP_OFFSET 44 -#define IRQ4_IRP_OFFSET 48 -#define IRQ5_IRP_OFFSET 52 - -#define IRQ0_PRIORITY 1 -#define IRQ1_PRIORITY 1 -#define IRQ2_PRIORITY 1 -#define IRQ3_PRIORITY 1 -#define IRQ4_PRIORITY 1 -#define IRQ5_PRIORITY 1 - -static void enable_onChip2_irq(unsigned int irq); -void disable_onChip2_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_onChip2_irq disable_onChip2_irq - -static void mask_and_ack_onChip2(unsigned int); -static void end_onChip2_irq(unsigned int irq); - -static unsigned int startup_onChip2_irq(unsigned int irq) -{ - enable_onChip2_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type onChip2_irq_type = { - "Extended-IPR", - startup_onChip2_irq, - shutdown_onChip2_irq, - enable_onChip2_irq, - disable_onChip2_irq, - mask_and_ack_onChip2, - end_onChip2_irq -}; - -void disable_onChip2_irq(unsigned int irq) -{ - unsigned long val, flags; - /* Set priority in IPR to 0 */ - int offset = ipr_data[irq-TIMER_IRQ].offset - 32; - unsigned long intc_ipr_address = INTC_IPRC + (offset/16*INTC_SIZE); - unsigned short mask = 0xffff ^ (0xf << (offset%16)); - - save_and_cli(flags); - val = ctrl_inw(intc_ipr_address); - val &= mask; - ctrl_outw(val, intc_ipr_address); - restore_flags(flags); -} - -static void enable_onChip2_irq(unsigned int irq) -{ - unsigned long val, flags; - /* Set priority in IPR back to original value */ - int offset = ipr_data[irq-TIMER_IRQ].offset - 32; - int priority = ipr_data[irq-TIMER_IRQ].priority; - unsigned long intc_ipr_address = INTC_IPRC + (offset/16*INTC_SIZE); - unsigned short value = (priority << (offset%16)); - - save_and_cli(flags); - val = ctrl_inw(intc_ipr_address); - val |= value; - ctrl_outw(val, intc_ipr_address); - restore_flags(flags); -} - -static void mask_and_ack_onChip2(unsigned int irq) -{ - disable_onChip2_irq(irq); - if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { - /* Clear external interrupt request */ - int a = ctrl_inb(INTC_IRR0); - a &= ~(1 << (irq - IRQ0_IRQ)); - ctrl_outb(a, INTC_IRR0); - } -} - -static void end_onChip2_irq(unsigned int irq) -{ - enable_onChip2_irq(irq); -} -#endif /* CONFIG_CPU_SUBTYPE_SH7709 */ - -void __init init_IRQ(void) -{ - int i; - - for (i = TIMER_IRQ; i < NR_IRQS; i++) { - irq_desc[i].handler = &onChip_irq_type; - } - -#ifdef CONFIG_CPU_SUBTYPE_SH7709 - - /* - * Initialize the Interrupt Controller (INTC) - * registers to their power on values - */ - - ctrl_outb(0, INTC_IRR0); - ctrl_outb(0, INTC_IRR1); - ctrl_outb(0, INTC_IRR2); - - ctrl_outw(0, INTC_ICR0); - ctrl_outw(0, INTC_ICR1); - ctrl_outw(0, INTC_ICR2); - ctrl_outw(0, INTC_INTER); - ctrl_outw(0, INTC_IPRA); - ctrl_outw(0, INTC_IPRB); - ctrl_outw(0, INTC_IPRC); - ctrl_outw(0, INTC_IPRD); - ctrl_outw(0, INTC_IPRE); - - for (i = IRQ0_IRQ; i < NR_IRQS; i++) { - irq_desc[i].handler = &onChip2_irq_type; - } - - /* - * Enable external irq(INTC IRQ mode). - * You should set corresponding bits of PFC to "00" - * to enable these interrupts. - */ - set_ipr_data(IRQ0_IRQ, IRQ0_IRP_OFFSET, IRQ0_PRIORITY); - set_ipr_data(IRQ1_IRQ, IRQ1_IRP_OFFSET, IRQ1_PRIORITY); - set_ipr_data(IRQ2_IRQ, IRQ2_IRP_OFFSET, IRQ2_PRIORITY); - set_ipr_data(IRQ3_IRQ, IRQ3_IRP_OFFSET, IRQ3_PRIORITY); - set_ipr_data(IRQ4_IRQ, IRQ4_IRP_OFFSET, IRQ4_PRIORITY); - set_ipr_data(IRQ5_IRQ, IRQ5_IRP_OFFSET, IRQ5_PRIORITY); -#endif /* CONFIG_CPU_SUBTYPE_SH7709 */ -} Index: arch/sh/kernel/irq_se.c =================================================================== RCS file: irq_se.c diff -N irq_se.c --- /dev/null Tue May 5 13:32:27 1998 +++ irq_se.c Tue May 2 03:56:42 2000 @@ -0,0 +1,55 @@ +/* $Id$ + * + * linux/arch/sh/kernel/irq_se.c + * + * Copyright (C) 2000 Niibe Yutaka + * + * Interrupt handling for Hitachi SolutionEngine. + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> + +void __init init_se_IRQ(void) +{ + int i; + + /* + * Super I/O (Just mimic PC): + * 1: keyboard + * 3: serial 0 + * 4: serial 1 + * 5: printer + * 6: floppy + * 8: rtc + * 12: mouse + * 14: ide0 + */ + set_ipr_data(14, BCR_IRP_ADDR+0, 2, 14); + set_ipr_data(12, BCR_IRP_ADDR+0, 1, 12); + set_ipr_data( 8, BCR_IRP_ADDR+2, 1, 8); + set_ipr_data( 6, BCR_IRP_ADDR+4, 3, 6); + set_ipr_data( 5, BCR_IRP_ADDR+4, 2, 5); + set_ipr_data( 4, BCR_IRP_ADDR+4, 1, 4); + set_ipr_data( 3, BCR_IRP_ADDR+4, 0, 3); + set_ipr_data( 1, BCR_IRP_ADDR+6, 3, 1); + + set_ipr_data(10, BCR_IRP_ADDR+6, 1, 10); /* LAN */ + + set_ipr_data(15, BCR_IRP_ADDR+8, 3, 13); /* PCIRQ3 */ + set_ipr_data(11, BCR_IRP_ADDR+8, 2, 11); /* PCIRQ2 */ + set_ipr_data( 9, BCR_IRP_ADDR+8, 1, 9); /* PCIRQ1 */ + set_ipr_data( 7, BCR_IRP_ADDR+8, 0, 7); /* PCIRQ0 */ + + /* #2, #13 are available for other interrupt sources. */ + /* NOTE: #2 and #13 are not used on PC (it's cascade to 9) */ + + make_ipr_irq(1); + for (i = 3; i < 15; i++) { + make_ipr_irq(i); + } +} + +module_init(init_se_IRQ); Index: arch/sh/kernel/time.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/time.c,v retrieving revision 1.6 diff -u -r1.6 time.c --- arch/sh/kernel/time.c 2000/05/02 00:10:09 1.6 +++ arch/sh/kernel/time.c 2000/05/02 10:56:42 @@ -47,9 +47,6 @@ #define RCR2_RESET 0x02 /* Reset bit */ #define RCR2_START 0x01 /* Start bit */ -#define RTC_IRQ 22 -#define RTC_IPR_OFFSET 0 - #if defined(__sh3__) #define TMU_TOCR 0xfffffe90 /* Byte access */ #define TMU_TSTR 0xfffffe92 /* Byte access */ @@ -400,9 +397,7 @@ xtime.tv_sec = get_rtc_time(); xtime.tv_usec = 0; - set_ipr_data(TIMER_IRQ, TIMER_IPR_OFFSET, TIMER_PRIORITY); setup_irq(TIMER_IRQ, &irq0); - set_ipr_data(RTC_IRQ, RTC_IPR_OFFSET, TIMER_PRIORITY); setup_irq(RTC_IRQ, &irq1); /* Check how fast it is.. */ Index: arch/sh/mm/fault.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/mm/fault.c,v retrieving revision 1.8 diff -u -r1.8 fault.c --- arch/sh/mm/fault.c 2000/04/30 23:33:47 1.8 +++ arch/sh/mm/fault.c 2000/05/02 10:56:42 @@ -210,18 +210,20 @@ printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); else printk(KERN_ALERT "Unable to handle kernel paging request"); - printk(" at virtual address %08lx\n",address); + printk(" at virtual address %08lx\n", address); printk(KERN_ALERT "pc = %08lx\n", regs->pc); - asm volatile("mov.l %1,%0" + asm volatile("mov.l %1, %0" : "=r" (page) : "m" (__m(MMU_TTB))); - page = ((unsigned long *) page)[address >> 22]; - printk(KERN_ALERT "*pde = %08lx\n", page); - if (page & _PAGE_PRESENT) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; - printk(KERN_ALERT "*pte = %08lx\n", page); + if (page) { + page = ((unsigned long *) page)[address >> 22]; + printk(KERN_ALERT "*pde = %08lx\n", page); + if (page & _PAGE_PRESENT) { + page &= PAGE_MASK; + address &= 0x003ff000; + page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; + printk(KERN_ALERT "*pte = %08lx\n", page); + } } die("Oops", regs, writeaccess); do_exit(SIGKILL); Index: drivers/char/sh-sci.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/drivers/char/sh-sci.c,v retrieving revision 1.5 diff -u -r1.5 sh-sci.c --- drivers/char/sh-sci.c 2000/05/02 00:10:09 1.5 +++ drivers/char/sh-sci.c 2000/05/02 10:56:42 @@ -746,7 +746,7 @@ int i; for (i=SCI_ERI_IRQ; i<SCI_IRQ_END; i++) - set_ipr_data(i, SCI_IPR_OFFSET, SCI_PRIORITY); + set_ipr_data(i, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); port = &sci_ports[0]; Index: drivers/char/sh-sci.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/drivers/char/sh-sci.h,v retrieving revision 1.3 diff -u -r1.3 sh-sci.h --- drivers/char/sh-sci.h 2000/05/02 00:10:09 1.3 +++ drivers/char/sh-sci.h 2000/05/02 10:56:42 @@ -56,7 +56,8 @@ #define SCI_TEI_IRQ 26 #define SCI_IRQ_END 27 -#define SCI_IPR_OFFSET (16+4) +#define SCI_IPR_ADDR INTC_IPRB +#define SCI_IPR_POS 1 #endif #if defined(CONFIG_SH_SCIF_SERIAL) @@ -77,7 +78,8 @@ #define SCSCR_INIT 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ /* 0x33 when external clock is used */ -#define SCI_IPR_OFFSET (64+4) +#define SCI_IPR_ADDR INTC_IPRE +#define SCI_IPR_POS 1 #elif defined(__SH4__) #define SCSMR (volatile unsigned short *)0xFFE80000 @@ -92,7 +94,8 @@ #define SCLSR 0xFFE80024 #define SCSCR_INIT 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ -#define SCI_IPR_OFFSET (32+4) +#define SCI_IPR_ADDR INTC_IPRB +#define SCI_IPR_POS 1 #endif Index: include/asm-sh/irq.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/include/asm-sh/irq.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 irq.h --- include/asm-sh/irq.h 2000/04/14 16:48:21 1.1.1.1 +++ include/asm-sh/irq.h 2000/05/02 10:56:44 @@ -6,15 +6,31 @@ * linux/include/asm-sh/irq.h * * Copyright (C) 1999 Niibe Yutaka + * Copyright (C) 2000 Kazumoto Kojima * */ #include <linux/config.h> -#define TIMER_IRQ 16 /* Hard-wired */ -#define TIMER_IPR_OFFSET 12 -#define TIMER_PRIORITY 2 +#if defined(__sh3__) +#define INTC_IPRA 0xfffffee2UL +#define INTC_IPRB 0xfffffee4UL +#elif defined(__SH4__) +#define INTC_IPRA 0xffd00004UL +#define INTC_IPRA 0xffd00008UL +#define INTC_IPRC 0xffd0000cUL +#endif + +#define TIMER_IRQ 16 +#define TIMER_IPR_ADDR INTC_IPRA +#define TIMER_IPR_POS 3 +#define TIMER_PRIORITY 2 +#define RTC_IRQ 22 +#define RTC_IPR_ADDR INTC_IPRA +#define RTC_IPR_POS 0 +#define RTC_PRIORITY TIMER_PRIORITY + #if defined(__SH4__) /* * 48 = 32+16 @@ -37,8 +53,56 @@ /* * Function for "on chip support modules". */ -extern void set_ipr_data(unsigned int irq, int offset, int priority); -extern void make_onChip_irq(unsigned int irq); +extern void set_ipr_data(unsigned int irq, unsigned int addr, + int pos, int priority); +extern void make_ipr_irq(unsigned int irq); extern void make_imask_irq(unsigned int irq); + +#if defined(CONFIG_CPU_SUBTYPE_SH7709) +#define INTC_IRR0 0xa4000004UL +#define INTC_IRR1 0xa4000006UL +#define INTC_IRR2 0xa4000008UL + +#define INTC_ICR0 0xfffffee0UL +#define INTC_ICR1 0xa4000010UL +#define INTC_ICR2 0xa4000012UL +#define INTC_INTER 0xa4000014UL + +#define INTC_IPRC 0xa4000016UL +#define INTC_IPRD 0xa4000018UL +#define INTC_IPRE 0xa400001aUL + +#define IRQ0_IRQ 32 +#define IRQ1_IRQ 33 +#define IRQ2_IRQ 34 +#define IRQ3_IRQ 35 +#define IRQ4_IRQ 36 +#define IRQ5_IRQ 37 + +#define IRQ0_IRP_ADDR INTC_IPRC +#define IRQ1_IRP_ADDR INTC_IPRC +#define IRQ2_IRP_ADDR INTC_IPRC +#define IRQ3_IRP_ADDR INTC_IPRC +#define IRQ4_IRP_ADDR INTC_IPRD +#define IRQ5_IRP_ADDR INTC_IPRD + +#define IRQ0_IRP_POS 0 +#define IRQ1_IRP_POS 1 +#define IRQ2_IRP_POS 2 +#define IRQ3_IRP_POS 3 +#define IRQ4_IRP_POS 0 +#define IRQ5_IRP_POS 1 + +#define IRQ0_PRIORITY 1 +#define IRQ1_PRIORITY 1 +#define IRQ2_PRIORITY 1 +#define IRQ3_PRIORITY 1 +#define IRQ4_PRIORITY 1 +#define IRQ5_PRIORITY 1 +#endif + +#ifdef CONFIG_SH_SOLUTION_ENGINE +#define BCR_IRP_ADDR 0xb1400000 /* FPGA */ +#endif #endif /* __ASM_SH_IRQ_H */ |
From: <pi...@li...> - 2000-05-02 00:25:24
|
Hello Niibe, NIIBE Yutaka wrote: > Hello Pierre! > > Thanks for your feedback. > > (1) RAMDISK issue > > I'll try that. Thanks. > > (2) Initialization of SCI > > I think that this issue is resolved in current kernel (2.3.99-pre6 and > later). If not, please let us know. I was working on pre5 but I'll upgrade and give it a try. > (3) Peripheral clock > > > Ideally, I think it'd be good to have an option in the .config to > > set the bus clock speed and have several tables defined and > > selected with #ifdefs. > > Yes, that'd be a solution. Alternatively, we could use the value > measured with RTC. I'm thinking exporting the variable > sh_periheral_clock and sh_module_clock from time.c. I know that > current code of time.c is not correct for all the cases, but it works > at least for me. I have to carry my modifications to the kernel to pre6 then I'll make entries in the SH defconfigs. It'll be a solution until something nicer is done, but I don't think it's too critical. > > I don't know if any of the above will help anyone but I thought I > > might share my findings. > > Surely, it helps much. Thank you. > > > Now for the plea for help :-) : > > Yes. Welcome to the development team!! > > > I assume everybody on the list has userland programs compiled > > dynamically and running good on their boards. For some reason, I > > can run programs that have been compiled statically against glibc > > just fine, but I can't run dynamically linked programs because > > ld.so segfaults (I use Kaz' latest patch for glibc). What happens > > is that ld.so starts, and eventually the function > > elf_machine_rela() (in sysdeps/sh/sh3/dl-machine.h) is called > > during the initial relocation from _dl_start() and the segfault > > occurs when the code tries (I think) to poke a fixed-up address in > > the code section (which is read-only) instead of the GOT (which is > > read-write). > > Your description is correct. I guess that the target label to be > resolved is the one of libgcc.a, isn't it? Here is the story. > --8<--8<--SNIP-SNIP--8<--8<-- > Please let me know how this works (or not) for you, if you will try. Wow, now that's indepth knowledge :) I will certainly try and let you know my results. Thank you very much, Take care --- Pierre-Philippe Coupard <pi...@li...> Software Engineer, Lineo, Inc. 801-426-5001 x 208 --- |
From: <pi...@li...> - 2000-05-02 00:06:05
|
Hello Kaz, Thanks for your answer, it is much appreciated kaz Kojima wrote: > Can you please give us the result of readelf -r ld.so? It shows > relocations of ld.so. Sure. Here it goes : --8<--8<--SNIP-SNIP--8<--8<-- Relocation section '.rela.text' at offset 0x1710 contains 15 entries: Offset Info Type Symbol's Value Symbol's Name Addend 00003288 000a5 R_SH_RELATIVE 00010ec0 00006294 000a5 R_SH_RELATIVE 00010faa 00007b98 000a5 R_SH_RELATIVE 00010faa 00007fdc 000a5 R_SH_RELATIVE 00010faa 00008208 000a5 R_SH_RELATIVE 00010faa 00008558 000a5 R_SH_RELATIVE 00010faa 00008c10 000a5 R_SH_RELATIVE 00010faa 00008f80 000a5 R_SH_RELATIVE 00010faa 0000ca3c 000a5 R_SH_RELATIVE 00010faa 0000cdac 000a5 R_SH_RELATIVE 00010faa 0000f550 000a5 R_SH_RELATIVE 00010ec0 0000f670 000a5 R_SH_RELATIVE 00010ec0 00010374 000a5 R_SH_RELATIVE 00010f0c 00010654 000a5 R_SH_RELATIVE 00010ec0 00010d50 000a5 R_SH_RELATIVE 00010ec0 Relocation section '.rela.got' at offset 0x17c4 contains 65 entries: Offset Info Type Symbol's Value Symbol's Name Addend 00023924 000a5 R_SH_RELATIVE 00001f60 000239f4 000a5 R_SH_RELATIVE 00010160 000239f0 000a5 R_SH_RELATIVE 00023890 00023980 000a5 R_SH_RELATIVE 00023c10 000239e4 000a5 R_SH_RELATIVE 00023bfc 00023930 000a5 R_SH_RELATIVE 00023c24 00023988 000a5 R_SH_RELATIVE 00023e58 00023934 000a5 R_SH_RELATIVE 00023e5c 00023920 000a5 R_SH_RELATIVE 0000b660 00023950 000a5 R_SH_RELATIVE 00023e64 00023984 000a5 R_SH_RELATIVE 00023e6c 000239d0 000a5 R_SH_RELATIVE 00023898 000239e8 000a5 R_SH_RELATIVE 0000dbc0 00023998 000a5 R_SH_RELATIVE 00023e78 0002399c 000a5 R_SH_RELATIVE 00023e7c 00023914 000a5 R_SH_RELATIVE 00023e88 000239b4 000a5 R_SH_RELATIVE 0000b0e0 00023944 000a5 R_SH_RELATIVE 00023e90 0002392c 000a5 R_SH_RELATIVE 00023e98 00023978 000a5 R_SH_RELATIVE 00023e9c 000239b0 000a5 R_SH_RELATIVE 0000b140 00023940 000a5 R_SH_RELATIVE 00001ee0 0002394c 000a5 R_SH_RELATIVE 00023ea4 00023958 000a5 R_SH_RELATIVE 000135c4 0002397c 000a5 R_SH_RELATIVE 00023eb0 00023a00 000a5 R_SH_RELATIVE 00010780 000239fc 000a5 R_SH_RELATIVE 000107a0 0002398c 000a5 R_SH_RELATIVE 00023894 000239f8 000a5 R_SH_RELATIVE 00023eb8 000239e0 000a5 R_SH_RELATIVE 00023ef4 00023970 000a5 R_SH_RELATIVE 00023ebc 000239ec 000a5 R_SH_RELATIVE 0002389c 000239a8 000a5 R_SH_RELATIVE 0001216c 00023928 000a5 R_SH_RELATIVE 00023ec0 000239d4 000a5 R_SH_RELATIVE 00023ecc 000239d8 000a5 R_SH_RELATIVE 00023ed0 00023948 000a5 R_SH_RELATIVE 00023ee8 000239ac 000a5 R_SH_RELATIVE 00023864 000239a4 000a5 R_SH_RELATIVE 00023ef0 000239c4 011a3 R_SH_GLOB_DAT 00023c04 __libc_internal_tsd_set + 0 00023a08 015a3 R_SH_GLOB_DAT 00000000 __pthread_mutex_lock + 0 0002396c 016a3 R_SH_GLOB_DAT 00023c08 _dl_profile_output + 0 00023910 017a3 R_SH_GLOB_DAT 00023c0c __libc_stack_end + 0 00023994 018a3 R_SH_GLOB_DAT 00023888 _dl_debug_fd + 0 00023964 019a3 R_SH_GLOB_DAT 00023c14 _dl_initial_searchlist + 0 000239a0 01ea3 R_SH_GLOB_DAT 00023e50 _dl_platformlen + 0 00023974 020a3 R_SH_GLOB_DAT 00023e54 _dl_debug_impcalls + 0 00023a04 021a3 R_SH_GLOB_DAT 00000000 __pthread_mutex_init + 0 0002395c 026a3 R_SH_GLOB_DAT 00023e60 _dl_profile + 0 000239b8 028a3 R_SH_GLOB_DAT 00023e70 _dl_global_scope_alloc + 0 00023954 02aa3 R_SH_GLOB_DAT 00023e74 __libc_enable_secure + 0 00023960 02ca3 R_SH_GLOB_DAT 00023e80 _dl_global_scope + 0 000239c0 02da3 R_SH_GLOB_DAT 00023e8c __libc_internal_tsd_get + 0 00023a10 02fa3 R_SH_GLOB_DAT 00000000 __pthread_mutex_unlock + 0 0002393c 032a3 R_SH_GLOB_DAT 00023e94 _dl_lazy + 0 000239cc 033a3 R_SH_GLOB_DAT 0000b780 _dl_debug_state + 0 00023a0c 035a3 R_SH_GLOB_DAT 00000000 __pthread_mutex_destroy + 0 00023918 038a3 R_SH_GLOB_DAT 00023ea0 _dl_main_searchlist + 0 00023990 03ea3 R_SH_GLOB_DAT 00023eac _dl_origin_path + 0 0002391c 042a3 R_SH_GLOB_DAT 00023eb4 _dl_starting_up + 0 000239bc 044a3 R_SH_GLOB_DAT 0000ca70 _dl_mcount + 0 000239dc 047a3 R_SH_GLOB_DAT 00023830 _dl_fpu_control + 0 00023938 048a3 R_SH_GLOB_DAT 00023ec4 _dl_loaded + 0 00023968 04aa3 R_SH_GLOB_DAT 00023ec8 _dl_profile_map + 0 000239c8 04ca3 R_SH_GLOB_DAT 00023ed4 _r_debug + 0 Relocation section '.rela.plt' at offset 0x1ad0 contains 25 entries: Offset Info Type Symbol's Value Symbol's Name Addend 000238ac 015a4 R_SH_JMP_SLOT 00000000 __pthread_mutex_lock + 0 000238b0 01ba4 R_SH_JMP_SLOT 0000cdc0 _dl_sysdep_start + 0 000238b4 021a4 R_SH_JMP_SLOT 00000000 __pthread_mutex_init + 0 000238b8 022a4 R_SH_JMP_SLOT 0000d990 malloc + 0 000238bc 025a4 R_SH_JMP_SLOT 000082c0 _dl_lookup_versioned_symb + 0 000238c0 02ba4 R_SH_JMP_SLOT 00007920 _dl_lookup_symbol + 0 000238c4 02ea4 R_SH_JMP_SLOT 0000daa0 calloc + 0 000238c8 02fa4 R_SH_JMP_SLOT 00000000 __pthread_mutex_unlock + 0 000238cc 033a4 R_SH_JMP_SLOT 0000b780 _dl_debug_state + 0 000238d0 034a4 R_SH_JMP_SLOT 00005060 _dl_dst_substitute + 0 000238d4 035a4 R_SH_JMP_SLOT 00000000 __pthread_mutex_destroy + 0 000238d8 037a4 R_SH_JMP_SLOT 0000b550 _dl_init_next + 0 000238dc 039a4 R_SH_JMP_SLOT 0000db20 realloc + 0 000238e0 03aa4 R_SH_JMP_SLOT 0000c1f0 _dl_check_all_versions + 0 000238e4 03ba4 R_SH_JMP_SLOT 0000b730 _dl_debug_initialize + 0 000238e8 03fa4 R_SH_JMP_SLOT 0000c250 _dl_start_profile + 0 000238ec 040a4 R_SH_JMP_SLOT 00009460 _dl_relocate_object + 0 000238f0 041a4 R_SH_JMP_SLOT 00004f50 _dl_dst_count + 0 000238f4 043a4 R_SH_JMP_SLOT 000078d0 _dl_unload_cache + 0 000238f8 045a4 R_SH_JMP_SLOT 0000b880 _dl_debug_message + 0 000238fc 046a4 R_SH_JMP_SLOT 000070c0 _dl_map_object + 0 00023900 049a4 R_SH_JMP_SLOT 0000b190 _dl_signal_error + 0 00023904 04da4 R_SH_JMP_SLOT 0000b380 _dl_catch_error + 0 00023908 04ea4 R_SH_JMP_SLOT 0000daf0 free + 0 0002390c 04fa4 R_SH_JMP_SLOT 0000a460 _dl_map_object_deps + 0 --8<--8<--SNIP-SNIP--8<--8<-- > I imagine that your ld.so has .rela.text and the relocation > R_SH_DIR32 or so. It needs the modification of .text segment > of ld.so and becomes the cause of fail as you describe. Sounds pretty much like the problem I have > Ordinary this type of relocation isn't problem at all since > ld.so will modify the .text segment of the ELF object using > mprotect. But in the bootstrap of ld.so, there is not working > ld.so yet :-) That would explain :) From what I have been able to gather (and understand), offsets are extracted out of the relocation table, added to the load address and a new fixed-up value is simply written to it (which fails). There is nothing fancy there. > I want to know also which version of toolchain and their patch I use : - binutils-000218 with the binutils-000205 SH patch and the modifications by hand described in Jerome's FAQ. My target name is "sh-pc-linux-gnu" and your PIC patches for SH (binutils-000123-000131 if I remember correctly). I had to patch some things by hand because of syntax changes between binutils 000205 and 000218. - gcc-core 2.95.2 with the gcc-2.95.2-000203 SH patch and gcc-2.95.2-symbol-vis-000205 patch. Again, my target name is "sh-pc-linux-gnu" The kernel compiles and works dandy with these tools, and so do statically linked programs and the bootloader I created for that particular board (and that I can't disclose unfortunately). > do you use. Niibe-san's visibility patchs for gcc/binutils may > solve your problem. Please check > ftp://ftp.m17n.org/pub/linux-sh/binutils-000218-000219.diff.gz > and > ftp://ftp.m17n.org/pub/linux-sh/gcc-symbol-vis-000219.diff.gz I'll give them a try right now ! Thanks, Take care --- Pierre-Philippe Coupard <pi...@li...> Software Engineer, Lineo, Inc. 801-426-5001 x 208 --- |
From: NIIBE Y. <gn...@ch...> - 2000-05-01 23:43:12
|
Hello Pierre! Thanks for your feedback. (1) RAMDISK issue I'll try that. Thanks. (2) Initialization of SCI I think that this issue is resolved in current kernel (2.3.99-pre6 and later). If not, please let us know. (3) Peripheral clock > Ideally, I think it'd be good to have an option in the .config to > set the bus clock speed and have several tables defined and > selected with #ifdefs. Yes, that'd be a solution. Alternatively, we could use the value measured with RTC. I'm thinking exporting the variable sh_periheral_clock and sh_module_clock from time.c. I know that current code of time.c is not correct for all the cases, but it works at least for me. > I don't know if any of the above will help anyone but I thought I > might share my findings. Surely, it helps much. Thank you. > Now for the plea for help :-) : Yes. Welcome to the development team!! > I assume everybody on the list has userland programs compiled > dynamically and running good on their boards. For some reason, I > can run programs that have been compiled statically against glibc > just fine, but I can't run dynamically linked programs because > ld.so segfaults (I use Kaz' latest patch for glibc). What happens > is that ld.so starts, and eventually the function > elf_machine_rela() (in sysdeps/sh/sh3/dl-machine.h) is called > during the initial relocation from _dl_start() and the segfault > occurs when the code tries (I think) to poke a fixed-up address in > the code section (which is read-only) instead of the GOT (which is > read-write). Your description is correct. I guess that the target label to be resolved is the one of libgcc.a, isn't it? Here is the story. ---------------- (a) Libgcc is the library of functions which GCC assumes. In the case of SuperH, division results the function call to libgcc, for example. (b) ld.so is the dynamic loader, it could not depends on other libraries, by definition (since it *is* the first entity to be loaded and it load other libraries). (c) In the current setting of GCC and GNU Binutils, there's no difference between libgcc and other libraries. The linker handles libgcc as just a library. [... I forgot the detail, I'll explain later if needed ...] (z) In the current building process of GNU C library, we unfortunately have relocation entries for libgcc. ---------------- There'd be many ways to resolve this issue. Say, having libgcc shared library, changing GNU C library building process, and so on. My trial is changing GCC so that we can distingush the label of libgcc functions. Please get the patch from: ftp://ftp.m17n.org/pub/super-h/gcc-symbol-vis-000501.diff.gz It's agains the Kaz' patch of gcc-2.95.2-000228. WARNING: This is just a experimental hack. This may not included standard distribution of GCC, since I did this hack without seeing the proposed-but-not-yet-released gABI, guess(and expect)ing the feature. With this patch, you don't see the entries on ld.so. Again, this may be work around, not the solution. We have to think hard, more... Please let me know how this works (or not) for you, if you will try. -- Niibe Yutaka |
From: kaz K. <kk...@rr...> - 2000-05-01 23:24:07
|
Hi > ld.so starts, and eventually the function elf_machine_rela() (in > sysdeps/sh/sh3/dl-machine.h) is called during the initial relocation > from _dl_start() and the segfault occurs when the code tries (I think) > to poke a fixed-up address in the code section (which is read-only) > instead of the GOT (which is read-write). > > I believe it's a linker problem, but I'm no expert with ld.so nor ld so > I'm having hard times figuring out what's wrong. Anybody out there has > a clue what the problem might be ? I have traces of ld.so's startup and > other informations relevant to the problem if you think it'd be helpful. Can you please give us the result of readelf -r ld.so? It shows relocations of ld.so. I imagine that your ld.so has .rela.text and the relocation R_SH_DIR32 or so. It needs the modification of .text segment of ld.so and becomes the cause of fail as you describe. Ordinary this type of relocation isn't problem at all since ld.so will modify the .text segment of the ELF object using mprotect. But in the bootstrap of ld.so, there is not working ld.so yet :-) I want to know also which version of toolchain and their patch do you use. Niibe-san's visibility patchs for gcc/binutils may solve your problem. Please check ftp://ftp.m17n.org/pub/linux-sh/binutils-000218-000219.diff.gz and ftp://ftp.m17n.org/pub/linux-sh/gcc-symbol-vis-000219.diff.gz kaz |
From: <pi...@li...> - 2000-05-01 17:30:50
|
Hello Niibe-San and everybody NIIBE Yutaka wrote: > To compare the behavior (of SH-4), I worked for SH7709A (in the > office). It's another SolutionEngine. It also failed with RAMDISK > support (like SH-4). > > In my home, SH7708 works fine (with no RAMDISK), RAMDISK may be the > cause. Speaking of which ... I don't know if it has anything to do with it but there it goes : I've been working on getting the 2.3.99-pre? kernels going on Hypercom's "WindowsCE ICE" board (which is a flavor of the P2 board from Hitachi, I understand) for some time now : this board has a 7707 and 16M of RAM. I had to do some modifications to the ramdisk (and the SCI and tty drivers) to get the kernel to boot and use the SCI as initial terminal on this board : 1) In the ramdisk : it appears that the following lines in drivers/block/rd.c panic the kernel when the kernel tries to mount the initrd filesystem : --8<--8<--SNIP-SNIP--8<--8<-- /* * Immunize device against invalidate_buffers() and prune_icache(). */ if (rd_inode[DEVICE_NR(inode->i_rdev)] == NULL) { if (!inode->i_bdev) return -ENXIO; if ((rd_inode[DEVICE_NR(inode->i_rdev)] = igrab(inode)) != NULL) atomic_inc(&rd_inode[DEVICE_NR(inode->i_rdev)]->i_bdev->bd_openers); } --8<--8<--SNIP-SNIP--8<--8<-- If I comment out these lines, the ramdisk works just fine. They seem to have been added to the kernel fairly recently so I doubt they have been exercised a lot yet. 2) In drivers/char/tty_io.c : the SCI driver doesn't get registered when trying to use it as initial console, so I had to add several lines to get it registered explicitely. Here is the patch : --8<--8<--SNIP-SNIP--8<--8<-- diff -ruN linux_ORIG/drivers/char/tty_io.c linux_PATCHED/drivers/char/tty_io.c --- linux_ORIG/drivers/char/tty_io.c Tue Mar 21 14:04:53 2000 +++ linux_PATCHED/drivers/char/tty_io.c Fri Mar 31 16:13:53 2000 @@ -141,6 +141,11 @@ #ifdef CONFIG_SX extern int sx_init (void); #endif +#ifdef CONFIG_SH_SCI_SERIAL +extern int sci_init (void); +#endif #if defined(CONFIG_MVME162_SCC) || defined(CONFIG_BVME6000_SCC) || defined(CONFIG_MVME147_SCC) extern int vme_scc_init (void); extern long vme_scc_console_init(void); @@ -2317,6 +2322,11 @@ #ifdef CONFIG_SX sx_init(); #endif +#ifdef CONFIG_SH_SCI_SERIAL +sci_init(); +#endif #ifdef CONFIG_RIO rio_init(); #endif --8<--8<--SNIP-SNIP--8<--8<-- 3) In driver/char/sh-sci.c and driver/char/sh-sci.h : the driver assumes a bus clock speed of 14 Mhz. The board I'm working on has a bus clock speed of 30 Mhz, which changes all the timing values for the SCI clock. So, I modified the table and the code to use both timing counter values and clock sources, so that the range of baudrates is higher. Also, I've added a small bit of code to set the baud rate in serial_console_setup(), otherwise the baud rate is not set when using the SCI as initial console. Here is the diff : --8<--8<--SNIP-SNIP--8<--8<-- diff -ruN linux_ORIG/drivers/char/sh-sci.c linux_PATCHED/drivers/char/sh-sci.c --- linux_ORIG/drivers/char/sh-sci.c Mon May 1 10:55:09 2000 +++ linux_PATCHED/drivers/char/sh-sci.c Tue Apr 25 10:18:00 2000 @@ -115,37 +115,73 @@ static void sci_set_baud(struct sci_port *port) { int t; +/*PPC*/ int cks; switch (port->gs.baud) { case 0: t = -1; break; +/*PPC*/ + case 110: + t = BPS_110; + cks = CKS_BPS_110; + break; + case 150: + t = BPS_150; + cks = CKS_BPS_150; + break; + case 300: + t = BPS_300; + cks = CKS_BPS_300; + break; + case 600: + t = BPS_600; + cks = CKS_BPS_600; + break; + case 1200: + t = BPS_1200; + cks = CKS_BPS_1200; + break; +/*\PPC*/ case 2400: t = BPS_2400; +/*PPC*/ cks = CKS_BPS_2400; break; case 4800: t = BPS_4800; +/*PPC*/ cks = CKS_BPS_4800; break; case 9600: t = BPS_9600; +/*PPC*/ cks = CKS_BPS_9600; break; case 19200: t = BPS_19200; +/*PPC*/ cks = CKS_BPS_19200; break; case 38400: t = BPS_38400; +/*PPC*/ cks = CKS_BPS_38400; + break; +/*PPC*/ + case 57600: + t = BPS_57600; + cks = CKS_BPS_57600; break; +/*\PPC*/ default: printk(KERN_INFO "sci: unsupported baud rate: %d, use 115200 instead.\n", port->gs.baud); case 115200: t = BPS_115200; +/*PPC*/ cks = CKS_BPS_115200; break; } if (t > 0) { sci_setsignals (port, 1, -1); if(t >= 256) { - ctrl_out((ctrl_in(SCSMR) & ~3) | 1, SCSMR); +/*PPC ctrl_out((ctrl_in(SCSMR) & ~3) | 1, SCSMR);*/ +/*PPC*/ ctrl_out((ctrl_in(SCSMR) & ~3) | cks, SCSMR); t >>= 2; } ctrl_outb(t, SCBRR); @@ -659,8 +695,10 @@ sci_driver.type = TTY_DRIVER_TYPE_SERIAL; sci_driver.subtype = SERIAL_TYPE_NORMAL; sci_driver.init_termios = tty_std_termios; - sci_driver.init_termios.c_cflag = - B115200 | CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS; +/*PPC sci_driver.init_termios.c_cflag =*/ +/*PPC B115200 | CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS;*/ +/*PPC*/ sci_driver.init_termios.c_cflag = +/*PPC*/ SCI_DEFAULT_SPEED | CS8 | CREAD | HUPCL | CLOCAL; sci_driver.flags = TTY_DRIVER_REAL_RAW; sci_driver.refcount = &sci_refcount; sci_driver.table = sci_table; @@ -747,6 +785,7 @@ #ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB gdb_detach(); #endif +/*PPC*/ printk(KERN_ERR "SCI serial driver registered (major 4)\n"); return 0; /* Return -EIO when not detected */ } @@ -922,7 +961,8 @@ */ static int __init serial_console_setup(struct console *co, char *options) { - int baud = 115200; +/*PPC int baud = 115200;*/ +/*PPC*/ int baud = SCI_DEFAULT_SPEED_VAL; int bits = 8; int parity = 'n'; int cflag = CREAD | HUPCL | CLOCAL; @@ -978,6 +1018,19 @@ co->cflag = cflag; /* XXX: set baud, char, and parity here. */ +/*PPC*/ + { + struct termios termios; + struct tty_struct tty; + struct sci_port port; + + termios.c_cflag=cflag; + port.gs.baud=baud; + tty.termios=&termios; + port.gs.tty=&tty; + sci_set_termios_cflag(&port); + } +/*\PPC*/ return 0; } diff -ru linux_ORIG/drivers/char/sh-sci.h linux_PATCHED/drivers/char/sh-sci.h --- linux_ORIG/drivers/char/sh-sci.h Mon May 1 10:55:33 2000 +++ linux_PATCHED/drivers/char/sh-sci.h Tue Apr 25 14:18:29 2000 @@ -9,6 +9,9 @@ */ #include <linux/config.h> +/*PPC*/ #define SCI_DEFAULT_SPEED B9600 +/*PPC*/ #define SCI_DEFAULT_SPEED_VAL 9600 + #if defined(CONFIG_SH_SCI_SERIAL) #if defined(__sh3__) #define SCSMR (volatile unsigned char *)0xfffffe80 @@ -28,7 +31,8 @@ #define SCSPTR 0xffe0001c #endif -#define SCSCR_INIT 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ +/*PPC #define SCSCR_INIT 0x30 *//* TIE=0,RIE=0,TE=1,RE=1 */ +/*PPC*/ #define SCSCR_INIT 0x31 /* TIE=0,RIE=0,TE=1,RE=1,CKE1=0,CKE0=1*/ #define SCI_TD_E 0x80 #define SCI_RD_F 0x40 @@ -187,7 +191,7 @@ * -- Greg Banks 27Feb2000 */ -#if defined(__sh3__) +/*PPC #if defined(__sh3__) #define PCLK 14745600 #elif defined(__SH4__) #define PCLK 33333333 @@ -199,4 +203,33 @@ #define BPS_9600 SCBRR_VALUE(9600) #define BPS_19200 SCBRR_VALUE(19200) #define BPS_38400 SCBRR_VALUE(38400) -#define BPS_115200 SCBRR_VALUE(115200) +#define BPS_115200 SCBRR_VALUE(115200)*/ + +/* PPC : This table is made from the Hitachi 7707 hardware manual. + It assumes + a bus clock of 30Mhz. It also specifies the clock source so that we can use + a greater range of baudrates */ +#define BPS_110 132 +#define CKS_BPS_110 3 +#define BPS_150 97 +#define CKS_BPS_150 2 +#define BPS_300 194 +#define CKS_BPS_300 2 +#define BPS_600 97 +#define CKS_BPS_600 2 +#define BPS_1200 194 +#define CKS_BPS_1200 1 +#define BPS_2400 97 +#define CKS_BPS_2400 1 +#define BPS_4800 194 +#define CKS_BPS_4800 0 +#define BPS_9600 97 +#define CKS_BPS_9600 0 +#define BPS_19200 48 +#define CKS_BPS_19200 0 +#define BPS_38400 23 +#define CKS_BPS_38400 0 +#define BPS_57600 15 +#define CKS_BPS_57600 0 +#define BPS_115200 7 +#define CKS_BPS_115200 0 --8<--8<--SNIP-SNIP--8<--8<-- Ideally, I think it'd be good to have an option in the .config to set the bus clock speed and have several tables defined and selected with #ifdefs. I don't know if any of the above will help anyone but I thought I might share my findings. Now for the plea for help :-) : I assume everybody on the list has userland programs compiled dynamically and running good on their boards. For some reason, I can run programs that have been compiled statically against glibc just fine, but I can't run dynamically linked programs because ld.so segfaults (I use Kaz' latest patch for glibc). What happens is that ld.so starts, and eventually the function elf_machine_rela() (in sysdeps/sh/sh3/dl-machine.h) is called during the initial relocation from _dl_start() and the segfault occurs when the code tries (I think) to poke a fixed-up address in the code section (which is read-only) instead of the GOT (which is read-write). I believe it's a linker problem, but I'm no expert with ld.so nor ld so I'm having hard times figuring out what's wrong. Anybody out there has a clue what the problem might be ? I have traces of ld.so's startup and other informations relevant to the problem if you think it'd be helpful. Thanks in advance. Take care [BTW, you guys are doing a tremendous job with the LinuxSH project ! well done !] --- Pierre-Philippe Coupard <pi...@li...> Software Engineer, Lineo, Inc. 801-426-5001 x 208 --- |
From: NIIBE Y. <gn...@ch...> - 2000-05-01 10:53:30
|
... is support of SH7709A. To compare the behavior (of SH-4), I worked for SH7709A (in the office). It's another SolutionEngine. It also failed with RAMDISK support (like SH-4). In my home, SH7708 works fine (with no RAMDISK), RAMDISK may be the cause. It would be good if PCLK is _not_ constant, but get the value from time.c. I'll commit this tomorrow. -------------------------- 2000-05-01 NIIBE Yutaka <gn...@m1...> Support of SH7709A. * arch/sh/kernel/time.c (do_timer_interrupt): Remove Takeshi's debugging code (output to Port C). * drivers/char/sh-sci.h (PCLK): Added value for my SH7709A board. * drivers/char/sh-sci.c (sci_set_termios_cflag): Added SH7709's SCPCR/SCPDR handling. (put_char, get_char): Added dummy read of SC_SR, Without this, some garbage characters would appear in the line on SH7709A. Index: arch/sh/kernel/time.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/time.c,v retrieving revision 1.5 diff -u -r1.5 time.c --- arch/sh/kernel/time.c 2000/04/30 23:33:47 1.5 +++ arch/sh/kernel/time.c 2000/05/01 10:35:48 @@ -204,13 +204,6 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { do_timer(regs); -#ifdef TAKESHI - { - unsigned long what_is_this=0xa4000124; - - ctrl_outb(ctrl_inb(what_is_this)+1,what_is_this); - } -#endif #if 0 if (!user_mode(regs)) sh_do_profile(regs->pc); Index: drivers/char/sh-sci.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/drivers/char/sh-sci.c,v retrieving revision 1.4 diff -u -r1.4 sh-sci.c --- drivers/char/sh-sci.c 2000/04/15 07:08:02 1.4 +++ drivers/char/sh-sci.c 2000/05/01 10:35:49 @@ -189,10 +189,35 @@ ctrl_out(smr_val, SCSMR); #if defined(CONFIG_SH_SCIF_SERIAL) +#if defined(__sh3__) + { /* For SH7709, SH7709A, SH7729 */ + unsigned short data; + + /* We need to set SCPCR to enable RTS/CTS */ + data = ctrl_inw(SCPCR); + /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ + ctrl_outw(data&0x0fcf, SCPCR); + } +#endif if (C_CRTSCTS(port->gs.tty)) fcr_val |= 0x08; - else + else { +#if defined(__sh3__) + unsigned short data; + + /* We need to set SCPCR to enable RTS/CTS */ + data = ctrl_inw(SCPCR); + /* Clear out SCP7MD1,0, SCP4MD1,0, + Set SCP6MD1,0 = {01} (output) */ + ctrl_outw((data&0x0fcf)|0x1000, SCPCR); + + data = ctrl_inb(SCPDR); + /* Set /RTS2 (bit6) = 0 */ + ctrl_outb(data&0xbf, SCPDR); +#elif defined(__SH4__) ctrl_outw(0x0080, SCSPTR); /* Set RTS = 1 */ +#endif + } ctrl_out(fcr_val, SCFCR); #endif @@ -789,8 +814,8 @@ while (!(status & SCI_TD_E)); ctrl_outb(c, SC_TDR); + ctrl_in(SC_SR); /* Dummy read */ ctrl_out(SCI_TD_E_CLEAR, SC_SR); - restore_flags(flags); } @@ -817,6 +842,7 @@ } } while (!(status & SCI_RD_F)); c = ctrl_inb(SC_RDR); + ctrl_in(SC_SR); /* Dummy read */ ctrl_out(SCI_RDRF_CLEAR, SC_SR); restore_flags(flags); Index: drivers/char/sh-sci.h =================================================================== RCS file: /cvsroot/linuxsh/kernel/drivers/char/sh-sci.h,v retrieving revision 1.2 diff -u -r1.2 sh-sci.h --- drivers/char/sh-sci.h 2000/04/14 17:25:44 1.2 +++ drivers/char/sh-sci.h 2000/05/01 10:35:49 @@ -69,7 +69,10 @@ #define SC_RDR 0xA400015A #define SCFCR (volatile unsigned char *)0xA400015C #define SCFDR 0xA400015E -#undef SCSPTR /* Is there any register for RTS?? */ + +#undef SCSPTR /* SH7709 doesn't have SCSPTR */ +#define SCPCR 0xA4000116 /* Instead, it has SCPCR and SCPDR */ +#define SCPDR 0xA4000136 #undef SCLSR #define SCSCR_INIT 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ @@ -187,8 +190,17 @@ * -- Greg Banks 27Feb2000 */ +/* + * XXX: Well, this is not relevant... + * Should we have config option for peripheral clock? + * Or we get the value from time.c. + */ #if defined(__sh3__) -#define PCLK 14745600 +#if defined(CONFIG_CPU_SUBTYPE_SH7709) +#define PCLK 33333333 +#else +#define PCLK 14745600 /* Isn't it 15MHz? */ +#endif #elif defined(__SH4__) #define PCLK 33333333 #endif |
From: Mitch D. <mj...@au...> - 2000-05-01 02:01:56
|
NIIBE Yutaka wrote: > > While chasing the bug which stops SH-4 running, I've found two more > bugs. But this doesn't fix my problem... > > Index: mm/vmscan.c > =================================================================== > RCS file: /cvsroot/linuxsh/kernel/mm/vmscan.c,v > retrieving revision 1.1.1.3 > diff -u -r1.1.1.3 vmscan.c > --- mm/vmscan.c 2000/04/29 15:46:04 1.1.1.3 > +++ mm/vmscan.c 2000/04/30 03:45:48 > @@ -388,7 +388,7 @@ > continue; > /* small processes are swapped out less */ > while ((mm->swap_cnt << 2 * (i + 1) < max_cnt) > - && i++ < 10) > + && i++ < 10); This code changed in pre7-1, so if it's a bug I don't think we'll be the only people to have it. Regards, Mitch. -- | mailto:mj...@au... | Not the official view of: | | mailto:mj...@al... | Australian Calculator Opn | | Certified Linux Evangelist! | Hewlett Packard Australia | |
From: NIIBE Y. <gn...@ch...> - 2000-04-30 23:40:17
|
And another one. I'll commit this too. 2000-04-30 NIIBE Yutaka <gn...@m1...> * arch/sh/kernel/entry.S (restore_all): Bug fix. We should consider FPU exception within the critical region. We should not change the IMASK value in this case. Or else, we would introduce a "hole" in the critical region. Index: arch/sh/kernel/entry.S =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/entry.S,v retrieving revision 1.9 diff -u -r1.9 entry.S --- arch/sh/kernel/entry.S 2000/04/30 00:50:23 1.9 +++ arch/sh/kernel/entry.S 2000/04/30 23:27:35 @@ -492,7 +492,16 @@ mov.l 2f, $k1 and $k1, $k2 ! Mask orignal SR value or $k0, $k2 ! Inherit current FD-bit - or $g_imask, $k2 ! Inherit the IMASK-bits + ! + mov $k3, $k0 ! Calculate IMASK-bits + shlr2 $k0 + and #0x3c, $k0 + cmp/eq #0x3c, $k0 + bf/s 7f + mov $g_imask, $k0 + shll2 $k0 + ! +7: or $k0, $k2 ! Set the IMASK-bits ldc $k2, $ssr ! #if defined(__SH4__) @@ -507,7 +516,7 @@ ! There's the case we don't get FPU now stc $sr, $k2 tst $k1, $k2 - bt 7f + bt 8f ! We need to grab FPU here xor $k1, $k2 ldc $k2, $sr ! Grab FPU @@ -519,7 +528,7 @@ ! ! Restoring FPU... ! -7: mov.l 3f, $k1 +8: mov.l 3f, $k1 lds $k1, $fpscr fmov.s @$r15+, $fr0 fmov.s @$r15+, $fr1 |
From: NIIBE Y. <gn...@ch...> - 2000-04-30 04:40:19
|
While chasing the bug which stops SH-4 running, I've found two more bugs. But this doesn't fix my problem... I'll commit this tomorrow. Index: ChangeLog =================================================================== RCS file: /cvsroot/linuxsh/kernel/ChangeLog,v retrieving revision 1.11 diff -u -r1.11 ChangeLog --- ChangeLog 2000/04/30 00:51:08 1.11 +++ ChangeLog 2000/04/30 03:45:38 @@ -1,3 +1,11 @@ +2000-04-30 NIIBE Yutaka <gn...@m1...> + + * arch/sh/mm/fault.c (update_mmu_cache): Bug fix. We need to + flush ITLB. + + * arch/sh/kernel/time.c (time_init): Bug fix. The interval + should depend on HZ. + 2000-04-29 NIIBE Yutaka <gn...@m1...> * arch/sh/mm/cache.c (flush_cache_all): Don't touch CCR. Index: arch/sh/kernel/time.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/time.c,v retrieving revision 1.4 diff -u -r1.4 time.c --- arch/sh/kernel/time.c 2000/04/28 17:58:50 1.4 +++ arch/sh/kernel/time.c 2000/04/30 03:45:39 @@ -436,7 +436,7 @@ module_clock = master_clock/pfc; printk("Module clock: %d.%02dMHz\n", (module_clock/1000000), (module_clock % 1000000)/10000); - interval = (module_clock/400); + interval = (module_clock/(HZ*4)); printk("Interval = %ld\n", interval); Index: arch/sh/mm/fault.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/mm/fault.c,v retrieving revision 1.7 diff -u -r1.7 fault.c --- arch/sh/mm/fault.c 2000/04/30 00:50:23 1.7 +++ arch/sh/mm/fault.c 2000/04/30 03:45:39 @@ -261,18 +261,24 @@ unsigned long pteaddr; save_and_cli(flags); +#if defined(__SH4__) /* - * We don't need to set PTEH register. - * It's automatically set by the hardware. + * ITLB is not affected by "ldtlb" instruction. + * So, we need to flush the entry by ourselves. */ + __flush_tlb_page(vma->vm_mm, address&PAGE_MASK); +#endif + + /* Set PTEH register */ + pteaddr = (address & MMU_VPN_MASK) | + (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK); + ctrl_outl(pteaddr, MMU_PTEH); + + /* Set PTEL register */ pteval = pte_val(pte); pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ pteval |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */ - /* Set PTEL register */ ctrl_outl(pteval, MMU_PTEL); - /* Set PTEH register */ - pteaddr = (address & MMU_VPN_MASK) | (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK); - ctrl_outl(pteaddr, MMU_PTEH); /* Load the TLB */ asm volatile("ldtlb": /* no output */ : /* no input */ : "memory"); Bug fix for standard kernel. -------------------------------------- Index: fs/super.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/fs/super.c,v retrieving revision 1.1.1.6 diff -u -r1.1.1.6 super.c --- fs/super.c 2000/04/29 15:46:02 1.1.1.6 +++ fs/super.c 2000/04/30 03:45:40 @@ -1562,7 +1562,7 @@ } ROOT_DEV = new_root_dev; mount_root(); -#if 1 +#if 0 shrink_dcache(); printk("change_root: old root has d_count=%d\n", old_root->d_count); #endif Index: mm/vmscan.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/mm/vmscan.c,v retrieving revision 1.1.1.3 diff -u -r1.1.1.3 vmscan.c --- mm/vmscan.c 2000/04/29 15:46:04 1.1.1.3 +++ mm/vmscan.c 2000/04/30 03:45:48 @@ -388,7 +388,7 @@ continue; /* small processes are swapped out less */ while ((mm->swap_cnt << 2 * (i + 1) < max_cnt) - && i++ < 10) + && i++ < 10); mm->swap_cnt >>= i; mm->swap_cnt += i; /* if swap_cnt reaches 0 */ /* we're big -> hog treatment */ |
From: Mitch D. <mj...@hp...> - 2000-04-29 17:25:09
|
> Mitch Davis wrote: > > I have imported the source for Linux kernel version 2.3.99pre6-7 > > into our CVS repository. > > Thank you. > > But, current is Linux 2.3.99-pre6. Silly me, thanks for pointing that out. I have now imported the source for Linux kernel version 2.3.99pre7-1 (which is later than pre6) into our CVS repository. In future I intend doing kernel imports at most once per week. Any more than that and I will spend all my time importing kernels and never do all the other things I want to do. If anyone has any problems with this release, please let me know. Regards, Mitch. -- | mailto:mj...@au... | Not the official view of: | | mailto:mj...@al... | Australian Calculator Opn | | Certified Linux Evangelist! | Hewlett Packard Australia | |
From: NIIBE Y. <gn...@ch...> - 2000-04-29 01:52:46
|
Mitch Davis wrote: > I have imported the source for Linux kernel version 2.3.99pre6-7 > into our CVS repository. Thank you. But, current is Linux 2.3.99-pre6. Sorry for my ambiguous statement. You can check the current status with: $ finger @finger.kernel.org -- |
From: Mitch D. <mj...@au...> - 2000-04-28 20:20:34
|
Hi guys, I have imported the source for Linux kernel version 2.3.99pre6-7 into our CVS repository. Because Niibe-san sent all of our changes to Linus, and he included them, we now have pretty much a *standard* official kernel which will be useful to people out of the box. Niibe-san, you may do what you need to with the cache stuff. If not having this fix hinders or prevents operation, I would suggest getting this thoroughly tested, then sent to Linus before he finally closes the door and releases Linux 2.4.0. Well done to all! Regards, Mitch. -- | mailto:mj...@au... | Not the official view of: | | mailto:mj...@al... | Australian Calculator Opn | | Certified Linux Evangelist! | Hewlett Packard Australia | |
From: NIIBE Y. <gn...@ch...> - 2000-04-28 07:32:46
|
I think I've fixed issues for cache.c. Here is ChangeLog and the file. (It looks good than the diffs to review). I'll commit this after the import of the 2.3.99.pre6. -------------------------- 2000-04-28 NIIBE Yutaka <gn...@m1...> Bug fixes of cache handling of SH-4. * arch/sh/mm/cache.c (dcache_flush_range, dcache_purge_range, dcache_wback_range): Renamed from cache_flush_area, cache_purge_area, cache_wback_area, and only handle D-cache. (icache_purge_range): New function. (flush_icache_range): Use icache_purge_range. (flush_icache_page): Bug fix. Rewritten. (flush_cache_range): Bug fix. Rewritten. (flush_page_to_ram): Implemented. (cache_wback_all): Assumes it is called P2 area, and make it inline function. (cache_init): Jump to P2-area before calling cache_wback_all. (flush_cache_all): Likewise. (CACHE_IC_ENTRY_SHIFT, CACHE_IC_NUM_ENTRIES, CACHE_OC_ENTRY_PHYS_MASK): New macros. * include/asm-sh/cache.h (cache_flush_area, cache_purge_area, cache_wback_area): Hide them as cache.c static function. 2000-04-27 NIIBE Yutaka <gn...@m1...> Bug fix of cache handling of SH-4. * arch/sh/mm/cache.c (flush_page_to_ram): Replaced from __flush_page_to_ram. * include/asm-sh/pgtable.h (__flush_page_to_ram): Removed. (flush_page_to_ram): Declare directly. * include/asm-sh/system.h (back_to_P1): Added one more nop. -------------------------- /* $Id: cache.c,v 1.14 2000/04/27 13:50:11 gniibe Exp $ * * linux/arch/sh/mm/cache.c * * Copyright (C) 1999, 2000 Niibe Yutaka * */ #include <linux/init.h> #include <linux/mman.h> #include <linux/mm.h> #include <linux/threads.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/processor.h> #include <asm/cache.h> #include <asm/io.h> #include <asm/uaccess.h> #if defined(__sh3__) #define CCR 0xffffffec /* Address of Cache Control Register */ #define CCR_CACHE_VAL 0x00000005 /* 8k-byte cache, P1-wb, enable */ #define CCR_CACHE_INIT 0x0000000d /* 8k-byte cache, CF, P1-wb, enable */ #define CCR_CACHE_ENABLE 1 #define CACHE_IC_ADDRESS_ARRAY 0xf0000000 /* SH-3 has unified cache system */ #define CACHE_OC_ADDRESS_ARRAY 0xf0000000 #define CACHE_VALID 1 #define CACHE_UPDATED 2 /* 7709A/7729 has 16K cache (256-entry), while 7702 has only 2K(direct) 7702 is not supported (yet) */ struct _cache_system_info { int way_shift; int entry_mask; int num_entries; }; static struct _cache_system_info cache_system_info; #define CACHE_OC_WAY_SHIFT (cache_system_info.way_shift) #define CACHE_IC_WAY_SHIFT (cache_system_info.way_shift) #define CACHE_OC_ENTRY_SHIFT 4 #define CACHE_OC_ENTRY_MASK (cache_system_info.entry_mask) #define CACHE_IC_ENTRY_MASK (cache_system_info.entry_mask) #define CACHE_OC_NUM_ENTRIES (cache_system_info.num_entries) #define CACHE_OC_NUM_WAYS 4 #define CACHE_IC_NUM_WAYS 4 #elif defined(__SH4__) #define CCR 0xff00001c /* Address of Cache Control Register */ #define CCR_CACHE_VAL 0x00000105 /* 8k+16k-byte cache,P1-wb,enable */ #define CCR_CACHE_INIT 0x0000090d /* 8k+16k-byte cache,ICI,OCI,P1-wb,enable */ #define CCR_CACHE_ENABLE 0x00000101 #define CACHE_IC_ADDRESS_ARRAY 0xf0000000 #define CACHE_OC_ADDRESS_ARRAY 0xf4000000 #define CACHE_VALID 1 #define CACHE_UPDATED 2 #define CACHE_OC_WAY_SHIFT 13 #define CACHE_IC_WAY_SHIFT 13 #define CACHE_OC_ENTRY_SHIFT 5 #define CACHE_IC_ENTRY_SHIFT 5 #define CACHE_OC_ENTRY_MASK 0x3fe0 #define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0 #define CACHE_IC_ENTRY_MASK 0x1fe0 #define CACHE_IC_NUM_ENTRIES 256 #define CACHE_OC_NUM_ENTRIES 512 #define CACHE_OC_NUM_WAYS 1 #define CACHE_IC_NUM_WAYS 1 #endif /* * Write back all the cache. * * For SH-4, we only need to flush (write back) Operand Cache, * as Instruction Cache doesn't have "updated" data. * * Assumes that this is called in interrupt disabled context, and P2. * Shuld be INLINE function. */ static inline void cache_wback_all(void) { unsigned long addr, data, i, j; for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { for (j=0; j<CACHE_OC_NUM_WAYS; j++) { addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)| (i<<CACHE_OC_ENTRY_SHIFT); data = ctrl_inl(addr); if (data & CACHE_UPDATED) { data &= ~CACHE_UPDATED; ctrl_outl(data, addr); } } } } static void detect_cpu_and_cache_system(void) { #if defined(__sh3__) unsigned long addr0, addr1, data0, data1, data2, data3; jump_to_P2(); /* * Check if the entry shadows or not. * When shadowed, it's 128-entry system. * Otherwise, it's 256-entry system. */ addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12); addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12); data0 = ctrl_inl(addr0); data0 ^= 0x00000001; ctrl_outl(data0,addr0); data1 = ctrl_inl(addr1); data2 = data1 ^ 0x00000001; ctrl_outl(data2,addr1); data3 = ctrl_inl(addr0); /* Invaliate them, in case the cache has been enabled already. */ ctrl_outl(data0&~0x00000001, addr0); ctrl_outl(data2&~0x00000001, addr1); back_to_P1(); if (data0 == data1 && data2 == data3) { /* Shadow */ cache_system_info.way_shift = 11; cache_system_info.entry_mask = 0x7f0; cache_system_info.num_entries = 128; cpu_data->type = CPU_SH7708; } else { /* 7709A or 7729 */ cache_system_info.way_shift = 12; cache_system_info.entry_mask = 0xff0; cache_system_info.num_entries = 256; cpu_data->type = CPU_SH7729; } #elif defined(__SH4__) cpu_data->type = CPU_SH7750; #endif } void __init cache_init(void) { unsigned long ccr; detect_cpu_and_cache_system(); ccr = ctrl_inl(CCR); if (ccr == CCR_CACHE_VAL) return; jump_to_P2(); if (ccr & CCR_CACHE_ENABLE) /* * XXX: Should check RA here. * If RA was 1, we only need to flush the half of the caches. */ cache_wback_all(); ctrl_outl(CCR_CACHE_INIT, CCR); back_to_P1(); } #if defined(__SH4__) /* * SH-4 has virtually indexed and physically tagged cache. */ /* * Write back D-caches to memory (if needed) and invalidate then. * * START, END: Virtual Address */ static void dcache_flush_range(unsigned long start, unsigned long end) { unsigned long v; start &= ~(L1_CACHE_BYTES-1); for (v = start; v < end; v+=L1_CACHE_BYTES) { asm volatile("ocbp %0" : /* no output */ : "m" (__m(v))); } } /* * Purge (just invalidate, no write back) the D-caches. * * START, END: Virtual Address * * FYI: * On SH-3, it seems that we have no way to just purge (with no write * back action) the cache line. */ static void dcache_purge_range(unsigned long start, unsigned long end) { unsigned long v; start &= ~(L1_CACHE_BYTES-1); for (v = start; v < end; v+=L1_CACHE_BYTES) { asm volatile("ocbi %0" : /* no output */ : "m" (__m(v))); } } /* * Write back the dirty D-caches, but not invalidate them. * * START, END: Virtual Address */ static void dcache_wback_range(unsigned long start, unsigned long end) { unsigned long v; start &= ~(L1_CACHE_BYTES-1); for (v = start; v < end; v+=L1_CACHE_BYTES) { asm volatile("ocbwb %0" : /* no output */ : "m" (__m(v))); } } /* * Invalidate I-caches. * * START, END: Virtual Address * */ static void icache_purge_range(unsigned long start, unsigned long end) { unsigned long addr, data, v; start &= ~(L1_CACHE_BYTES-1); jump_to_P2(); /* * To handle the cache-line, we calculate the entry with virtual * address: entry = vaddr & CACHE_IC_ENTRY_MASK. * * With A-bit "on", data written to is translated by MMU and * compared the tag of cache and if it's not matched, nothing * will be occurred. (We can avoid flushing other caches.) * */ for (v = start; v < end; v+=L1_CACHE_BYTES) { addr = CACHE_IC_ADDRESS_ARRAY | (v&CACHE_IC_ENTRY_MASK) | 0x8 /* A-bit */; data = (v&0xfffffc00); /* Valid=0 */ ctrl_outl(data, addr); } back_to_P1(); } /* * Write back the range of D-cache, and purge the I-cache. * * Called from sh/kernel/signal.c. */ void flush_icache_range(unsigned long start, unsigned long end) { dcache_wback_range(start, end); icache_purge_range(start, end); } /* * Invalidate the I-cache of the page (don't need to write back D-cache). * * Called from kernel/ptrace.c, mm/memory.c after flush_page_to_ram is called. */ void flush_icache_page(struct vm_area_struct *vma, struct page *pg) { unsigned long phys, addr, data, i; /* * Alas, we don't know where the virtual address is, * So, we can't use icache_purge_range(). */ /* Physical address of this page */ phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; jump_to_P2(); /* Loop all the I-cache */ for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) { addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT); data = ctrl_inl(addr); if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { data &= ~CACHE_VALID; ctrl_outl(data, addr); } } back_to_P1(); } void flush_cache_all(void) { unsigned long flags; save_and_cli(flags); jump_to_P2(); /* Write back Operand Cache */ cache_wback_all(); /* Then, invalidate Instruction Cache and Operand Cache */ ctrl_outl(CCR_CACHE_INIT, CCR); back_to_P1(); restore_flags(flags); } void flush_cache_mm(struct mm_struct *mm) { /* Is there any good way? */ /* XXX: possibly call flush_cache_range for each vm area */ flush_cache_all(); } void flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { /* * Calling * dcache_flush_range(start, end); * is not good for the purpose of this function. That is, * flushing cache lines indexed by the virtual address is not * sufficient. * * Instead, we need to flush the relevant cache lines which * hold the data of the corresponding physical memory, as we * have "alias" issues. * * This is needed because, kernel accesses the memory through * P1-area (and/or U0-area) and user-space accesses through U0-area. * And P1-area and U0-area may use different cache lines for * same physical memory. * * If we would call dcache_flush_range(), the line of P1-area * could remain in the cache, unflushed. */ unsigned long addr, data, v; start &= ~(L1_CACHE_BYTES-1); jump_to_P2(); for (v = start; v < end; v+=L1_CACHE_BYTES) { addr = CACHE_OC_ADDRESS_ARRAY | (v&CACHE_OC_ENTRY_PHYS_MASK) | 0x8 /* A-bit */; data = (v&0xfffffc00); /* Update=0, Valid=0 */ /* Try all the cases for aliases */ ctrl_outl(data, addr); ctrl_outl(data, addr | 0x1000); ctrl_outl(data, addr | 0x2000); ctrl_outl(data, addr | 0x3000); } back_to_P1(); #if 1 icache_purge_range(start, end); /* Do we needed this? */ #endif } void flush_cache_page(struct vm_area_struct *vma, unsigned long addr) { flush_cache_range(vma->vm_mm, addr, addr+PAGE_SIZE); } void flush_page_to_ram(struct page *pg) { unsigned long phys, addr, data, i; /* Physical address of this page */ phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; jump_to_P2(); /* Loop all the D-cache */ for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT); data = ctrl_inl(addr); if ((data & CACHE_UPDATED) && (data&PAGE_MASK) == phys) { data &= ~(CACHE_UPDATED|CACHE_VALID); ctrl_outl(data, addr); } } back_to_P1(); } #endif |