includes
H8S architecture support
signal handling problem fix
gcc-3.3 support
vfork/clone return value fix
added show_stack
build error and warning fix
blkdev location cleanup
--
Yoshinori Sato
<[email protected]>
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/asm-offsets.c linux-2.6.0-test2-h8300/arch/h8300/kernel/asm-offsets.c
--- linux-2.6.0-test2/arch/h8300/kernel/asm-offsets.c 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/asm-offsets.c 2003-07-14 15:17:52.000000000 +0900
@@ -40,7 +40,6 @@
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
DEFINE(THREAD_CCR, offsetof(struct thread_struct, ccr));
- DEFINE(THREAD_VFORK, offsetof(struct thread_struct, vfork_ret));
DEFINE(PT_PTRACED, PT_PTRACED);
DEFINE(PT_DTRACE, PT_DTRACE);
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/gpio.c linux-2.6.0-test2-h8300/arch/h8300/kernel/gpio.c
--- linux-2.6.0-test2/arch/h8300/kernel/gpio.c 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/gpio.c 2003-07-19 22:32:18.000000000 +0900
@@ -6,7 +6,7 @@
*/
/*
- * H8/300H Internal I/O Port Management
+ * Internal I/O Port Management
*/
#include <linux/config.h>
@@ -15,50 +15,56 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/fs.h>
+#include <linux/init.h>
+#define _(addr) (volatile unsigned char *)(addr)
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
-#define P1DDR (unsigned char *)0xfee000
-#define P2DDR (unsigned char *)0xfee001
-#define P3DDR (unsigned char *)0xfee002
-#define P4DDR (unsigned char *)0xfee003
-#define P5DDR (unsigned char *)0xfee004
-#define P6DDR (unsigned char *)0xfee005
-#define P8DDR (unsigned char *)0xfee007
-#define P9DDR (unsigned char *)0xfee008
-#define PADDR (unsigned char *)0xfee009
-#define PBDDR (unsigned char *)0xfee00A
-#endif
-#if defined(CONFIG_H83002) || defined(CONFIG_H8048)
-#define P1DDR (unsigned char *)0xffffc0
-#define P2DDR (unsigned char *)0xffffc1
-#define P3DDR (unsigned char *)0xffffc4
-#define P4DDR (unsigned char *)0xffffc5
-#define P5DDR (unsigned char *)0xffffc8
-#define P6DDR (unsigned char *)0xffffc9
-#define P8DDR (unsigned char *)0xffffcd
-#define P9DDR (unsigned char *)0xffffd0
-#define PADDR (unsigned char *)0xffffd1
-#define PBDDR (unsigned char *)0xffffd4
+#include <asm/regs306x.h>
+static volatile unsigned char *ddrs[] = {
+ _(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
+ NULL, _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
+};
+#define MAX_PORT 11
#endif
-#if defined(P1DDR)
-
+ #if defined(CONFIG_H83002) || defined(CONFIG_H8048)
+/* Fix me!! */
+#include <asm/regs306x.h>
+static volatile unsigned char *ddrs[] = {
+ _(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
+ NULL, _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
+};
#define MAX_PORT 11
+#endif
+
+#if defined(CONFIG_H8S2678)
+#include <asm/regs267x.h>
+static volatile unsigned char *ddrs[] = {
+ _(P1DDR),_(P2DDR),_(P3DDR),NULL ,_(P5DDR),_(P6DDR),
+ _(P7DDR),_(P8DDR),NULL, _(PADDR),_(PBDDR),_(PCDDR),
+ _(PDDDR),_(PEDDR),_(PFDDR),_(PGDDR),_(PHDDR),
+ _(PADDR),_(PBDDR),_(PCDDR),_(PDDDR),_(PEDDR),_(PFDDR),
+ _(PGDDR),_(PHDDR)
+};
+#define MAX_PORT 17
+#endif
+#undef _
+
+#if !defined(P1DDR)
+#error Unsuppoted CPU Selection
+#endif
static struct {
unsigned char used;
unsigned char ddr;
} gpio_regs[MAX_PORT];
-static volatile unsigned char *ddrs[] = {
- P1DDR,P2DDR,P3DDR,P4DDR,P5DDR,P6DDR,NULL,P8DDR,P9DDR,PADDR,PBDDR,
-};
-
extern char *_platform_gpio_table(int length);
int h8300_reserved_gpio(int port, unsigned int bits)
{
unsigned char *used;
+
if (port < 0 || port >= MAX_PORT)
return -1;
used = &(gpio_regs[port].used);
@@ -71,6 +77,7 @@
int h8300_free_gpio(int port, unsigned int bits)
{
unsigned char *used;
+
if (port < 0 || port >= MAX_PORT)
return -1;
used = &(gpio_regs[port].used);
@@ -82,16 +89,16 @@
int h8300_set_gpio_dir(int port_bit,int dir)
{
- const unsigned char mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int port = (port_bit >> 8) & 0xff;
- int bit = port_bit & 0x07;
+ int bit = port_bit & 0xff;
+
if (ddrs[port] == NULL)
return 0;
- if (gpio_regs[port].used & mask[bit]) {
+ if (gpio_regs[port].used & bit) {
if (dir)
- gpio_regs[port].ddr |= mask[bit];
+ gpio_regs[port].ddr |= bit;
else
- gpio_regs[port].ddr &= ~mask[bit];
+ gpio_regs[port].ddr &= ~bit;
*ddrs[port] = gpio_regs[port].ddr;
return 1;
} else
@@ -100,13 +107,13 @@
int h8300_get_gpio_dir(int port_bit)
{
- const unsigned char mask[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int port = (port_bit >> 8) & 0xff;
- int bit = port_bit & 0x07;
+ int bit = port_bit & 0xff;
+
if (ddrs[port] == NULL)
return 0;
- if (gpio_regs[port].used & mask[bit]) {
- return (gpio_regs[port].ddr & mask[bit]) != 0;
+ if (gpio_regs[port].used & bit) {
+ return (gpio_regs[port].ddr & bit) != 0;
} else
return -1;
}
@@ -132,10 +139,11 @@
return result;
}
-static int gpio_proc_read(char *buf, char **start, off_t offset, int len, int unused)
+static int gpio_proc_read(char *buf, char **start, off_t offset,
+ int len, int *unused_i, void *unused_v)
{
int c,outlen;
- const static char port_name[]="123456789AB";
+ const static char port_name[]="123456789ABCDEFGH";
outlen = 0;
for (c = 0; c < MAX_PORT; c++) {
if (ddrs[c] == NULL)
@@ -147,20 +155,20 @@
return outlen;
}
-static const struct proc_dir_entry proc_gpio = {
- 0, 4,"gpio",S_IFREG | S_IRUGO, 1, 0, 0, 0, NULL, gpio_proc_read,
-};
+static __init int register_proc(void)
+{
+ struct proc_dir_entry *proc_gpio;
+
+ proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
+ if (proc_gpio)
+ proc_gpio->read_proc = gpio_proc_read;
+ return proc_gpio != NULL;
+}
+
+__initcall(register_proc);
#endif
-int h8300_gpio_init(void)
+void __init h8300_gpio_init(void)
{
memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs));
-#if 0 && defined(CONFIG_PROC_FS)
- proc_register(&proc_root,&proc_gpio);
-#endif
- return 0;
}
-
-#else
-#error Unsuppoted CPU Selection
-#endif
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/process.c linux-2.6.0-test2-h8300/arch/h8300/kernel/process.c
--- linux-2.6.0-test2/arch/h8300/kernel/process.c 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/process.c 2003-07-19 21:41:33.000000000 +0900
@@ -44,12 +44,12 @@
#include <asm/setup.h>
#include <asm/pgtable.h>
-asmlinkage void ret_from_exception(void);
+asmlinkage void ret_from_fork(void);
/*
* The idle loop on an H8/300..
*/
-#if !defined(CONFIG_H8300H_SIM)
+#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
void default_idle(void)
{
while(1) {
@@ -85,20 +85,20 @@
void machine_restart(char * __unused)
{
- cli();
+ local_irq_disable();
__asm__("jmp @@0");
}
void machine_halt(void)
{
- cli();
+ local_irq_disable();
__asm__("sleep");
for (;;);
}
void machine_power_off(void)
{
- cli();
+ local_irq_disable();
__asm__("sleep");
for (;;);
}
@@ -110,10 +110,13 @@
regs->pc, regs->ccr);
printk("ORIG_ER0: %08lx ER0: %08lx ER1: %08lx\n",
regs->orig_er0, regs->er0, regs->er1);
- printk("ER2: %08lx ER3: %08lx\n",
- regs->er2, regs->er3);
- if (!(regs->ccr & 0x10))
+ printk("ER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx\n",
+ regs->er2, regs->er3, regs->er4, regs->er5);
+ printk("ER6' %08lx ",regs->er6);
+ if (user_mode(regs))
printk("USP: %08lx\n", rdusp());
+ else
+ printk("\n");
}
/*
@@ -122,34 +125,29 @@
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval;
- register long clone_arg asm("er1");
+ long clone_arg;
mm_segment_t fs;
fs = get_fs();
set_fs (KERNEL_DS);
clone_arg = flags | CLONE_VM;
-
- __asm__ __volatile__ (
- "mov.l sp, er2\n\t"
- "mov.l %1,er0\n\t"
- "mov.l %5,er1\n\t"
- "trapa #0\n\t"
- "cmp.l sp, er2\n\t"
- "beq 1f\n\t"
- "mov.l %3, er0\n\t"
- "jsr @%4\n\t"
- "mov.l %2, er0\n\t"
- "trapa #0\n"
- "1:\n\t"
- "mov.l er0,%0"
- : "=r" (retval)
- : "i" (__NR_clone),
- "i" (__NR_exit),
- "r" (arg),
- "r" (fn),
- "r" (clone_arg)
- : "cc", "er0", "er1", "er2", "er3");
-
+ __asm__("mov.l sp,er3\n\t"
+ "sub.l er2,er2\n\t"
+ "mov.l %2,er1\n\t"
+ "mov.l %1,er0\n\t"
+ "trapa #0\n\t"
+ "cmp.l sp,er3\n\t"
+ "beq 1f\n\t"
+ "mov.l %4,er0\n\t"
+ "mov.l %3,er1\n\t"
+ "jsr @er1\n\t"
+ "mov.l %5,er0\n\t"
+ "trapa #0\n"
+ "1:\n\t"
+ "mov.l er0,%0"
+ :"=r"(retval)
+ :"i"(__NR_clone),"g"(clone_arg),"g"(fn),"g"(arg),"i"(__NR_exit)
+ :"er0","er1","er2","er3");
set_fs (fs);
return retval;
}
@@ -172,24 +170,20 @@
asmlinkage int h8300_vfork(struct pt_regs *regs)
{
- struct task_struct *p;
- p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
}
asmlinkage int h8300_clone(struct pt_regs *regs)
{
unsigned long clone_flags;
unsigned long newsp;
- struct task_struct *p;
/* syscall2 puts clone_flags in er1 and usp in er2 */
clone_flags = regs->er1;
newsp = regs->er2;
if (!newsp)
newsp = rdusp();
- p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
- return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+ return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
}
@@ -198,25 +192,15 @@
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
- struct switch_stack * childstack, *stack;
- unsigned long stack_offset, *retp;
- stack_offset = KTHREAD_SIZE - sizeof(struct pt_regs);
childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
*childregs = *regs;
-
- retp = (unsigned long *) regs-2;
- stack = ((struct switch_stack *) retp) - 1;
-
- childstack = ((struct switch_stack *) childregs) - 1;
- *childstack = *stack;
+ childregs->retpc = (unsigned long) ret_from_fork;
childregs->er0 = 0;
- childstack->retpc = (unsigned long) ret_from_exception;
p->thread.usp = usp;
- p->thread.ksp = (unsigned long)childstack;
- p->thread.vfork_ret = 0;
+ p->thread.ksp = (unsigned long)childregs;
return 0;
}
@@ -226,8 +210,6 @@
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
- struct switch_stack *sw;
-
/* changed the size calculations - should hopefully work better. lbt */
dump->magic = CMAGIC;
dump->start_code = 0;
@@ -239,14 +221,13 @@
dump->u_ssize = 0;
dump->u_ar0 = (struct user_regs_struct *)(((int)(&dump->regs)) -((int)(dump)));
- sw = ((struct switch_stack *)regs) - 1;
dump->regs.er0 = regs->er0;
dump->regs.er1 = regs->er1;
dump->regs.er2 = regs->er2;
dump->regs.er3 = regs->er3;
- dump->regs.er4 = sw->er4;
- dump->regs.er5 = sw->er5;
- dump->regs.er6 = sw->er6;
+ dump->regs.er4 = regs->er4;
+ dump->regs.er5 = regs->er5;
+ dump->regs.er6 = regs->er6;
dump->regs.orig_er0 = regs->orig_er0;
dump->regs.ccr = regs->ccr;
dump->regs.pc = regs->pc;
@@ -259,7 +240,7 @@
{
int error;
char * filename;
- struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy+4);
+ struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
lock_kernel();
filename = getname(name);
@@ -283,14 +264,7 @@
unsigned long thread_saved_pc(struct task_struct *tsk)
{
- struct switch_stack *sw = (struct switch_stack *)(tsk->thread.ksp);
-
- /* Check whether the thread is blocked in resume() */
- if (sw->retpc > (unsigned long)scheduling_functions_start_here &&
- sw->retpc < (unsigned long)scheduling_functions_end_here)
- return ((unsigned long *)sw->er6)[1];
- else
- return sw->retpc;
+ return ((struct pt_regs *)tsk->thread.esp0)->pc;
}
unsigned long get_wchan(struct task_struct *p)
@@ -302,7 +276,7 @@
return 0;
stack_page = (unsigned long)p;
- fp = ((struct switch_stack *)p->thread.ksp)->er6;
+ fp = ((struct pt_regs *)p->thread.ksp)->er6;
do {
if (fp < stack_page+sizeof(struct task_struct) ||
fp >= 8184+stack_page)
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/ptrace.c linux-2.6.0-test2-h8300/arch/h8300/kernel/ptrace.c
--- linux-2.6.0-test2/arch/h8300/kernel/ptrace.c 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/ptrace.c 2003-07-14 15:17:52.000000000 +0900
@@ -46,14 +46,12 @@
/* Find the stack offset for a register, relative to thread.esp0. */
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
-#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
- - sizeof(struct switch_stack))
/* Mapping from PT_xxx to the stack offset at which the register is
saved. Notice that usp has no stack-slot and needs to be treated
specially (see get_reg/put_reg below). */
static const int regoff[] = {
- PT_REG(er1), PT_REG(er2), PT_REG(er3), SW_REG(er4),
- SW_REG(er5), SW_REG(er6), PT_REG(er0), PT_REG(orig_er0),
+ PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
+ PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0),
PT_REG(ccr), PT_REG(pc)
};
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/setup.c linux-2.6.0-test2-h8300/arch/h8300/kernel/setup.c
--- linux-2.6.0-test2/arch/h8300/kernel/setup.c 2003-07-28 10:31:02.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/setup.c 2003-07-28 12:40:08.000000000 +0900
@@ -1,5 +1,5 @@
/*
- * linux/arch/h8300h/kernel/setup.c
+ * linux/arch/h8300/kernel/setup.c
*
* Copyleft ()) 2000 James D. Schettine {[email protected]}
* Copyright (C) 1999,2000 Greg Ungerer ([email protected])
@@ -9,7 +9,7 @@
* Copyright (C) 2000 Lineo Inc. (http://www.lineo.com)
* Copyright (C) 2001 Lineo, Inc. <http://www.lineo.com>
*
- * H8/300H porting Yoshinori Sato <[email protected]>
+ * H8/300 porting Yoshinori Sato <[email protected]>
*/
/*
@@ -38,10 +38,22 @@
#include <asm/pgtable.h>
#endif
-#if defined(CONFIG_CPU_H8300H)
+#if defined(__H8300H__)
#define CPU "H8/300H"
#endif
+#if defined(__H8300S__)
+#define CPU "H8S"
+#endif
+
+#if defined(CONFIG_INTELFLASH)
+#define BLKOFFSET 512
+#else
+#define BLKOFFSET 0
+#endif
+
+#define STUBSIZE 0xc000;
+
unsigned long rom_length;
unsigned long memory_start;
unsigned long memory_end;
@@ -54,10 +66,12 @@
extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
extern int _ramstart, _ramend;
extern char _target_name[];
+extern void h8300_gpio_init(void);
-#if defined(CONFIG_H8300H_SIM) && defined(CONFIG_GDB_MAGICPRINT)
+#if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) \
+ && defined(CONFIG_GDB_MAGICPRINT)
/* printk with gdb service */
-static void gdb_console_output(struct console *c, char *msg, unsigned len)
+static void gdb_console_output(struct console *c, const char *msg, unsigned len)
{
for (; len > 0; len--) {
asm("mov.w %0,r2\n\t"
@@ -77,7 +91,7 @@
}
static const struct console gdb_console = {
- name: "gdb",
+ name: "gdb_con",
write: gdb_console_output,
device: NULL,
setup: gdb_console_setup,
@@ -86,26 +100,48 @@
};
#endif
-void setup_arch(char **cmdline_p)
+void __init setup_arch(char **cmdline_p)
{
int bootmap_size;
- memory_start = PAGE_ALIGN((unsigned long)(&_ramstart));
- memory_end = &_ramend; /* by now the stack is part of the init task */
+ memory_start = (unsigned long) &_ramstart;
+
+ /* allow for ROMFS on the end of the kernel */
+ if (memcmp((void *)(memory_start + BLKOFFSET), "-rom1fs-", 8) == 0) {
+#if defined(CONFIG_BLK_DEV_INITRD)
+ initrd_start = memory_start += BLKOFFSET;
+ initrd_end = memory_start += be32_to_cpu(((unsigned long *) (memory_start))[2]);
+#else
+ memory_start += BLKOFFSET;
+ memory_start += be32_to_cpu(((unsigned long *) memory_start)[2]);
+#endif
+ }
+ memory_start = PAGE_ALIGN(memory_start);
+#if !defined(CONFIG_BLKDEV_RESERVE)
+ memory_end = (unsigned long) &_ramend; /* by now the stack is part of the init task */
+#if defined(CONFIG_GDB_DEBUG)
+ memory_end -= STUBSIZE;
+#endif
+#else
+ if ((memory_end < CONFIG_BLKDEV_RESERVE_ADDRESS) &&
+ (memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS)
+ /* overlap userarea */
+ memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS;
+#endif
init_mm.start_code = (unsigned long) &_stext;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) 0;
-#if defined(CONFIG_H8300H_SIM) && defined(CONFIG_GDB_MAGICPRINT)
+#if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) && defined(CONFIG_GDB_MAGICPRINT)
register_console(&gdb_console);
#endif
- printk("\x0F\r\n\nuClinux " CPU "\n");
+ printk("\r\n\nuClinux " CPU "\n");
printk("Target Hardware: %s\n",_target_name);
printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
- printk("H8/300H support by Yoshinori Sato <[email protected]>\n");
+ printk("H8/300 series support by Yoshinori Sato <[email protected]>\n");
#ifdef DEBUG
printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
@@ -157,6 +193,7 @@
* get kmalloc into gear
*/
paging_init();
+ h8300_gpio_init();
#ifdef DEBUG
printk("Done setup_arch\n");
#endif
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/signal.c linux-2.6.0-test2-h8300/arch/h8300/kernel/signal.c
--- linux-2.6.0-test2/arch/h8300/kernel/signal.c 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/signal.c 2003-07-14 15:17:52.000000000 +0900
@@ -9,7 +9,8 @@
*/
/*
- * uClinux H8/300 support by Yoshinori Sato
+ * uClinux H8/300 support by Yoshinori Sato <[email protected]>
+ * and David McCullough <[email protected]>
*
* Based on
* Linux/m68k by Hamish Macdonald
@@ -151,26 +152,29 @@
struct sigframe
{
+ long dummy_er0;
+ long dummy_vector;
+#if defined(CONFIG_CPU_H8S)
+ short dummy_exr;
+#endif
char *pretcode;
- int sig;
- int code;
- struct sigcontext *psc;
- char retcode[6];
+ unsigned char retcode[8];
unsigned long extramask[_NSIG_WORDS-1];
struct sigcontext sc;
-};
+} __attribute__((aligned(2),packed));
struct rt_sigframe
{
+ long dummy_er0;
+ long dummy_vector;
+#if defined(CONFIG_CPU_H8S)
+ short dummy_exr;
+#endif
char *pretcode;
- int sig;
- struct siginfo *pinfo;
- void *puc;
- char retcode[6];
+ unsigned char retcode[8];
struct siginfo info;
struct ucontext uc;
-};
-
+} __attribute__((aligned(2),packed));
static inline int
restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
@@ -200,8 +204,7 @@
}
static inline int
-rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
- struct ucontext *uc, int *pd0)
+rt_restore_ucontext(struct pt_regs *regs, struct ucontext *uc, int *pd0)
{
int temp;
greg_t *gregs = uc->uc_mcontext.gregs;
@@ -216,9 +219,9 @@
err |= __get_user(regs->er1, &gregs[1]);
err |= __get_user(regs->er2, &gregs[2]);
err |= __get_user(regs->er3, &gregs[3]);
- err |= __get_user(sw->er4, &gregs[4]);
- err |= __get_user(sw->er5, &gregs[5]);
- err |= __get_user(sw->er6, &gregs[6]);
+ err |= __get_user(regs->er4, &gregs[4]);
+ err |= __get_user(regs->er5, &gregs[5]);
+ err |= __get_user(regs->er6, &gregs[6]);
err |= __get_user(usp, &gregs[7]);
wrusp(usp);
err |= __get_user(regs->pc, &gregs[8]);
@@ -238,8 +241,7 @@
asmlinkage int do_sigreturn(unsigned long __unused,...)
{
- struct switch_stack *sw = (struct switch_stack *) &__unused;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+ struct pt_regs *regs = (struct pt_regs *) &__unused;
unsigned long usp = rdusp();
struct sigframe *frame = (struct sigframe *)(usp - 4);
sigset_t set;
@@ -270,8 +272,7 @@
asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
{
- struct switch_stack *sw = (struct switch_stack *) &__unused;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+ struct pt_regs *regs = (struct pt_regs *) &__unused;
unsigned long usp = rdusp();
struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
sigset_t set;
@@ -288,7 +289,7 @@
recalc_sigpending();
spin_lock_irq(¤t->sighand->siglock);
- if (rt_restore_ucontext(regs, sw, &frame->uc, &er0))
+ if (rt_restore_ucontext(regs, &frame->uc, &er0))
goto badframe;
return er0;
@@ -312,7 +313,6 @@
static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
{
- struct switch_stack *sw = (struct switch_stack *)regs - 1;
greg_t *gregs = uc->uc_mcontext.gregs;
int err = 0;
@@ -321,9 +321,9 @@
err |= __put_user(regs->er1, &gregs[1]);
err |= __put_user(regs->er2, &gregs[2]);
err |= __put_user(regs->er3, &gregs[3]);
- err |= __put_user(sw->er4, &gregs[4]);
- err |= __put_user(sw->er5, &gregs[5]);
- err |= __put_user(sw->er6, &gregs[6]);
+ err |= __put_user(regs->er4, &gregs[4]);
+ err |= __put_user(regs->er5, &gregs[5]);
+ err |= __put_user(regs->er6, &gregs[6]);
err |= __put_user(rdusp(), &gregs[7]);
err |= __put_user(regs->pc, &gregs[8]);
err |= __put_user(regs->ccr, &gregs[9]);
@@ -355,15 +355,6 @@
frame = get_sigframe(ka, regs, sizeof(*frame));
- err |= __put_user((current_thread_info()->exec_domain
- && current_thread_info()->exec_domain->signal_invmap
- && sig < 32
- ? current_thread_info()->exec_domain->signal_invmap[sig]
- : sig),
- &frame->sig);
-
- err |= __put_user(&frame->sc, &frame->psc);
-
if (_NSIG_WORDS > 1)
err |= copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask));
@@ -376,8 +367,8 @@
/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
- (long *)(frame->retcode + 0));
- err |= __put_user(0x5700, (short *)(frame->retcode + 4));
+ (unsigned long *)(frame->retcode + 0));
+ err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
if (err)
@@ -386,6 +377,12 @@
/* Set up registers for signal handler */
wrusp ((unsigned long) frame);
regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->er0 = (current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig);
+ regs->er1 = (unsigned long)&(frame->sc);
return;
@@ -403,14 +400,6 @@
frame = get_sigframe(ka, regs, sizeof(*frame));
- err |= __put_user((current_thread_info()->exec_domain
- && current_thread_info()->exec_domain->signal_invmap
- && sig < 32
- ? current_thread_info()->exec_domain->signal_invmap[sig]
- : sig),
- &frame->sig);
- err |= __put_user(&frame->info, &frame->pinfo);
- err |= __put_user(&frame->uc, &frame->puc);
err |= copy_siginfo_to_user(&frame->info, info);
/* Create the ucontext. */
@@ -438,7 +427,14 @@
/* Set up registers for signal handler */
wrusp ((unsigned long) frame);
- regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->er0 = (current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig);
+ regs->er1 = (unsigned long)&(frame->info);
+ regs->er2 = (unsigned long)&frame->uc;
return;
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/sys_h8300.c linux-2.6.0-test2-h8300/arch/h8300/kernel/sys_h8300.c
--- linux-2.6.0-test2/arch/h8300/kernel/sys_h8300.c 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/sys_h8300.c 2003-07-14 15:17:52.000000000 +0900
@@ -281,9 +281,8 @@
#if defined(CONFIG_SYSCALL_PRINT)
asmlinkage void syscall_print(void *dummy,...)
{
- struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy);
- unsigned long *usp=rdusp()+8;
- printk("call %06x:%d 1:%08x,2:%08x,3:%08x,ret:%08x\n",
- ((*usp) & 0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
+ struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
+ printk("call %06lx:%ld 1:%08lx,2:%08lx,3:%08lx,ret:%08lx\n",
+ ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
}
#endif
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/syscalls.S linux-2.6.0-test2-h8300/arch/h8300/kernel/syscalls.S
--- linux-2.6.0-test2/arch/h8300/kernel/syscalls.S 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/syscalls.S 2003-07-19 22:32:18.000000000 +0900
@@ -312,3 +312,7 @@
mov.l #SYMBOL_NAME(h8300_fork),er0
jmp @SYMBOL_NAME(syscall_trampoline)
+SYMBOL_NAME_LABEL(sys_vfork)
+ mov.l #SYMBOL_NAME(h8300_vfork),er0
+ jmp @SYMBOL_NAME(syscall_trampoline)
+
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/time.c linux-2.6.0-test2-h8300/arch/h8300/kernel/time.c
--- linux-2.6.0-test2/arch/h8300/kernel/time.c 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/time.c 2003-07-14 15:17:52.000000000 +0900
@@ -110,8 +110,11 @@
tv->tv_usec = usec;
}
-void do_settimeofday(struct timeval *tv)
+int do_settimeofday(struct timespec *tv)
{
+ if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+ return -EINVAL;
+
write_lock_irq(&xtime_lock);
/* This is revolting. We need to set the xtime.tv_usec
* correctly. However, the value in this location is
@@ -119,16 +122,17 @@
* Discover what correction gettimeofday
* would have done, and then undo it!
*/
- while (tv->tv_usec < 0) {
- tv->tv_usec += 1000000;
+ while (tv->tv_nsec < 0) {
+ tv->tv_nsec += NSEC_PER_SEC;
tv->tv_sec--;
}
xtime.tv_sec = tv->tv_sec;
- xtime.tv_nsec = (tv->tv_usec * 1000);
+ xtime.tv_nsec = tv->tv_nsec;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
- write_unlock_irq(&xtime_lock);
+ write_sequnlock_irq(&xtime_lock);
+ return 0;
}
diff -Nru linux-2.6.0-test2/arch/h8300/kernel/traps.c linux-2.6.0-test2-h8300/arch/h8300/kernel/traps.c
--- linux-2.6.0-test2/arch/h8300/kernel/traps.c 2003-07-14 15:00:22.000000000 +0900
+++ linux-2.6.0-test2-h8300/arch/h8300/kernel/traps.c 2003-07-19 21:41:33.000000000 +0900
@@ -72,15 +72,17 @@
(int) current->mm->end_data,
(int) current->mm->end_data,
(int) current->mm->brk);
- printk("USER-STACK=%08x KERNEL-STACK=%08x\n\n",
+ printk("USER-STACK=%08x KERNEL-STACK=%08lx\n\n",
(int) current->mm->start_stack,
(int) PAGE_SIZE+(unsigned long)current);
}
printk("PC: %08lx\n", (long)fp->pc);
- printk("CCR: %08lx SP: %08lx\n", fp->ccr, (long) fp);
+ printk("CCR: %02x SP: %08lx\n", fp->ccr, (long) fp);
printk("ER0: %08lx ER1: %08lx ER2: %08lx ER3: %08lx\n",
fp->er0, fp->er1, fp->er2, fp->er3);
+ printk("ER4: %08lx ER5: %08lx ER6: %08lx\n",
+ fp->er4, fp->er5, fp->er6);
printk("\nCODE:");
tp = ((unsigned char *) fp->pc) - 0x20;
for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
@@ -122,3 +124,53 @@
do_exit(SIGSEGV);
}
+
+extern char _start, _etext;
+#define check_kernel_text(addr) \
+ ((addr >= (unsigned long)(&_start)) && \
+ (addr < (unsigned long)(&_etext)))
+
+static int kstack_depth_to_print = 24;
+
+void show_stack(struct task_struct *task, unsigned long *esp)
+{
+ unsigned long *stack, addr;
+ int i;
+
+ if (esp == NULL)
+ esp = (unsigned long *) &esp;
+
+ stack = esp;
+
+ printk("Stack from %08lx:", (unsigned long)stack);
+ for (i = 0; i < kstack_depth_to_print; i++) {
+ if (((unsigned long)stack & (THREAD_SIZE - 1)) == 0)
+ break;
+ if (i % 8 == 0)
+ printk("\n ");
+ printk(" %08lx", *stack++);
+ }
+
+ printk("\nCall Trace:");
+ i = 0;
+ stack = esp;
+ while (((unsigned long)stack & (THREAD_SIZE - 1)) == 0) {
+ addr = *stack++;
+ /*
+ * If the address is either in the text segment of the
+ * kernel, or in the region which contains vmalloc'ed
+ * memory, it *may* be the address of a calling
+ * routine; if so, print it so that someone tracing
+ * down the cause of the crash will be able to figure
+ * out the call path that was taken.
+ */
+ if (check_kernel_text(addr)) {
+ if (i % 4 == 0)
+ printk("\n ");
+ printk(" [<%08lx>]", addr);
+ i++;
+ }
+ }
+ printk("\n");
+}
+