⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtai_hal.h

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 H
📖 第 1 页 / 共 2 页
字号:
/** *   @ingroup hal *   @file * *   ARTI -- RTAI-compatible Adeos-based Real-Time Interface. Based on *   the original RTAI layer for x86. * *   Original RTAI/x86 layer implementation: \n *   Copyright &copy; 2000 Paolo Mantegazza, \n *   Copyright &copy; 2000 Steve Papacharalambous, \n *   Copyright &copy; 2000 Stuart Hughes, \n *   and others. * *   RTAI/x86 rewrite over Adeos: \n *   Copyright &copy 2002 Philippe Gerum. * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, *   USA; either version 2 of the License, or (at your option) any later *   version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//** * @addtogroup hal *@{*/#ifndef _RTAI_ASM_I386_HAL_H#define _RTAI_ASM_I386_HAL_H#include <asm/rtai_vectors.h>#include <rtai_types.h>#ifdef CONFIG_SMP#define RTAI_NR_CPUS  CONFIG_RTAI_CPUS#else /* !CONFIG_SMP */#define RTAI_NR_CPUS  1#endif /* CONFIG_SMP */static __inline__ unsigned long ffnz (unsigned long word) {    /* Derived from bitops.h's ffs() */    __asm__("bsfl %1, %0"	    : "=r" (word)	    : "r"  (word));    return word;}static inline unsigned long long rtai_ulldiv (unsigned long long ull,					      unsigned long uld,					      unsigned long *r) {    /*     * Fixed by Marco Morandini <morandini@aero.polimi.it> to work     * with the -fnostrict-aliasing and -O2 combination using GCC     * 3.x.     */    unsigned long long qf, rf;    unsigned long tq, rh;    union { unsigned long long ull; unsigned long ul[2]; } p, q;    p.ull = ull;    q.ull = 0;    rf = 0x100000000ULL - (qf = 0xFFFFFFFFUL / uld) * uld;    while (p.ull >= uld) {    	q.ul[1] += (tq = p.ul[1] / uld);	rh = p.ul[1] - tq * uld;	q.ull  += rh * qf + (tq = p.ul[0] / uld);	p.ull   = rh * rf + (p.ul[0] - tq * uld);    }    if (r)	*r = p.ull;    return q.ull;}static inline int rtai_imuldiv (int i, int mult, int div) {    /* Returns (int)i = (int)i*(int)(mult)/(int)div. */        int dummy;    __asm__ __volatile__ ( \	"mull %%edx\t\n" \	"div %%ecx\t\n" \	: "=a" (i), "=d" (dummy)       	: "a" (i), "d" (mult), "c" (div));    return i;}static inline long long rtai_llimd(long long ll, int mult, int div) {    /* Returns (long long)ll = (int)ll*(int)(mult)/(int)div. */    __asm__ __volatile ( \	"movl %%edx,%%ecx\t\n" \	"mull %%esi\t\n" \	"movl %%eax,%%ebx\n\t" \	"movl %%ecx,%%eax\t\n" \        "movl %%edx,%%ecx\t\n" \        "mull %%esi\n\t" \	"addl %%ecx,%%eax\t\n" \	"adcl $0,%%edx\t\n" \        "divl %%edi\n\t" \        "movl %%eax,%%ecx\t\n" \        "movl %%ebx,%%eax\t\n" \	"divl %%edi\n\t" \	"sal $1,%%edx\t\n" \        "cmpl %%edx,%%edi\t\n" \        "movl %%ecx,%%edx\n\t" \	"jge 1f\t\n" \        "addl $1,%%eax\t\n" \        "adcl $0,%%edx\t\n" \	"1:\t\n" \	: "=A" (ll) \	: "A" (ll), "S" (mult), "D" (div) \	: "%ebx", "%ecx");    return ll;}/* *  u64div32c.c is a helper function provided, 2003-03-03, by: *  Copyright (C) 2003 Nils Hagge <hagge@rts.uni-hannover.de> */static inline unsigned long long rtai_u64div32c(unsigned long long a,						unsigned long b,						int *r) {    __asm__ __volatile(       "\n        movl    %%eax,%%ebx"       "\n        movl    %%edx,%%eax"       "\n        xorl    %%edx,%%edx"       "\n        divl    %%ecx"       "\n        xchgl   %%eax,%%ebx"       "\n        divl    %%ecx"       "\n        movl    %%edx,%%ecx"       "\n        movl    %%ebx,%%edx"       : "=a" (((unsigned long *)((void *)&a))[0]), "=d" (((unsigned long *)((void *)&a))[1])       : "a" (((unsigned long *)((void *)&a))[0]), "d" (((unsigned long *)((void *)&a))[1]), "c" (b)       : "%ebx"       );    return a;}#if defined(__KERNEL__) && !defined(__cplusplus)#include <linux/sched.h>#include <linux/interrupt.h>#include <asm/system.h>#include <asm/io.h>#include <asm/rtai_atomic.h>#include <asm/rtai_fpu.h>#ifdef __USE_APIC__#include <asm/fixmap.h>#include <asm/apic.h>#endif /* __USE_APIC__ */#include <rtai_trace.h>#define RTAI_DOMAIN_ID  0x52544149#define RTAI_NR_SRQS    32#define RTAI_SMP_NOTIFY_VECTOR    RTAI_APIC1_VECTOR#define RTAI_SMP_NOTIFY_IPI       RTAI_APIC1_IPI#define RTAI_APIC_TIMER_VECTOR    RTAI_APIC2_VECTOR#define RTAI_APIC_TIMER_IPI       RTAI_APIC2_IPI#define RTAI_TIMER_8254_IRQ       0#define RTAI_FREQ_8254            1193180#define RTAI_APIC_ICOUNT	  ((RTAI_FREQ_APIC + HZ/2)/HZ)#define RTAI_COUNTER_2_LATCH      0xfffe#define RTAI_LATENCY_8254         CONFIG_RTAI_SCHED_8254_LATENCY#define RTAI_SETUP_TIME_8254      2011 #define RTAI_CALIBRATED_APIC_FREQ 0#define RTAI_FREQ_APIC            (rtai_tunables.apic_freq)#define RTAI_LATENCY_APIC         CONFIG_RTAI_SCHED_APIC_LATENCY#define RTAI_SETUP_TIME_APIC      1000#define RTAI_TIME_LIMIT            0x7FFFFFFFFFFFFFFFLL#define RTAI_IFLAG  9#define rtai_cli()                     adeos_stall_pipeline_from(&rtai_domain)#define rtai_sti()                     adeos_unstall_pipeline_from(&rtai_domain)#define rtai_local_irq_save(x)         ((x) = adeos_test_and_stall_pipeline_from(&rtai_domain))#define rtai_local_irq_restore(x)      adeos_restore_pipeline_from(&rtai_domain,(x))#define rtai_local_irq_flags(x)        ((x) = adeos_test_pipeline_from(&rtai_domain))#define rtai_local_irq_test()          adeos_test_pipeline_from(&rtai_domain)#define rtai_get_iflag_and_cli()       ((!adeos_test_and_stall_pipeline_from(&rtai_domain)) << RTAI_IFLAG)/* Use these ones when fiddling with the (local A)PIC */#define rtai_hw_lock(flags)            adeos_hw_local_irq_save(flags)#define rtai_hw_unlock(flags)          adeos_hw_local_irq_restore(flags)#define rtai_hw_enable()               adeos_hw_sti()#define rtai_hw_disable()              adeos_hw_cli()#define rtai_linux_sti()                adeos_unstall_pipeline_from(adp_root)#define rtai_linux_cli()                adeos_stall_pipeline_from(adp_root)#define rtai_linux_local_irq_save(x)    ((x) = adeos_test_and_stall_pipeline_from(adp_root))#define rtai_linux_local_irq_restore(x) adeos_restore_pipeline_from(adp_root,x)#define rtai_linux_local_irq_restore_nosync(x,cpuid) adeos_restore_pipeline_nosync(adp_root,x,cpuid)typedef void (*rt_irq_handler_t)(unsigned irq,				 void *cookie);/* Bits from rtai_status. */#define RTAI_USE_APIC  0#ifdef CONFIG_X86_TSC#define RTAI_CALIBRATED_CPU_FREQ   0#define RTAI_CPU_FREQ             (rtai_tunables.cpu_freq)static inline unsigned long long rtai_rdtsc (void) {    unsigned long long t;    __asm__ __volatile__( "rdtsc" : "=A" (t));    return t;}#else  /* !CONFIG_X86_TSC */#define RTAI_CPU_FREQ             RTAI_FREQ_8254#define RTAI_CALIBRATED_CPU_FREQ  RTAI_FREQ_8254#define rtai_rdtsc() rd_8254_ts()#endif /* CONFIG_X86_TSC */struct calibration_data {    unsigned long cpu_freq;    unsigned long apic_freq;    int latency;    int setup_time_TIMER_CPUNIT;    int setup_time_TIMER_UNIT;    int timers_tol[RTAI_NR_CPUS];};struct apic_timer_setup_data {    int mode;    int count;};extern struct rt_times rt_times;extern struct rt_times rt_smp_times[RTAI_NR_CPUS];extern struct calibration_data rtai_tunables;extern volatile unsigned long rtai_status;extern volatile unsigned long rtai_cpu_realtime;extern volatile unsigned long rtai_cpu_lock;extern volatile unsigned long rtai_cpu_lxrt;extern struct rtai_switch_data {    struct task_struct *oldtask;    unsigned long oldflags;} rtai_linux_context[RTAI_NR_CPUS];extern adomain_t rtai_domain;extern int rtai_adeos_ptdbase;/* rtai_get_current() is Adeos-specific. Since real-time interrupt   handlers are called on behalf of the RTAI domain stack, we cannot   infere the "current" Linux task address using %esp. We must use the   suspended Linux domain's stack pointer instead. */static inline struct task_struct *rtai_get_root_current (int cpuid) {#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)    return (struct task_struct *)(((u_long)adp_root->esp[cpuid]) & (~8191UL));#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */    return ((struct thread_info *)(((u_long)adp_root->esp[cpuid]) & (~8191UL)))->task;#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */}static inline struct task_struct *rtai_get_current (int cpuid){    int *esp;    __asm__ volatile("movl %%esp, %0" : "=r" (esp));    if (esp >= rtai_domain.estackbase[cpuid] && esp < rtai_domain.estackbase[cpuid] + 2048)	return rtai_get_root_current(cpuid);    return get_current();}#define rt_spin_lock(lock)    spin_lock(lock)#define rt_spin_unlock(lock)  spin_unlock(lock)static inline void rt_spin_lock_irq(spinlock_t *lock) {    rtai_cli();    rt_spin_lock(lock);}static inline void rt_spin_unlock_irq(spinlock_t *lock) {    rt_spin_unlock(lock);    rtai_sti();}static inline unsigned long rt_spin_lock_irqsave(spinlock_t *lock) {    unsigned long flags;    rtai_local_irq_save(flags);    rt_spin_lock(lock);    return flags;}static inline void rt_spin_unlock_irqrestore(unsigned long flags,					     spinlock_t *lock) {    rt_spin_unlock(lock);    rtai_local_irq_restore(flags);}#ifdef CONFIG_SMP#define CPU_RELAX(x) \do { \   int i = 0; \   do \     cpu_relax(); \   while (++i < x); \} while(0)#else /* !CONFIG_SMP */#define CPU_RELAX(x)#endif /* CONFIG_SMP */irqreturn_t rtai_broadcast_to_local_timers(int irq,					   void *dev_id,					   struct pt_regs *regs);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -