Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
magic-lantern
magic-lantern
Commits
bfea5ff5a978
Commit
2c06cd31
authored
Mar 05, 2019
by
alex@thinkpad
Browse files
QEMU: 32-bit DIGIC timer support (DIGIC 6 and newer)
--HG-- branch : qemu
parent
5cb1c1a020f7
Changes
2
Hide whitespace changes
Inline
Side-by-side
contrib/qemu/eos/eos.c
View file @
bfea5ff5
...
...
@@ -28,7 +28,8 @@
#define IGNORE_CONNECT_POLL
#define DIGIC_TIMER_STEP 0x100
#define DIGIC_TIMER_MASK (0xFFFFF & ~(DIGIC_TIMER_STEP-1))
#define DIGIC_TIMER20_MASK (0x000FFFFF & ~(DIGIC_TIMER_STEP-1))
#define DIGIC_TIMER32_MASK (0xFFFFFFFF & ~(DIGIC_TIMER_STEP-1))
/* Machine class */
...
...
@@ -494,9 +495,11 @@ static void eos_interrupt_timer_body(EOSState *s)
return
;
}
s
->
digic_timer
+=
DIGIC_TIMER_STEP
;
s
->
digic_timer
&=
DIGIC_TIMER_MASK
;
s
->
digic_timer20
+=
DIGIC_TIMER_STEP
;
s
->
digic_timer20
&=
DIGIC_TIMER20_MASK
;
s
->
digic_timer32
+=
DIGIC_TIMER_STEP
;
s
->
digic_timer32
&=
DIGIC_TIMER32_MASK
;
for
(
pos
=
0
;
pos
<
COUNT
(
s
->
timer_enabled
);
pos
++
)
{
if
(
s
->
timer_enabled
[
pos
])
...
...
@@ -559,7 +562,7 @@ static void eos_interrupt_timer_body(EOSState *s)
for
(
int
id
=
0
;
id
<
COUNT
(
s
->
UTimers
);
id
++
)
{
if
(
s
->
UTimers
[
id
].
active
&&
s
->
UTimers
[
id
].
output_compare
==
s
->
digic_timer
)
if
(
s
->
UTimers
[
id
].
active
&&
s
->
UTimers
[
id
].
output_compare
==
s
->
digic_timer
32
)
{
if
(
qemu_loglevel_mask
(
EOS_LOG_IO
))
{
fprintf
(
stderr
,
"[TIMER] Firing UTimer #%d
\n
"
,
id
);
...
...
@@ -580,7 +583,7 @@ static void eos_interrupt_timer_body(EOSState *s)
for
(
pos
=
0
;
pos
<
COUNT
(
s
->
HPTimers
);
pos
++
)
{
if
(
s
->
HPTimers
[
pos
].
active
&&
s
->
HPTimers
[
pos
].
output_compare
==
s
->
digic_timer
)
if
(
s
->
HPTimers
[
pos
].
active
&&
s
->
HPTimers
[
pos
].
output_compare
==
s
->
digic_timer
20
)
{
if
(
qemu_loglevel_mask
(
EOS_LOG_IO
))
{
fprintf
(
stderr
,
"[HPTimer] Firing HPTimer #%d
\n
"
,
pos
);
...
...
@@ -2303,22 +2306,22 @@ unsigned int eos_handle_utimer ( unsigned int parm, EOSState *s, unsigned int ad
/* fixme: duplicate code (same as HPTimer offset 1x4) */
if
(
type
&
MODE_WRITE
)
{
/* upper rounding, to test for equality with digic_timer */
int
rounded
=
(
value
+
DIGIC_TIMER_STEP
)
&
DIGIC_TIMER_MASK
;
/* upper rounding, to test for equality with digic_timer
32
*/
u
int
32_t
rounded
=
(
value
+
DIGIC_TIMER_STEP
)
&
DIGIC_TIMER
32
_MASK
;
s
->
UTimers
[
timer_id
].
output_compare
=
rounded
;
/* for some reason, the value set to output compare
* is sometimes a little behind digic_timer */
int
actual_delay
=
(
(
int32_t
)(
rounded
-
s
->
digic_timer
)
<<
12
)
>>
12
;
* is sometimes a little behind digic_timer
32
*/
int
actual_delay
=
(
int32_t
)(
rounded
-
s
->
digic_timer
32
)
;
if
(
actual_delay
<
0
)
{
/* workaround: when this happens, trigger right away */
s
->
UTimers
[
timer_id
].
output_compare
=
s
->
digic_timer
+
DIGIC_TIMER_STEP
;
s
->
UTimers
[
timer_id
].
output_compare
=
s
->
digic_timer
32
+
DIGIC_TIMER_STEP
;
}
msg
=
"UTimer #%d: output compare (delay %d microseconds)"
;
msg_arg2
=
value
-
s
->
digic_timer_last_read
;
msg_arg2
=
value
-
s
->
digic_timer
32
_last_read
;
}
else
{
...
...
@@ -2378,22 +2381,22 @@ unsigned int eos_handle_hptimer ( unsigned int parm, EOSState *s, unsigned int a
case
0x104
:
if
(
type
&
MODE_WRITE
)
{
/* upper rounding, to test for equality with digic_timer */
int
rounded
=
(
value
+
DIGIC_TIMER_STEP
)
&
DIGIC_TIMER_MASK
;
/* upper rounding, to test for equality with digic_timer
20
*/
int
rounded
=
(
value
+
DIGIC_TIMER_STEP
)
&
DIGIC_TIMER
20
_MASK
;
s
->
HPTimers
[
timer_id
].
output_compare
=
rounded
;
/* for some reason, the value set to output compare
* is sometimes a little behind digic_timer */
int
actual_delay
=
((
int32_t
)(
rounded
-
s
->
digic_timer
)
<<
12
)
>>
12
;
* is sometimes a little behind digic_timer
20
*/
int
actual_delay
=
((
int32_t
)(
rounded
-
s
->
digic_timer
20
)
<<
12
)
>>
12
;
if
(
actual_delay
<
0
)
{
/* workaround: when this happens, trigger right away */
s
->
HPTimers
[
timer_id
].
output_compare
=
s
->
digic_timer
+
DIGIC_TIMER_STEP
;
s
->
HPTimers
[
timer_id
].
output_compare
=
s
->
digic_timer
20
+
DIGIC_TIMER_STEP
;
}
msg
=
"HPTimer #%d: output compare (delay %d microseconds)"
;
msg_arg2
=
value
-
s
->
digic_timer_last_read
;
msg_arg2
=
value
-
s
->
digic_timer
20
_last_read
;
}
else
{
...
...
@@ -3800,7 +3803,11 @@ unsigned int eos_handle_digic_timer ( unsigned int parm, EOSState *s, unsigned i
}
else
{
ret
=
s
->
digic_timer_last_read
=
s
->
digic_timer
;
if
(
parm
)
{
ret
=
s
->
digic_timer32_last_read
=
s
->
digic_timer32
;
}
else
{
ret
=
s
->
digic_timer20_last_read
=
s
->
digic_timer20
;
}
if
(
!
(
qemu_loglevel_mask
(
CPU_LOG_INT
)
&&
qemu_loglevel_mask
(
EOS_LOG_VERBOSE
)))
...
...
contrib/qemu/eos/eos.h
View file @
bfea5ff5
...
...
@@ -152,7 +152,7 @@ typedef struct
struct
HPTimer
{
int
active
;
int
output_compare
;
u
int
32_t
output_compare
;
int
triggered
;
};
...
...
@@ -275,8 +275,10 @@ typedef struct
uint32_t
irq_enabled
[
INT_ENTRIES
];
uint32_t
irq_schedule
[
INT_ENTRIES
];
uint32_t
irq_id
;
uint32_t
digic_timer
;
uint32_t
digic_timer_last_read
;
uint32_t
digic_timer20
;
uint32_t
digic_timer32
;
uint32_t
digic_timer20_last_read
;
uint32_t
digic_timer32_last_read
;
uint32_t
timer_reload_value
[
20
];
uint32_t
timer_current_value
[
20
];
uint32_t
timer_enabled
[
20
];
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment