1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/c64x.h>
#include <direct/clock.h>
#include <direct/messages.h>
#include <direct/system.h>
#include <direct/util.h>
#define C64X_DEVICE "/dev/c64x"
#define C64X_DEVICE0 "/dev/c64x0"
#define C64X_QLEN direct_page_align( sizeof(c64xTaskControl) )
#define C64X_MLEN direct_page_align( 0x2000000 )
static const char *state_names[] = { "DONE", "ERROR", "TODO", "RUNNING" };
// manual (examples)
//#define DAVINCI_C64X_IDLE_MAX (567087584/10)
//#define DAVINCI_C64X_IDLE_MAX (59457217)
// auto
#ifndef DAVINCI_C64X_IDLE_MAX
#define DAVINCI_C64X_IDLE_MAX (0)
#endif
int main (int argc, char *argv[])
{
int fd;
void *mem;
c64xTaskControl *ctl;
c64xTask *queue;
int idle_max = DAVINCI_C64X_IDLE_MAX;
uint32_t idle_last = 0;
long long stamp_last = 0;
fd = direct_try_open( C64X_DEVICE, C64X_DEVICE0, O_RDONLY, true );
if (fd < 0)
return -1;
ctl = mmap( NULL, C64X_QLEN, PROT_READ, MAP_SHARED, fd, 0 );
if (ctl == MAP_FAILED) {
D_PERROR( "C64XDump: Mapping %lu bytes at %lu via '%s' failed!\n", C64X_QLEN, 0UL, C64X_DEVICE );
close( fd );
return -2;
}
mem = mmap( NULL, C64X_MLEN, PROT_READ, MAP_SHARED, fd, C64X_QLEN );
if (mem == MAP_FAILED) {
D_PERROR( "C64XDump: Mapping %lu bytes at %lu via '%s' failed!\n", C64X_MLEN, C64X_QLEN, C64X_DEVICE );
munmap( (void*)ctl, C64X_QLEN );
close( fd );
return -2;
}
queue = mem + (0x8fe00000 - 0x8e000000);
while (1) {
usleep( 250000 );
int loadx = 1000;
uint32_t counter = ctl->idlecounter;
long long stamp = direct_clock_get_abs_micros();
uint32_t ql_dsp = ctl->QL_dsp;
uint32_t ql_arm = ctl->QL_arm;
uint32_t qh_dsp = ctl->QH_dsp;
uint32_t qh_arm = ctl->QH_arm;
uint32_t task = queue[ql_dsp & C64X_QUEUE_MASK].c64x_function;
int dl, dh;
dl = ql_arm - ql_dsp;
if (dl < 0)
dl += C64X_QUEUE_LENGTH;
dh = qh_arm - qh_dsp;
if (dh < 0)
dh += C64X_QUEUE_LENGTH;
printf( "\e[H\e[J" );
printf( "High Q: arm %5d - dsp %5d = %d\n", qh_arm, qh_dsp, dh );
printf( "Low Q: arm %5d - dsp %5d = %d\n", ql_arm, ql_dsp, dl );
printf( " (%08x: func %d - %s)\n",
task, (task >> 2) & 0x3fff, state_names[task & 3] );
printf( "Counter: %u\n", counter );
if (counter >= idle_last && idle_last) {
long long int cdiff = counter - idle_last;
long long int tdiff = stamp - stamp_last;
long long int diff = cdiff * 1200000 / tdiff;
#if !DAVINCI_C64X_IDLE_MAX
if (diff > idle_max)
idle_max = diff;
#endif
loadx = (idle_max - diff) * 1000 / idle_max;
}
if (idle_max)
printf( "Load: %d.%d%% (idle_max %d)\n", loadx / 10, loadx % 10, idle_max );
idle_last = counter;
stamp_last = stamp;
}
munmap( (void*)mem, C64X_MLEN );
munmap( (void*)ctl, C64X_QLEN );
close( fd );
return 0;
}
|