yann@1: [ This patch not accepted into kernel for now - it touches the core too much - yann@1: but it's ok for crosstool since we just want to check whether toolchain is ok, yann@1: I think. I had to rediff the sched.h changes with -U5 to get them to yann@1: apply properly -- patch got confused with just three lines of context?! -dank ] yann@1: yann@1: Date: Sun, 5 Sep 2004 12:41:08 +0200 (CEST) yann@1: From: Geert Uytterhoeven yann@1: Sender: geert@linux-m68k.org yann@1: To: Dan Kegel yann@1: cc: Roman Zippel , yann@1: Matthias Urlichs , yann@1: Linux Kernel Mailing List , yann@1: Linux/m68k yann@1: Subject: Re: Getting kernel.org kernel to build for m68k? yann@1: In-Reply-To: yann@1: Message-ID: yann@1: yann@1: On Wed, 1 Sep 2004, Geert Uytterhoeven wrote: yann@1: > On Tue, 31 Aug 2004, Dan Kegel wrote: yann@1: > > I noticed today that Linus's m68k kernel can't be built (at least with gcc-3.4.1). yann@1: > > yann@1: > > The first problem I ran into, yann@1: > > CC arch/m68k/kernel/asm-offsets.s yann@1: > > In file included from include/linux/spinlock.h:12, yann@1: > > from include/linux/capability.h:45, yann@1: > > from include/linux/sched.h:7, yann@1: > > from arch/m68k/kernel/asm-offsets.c:12: yann@1: > > include/linux/thread_info.h:30: error: parse error before '{' token yann@1: > > is solved already in the m68k tree. yann@1: > > (In particular, yann@1: > > the #ifndef __HAVE_THREAD_FUNCTIONS ... #endif in yann@1: > > http://linux-m68k-cvs.apia.dhs.org/c/cvsweb/linux/include/linux/thread_info.h?rev=1.5;content-type=text%2Fplain yann@1: > > probably solves it.) yann@1: > > There are other problems after that. yann@1: > yann@1: > Roman Zippel changed the threading stuff on m68k. Since it would affect other yann@1: > architectures, I never submitted it on my own. yann@1: > yann@1: > In short, we never really compile this code, since the m68k tree doesn't use it yann@1: > anymore. And yes, it even fails with older compiler versions, like 2.95.2. yann@1: yann@1: The second part doesn't seem to be true: the code is used. And it does compile yann@1: after applying the fixes below, even with gcc 3.4.1. yann@1: yann@1: > > Any chance you could spend a bit of time sending Linus enough yann@1: > > patches for his kernel to build for m68k, if not run? yann@1: > yann@1: > I'll make sure a plain kernel.org kernel can build an m68k kernel. yann@1: yann@1: The patch below makes the plain kernel.org 2.6.8.1 compile for m68k, yann@1: using gcc 2.95.2 or 3.3.3 (3.4.1 needs a few more changes in random yann@1: places). The resulting kernel (I booted the gcc 2.95.2 case) works fine on my yann@1: Amiga. yann@1: yann@1: It's more or less the patch created by Matthias Urlichs last year, so yann@1: the credits are his: yann@1: yann@1: | This change implements a reasonable compromise between the task_info->flags yann@1: | variable in other ports, which is too much work in the syscall path on m68k, yann@1: | and moving the whole structure to thread_struct, which is way too intrusive yann@1: | on other ports. yann@1: yann@1: The patch does affect generic code a bit, but the collateral damage is yann@1: kept to a minimum. yann@1: yann@1: We can still keep Roman's thread info abstractions[*] in Linux/m68k CVS, but yann@1: I'd really like the plain kernel.org kernel to be in a working state as well. yann@1: That way more people may do cross-compile tests for m68k. yann@1: yann@1: Hence if no one objects, I'll submit the patch to Andrew and Linus. yann@1: yann@1: All comments are welcome! yann@1: yann@1: --- linux-2.6.8.1/arch/m68k/kernel/asm-offsets.c 2004-04-28 15:48:59.000000000 +0200 yann@1: +++ linux-m68k-2.6.8.1/arch/m68k/kernel/asm-offsets.c 2004-09-05 12:04:00.000000000 +0200 yann@1: @@ -31,6 +31,7 @@ int main(void) yann@1: DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, thread.work.sigpending)); yann@1: DEFINE(TASK_NOTIFY_RESUME, offsetof(struct task_struct, thread.work.notify_resume)); yann@1: DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); yann@1: + DEFINE(TASK_TINFO, offsetof(struct task_struct, thread_info)); yann@1: DEFINE(TASK_MM, offsetof(struct task_struct, mm)); yann@1: DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); yann@1: yann@1: @@ -45,6 +46,9 @@ int main(void) yann@1: DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); yann@1: DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); yann@1: yann@1: + /* offsets into the thread_info struct */ yann@1: + DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count)); yann@1: + yann@1: /* offsets into the pt_regs */ yann@1: DEFINE(PT_D0, offsetof(struct pt_regs, d0)); yann@1: DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0)); yann@1: --- linux-2.6.8.1/arch/m68k/kernel/entry.S 2004-05-24 11:13:22.000000000 +0200 yann@1: +++ linux-m68k-2.6.8.1/arch/m68k/kernel/entry.S 2004-09-02 20:13:12.000000000 +0200 yann@1: @@ -134,13 +134,13 @@ ENTRY(system_call) yann@1: yann@1: syscall_exit_work: yann@1: btst #5,%sp@(PT_SR) | check if returning to kernel yann@1: - bnes 1b | if so, skip resched, signals yann@1: + bnes 1b | if so, skip everything yann@1: tstw %d0 yann@1: - jeq do_signal_return yann@1: + jeq do_signal_return | jump if only sig_pending or notify_resume yann@1: tstb %d0 yann@1: - jne do_delayed_trace yann@1: + jne do_delayed_trace | jump if delayed_trace yann@1: yann@1: - pea resume_userspace yann@1: + pea resume_userspace | need_resched is set yann@1: jmp schedule yann@1: yann@1: ret_from_exception: yann@1: @@ -223,10 +223,14 @@ ENTRY(nmi_handler) yann@1: */ yann@1: inthandler: yann@1: SAVE_ALL_INT yann@1: - GET_CURRENT(%d0) yann@1: - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+2) yann@1: - | put exception # in d0 yann@1: - bfextu %sp@(PT_VECTOR){#4,#10},%d0 yann@1: + /* GET_CURRENT(%d0) */ yann@1: + movel %sp,%d0 yann@1: + andw #-THREAD_SIZE,%d0 yann@1: + movel %d0,%a1 yann@1: + addqb #1,%a1@(TINFO_PREEMPT+2) yann@1: + movel %a1@,%curptr yann@1: + yann@1: + bfextu %sp@(PT_VECTOR){#4,#10},%d0 | put exception # in d0 yann@1: yann@1: movel %sp,%sp@- yann@1: movel %d0,%sp@- | put vector # on stack yann@1: @@ -243,7 +247,8 @@ inthandler: yann@1: 3: addql #8,%sp | pop parameters off stack yann@1: yann@1: ret_from_interrupt: yann@1: - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+2) yann@1: + movel %curptr@(TASK_TINFO),%a1 yann@1: + subqb #1,%a1@(TINFO_PREEMPT+2) yann@1: jeq 1f yann@1: 2: yann@1: RESTORE_ALL yann@1: --- linux-2.6.8.1/include/asm-m68k/processor.h 2004-04-28 15:49:03.000000000 +0200 yann@1: +++ linux-m68k-2.6.8.1/include/asm-m68k/processor.h 2004-09-02 20:29:32.000000000 +0200 yann@1: @@ -84,7 +84,6 @@ struct thread_struct { yann@1: ksp: sizeof(init_stack) + (unsigned long) init_stack, \ yann@1: sr: PS_S, \ yann@1: fs: __KERNEL_DS, \ yann@1: - info: INIT_THREAD_INFO(init_task) \ yann@1: } yann@1: yann@1: /* yann@1: --- linux-2.6.8.1/include/asm-m68k/thread_info.h 2004-05-24 11:13:53.000000000 +0200 yann@1: +++ linux-m68k-2.6.8.1/include/asm-m68k/thread_info.h 2004-09-05 12:19:47.000000000 +0200 yann@1: @@ -6,7 +6,7 @@ yann@1: #include yann@1: yann@1: struct thread_info { yann@1: - struct task_struct *task; /* main task structure */ yann@1: + struct task_struct *task; /* main task structure, must be first! */ yann@1: struct exec_domain *exec_domain; /* execution domain */ yann@1: __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ yann@1: __u32 cpu; /* should always be 0 on m68k */ yann@1: @@ -21,7 +21,8 @@ struct thread_info { yann@1: { \ yann@1: .task = &tsk, \ yann@1: .exec_domain = &default_exec_domain, \ yann@1: - .restart_block = { \ yann@1: + .preempt_count = 1, \ yann@1: + .restart_block = { \ yann@1: .fn = do_no_restart_syscall, \ yann@1: }, \ yann@1: } yann@1: @@ -35,10 +36,11 @@ struct thread_info { yann@1: #define free_thread_info(ti) free_pages((unsigned long)(ti),1) yann@1: #endif /* PAGE_SHIFT == 13 */ yann@1: yann@1: -//#define init_thread_info (init_task.thread.info) yann@1: +#define init_thread_info (init_thread_union.thread_info) yann@1: #define init_stack (init_thread_union.stack) yann@1: yann@1: -#define current_thread_info() (current->thread_info) yann@1: +register __u32 current_thread_info_reg asm("sp"); yann@1: +#define current_thread_info() ((struct thread_info *)(current_thread_info_reg & ~0x1fff)) yann@1: yann@1: yann@1: #define __HAVE_THREAD_FUNCTIONS yann@1: @@ -91,8 +93,12 @@ extern int thread_flag_fixme(void); yann@1: }) yann@1: yann@1: #define __get_set_tsk_thread_flag(tsk, flag, val) ({ \ yann@1: - int __res = __get_tsk_thread_flag(tsk, flag); \ yann@1: + int __res; \ yann@1: + unsigned long __flags; \ yann@1: + local_irq_save(__flags); \ yann@1: + __res = __get_tsk_thread_flag(tsk, flag); \ yann@1: __set_tsk_thread_flag(tsk, flag, val); \ yann@1: + local_irq_restore(__flags); \ yann@1: __res; \ yann@1: }) yann@1: yann@1: @@ -105,7 +111,4 @@ extern int thread_flag_fixme(void); yann@1: #define clear_thread_flag(flag) clear_tsk_thread_flag(current, flag) yann@1: #define test_thread_flag(flag) test_tsk_thread_flag(current, flag) yann@1: yann@1: -#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED) yann@1: -#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED) yann@1: - yann@1: #endif /* _ASM_M68K_THREAD_INFO_H */ yann@1: --- linux-2.6.8/include/linux/sched.h.old 2004-09-13 21:48:58.000000000 -0700 yann@1: +++ linux-2.6.8/include/linux/sched.h 2004-09-13 21:50:26.000000000 -0700 yann@1: @@ -975,10 +975,11 @@ yann@1: task_unlock(task); yann@1: yann@1: return mm; yann@1: } yann@1: yann@1: +#ifndef __HAVE_THREAD_FUNCTIONS yann@1: yann@1: /* set thread flags in other task's structures yann@1: * - see asm/thread_info.h for TIF_xxxx flags available yann@1: */ yann@1: static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag) yann@1: @@ -1004,10 +1005,12 @@ yann@1: static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag) yann@1: { yann@1: return test_ti_thread_flag(tsk->thread_info,flag); yann@1: } yann@1: yann@1: +#endif /* __HAVE_THREAD_FUNCTIONS */ yann@1: + yann@1: static inline void set_tsk_need_resched(struct task_struct *tsk) yann@1: { yann@1: set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); yann@1: } yann@1: yann@1: --- linux-2.6.8.1/include/linux/thread_info.h 2004-04-27 20:42:22.000000000 +0200 yann@1: +++ linux-m68k-2.6.8.1/include/linux/thread_info.h 2004-09-04 21:24:36.000000000 +0200 yann@1: @@ -21,6 +21,7 @@ extern long do_no_restart_syscall(struct yann@1: #include yann@1: yann@1: #ifdef __KERNEL__ yann@1: +#ifndef __HAVE_THREAD_FUNCTIONS yann@1: yann@1: /* yann@1: * flag set/clear/test wrappers yann@1: @@ -77,16 +78,11 @@ static inline int test_ti_thread_flag(st yann@1: return test_bit(flag,&ti->flags); yann@1: } yann@1: yann@1: -static inline void set_need_resched(void) yann@1: -{ yann@1: - set_thread_flag(TIF_NEED_RESCHED); yann@1: -} yann@1: +#endif /* __HAVE_THREAD_FUNCTIONS */ yann@1: yann@1: -static inline void clear_need_resched(void) yann@1: -{ yann@1: - clear_thread_flag(TIF_NEED_RESCHED); yann@1: -} yann@1: +#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED) yann@1: +#define clear_need_resched(void) clear_thread_flag(TIF_NEED_RESCHED) yann@1: yann@1: -#endif yann@1: +#endif /* __KERNEL__ */ yann@1: yann@1: #endif /* _LINUX_THREAD_INFO_H */ yann@1: yann@1: Gr{oetje,eeting}s, yann@1: yann@1: Geert yann@1: yann@1: [*] For reference: yann@1: yann@1: http://linux-m68k-cvs.ubb.ca/~geert/linux-m68k-2.6.x-merging/POSTPONED/156-thread_info.diff yann@1: yann@1: -- yann@1: Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org yann@1: yann@1: In personal conversations with technical people, I call myself a hacker. But yann@1: when I'm talking to journalists I just say "programmer" or something like that. yann@1: -- Linus Torvalds yann@1: yann@1: yann@1: