[PATCH] linux-2.6.0-test2 h8300 archtecure support update (5/6)

From: Yoshinori Sato (ysato@users.sourceforge.jp)
Date: Mon Jul 28 2003 - 09:18:58 EST


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
<ysato@users.sourceforge.jp>

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 {james@telos-systems.com} * Copyright (C) 1999,2000 Greg Ungerer (gerg@snapgear.com) @@ -9,7 +9,7 @@ * Copyright (C) 2000 Lineo Inc. (www.lineo.com) * Copyright (C) 2001 Lineo, Inc. <www.lineo.com> * - * H8/300H porting Yoshinori Sato <ysato@users.sourceforge.jp> + * H8/300 porting Yoshinori Sato <ysato@users.sourceforge.jp> */ /* @@ -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 <ysato@users.sourceforge.jp>\n"); + printk("H8/300 series support by Yoshinori Sato <ysato@users.sourceforge.jp>\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 <ysato@users.sourceforge.jp> + * and David McCullough <davidm@snapgear.com> * * 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(&current->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"); +} + - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Jul 31 2003 - 22:00:36 EST