00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
#ifndef _RTAI_ASM_PPC_HAL_H
00041
#define _RTAI_ASM_PPC_HAL_H
00042
00043
#include <asm/rtai_vectors.h>
00044
#include <rtai_types.h>
00045
00046
#ifdef CONFIG_SMP
00047
#define RTAI_NR_CPUS CONFIG_RTAI_CPUS
00048
#else
00049 #define RTAI_NR_CPUS 1
00050
#endif
00051
00052
static inline int ffnz(
unsigned long ul) {
00053
00054 __asm__ __volatile__ (
"cntlzw %0, %1" :
"=r" (ul) :
"r" (ul & (-ul)));
00055
00056
return 31 - ul;
00057 }
00058
00059
00060 static inline unsigned long long rtai_ullmul(
unsigned long m0,
00061
unsigned long m1) {
00062
00063
unsigned long long res;
00064
00065 __asm__ __volatile__ (
"mulhwu %0, %1, %2"
00066 :
"=r" (((
unsigned long *)(
void *)&res)[0])
00067 :
"%r" (m0),
"r" (m1));
00068 ((
unsigned long *)(
void *)&res)[1] = m0*m1;
00069
00070
return res;
00071 }
00072
00073
00074
static inline unsigned long long rtai_ulldiv(
unsigned long long ull,
00075
unsigned long uld,
00076
unsigned long *r) {
00077
00078
unsigned long long q, rf;
00079
unsigned long qh, rh, ql, qf;
00080
00081 q = 0;
00082 rf = (
unsigned long long)(0xFFFFFFFF - (qf = 0xFFFFFFFF / uld) * uld) + 1ULL;
00083
00084
while (ull >= uld)
00085 {
00086 ((
unsigned long *)(
void *)&q)[0] += (qh = ((
unsigned long *)(
void *)&ull)[0] / uld);
00087 rh = ((
unsigned long *)(
void *)&ull)[0] - qh * uld;
00088 q += rh * (
unsigned long long)qf + (ql = ((
unsigned long *)(
void *)&ull)[1] / uld);
00089 ull = rh * rf + (((
unsigned long *)(
void *)&ull)[1] - ql * uld);
00090 }
00091
00092 *r = ull;
00093
return q;
00094 }
00095
00096
static inline int rtai_imuldiv(
int i,
int mult,
int div) {
00097
00098
00099
00100
unsigned long q, r;
00101
00102 q =
rtai_ulldiv(
rtai_ullmul(i, mult), div, &r);
00103
00104
return (r + r) > div ? q + 1 : q;
00105 }
00106
00107 static inline unsigned long long rtai_llimd(
unsigned long long ull,
00108
unsigned long mult,
00109
unsigned long div) {
00110
00111
00112
00113
unsigned long long low;
00114
unsigned long q, r;
00115
00116 low =
rtai_ullmul(((
unsigned long *)(
void *)&ull)[1], mult);
00117 q =
rtai_ulldiv(
rtai_ullmul(((
unsigned long *)(
void *)&ull)[0], mult) +
00118 ((
unsigned long *)(
void *)&low)[0], div, (
unsigned long *)(
void *)&low);
00119 low =
rtai_ulldiv(low, div, &r);
00120 ((
unsigned long *)(
void *)&low)[0] += q;
00121
00122
return (r + r) > div ? low + 1 : low;
00123 }
00124
00125
00126
#if defined(__KERNEL__) && !defined(__cplusplus)
00127
#include <linux/sched.h>
00128
#include <asm/system.h>
00129
#include <asm/io.h>
00130
#include <asm/time.h>
00131
#include <asm/rtai_atomic.h>
00132
#include <asm/rtai_fpu.h>
00133
#include <rtai_trace.h>
00134
00135
#define RTAI_DOMAIN_ID 0x52544149
00136
#define RTAI_NR_SRQS 32
00137
00138
#ifdef FIXME
00139
#define RTAI_SMP_NOTIFY_VECTOR RTAI_APIC3_VECTOR
00140
#define RTAI_SMP_NOTIFY_IPI RTAI_APIC3_IPI
00141
#define RTAI_APIC_TIMER_VECTOR RTAI_APIC4_VECTOR
00142
#define RTAI_APIC_TIMER_IPI RTAI_APIC4_IPI
00143
#endif
00144
00145
#define RTAI_TIMER_DECR_IRQ IPIPE_VIRQ_BASE
00146
#define RTAI_TIMER_8254_IRQ RTAI_TIMER_DECR_IRQ
00147
#define RTAI_FREQ_8254 (rtai_tunables.cpu_freq)
00148
#ifdef FIXME
00149
#define RTAI_APIC_ICOUNT ((RTAI_FREQ_APIC + HZ/2)/HZ)
00150
#define RTAI_COUNTER_2_LATCH 0xfffe
00151
#endif
00152
#define RTAI_LATENCY_8254 CONFIG_RTAI_SCHED_8254_LATENCY
00153
#define RTAI_SETUP_TIME_8254 500
00154
00155
#ifdef FIXME
00156
#define RTAI_CALIBRATED_APIC_FREQ 0
00157
#define RTAI_FREQ_APIC (rtai_tunables.apic_freq)
00158
#define RTAI_LATENCY_APIC CONFIG_RTAI_SCHED_APIC_LATENCY
00159
#define RTAI_SETUP_TIME_APIC 1000
00160
#endif
00161
00162
#define RTAI_TIME_LIMIT 0x7FFFFFFFFFFFFFFFLL
00163
00164
#define RTAI_IFLAG 15
00165
00166
#define rtai_cpuid() adeos_processor_id()
00167
#define rtai_tskext ptd
00168
00169
00170
#define rtai_hw_cli() adeos_hw_cli()
00171
#define rtai_hw_sti() adeos_hw_sti()
00172
#define rtai_hw_save_flags_and_cli(x) adeos_hw_local_irq_save(flags)
00173
#define rtai_hw_restore_flags(x) adeos_hw_local_irq_restore(flags)
00174
#define rtai_hw_save_flags(x) adeos_hw_local_irq_flags(flags)
00175
00176
00177
#define rtai_cli() adeos_hw_cli()
00178
#define rtai_sti() adeos_hw_sti()
00179
#define rtai_save_flags_and_cli(x) adeos_hw_local_irq_save(flags)
00180
#define rtai_restore_flags(x) adeos_hw_local_irq_restore(flags)
00181
#define rtai_save_flags(x) adeos_hw_local_irq_flags(flags)
00182
00183
00184
#define local_irq_restore_nosync(flags, cpuid) do { adp_root->cpudata[cpuid].status = flags; } while (0)
00185
00186
extern unsigned long adeos_pended;
00187
00188
#define adeos_pend_uncond(irq, cpuid) \
00189
do { \
00190
adp_root->cpudata[cpuid].irq_hits[irq]++; \
00191
__set_bit(irq & IPIPE_IRQ_IMASK, &adp_root->cpudata[cpuid].irq_pending_lo[irq >> IPIPE_IRQ_ISHIFT]); \
00192
__set_bit(irq >> IPIPE_IRQ_ISHIFT, &adp_root->cpudata[cpuid].irq_pending_hi); \
00193
__set_bit(cpuid, &adeos_pended); \
00194
} while (0)
00195
00196
#ifdef CONFIG_PREEMPT
00197
#define rtai_save_and_lock_preempt_count() \
00198
do { int *prcntp, prcnt; prcnt = xchg(prcntp = &preempt_count(), 1);
00199
#define rtai_restore_preempt_count() \
00200
*prcntp = prcnt; } while (0)
00201
#else
00202
#define rtai_save_and_lock_preempt_count();
00203
#define rtai_restore_preempt_count();
00204
#endif
00205
00206
typedef int (*rt_irq_handler_t)(
unsigned irq,
void *
cookie);
00207
00208
00209
#define RTAI_USE_APIC 0
00210
00211
#define RTAI_CALIBRATED_CPU_FREQ 0
00212
#define RTAI_CPU_FREQ (rtai_tunables.cpu_freq)
00213
00214
static inline unsigned long long rtai_rdtsc (
void) {
00215
00216
unsigned long long ts;
00217
unsigned long chk;
00218
00219 __asm__ __volatile__ (
"1: mftbu %0\n"
00220
" mftb %1\n"
00221
" mftbu %2\n"
00222
" cmpw %2,%0\n"
00223
" bne 1b\n"
00224 :
"=r" (((
unsigned long *)&ts)[0]),
00225
"=r" (((
unsigned long *)&ts)[1]),
00226
"=r" (chk));
00227
return ts;
00228 }
00229
00230
struct calibration_data {
00231
00232
unsigned long cpu_freq;
00233
unsigned long apic_freq;
00234
int latency;
00235
int setup_time_TIMER_CPUNIT;
00236
int setup_time_TIMER_UNIT;
00237
int timers_tol[
RTAI_NR_CPUS];
00238 };
00239
00240
struct apic_timer_setup_data {
00241
00242
int mode;
00243
int count;
00244 };
00245
00246
extern struct rt_times rt_times;
00247
00248
extern struct rt_times rt_smp_times[
RTAI_NR_CPUS];
00249
00250
extern struct calibration_data
rtai_tunables;
00251
00252
extern volatile unsigned long rtai_cpu_realtime;
00253
00254
extern volatile unsigned long rtai_cpu_lock;
00255
00256
extern struct rtai_switch_data {
00257
volatile unsigned long depth;
00258
volatile unsigned long oldflags;
00259 }
rtai_linux_context[
RTAI_NR_CPUS];
00260
00261
extern adomain_t
rtai_domain;
00262
00263
extern int rtai_adeos_ptdbase;
00264
00265
#ifdef CONFIG_SMP
00266
00267
#ifdef CONFIG_PREEMPT
00268
#define rt_spin_lock(lock) do { barrier(); _raw_spin_lock(lock); barrier(); } while (0)
00269
#define rt_spin_unlock(lock) do { barrier(); _raw_spin_unlock(lock); barrier(); } while (0)
00270
#else
00271
#define rt_spin_lock(lock) spin_lock(lock)
00272
#define rt_spin_unlock(lock) spin_unlock(lock)
00273
#endif
00274
00275
static inline void rt_spin_lock_irq(spinlock_t *lock) {
00276
00277
rtai_cli();
00278
rt_spin_lock(lock);
00279 }
00280
00281
static inline void rt_spin_unlock_irq(spinlock_t *lock) {
00282
00283
rt_spin_unlock(lock);
00284
rtai_sti();
00285 }
00286
00287
static inline unsigned long rt_spin_lock_irqsave(spinlock_t *lock) {
00288
00289
unsigned long flags;
00290
rtai_save_flags_and_cli(flags);
00291
rt_spin_lock(lock);
00292
return flags;
00293 }
00294
00295
static inline void rt_spin_unlock_irqrestore(
unsigned long flags, spinlock_t *lock)
00296 {
00297
rt_spin_unlock(lock);
00298 rtai_local_irq_restore(flags);
00299 }
00300
00301
static inline void rt_get_global_lock(
void)
00302 {
00303 barrier();
00304
rtai_cli();
00305
if (!test_and_set_bit(adeos_processor_id(), &rtai_cpu_lock)) {
00306
while (test_and_set_bit(31, &rtai_cpu_lock)) {
00307 cpu_relax();
00308 }
00309 }
00310 barrier();
00311 }
00312
00313
static inline void rt_release_global_lock(
void)
00314 {
00315 barrier();
00316
rtai_cli();
00317
if (test_and_clear_bit(adeos_processor_id(), &rtai_cpu_lock)) {
00318 test_and_clear_bit(31, &rtai_cpu_lock);
00319 cpu_relax();
00320 }
00321 barrier();
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
static inline void rt_global_cli(
void)
00337 {
00338 rt_get_global_lock();
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
static inline void rt_global_sti(
void)
00348 {
00349 rt_release_global_lock();
00350
rtai_sti();
00351 }
00352
00353
static volatile inline unsigned long rtai_save_flags_irqbit(
void)
00354 {
00355
unsigned long flags;
00356 rtai_save_flags(flags);
00357
return flags & (1 << RTAI_IFLAG);
00358 }
00359
static volatile inline unsigned long rtai_save_flags_irqbit_and_cli(
void)
00360 {
00361
unsigned long flags;
00362
rtai_save_flags_and_cli(flags);
00363
return flags & (1 << RTAI_IFLAG);
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
static inline int rt_global_save_flags_and_cli(
void)
00373 {
00374 barrier();
00375
unsigned long flags = rtai_save_flags_irqbit_and_cli();
00376
00377
if (!test_and_set_bit(adeos_processor_id(), &rtai_cpu_lock)) {
00378
while (test_and_set_bit(31, &rtai_cpu_lock)) {
00379 cpu_relax();
00380 }
00381 barrier();
00382
return flags | 1;
00383 }
00384 barrier();
00385
return flags;
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
static inline void rt_global_save_flags(
unsigned long *flags)
00396 {
00397
unsigned long hflags = rtai_save_flags_irqbit_and_cli();
00398
00399 *
flags = test_bit(adeos_processor_id(), &rtai_cpu_lock) ? hflags : hflags | 1;
00400
if (hflags) {
00401
rtai_sti();
00402 }
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
static inline void rt_global_restore_flags(
unsigned long flags)
00413 {
00414 barrier();
00415
switch (
flags & ((1 << RTAI_IFLAG) | 1)) {
00416
case (1 << RTAI_IFLAG) | 1:
00417 rt_release_global_lock();
00418
rtai_sti();
00419
break;
00420
case (1 << RTAI_IFLAG) | 0:
00421 rt_get_global_lock();
00422
rtai_sti();
00423
break;
00424
case (0 << RTAI_IFLAG) | 1:
00425 rt_release_global_lock();
00426
break;
00427
case (0 << RTAI_IFLAG) | 0:
00428 rt_get_global_lock();
00429
break;
00430 }
00431 barrier();
00432 }
00433
00434
#else
00435
00436
#define rt_spin_lock(lock)
00437
#define rt_spin_unlock(lock)
00438
00439
#define rt_spin_lock_irq(lock) do { rtai_cli(); } while (0)
00440
#define rt_spin_unlock_irq(lock) do { rtai_sti(); } while (0)
00441
00442
static inline unsigned long rt_spin_lock_irqsave(spinlock_t *lock)
00443 {
00444
unsigned long flags;
00445
rtai_save_flags_and_cli(flags);
00446
return flags;
00447 }
00448
#define rt_spin_unlock_irqrestore(flags, lock) do { rtai_restore_flags(flags); } while (0)
00449
00450
#define rt_get_global_lock() do { rtai_cli(); } while (0)
00451
#define rt_release_global_lock()
00452
00453
#define rt_global_cli() do { rtai_cli(); } while (0)
00454
#define rt_global_sti() do { rtai_sti(); } while (0)
00455
00456
static inline unsigned long rt_global_save_flags_and_cli(
void)
00457 {
00458
unsigned long flags;
00459
rtai_save_flags_and_cli(flags);
00460
return flags;
00461 }
00462
#define rt_global_restore_flags(flags) do { rtai_restore_flags(flags); } while (0)
00463
00464
#define rt_global_save_flags(flags) do { rtai_save_flags(*flags); } while (0)
00465
00466
#endif
00467
00468
int rt_printk(
const char *format, ...);
00469
00470
static inline void rt_switch_to_real_time(
int cpuid)
00471 {
00472
TRACE_RTAI_SWITCHTO_RT(cpuid);
00473
if (!
rtai_linux_context[
cpuid].depth++) {
00474
rtai_linux_context[
cpuid].oldflags = xchg(&adp_root->cpudata[cpuid].status, (1 << IPIPE_STALL_FLAG));
00475 test_and_set_bit(cpuid, &rtai_cpu_realtime);
00476 }
00477 }
00478
00479
static inline void rt_switch_to_linux(
int cpuid)
00480 {
00481
TRACE_RTAI_SWITCHTO_LINUX(cpuid);
00482
if (
rtai_linux_context[
cpuid].depth) {
00483
if (!--
rtai_linux_context[
cpuid].depth) {
00484 test_and_clear_bit(cpuid, &rtai_cpu_realtime);
00485 adp_root->cpudata[
cpuid].status =
rtai_linux_context[
cpuid].oldflags;
00486 }
00487
return;
00488 }
00489
rt_printk(
"*** ERROR: EXCESS LINUX_UNLOCK ***\n");
00490 }
00491
00492
#define in_hrt_mode(cpuid) (test_bit(cpuid, &rtai_cpu_realtime))
00493
00494
static inline void rt_set_timer_delay (
int delay) {
00495
00496
00497
if (delay == 0)
00498 {
00499
#ifdef CONFIG_40x
00500
return;
00501
#else
00502
if ((delay =
rt_times.intr_time -
rtai_rdtsc()) <= 0)
00503 {
00504
int lost = 0;
00505
do
00506 {
00507 lost++;
00508
rt_times.intr_time += (
RTIME)
rt_times.periodic_tick;
00509 }
00510
while ((delay =
rt_times.intr_time -
rtai_rdtsc()) <= 0);
00511
printk(
"%d timer interrupt(s) lost\n", lost);
00512 }
00513
#endif
00514 }
00515
#ifdef CONFIG_40x
00516
mtspr(SPRN_PIT, delay);
00517
#else
00518
set_dec(delay);
00519
#endif
00520
}
00521
00522
00523
00524
#ifdef FIXME
00525
void rtai_attach_lxrt(
void);
00526
00527
void rtai_detach_lxrt(
void);
00528
00529
void rtai_switch_linux_mm(
struct task_struct *prev,
00530
struct task_struct *next,
00531
int cpuid);
00532
#endif
00533
00534
#endif
00535
00536
00537
00538
#ifdef __KERNEL__
00539
00540
#include <linux/kernel.h>
00541
00542
#ifdef __cplusplus
00543
extern "C" {
00544
#endif
00545
00546
int rt_request_irq(
unsigned irq,
int (*handler)(
unsigned irq,
void *cookie),
void *cookie,
int retmode);
00547
00548
int rt_release_irq(
unsigned irq);
00549
00550
void rt_set_irq_cookie(
unsigned irq,
00551
void *cookie);
00552
00553
00554
00555
00556
00557
unsigned rt_startup_irq(
unsigned irq);
00558
00559
void rt_shutdown_irq(
unsigned irq);
00560
00561
void rt_enable_irq(
unsigned irq);
00562
00563
void rt_disable_irq(
unsigned irq);
00564
00565
void rt_mask_and_ack_irq(
unsigned irq);
00566
00567
void rt_unmask_irq(
unsigned irq);
00568
00569
void rt_ack_irq(
unsigned irq);
00570
00571
00572
void rt_do_irq(
unsigned irq);
00573
00574
int rt_request_linux_irq(
unsigned irq,
00575
int (*handler)(
int irq,
00576
void *dev_id,
00577
struct pt_regs *regs),
00578
char *name,
00579
void *dev_id);
00580
00581
int rt_free_linux_irq(
unsigned irq,
00582
void *dev_id);
00583
00584
void rt_pend_linux_irq(
unsigned irq);
00585
00586
void rt_pend_linux_srq(
unsigned srq);
00587
00588
int rt_request_srq(
unsigned label,
00589
void (*k_handler)(
void),
00590
long long (*u_handler)(
unsigned));
00591
00592
int rt_free_srq(
unsigned srq);
00593
00594
int rt_assign_irq_to_cpu(
int irq,
00595
unsigned long cpus_mask);
00596
00597
int rt_reset_irq_to_sym_mode(
int irq);
00598
00599
void rt_request_timer_cpuid(
void (*handler)(
void),
00600
unsigned tick,
00601
int cpuid);
00602
00603
#ifdef FIXME
00604
void rt_request_apic_timers(
void (*handler)(
void),
00605
struct apic_timer_setup_data *tmdata);
00606
00607
void rt_free_apic_timers(
void);
00608
#endif
00609
00610
int rt_request_timer(
void (*handler)(
void),
00611
unsigned tick,
00612
int use_apic);
00613
00614
void rt_free_timer(
void);
00615
00616
#ifdef FIXME
00617
RT_TRAP_HANDLER rt_set_trap_handler(
RT_TRAP_HANDLER handler);
00618
#endif
00619
00620
void rt_mount(
void);
00621
00622
void rt_umount(
void);
00623
00624 void (*
rt_set_ihook(
void (*hookfn)(
int)))(
int);
00625
00626
#define rt_printk printk
00627
00628
unsigned long rtai_critical_enter(
void (*synch)(
void));
00629
00630
void rtai_critical_exit(
unsigned long flags);
00631
00632
void rtai_set_linux_task_priority(
struct task_struct *task,
int policy,
int prio);
00633
00634
#ifdef __cplusplus
00635
}
00636
#endif
00637
00638
#endif
00639
00640
#include <asm/rtai_oldnames.h>
00641
00642 #define RTAI_DEFAULT_TICK 100000
00643
#ifdef CONFIG_RTAI_TRACE
00644
#define RTAI_DEFAULT_STACKSZ 8192
00645
#else
00646 #define RTAI_DEFAULT_STACKSZ 4092
00647
#endif
00648
00649
00650
00651
#endif