diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-06-01 03:16:17 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-06-01 03:16:17 +0000 |
commit | d8d9b8f76f22b7a16a83e261e64f89ee611f49df (patch) | |
tree | 3067bc130b80d52808e6390c9fc7fc087ec1e33c /arch/m68k/kernel | |
parent | 19c9bba94152148523ba0f7ef7cffe3d45656b11 (diff) |
Initial revision
Diffstat (limited to 'arch/m68k/kernel')
-rw-r--r-- | arch/m68k/kernel/entry.S | 109 | ||||
-rw-r--r-- | arch/m68k/kernel/head.S | 14 | ||||
-rw-r--r-- | arch/m68k/kernel/ints.c | 3 | ||||
-rw-r--r-- | arch/m68k/kernel/m68k_ksyms.c | 4 | ||||
-rw-r--r-- | arch/m68k/kernel/process.c | 39 | ||||
-rw-r--r-- | arch/m68k/kernel/ptrace.c | 30 | ||||
-rw-r--r-- | arch/m68k/kernel/setup.c | 29 | ||||
-rw-r--r-- | arch/m68k/kernel/signal.c | 6 | ||||
-rw-r--r-- | arch/m68k/kernel/sys_m68k.c | 5 | ||||
-rw-r--r-- | arch/m68k/kernel/time.c | 21 | ||||
-rw-r--r-- | arch/m68k/kernel/traps.c | 10 |
11 files changed, 164 insertions, 106 deletions
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 2cb35e67f..ef5ef46d6 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -33,12 +33,13 @@ * 10(sp) - d5 * 14(sp) - a0 * 18(sp) - a1 - * 1C(sp) - d0 - * 20(sp) - orig_d0 - * 24(sp) - stack adjustment - * 28(sp) - sr - * 2A(sp) - pc - * 2E(sp) - format & vector + * 1C(sp) - a2 + * 20(sp) - d0 + * 24(sp) - orig_d0 + * 28(sp) - stack adjustment + * 2C(sp) - sr + * 2E(sp) - pc + * 32(sp) - format & vector */ /* @@ -47,6 +48,11 @@ * number 0 in the 'current_set' list. */ +/* + * 97/05/14 Andreas: Register %a2 is now set to the current task throughout + * the whole kernel. + */ + #include <linux/sys.h> #include <linux/config.h> #include <linux/linkage.h> @@ -57,6 +63,8 @@ .globl SYMBOL_NAME(kgdb_registers) #endif +#define curptr a2 + LENOSYS = 38 /* @@ -80,15 +88,15 @@ LTASK_FLAGS = 20 #define MAX_NOINT_IPL 0 #endif /* machine compilation types */ -LD0 = 0x1C -LORIG_D0 = 0x20 -LSR = 0x28 -LFORMATVEC = 0x2E +LD0 = 0x20 +LORIG_D0 = 0x24 +LSR = 0x2C +LFORMATVEC = 0x32 /* * This defines the normal kernel pt-regs layout. * - * regs are a2-a6 and d6-d7 preserved by C code + * regs a3-a6 and d6-d7 are preserved by C code * the kernel doesn't mess with usp unless it needs to */ #ifndef CONFIG_KGDB @@ -96,7 +104,7 @@ LFORMATVEC = 0x2E clrl %sp@-; /* stk_adj */ \ movel %d0,%sp@-; /* orig d0 */ \ movel %d0,%sp@-; /* d0 */ \ - moveml %d1-%d5/%a0-%a1,%sp@- + moveml %d1-%d5/%a0-%a1/%curptr,%sp@-; #else /* Need to save the "missing" registers for kgdb... */ @@ -104,25 +112,30 @@ LFORMATVEC = 0x2E clrl %sp@-; /* stk_adj */ \ movel %d0,%sp@-; /* orig d0 */ \ movel %d0,%sp@-; /* d0 */ \ - moveml %d1-%d5/%a0-%a1,%sp@-; \ + moveml %d1-%d5/%a0-%a1/%curptr,%sp@-; \ moveml %d6-%d7,SYMBOL_NAME(kgdb_registers)+GDBOFFA_D6; \ - moveml %a2-%a6,SYMBOL_NAME(kgdb_registers)+GDBOFFA_A2 + moveml %a3-%a6,SYMBOL_NAME(kgdb_registers)+GDBOFFA_A3; #endif #define RESTORE_ALL \ - moveml %sp@+,%a0-%a1/%d1-%d5; \ + moveml %sp@+,%a0-%a1/%curptr/%d1-%d5; \ movel %sp@+,%d0; \ addql #4,%sp; /* orig d0 */ \ addl %sp@+,%sp; /* stk adj */ \ rte -#define SWITCH_STACK_SIZE (7*4+4) /* includes return address */ +#define SWITCH_STACK_SIZE (6*4+4) /* includes return address */ #define SAVE_SWITCH_STACK \ - moveml %a2-%a6/%d6-%d7,%sp@- + moveml %a3-%a6/%d6-%d7,%sp@- #define RESTORE_SWITCH_STACK \ - moveml %sp@+,%a2-%a6/%d6-%d7 + moveml %sp@+,%a3-%a6/%d6-%d7 + +#define GET_CURRENT(tmp) \ + movel %sp,tmp; \ + andw &-8192,tmp; \ + movel tmp,%curptr; .globl SYMBOL_NAME(system_call), SYMBOL_NAME(buserr), SYMBOL_NAME(trap) .globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception) @@ -139,6 +152,7 @@ ENTRY(buserr) | signifies that the stack frame | is NOT for syscall + GET_CURRENT(%d0) movel %sp,%sp@- | stack frame pointer argument bsrl SYMBOL_NAME(buserr_c) addql #4,%sp @@ -150,6 +164,7 @@ ENTRY(trap) movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field | signifies that the stack frame | is NOT for syscall + GET_CURRENT(%d0) movel %sp,%sp@- | stack frame pointer argument bsrl SYMBOL_NAME(trap_c) addql #4,%sp @@ -190,6 +205,7 @@ ENTRY(system_call) SAVE_ALL movel %d0,%d2 + GET_CURRENT(%d0) | save top of frame pea %sp@ jbsr SYMBOL_NAME(set_esp0) @@ -197,8 +213,7 @@ ENTRY(system_call) cmpl #NR_syscalls,%d2 jcc badsys - movel SYMBOL_NAME(current_set),%a0 - btst #5,%a0@(LTASK_FLAGS+3) | PF_TRACESYS + btst #5,%curptr@(LTASK_FLAGS+3) | PF_TRACESYS jne do_trace jbsr @(SYMBOL_NAME(sys_call_table),%d2:l:4)@(0) movel %d0,%sp@(LD0) | save the return value @@ -208,24 +223,23 @@ SYMBOL_NAME_LABEL(ret_from_exception) bnes 2f | if so, skip resched, signals tstl SYMBOL_NAME(need_resched) jne SYMBOL_NAME(reschedule) - movel SYMBOL_NAME(current_set),%a0 - cmpl #SYMBOL_NAME(task),%a0 | task[0] cannot have signals + cmpl #SYMBOL_NAME(task),%curptr | task[0] cannot have signals jeq 2f - bclr #5,%a0@(LTASK_FLAGS+1) | check for delayed trace + bclr #5,%curptr@(LTASK_FLAGS+1) | check for delayed trace jne do_delayed_trace 5: - tstl %a0@(LTASK_STATE) | state + tstl %curptr@(LTASK_STATE) | state jne SYMBOL_NAME(reschedule) - tstl %a0@(LTASK_COUNTER) | counter + tstl %curptr@(LTASK_COUNTER) | counter jeq SYMBOL_NAME(reschedule) - movel %a0@(LTASK_BLOCKED),%d0 + movel %curptr@(LTASK_BLOCKED),%d0 movel %d0,%d1 | save blocked in d1 for sig handling notl %d0 - btst #4,%a0@(LTASK_FLAGS+3) | PF_PTRACED + btst #4,%curptr@(LTASK_FLAGS+3) | PF_PTRACED jeq 1f moveq #-1,%d0 | let the debugger see all signals -1: andl %a0@(LTASK_SIGNAL),%d0 +1: andl %curptr@(LTASK_SIGNAL),%d0 jne Lsignal_return 2: RESTORE_ALL @@ -248,7 +262,6 @@ do_delayed_trace: jbsr SYMBOL_NAME(send_sig) addql #8,%sp addql #4,%sp - movel SYMBOL_NAME(current_set),%a0 jra 5b /* @@ -260,6 +273,7 @@ SYMBOL_NAME_LABEL(inthandler) movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field | signifies that the stack frame | is NOT for syscall + GET_CURRENT(%d0) addql #1,SYMBOL_NAME(local_irq_count) | put exception # in d0 bfextu %sp@(LFORMATVEC){#4,#10},%d0 @@ -270,28 +284,31 @@ SYMBOL_NAME_LABEL(inthandler) addql #8,%sp | pop parameters off stack SYMBOL_NAME_LABEL(ret_from_interrupt) - /* check if we need to do software interrupts */ - movel SYMBOL_NAME(local_irq_count),%d1 - subql #1,%d1 - jne 4f -#if 0 - bfextu %sp@(LSR){#5,#3},%d0 | Check for nested interrupt. + subql #1,SYMBOL_NAME(local_irq_count) + jeq 1f +2: + RESTORE_ALL +1: +#if 1 + bfextu %sp@(LSR){#5,#3},%d0 | Check for nested interrupt. #if MAX_NOINT_IPL > 0 cmpiw #MAX_NOINT_IPL,%d0 #endif - jhi 4f + jhi 2b #endif + /* Let the rest run with interrupts allowed. This is safe since + the kernel never uses a non-standard ipl and this is the outer + level interrupt. */ + andw #ALLOWINT,%sr + + /* check if we need to do software interrupts */ + movel SYMBOL_NAME(bh_active),%d0 andl SYMBOL_NAME(bh_mask),%d0 - jeq 3f + jeq SYMBOL_NAME(ret_from_exception) - jbsr SYMBOL_NAME(do_bottom_half) -3: - clrl SYMBOL_NAME(local_irq_count) - jra SYMBOL_NAME(ret_from_exception) -4: - movel %d1,SYMBOL_NAME(local_irq_count) - RESTORE_ALL + pea SYMBOL_NAME(ret_from_exception) + jra SYMBOL_NAME(do_bottom_half) /* Handler for uninitialized and spurious interrupts */ @@ -398,7 +415,7 @@ SYMBOL_NAME_LABEL(resume) 3: /* get pointer to tss struct (a1 contains new task) */ - movel %a1,SYMBOL_NAME(current_set) + movel %a1,%curptr addl %d1,%a1 /* Skip address space switching if they are the same. */ @@ -419,7 +436,7 @@ SYMBOL_NAME_LABEL(resume) movec %cacr,%d0 oriw #LFLUSH_I_AND_D,%d0 movec %d0,%cacr - + /* switch the root pointer */ pmove %a1@(LTSS_CRP),%crp #endif diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index c2b72aa2d..36a4072ac 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -223,17 +223,9 @@ ENTRY(_start) movel %d0,%a0@ /* save cache mode for page tables */ /* - * raise interrupt level with MASTER bit set, copy isp to msp (if not 68060) + * raise interrupt level */ -#ifdef FROM_PL9 - movew #0x3700,%sr - is_060(1f) - movec %isp,%d0 - movel %d0,%sp -1: -#else movew #0x2700,%sr -#endif /* If running on an Atari, determine the I/O base of the @@ -896,8 +888,10 @@ Lcache68060: /* * Setup initial stack pointer + * We need to get current loaded up with our first task... */ - lea SYMBOL_NAME(init_user_stack)+PAGESIZE,%sp + lea SYMBOL_NAME(init_task_union),%a2 + lea 8192(%a2),%sp /* jump to the kernel start */ putr() diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index f49c38cd3..39e1fbce6 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -29,6 +29,7 @@ #include <linux/sched.h> #include <linux/kernel_stat.h> #include <linux/errno.h> +#include <linux/init.h> #include <asm/system.h> #include <asm/irq.h> @@ -79,7 +80,7 @@ void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq; * the IRQ handling routines. */ -void init_IRQ(void) +__initfunc(void init_IRQ(void)) { int i; diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index 3138d99df..f6bb0689b 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c @@ -6,6 +6,8 @@ #include <linux/mm.h> #include <linux/user.h> #include <linux/elfcore.h> +#include <linux/in6.h> +#include <linux/interrupt.h> #include <asm/setup.h> #include <asm/machdep.h> @@ -14,6 +16,7 @@ #include <asm/semaphore.h> #include <asm/checksum.h> #include <asm/hardirq.h> +#include <asm/softirq.h> asmlinkage long long __ashrdi3 (long long, int); extern char m68k_debug_device[]; @@ -40,6 +43,7 @@ EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(local_irq_count); +EXPORT_SYMBOL(__m68k_bh_counter); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 5422831a8..ad0662f22 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -10,6 +10,7 @@ * This file handles the architecture-dependent parts of process handling.. */ +#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -29,6 +30,23 @@ #include <asm/traps.h> #include <asm/machdep.h> #include <asm/setup.h> +#include <asm/pgtable.h> + +/* + * Initial task structure. Make this a per-architecture thing, + * because different architectures tend to have different + * alignment requirements and potentially different initial + * setup. + */ +static struct vm_area_struct init_mmap = INIT_MMAP; +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS; +struct mm_struct init_mm = INIT_MM; + +union task_union init_task_union + __attribute__((section("init_task"), aligned(2*PAGE_SIZE))) + = { task: INIT_TASK }; asmlinkage void ret_from_exception(void); @@ -46,8 +64,17 @@ asmlinkage int sys_idle(void) /* endless idle loop with no priority at all */ current->priority = -100; current->counter = -100; - for (;;) + for (;;){ + if (!need_resched) +#if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC) + /* block out HSYNC on the atari (falcon) */ + __asm__("stop #0x2200" : : : "cc"); +#else /* portable version */ + __asm__("stop #0x2000" : : : "cc"); +#endif /* machine compilation types */ + run_task_queue(&tq_scheduler); schedule(); + } ret = 0; out: unlock_kernel(); @@ -76,8 +103,8 @@ void show_regs(struct pt_regs * regs) printk("\n"); printk("Format %02x Vector: %04x PC: %08lx Status: %04x\n", regs->format, regs->vector, regs->pc, regs->sr); - printk("ORIG_D0: %08lx D0: %08lx A1: %08lx\n", - regs->orig_d0, regs->d0, regs->a1); + printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n", + regs->orig_d0, regs->d0, regs->a2, regs->a1); printk("A0: %08lx D5: %08lx D4: %08lx\n", regs->a0, regs->d5, regs->d4); printk("D3: %08lx D2: %08lx D1: %08lx\n", @@ -144,8 +171,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct switch_stack * childstack, *stack; unsigned long stack_offset, *retp; - stack_offset = PAGE_SIZE - sizeof(struct pt_regs); - childregs = (struct pt_regs *) (p->kernel_stack_page + stack_offset); + stack_offset = 2*PAGE_SIZE - sizeof(struct pt_regs); + childregs = (struct pt_regs *) ((unsigned long) p + stack_offset); *childregs = *regs; childregs->d0 = 0; @@ -231,7 +258,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump) dump->regs.d7 = sw->d7; dump->regs.a0 = regs->a0; dump->regs.a1 = regs->a1; - dump->regs.a2 = sw->a2; + dump->regs.a2 = regs->a2; dump->regs.a3 = sw->a3; dump->regs.a4 = sw->a4; dump->regs.a5 = sw->a5; diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index 70e341b31..be4149cbb 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c @@ -47,23 +47,11 @@ static int regoff[] = { PT_REG(d1), PT_REG(d2), PT_REG(d3), PT_REG(d4), PT_REG(d5), SW_REG(d6), SW_REG(d7), PT_REG(a0), - PT_REG(a1), SW_REG(a2), SW_REG(a3), SW_REG(a4), + PT_REG(a1), PT_REG(a2), SW_REG(a3), SW_REG(a4), SW_REG(a5), SW_REG(a6), PT_REG(d0), -1, PT_REG(orig_d0), PT_REG(sr), PT_REG(pc), }; -/* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) -{ - int i; - - for (i = 1; i < NR_TASKS; i++) { - if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; - } - return NULL; -} - /* * Get contents of register REGNO in task TASK. */ @@ -116,7 +104,7 @@ static unsigned long get_long(struct task_struct * tsk, repeat: pgdir = pgd_offset(vma->vm_mm, addr); if (pgd_none(*pgdir)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } if (pgd_bad(*pgdir)) { @@ -126,7 +114,7 @@ repeat: } pgmiddle = pmd_offset(pgdir,addr); if (pmd_none(*pgmiddle)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } if (pmd_bad(*pgmiddle)) { @@ -137,7 +125,7 @@ repeat: } pgtable = pte_offset(pgmiddle, addr); if (!pte_present(*pgtable)) { - do_no_page(tsk, vma, addr, 0); + handle_mm_fault(tsk, vma, addr, 0); goto repeat; } page = pte_page(*pgtable); @@ -168,7 +156,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsi repeat: pgdir = pgd_offset(vma->vm_mm, addr); if (!pgd_present(*pgdir)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } if (pgd_bad(*pgdir)) { @@ -178,7 +166,7 @@ repeat: } pgmiddle = pmd_offset(pgdir,addr); if (pmd_none(*pgmiddle)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } if (pmd_bad(*pgmiddle)) { @@ -189,12 +177,12 @@ repeat: } pgtable = pte_offset(pgmiddle, addr); if (!pte_present(*pgtable)) { - do_no_page(tsk, vma, addr, 1); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } page = pte_page(*pgtable); if (!pte_write(*pgtable)) { - do_wp_page(tsk, vma, addr, 2); + handle_mm_fault(tsk, vma, addr, 1); goto repeat; } /* this is a hack for non-kernel-mapped video buffers and similar */ @@ -340,7 +328,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (pid == 1) /* you may not mess with init */ goto out; ret = -ESRCH; - if (!(child = get_task(pid))) + if (!(child = find_task_by_pid(pid))) goto out; ret = -EPERM; if (request == PTRACE_ATTACH) { diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index dfd91d0d4..def50a747 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -18,6 +18,7 @@ #include <linux/genhd.h> #include <linux/errno.h> #include <linux/string.h> +#include <linux/init.h> #include <asm/bootinfo.h> #include <asm/setup.h> @@ -55,13 +56,13 @@ static struct mem_info m68k_ramdisk = { 0, 0 }; static char m68k_command_line[CL_SIZE]; char saved_command_line[CL_SIZE]; -void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)); +void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata; /* machine dependent keyboard functions */ -int (*mach_keyb_init) (void); +int (*mach_keyb_init) (void) __initdata; int (*mach_kbdrate) (struct kbd_repeat *) = NULL; void (*mach_kbd_leds) (unsigned int) = NULL; /* machine dependent irq functions */ -void (*mach_init_IRQ) (void); +void (*mach_init_IRQ) (void) __initdata; void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; void (*mach_get_model) (char *model) = NULL; int (*mach_get_hardware_list) (char *buffer) = NULL; @@ -73,12 +74,12 @@ void (*mach_gettod) (int*, int*, int*, int*, int*, int*); int (*mach_hwclk) (int, struct hwclk_time*) = NULL; int (*mach_set_clock_mmss) (unsigned long) = NULL; void (*mach_reset)( void ); -struct fb_info *(*mach_fb_init)(long *); +struct fb_info *(*mach_fb_init)(long *) __initdata; long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ -void (*mach_video_setup) (char *, int *); +void (*mach_video_setup) (char *, int *) __initdata; #ifdef CONFIG_BLK_DEV_FD -int (*mach_floppy_init) (void) = NULL; -void (*mach_floppy_setup) (char *, int *) = NULL; +int (*mach_floppy_init) (void) __initdata = NULL; +void (*mach_floppy_setup) (char *, int *) __initdata = NULL; void (*mach_floppy_eject) (void) = NULL; #endif @@ -94,7 +95,7 @@ extern void config_apollo(void); #define MASK_256K 0xfffc0000 -static void m68k_parse_bootinfo(const struct bi_record *record) +__initfunc(static void m68k_parse_bootinfo(const struct bi_record *record)) { while (record->tag != BI_LAST) { int unknown = 0; @@ -141,8 +142,8 @@ static void m68k_parse_bootinfo(const struct bi_record *record) } } -void setup_arch(char **cmdline_p, unsigned long * memory_start_p, - unsigned long * memory_end_p) + __initfunc(void setup_arch(char **cmdline_p, unsigned long * memory_start_p, + unsigned long * memory_end_p)) { unsigned long memory_start, memory_end; extern int _etext, _edata, _end; @@ -337,7 +338,7 @@ int get_hardware_list(char *buffer) } #ifdef CONFIG_BLK_DEV_FD -int floppy_init(void) +__initfunc(int floppy_init(void)) { if (mach_floppy_init) return mach_floppy_init(); @@ -345,7 +346,7 @@ int floppy_init(void) return 0; } -void floppy_setup(char *str, int *ints) +__initfunc(void floppy_setup(char *str, int *ints)) { if (mach_floppy_setup) mach_floppy_setup (str, ints); @@ -358,7 +359,7 @@ void floppy_eject(void) } #endif -unsigned long arch_kbd_init(void) +__initfunc(unsigned long arch_kbd_init(void)) { return mach_keyb_init(); } @@ -372,7 +373,7 @@ void arch_gettod(int *year, int *mon, int *day, int *hour, *year = *mon = *day = *hour = *min = *sec = 0; } -void video_setup (char *options, int *ints) +__initfunc(void video_setup (char *options, int *ints)) { if (mach_video_setup) mach_video_setup (options, ints); diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index c60e82b0b..52c13445d 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -42,7 +42,9 @@ #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) -asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options); +asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, + int options, unsigned long *ru); + asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs); const int frame_extra_sizes[16] = { @@ -466,7 +468,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs) if (signr != SIGCHLD) continue; /* check for SIGCHLD: it's special */ - while (sys_waitpid(-1,NULL,WNOHANG) > 0) + while (sys_wait4(-1,NULL,WNOHANG, NULL) > 0) /* nothing */; continue; } diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 5acfd1cbd..e29509cac 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -532,12 +532,15 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) */ vma = find_vma (current->mm, addr); ret = -EINVAL; + /* Check for overflow. */ + if (addr + len < addr) + goto out; if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) goto out; } if (CPU_IS_020_OR_030) { - if (scope == FLUSH_SCOPE_LINE) { + if (scope == FLUSH_SCOPE_LINE && len < 256) { unsigned long cacr; __asm__ ("movec %%cacr, %0" : "=r" (cacr)); if (cache & FLUSH_CACHE_INSN) diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index dbff49276..7b3acdfa6 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c @@ -27,6 +27,24 @@ static inline int set_rtc_mmss(unsigned long nowtime) return -1; } +static inline void do_profile (unsigned long pc) +{ + if (prof_buffer && current->pid) { + extern int _stext; + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + if (pc < prof_len) + ++prof_buffer[pc]; + else + /* + * Dont ignore out-of-bounds PC values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + ++prof_buffer[prof_len-1]; + } +} + /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick @@ -38,6 +56,9 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs) do_timer(regs); + if (!user_mode(regs)) + do_profile(regs->pc); + /* * If we have an externally synchronized Linux clock, then update * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index 1cc547907..25be40007 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -27,6 +27,7 @@ #include <linux/user.h> #include <linux/string.h> #include <linux/linkage.h> +#include <linux/init.h> #include <asm/setup.h> #include <asm/fpu.h> @@ -63,7 +64,7 @@ asm(".text\n" __ALIGN_STR "\n" SYMBOL_NAME_STR(nmihandler) ": rte"); -void trap_init (void) +__initfunc(void trap_init (void)) { int i; @@ -932,16 +933,15 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr) #endif console_verbose(); printk("%s: %08x\n",str,nr); - printk("PC: [<%08lx>]\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); + printk("PC: [<%08lx>]\nSR: %04x SP: %p a2: %08lx\n", + fp->pc, fp->sr, fp, fp->a2); printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", fp->d0, fp->d1, fp->d2, fp->d3); printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", fp->d4, fp->d5, fp->a0, fp->a1); - if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page) - printk("Corrupted stack page\n"); printk("Process %s (pid: %d, stackpage=%08lx)\n", - current->comm, current->pid, current->kernel_stack_page); + current->comm, current->pid, PAGE_SIZE+(unsigned long)current); #ifdef CONFIG_KGDB } #endif |