📄 rthal5g-2.4.22.patch
字号:
-/* how many counter cycles in a jiffy */-static unsigned long cycles_per_jiffy;- /* Cycle counter value at the previous timer interrupt.. */ static unsigned int timerhi, timerlo; @@ -90,6 +87,10 @@ */ static void null_timer_ack(void) { /* nothing */ } +#ifdef CONFIG_RTHAL+static volatile unsigned long rtai_count;+#endif+ /* * Null high precision timer functions for systems lacking one. */@@ -100,23 +101,43 @@ static void null_hpt_init(unsigned int count) { /* nothing */ } +/* how many counter cycles in a jiffy */+unsigned long cycles_per_jiffy=0; /* * Timer ack for an R4k-compatible timer of a known frequency. */ static void c0_timer_ack(void) {- unsigned int count;-+#ifndef CONFIG_RTHAL+ unsigned int count;+#endif /* Ack this timer interrupt and set the next one. */ expirelo += cycles_per_jiffy; write_c0_compare(expirelo); /* Check to see if we have missed any timer interrupts. */- count = read_c0_count();- if ((count - expirelo) < 0x7fffffff) {+#ifdef CONFIG_RTHAL+ rtai_count=+#else+ count=+#endif + read_c0_count();+ if ((+#ifdef CONFIG_RTHAL+ rtai_count+#else+ count+#endif+ - expirelo) < 0x7fffffff) { /* missed_timer_count++; */- expirelo = count + cycles_per_jiffy;+ expirelo = +#ifdef CONFIG_RTHAL+ rtai_count+#else+ count+#endif + + cycles_per_jiffy; write_c0_compare(expirelo); } }@@ -132,17 +153,28 @@ /* For use solely as a high precision timer. */ static void c0_hpt_init(unsigned int count) {+#ifdef CONFIG_RTHAL+ extern struct rt_hal rthal;+ + if (!rthal.rtai_active)+#endif+ write_c0_count(read_c0_count() - count); } /* For use both as a high precision timer and an interrupt source. */ static void c0_hpt_timer_init(unsigned int count) {- count = read_c0_count() - count;- expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy;- write_c0_count(expirelo - cycles_per_jiffy);- write_c0_compare(expirelo);- write_c0_count(count);+#ifdef CONFIG_RTHAL+ extern struct rt_hal rthal;++ if (rthal.rtai_active) return; //do nothing+#endif+ count = read_c0_count() - count;+ expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy;+ write_c0_count(expirelo - cycles_per_jiffy);+ write_c0_compare(expirelo);+ write_c0_count(count); } int (*mips_timer_state)(void);@@ -202,7 +234,10 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock);+ //steve here+ rtc_set_time(xtime.tv_sec);+ + write_unlock_irq (&xtime_lock); } @@ -223,6 +258,17 @@ return 0; } +/* usecs per counter cycle, shifted to left by 32 bits */+static unsigned int sll32_usecs_per_cycle;++/* Cycle counter value at the previous timer interrupt.. */+static unsigned int timerhi, timerlo;++/* expirelo is the count value for next CPU timer interrupt */+static unsigned int expirelo;++/* last time when xtime and rtc are sync'ed up */+static long last_rtc_update; /* The function pointer to one of the gettimeoffset funcs. */ unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset;@@ -405,47 +451,63 @@ #endif } +static inline int +bit64_compare(unsigned hi1, unsigned lo1, unsigned hi2, unsigned lo2)+{+ if (hi1 == hi2) + return lo1 - lo2;+ else+ return hi1 - hi2;+}+ /* * High-level timer interrupt service routines. This function * is set as irqaction->handler and is invoked through do_IRQ. */ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) {- unsigned long j;- unsigned int count;-- count = mips_hpt_read();- mips_timer_ack();-- /* Update timerhi/timerlo for intra-jiffy calibration. */- timerhi += count < timerlo; /* Wrap around */- timerlo = count;-- /*- * call the generic timer interrupt handling- */- do_timer(regs);-- /*- * If we have an externally synchronized Linux clock, then update- * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be- * called as close as possible to 500 ms before the new second starts.- */- read_lock(&xtime_lock);- if ((time_status & STA_UNSYNC) == 0 &&- xtime.tv_sec > last_rtc_update + 660 &&- xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&- xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {- if (rtc_set_mmss(xtime.tv_sec) == 0) {- last_rtc_update = xtime.tv_sec;- } else {- /* do it again in 60 s */- last_rtc_update = xtime.tv_sec - 600;- }- }- read_unlock(&xtime_lock);-- /*+ unsigned long j;+ unsigned int count = mips_hpt_read();+#ifdef CONFIG_RTHAL+ extern struct rt_hal rthal;+ + if(!rthal.rtai_active)+#endif + mips_timer_ack();+ + /* Update timerhi/timerlo for intra-jiffy calibration. */+ timerhi += count < timerlo; /* Wrap around */+ timerlo = count;+ + /*+ * call the generic timer interrupt handling+ */+ do_timer(regs);+ + /*+ * If we have an externally synchronized Linux clock, then update+ * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be+ * called as close as possible to 500 ms before the new second starts.+ */+ read_lock(&xtime_lock);+ if ((time_status & STA_UNSYNC) == 0 &&+ xtime.tv_sec > last_rtc_update + 660 &&+ xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&+ xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) + { + if (rtc_set_mmss(xtime.tv_sec) == 0) + { + last_rtc_update = xtime.tv_sec;+ }+ else + { + /* do it again in 60 s */+ last_rtc_update = xtime.tv_sec - 600;+ } + } + read_unlock(&xtime_lock);+ + /* * If jiffies has overflown in this timer_interrupt, we must * update the timer[hi]/[lo] to make fast gettimeoffset funcs * quotient calc still valid. -arca@@ -486,46 +548,33 @@ } } + #if !defined(CONFIG_SMP)+ /*+ * In UP mode, we call local_timer_interrupt() to do profiling+ * and process accouting.+ *+ * In SMP mode, local_timer_interrupt() is invoked by appropriate+ * low-level local timer interrupt handler.+ */+ local_timer_interrupt(irq, dev_id, regs);+ +#else /* CONFIG_SMP */+ + if (emulate_local_timer_interrupt) + { /*- * In UP mode, we call local_timer_interrupt() to do profiling+ * this is the place where we send out inter-process+ * interrupts and let each CPU do its own profiling * and process accouting. *- * In SMP mode, local_timer_interrupt() is invoked by appropriate- * low-level local timer interrupt handler.+ * Obviously we need to call local_timer_interrupt() for+ * the current CPU too. */- local_timer_interrupt(irq, dev_id, regs);--#else /* CONFIG_SMP */-- if (emulate_local_timer_interrupt) {- /*- * this is the place where we send out inter-process- * interrupts and let each CPU do its own profiling- * and process accouting.- *- * Obviously we need to call local_timer_interrupt() for- * the current CPU too.- */- panic("Not implemented yet!!!");- }-#endif /* CONFIG_SMP */-}--asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)-{- int cpu = smp_processor_id();-- irq_enter(cpu, irq);- kstat.irqs[cpu][irq]++;-- /* we keep interrupt disabled all the time */- timer_interrupt(irq, NULL, regs);-- irq_exit(cpu, irq);-- if (softirq_pending(cpu))- do_softirq();+ panic("Not implemented yet!!!");+ }+ +#endif /* CONFIG_SMP */ } asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)@@ -620,9 +669,6 @@ if (board_time_init) board_time_init(); - if (!rtc_set_mmss)- rtc_set_mmss = rtc_set_time;- xtime.tv_sec = rtc_get_time(); xtime.tv_usec = 0; @@ -673,8 +719,7 @@ do_gettimeoffset = fixed_rate_gettimeoffset; /* Calculate cache parameters. */- cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ;-+ cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ do_div64_32(sll32_usecs_per_cycle, 1000000, mips_hpt_frequency / 2,@@ -755,6 +800,44 @@ } EXPORT_SYMBOL(rtc_lock);++#ifdef CONFIG_RTHAL++void linux_mips_timer_intr(int irq, void *dev_id, struct pt_regs *regs)+{ + extern struct rt_hal rthal;+ + long flags;++ save_and_cli(flags);+ mips_timer_ack();+ rthal.tsc.hltsc[1] += (rtai_count < rthal.tsc.hltsc[0]);+ rthal.tsc.hltsc[0] = rtai_count; + restore_flags(flags);+ timer_interrupt(irq, dev_id, regs);+}++void linux_soft_mips_timer_intr(int irq, void *dev_id, struct pt_regs *regs)+{ + extern struct rt_hal rthal;+ unsigned long count;+ long flags;++ hard_save_flags_and_cli(flags);+ expirelo += cycles_per_jiffy;+ count = read_c0_count();++ if ((count - expirelo) < 0x7fffffff) {+ expirelo = count + cycles_per_jiffy;+ }+ + rthal.tsc.hltsc[1] += (count < rthal.tsc.hltsc[0]);+ rthal.tsc.hltsc[0] = count;+ hard_restore_flags(flags);+ timer_interrupt(irq, dev_id, regs);+}+#endif //CONFIG_RTHAL+ EXPORT_SYMBOL(to_tm); EXPORT_SYMBOL(rtc_set_time); EXPORT_SYMBOL(rtc_get_time);diff -Nur -X dontdiff.dat linux-2.4.22.orig/arch/mips/mm/pg-r4k.S linux-2.4.22/arch/mips/mm/pg-r4k.S--- linux-2.4.22.orig/arch/mips/mm/pg-r4k.S 2003-08-27 16:14:29.000000000 -0700+++ linux-2.4.22/arch/mips/mm/pg-r4k.S 2003-08-27 09:20:32.000000000 -0700@@ -166,6 +166,7 @@ LEAF(r4k_clear_page_r4600_v2) .set mips3+#ifndef CONFIG_RTHAL mfc0 a1, CP0_STATUS ori AT, a1, 1 xori AT, 1@@ -173,7 +174,13 @@ nop nop nop-+#else+ lw a1, (rthal + 36) //cli+ nop+ jalr a1+ nop+ move a1, v0+#endif .set volatile la AT, KSEG1 lw zero, (AT)@@ -193,6 +200,7 @@ sd zero, -8(a0) bne AT, a0, 1b +#ifndef CONFIG_RTHAL mfc0 AT, CP0_STATUS # __restore_flags andi a1, 1 ori AT, 1@@ -202,7 +210,13 @@ nop nop nop-+#else+ move a0, a1+ lw a1, (rthal + 32) //setflags+ nop+ jalr a1+ nop+#endif jr ra END(r4k_clear_page_r4600_v2) @@ -469,6 +483,7 @@ LEAF(r4k_copy_page_r4600_v2) .set mips3+#ifndef CONFIG_RTHAL mfc0 v1, CP0_STATUS ori AT, v1, 1 xori AT, 1@@ -477,7 +492,13 @@ nop nop nop-+#else+ lw a1, (rthal + 36) //cli+ nop+ jalr a1+ nop+ move v1, v0+#endif addiu AT, a0, _PAGE_SIZE 1: nop nop@@ -525,6 +546,7 @@ sw a2, -4(a0) bne AT, a0, 1b +#ifndef CONFIG_RTHAL mfc0 AT, CP0_STATUS # __restore_flags andi v1, 1 ori AT, 1@@ -534,6 +556,13 @@ nop nop nop+#else+ move a0, v1+ lw a1, (rthal + 32) //setflags+ nop+ jalr a1+ nop +#endif jr ra END(r4k_copy_page_r4600_v2) diff -Nur -X dontdiff.dat linux-2.4.22.orig/arch/mips/mm/tlb-r4k.c linux-2.4.22/arch/mips/mm/tlb-r4k.c--- linux-2.4.22.orig/arch/mips/mm/tlb-r4k.c 2003-08-27 16:14:29.000000000 -0700+++ linux-2.4.22/arch/mips/mm/tlb-r4k.c 2003-08-27 07:24:03.000000000 -0700@@ -24,6 +24,22 @@ #include <asm/pgtable.h> #include <asm/system.h> +#ifdef CONFIG_RTHAL+#if 1+/*+ * You may likely need this for your board...+ * Sucks that this eats away at some RTAI performance, too. :(+ * + * (then again, it beats crashing) -- don't forget include/asm/mmu_context.h+ */++#undef local_irq_save+#undef local_irq_restore+#define IRQ_SAFE_TLB+#define local_irq_save(x) hard_save_flags_and_cli(x)+#define local_irq_restore(x) hard_restore_flags(x)+#endif+#endif #undef DEBUG_TLB #undef DEBUG_TLBUPDATE @@ -41,7 +57,7 @@ int entry; #ifdef DEBUG_TLB- printk("[tlball]");+ printk("[tlball]\n"); #endif local_irq_save(flags);@@ -77,7 +93,7 @@ if (cpu_context(cpu, mm) != 0) { #ifdef DEBUG_TLB- printk("[tlbmm<%d>]", cpu_context(cpu, mm));+ printk("[tlbmm<%d>]\n", cpu_context(cpu, mm)); #endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -