From: Kazumoto K. <kk...@us...> - 2004-01-13 05:52:15
|
Update of /cvsroot/linuxsh/linux/arch/sh/kernel/cpu In directory sc8-pr-cvs1:/tmp/cvs-serv20694/arch/sh/kernel/cpu Modified Files: init.c rtc.c Log Message: Fixes for preempted kernel. 2004-01-12 Kaz Kojima <kk...@rr...> * arch/sh/kernel/signal.c (handle_signal): Disable interrupts in gUSA handling when enabling preemption. * arch/sh/kernel/process.c (__switch_to): Do gUSA handling when enabling preemption. * arch/sh/kernel/entry.S: Jump to resume_userspace if it's return to user space also in preemption case. Don't use short branches with far labels to avoid the assembler warnings. Correct the condition for exception path. 2004-01-12 SUGIOKA Toshinobu <su...@it...> * arch/sh/kernel/cpu/sh4/fpu.c (save_fpu): Clear PF_USEDFPU before saving fpu to avoid fpscr corruption while preemption. * arch/sh/kernel/process.c (copy_thread): Remove setting SR_FD already done in unlazy_fpu. 2004-01-12 SUGIOKA Toshinobu <su...@it...> * arch/sh/kernel/entry.S (restore_all): Don't inherit current FD-bit, resotore saved FD-bit instead. (handle_exception): Set FD-bit when entering kernel. * arch/sh/kernel/cpu/sh4/fpu.c (save_fpu): Add 2nd argument 'regs'. Reset FD-bit while fpu proccesing. Add 'regs' parameter for release_fpu. (restore_fpu): Reset FD-bit while fpu proccesing. (fpu_init): Likewise. (do_fpu_error): Add 'regs' parameter for save_fpu. (do_fpu_state_restore): Add 'regs' parameter for grab_fpu. * arch/sh/kernel/process.c (flush_thread): Add 'regs' parameter for clear_fpu. (dump_fpu): Add 'regs' parameter for unlazy_fpu. (copy_thread): Likewise. (__switch_to): Likewise. * arch/sh/kernel/signal.c (save_sigcontext_fpu): Add 'regs' argument. Add 'regs' parameter for unlazy_fpu. (restore_sigcontext): Add 'regs' parameter for clear_fpu. (setup_sigcontext): Add 'regs' parameter for save_sigcontext_fpu. * arch/sh/kernel/cpu/init.c (sh_cpu_init): Use disable_fpu instead of release_fpu. * include/asm-sh/processor.h: Include asm/ptrace.h for struct pt_regs. (start_thread): Set FD bit. (enable_fpu): New function. (disable_fpu): New function. (release_fpu): Set FD-bit of saved SR instead of current SR. (grub_fpu): Clear FD-bit of saved SR instead of current SR. (unlazy_fpu): Add 'regs' argument. Pass 'regs' to save_fpu. (clear_fpu): Add 'regs' argument. Pass 'regs' to release_fpu. * include/asm-sh/ptrace.h: Don't include asm/processor.h 2004-01-12 SUGIOKA Toshinobu <su...@it...> * arch/sh/kernel/cpu/rtc.c (sh_rtc_gettimeofday): Don't call schedule_timeout. Re-read RTC registers if MSB of R64CNT was changed while reading them on SH-4 which has unreliable CF bit. Reduce interrupt disabled area. 2004-01-12 Masaki Saitoh <mas...@aa...> * arch/sh/kernel/cpu/rtc.c (sh_rtc_gettimeofday): Protect RTC from interrupt. (sh_rtc_settimeofday): Likewise. * arch/sh/kernel/irq.c (do_IRQ): Prevent any preemption while the handler called. 2004-01-12 SUGIOKA Toshinobu <su...@it...> * arch/sh/mm/fault.c (update_mmu_cache): Protect __flush_tlb_page from interrupt. Index: init.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/cpu/init.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- init.c 26 Oct 2003 23:39:17 -0000 1.2 +++ init.c 13 Jan 2004 05:52:11 -0000 1.3 @@ -180,7 +180,7 @@ if (fpu_disabled) { printk("FPU Disabled\n"); cpu_data->flags &= ~CPU_HAS_FPU; - release_fpu(); + disable_fpu(); } /* FPU initialization */ Index: rtc.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/cpu/rtc.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- rtc.c 6 May 2003 23:28:48 -0000 1.3 +++ rtc.c 13 Jan 2004 05:52:11 -0000 1.4 @@ -23,10 +23,12 @@ void sh_rtc_gettimeofday(struct timespec *ts) { - unsigned int sec128, sec, min, hr, wk, day, mon, yr, yr100; + unsigned int sec128, sec, sec2, min, hr, wk, day, mon, yr, yr100, cf_bit; + unsigned long flags; again: do { + local_irq_save(flags); ctrl_outb(0, RCR1); /* Clear CF-bit */ sec128 = ctrl_inb(R64CNT); sec = ctrl_inb(RSECCNT); @@ -43,15 +45,10 @@ yr = ctrl_inb(RYRCNT); yr100 = (yr == 0x99) ? 0x19 : 0x20; #endif - } while ((ctrl_inb(RCR1) & RCR1_CF) != 0); - -#if RTC_BIT_INVERTED != 0 - /* Work around to avoid reading incorrect value. */ - if (sec128 == RTC_BIT_INVERTED) { - schedule_timeout(1); - goto again; - } -#endif + sec2 = ctrl_inb(R64CNT); + cf_bit = ctrl_inb(RCR1) & RCR1_CF; + local_irq_restore(flags); + } while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0); BCD_TO_BIN(yr100); BCD_TO_BIN(yr); @@ -65,6 +62,7 @@ hr > 23 || min > 59 || sec > 59) { printk(KERN_ERR "SH RTC: invalid value, resetting to 1 Jan 2000\n"); + local_irq_save(flags); ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */ ctrl_outb(0, RSECCNT); ctrl_outb(0, RMINCNT); @@ -99,7 +97,9 @@ { int retval = 0; int real_seconds, real_minutes, cmos_minutes; + unsigned long flags; + local_irq_save(flags); ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */ cmos_minutes = ctrl_inb(RMINCNT); @@ -130,6 +130,7 @@ } ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */ + local_irq_restore(flags); return retval; } |