2 Copyright © 2009-2012, The AROS Development Team. All rights reserved
9 #include <exec/types.h>
10 #include <devices/timer.h>
12 #include <proto/exec.h>
13 #include <aros/debug.h>
14 #include <proto/timer.h>
19 static BOOL
ata_Calibrate(struct IORequest
* tmr
, struct ataBase
*base
)
22 register ULONG scale
= 0x8000; // min iterations...
23 volatile register ULONG t
= 1;
24 struct timeval t1
, t2
;
25 struct Device
*TimerBase
= base
->ata_TimerBase
;
27 D(bug("[ATA ] Calibration started\n"));
29 while (scale
<= 0x80000000)
33 for (x
= 1; x
< scale
; x
++)
34 t
= (((t
+ x
) * t
) - x
) / x
; // add, mul, sub, div, trivial benchmark.
40 // ok, it's going to be totally insane, if secs > 1.
43 bug("[ATA ] micro wait useless.\n");
48 * we expect at least 10000 times longer period, which should be 'achievable'
49 * unlikely we will cross the magic boundary here of 4 billion instructions in 10 millisecond (yielding 400'000MIPS?)
50 * on the other side, if we go as low as 1, then 4 iterations of add/sub/mul/div is perfectly fine yielding a bit more than 400ns...
53 if (t2
.tv_micro
>= 10000)
58 D(bug("[ATA ] Executed %ld ops in %ldus\n", scale
, t2
.tv_micro
));
60 // always round up to the next value.. so 30.9 -> 31, 5.1 -> 6, etc
61 x
= (x
+ t2
.tv_micro
- 1) / t2
.tv_micro
;
64 bug("[ATA ] Approximate number of iterations per 100 nanoseconds: %ld\n", x
);
65 base
->ata_ItersPer100ns
= x
;
69 struct IORequest
*ata_OpenTimer(struct ataBase
*base
)
71 struct MsgPort
*p
= CreateMsgPort();
74 struct IORequest
*io
= CreateIORequest(p
, sizeof(struct timerequest
));
79 * ok. ECLOCK does not have too great resolution, either.
80 * we will have to sacrifice our performance a little bit, meaning, the 400ns will turn into (worst case) 2us.
81 * hopefully we won't have to call that TOO often...
83 if (0 == OpenDevice("timer.device", UNIT_MICROHZ
, io
, 0))
85 if (NULL
== base
->ata_TimerBase
)
87 base
->ata_TimerBase
= io
->io_Device
;
88 ata_Calibrate(io
, base
);
94 bug("[ATA ] Failed to open timer.device, unit MICROHZ\n");
100 bug("[ATA ] Failed to create timerequest\n");
106 bug("[ATA ] Failed to create timer port\n");
112 void ata_CloseTimer(struct IORequest
*tmr
)
116 struct MsgPort
*p
= tmr
->io_Message
.mn_ReplyPort
;
118 DeleteIORequest(tmr
);
123 void ata_WaitNano(register ULONG ns
, struct ataBase
*base
)
125 volatile register ULONG t
= 1;
126 ns
= (ns
+ 99) / 100;
127 ns
*= base
->ata_ItersPer100ns
;
130 t
= (((t
+ ns
) * t
) - ns
) / ns
; // add, mul, sub, div, trivial benchmark.
135 ULONG
ata_WaitTO(struct IORequest
* tmr
, ULONG secs
, ULONG micro
, ULONG sigs
)
137 ULONG sig
= 1 << tmr
->io_Message
.mn_ReplyPort
->mp_SigBit
;
139 //D(bug("[ATA--] Timed wait %lds %ldu\n", secs, micro));
141 tmr
->io_Command
= TR_ADDREQUEST
;
142 ((struct timerequest
*)tmr
)->tr_time
.tv_secs
= secs
;
143 ((struct timerequest
*)tmr
)->tr_time
.tv_micro
= micro
;
146 sigs
= Wait(sigs
| sig
);
147 if (0 == (sigs
& sig
))