|
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
---
|