summaryrefslogtreecommitdiffstats
path: root/arch/m68k/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-06-01 03:16:17 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-06-01 03:16:17 +0000
commitd8d9b8f76f22b7a16a83e261e64f89ee611f49df (patch)
tree3067bc130b80d52808e6390c9fc7fc087ec1e33c /arch/m68k/kernel
parent19c9bba94152148523ba0f7ef7cffe3d45656b11 (diff)
Initial revision
Diffstat (limited to 'arch/m68k/kernel')
-rw-r--r--arch/m68k/kernel/entry.S109
-rw-r--r--arch/m68k/kernel/head.S14
-rw-r--r--arch/m68k/kernel/ints.c3
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c4
-rw-r--r--arch/m68k/kernel/process.c39
-rw-r--r--arch/m68k/kernel/ptrace.c30
-rw-r--r--arch/m68k/kernel/setup.c29
-rw-r--r--arch/m68k/kernel/signal.c6
-rw-r--r--arch/m68k/kernel/sys_m68k.c5
-rw-r--r--arch/m68k/kernel/time.c21
-rw-r--r--arch/m68k/kernel/traps.c10
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