Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
EPOS Developers
OSDI with EPOS for INE5424
Commits
3266e295
Commit
3266e295
authored
Sep 04, 2021
by
Antônio Augusto Fröhlich
Browse files
This a part of Guto's solution to P3.
parent
7311811a
Changes
33
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
97 additions
and
1631 deletions
+97
-1631
app/hello/hello_traits.h
app/hello/hello_traits.h
+1
-1
app/philosophers_dinner/philosophers_dinner.cc
app/philosophers_dinner/philosophers_dinner.cc
+4
-25
app/philosophers_dinner/philosophers_dinner_traits.h
app/philosophers_dinner/philosophers_dinner_traits.h
+1
-1
app/producer_consumer/producer_consumer_traits.h
app/producer_consumer/producer_consumer_traits.h
+1
-1
include/architecture/armv7/armv7_cpu.h
include/architecture/armv7/armv7_cpu.h
+8
-3
include/architecture/armv8/armv8_cpu.h
include/architecture/armv8/armv8_cpu.h
+0
-244
include/architecture/armv8/armv8_mmu.h
include/architecture/armv8/armv8_mmu.h
+0
-84
include/architecture/armv8/armv8_pmu.h
include/architecture/armv8/armv8_pmu.h
+0
-202
include/architecture/armv8/armv8_traits.h
include/architecture/armv8/armv8_traits.h
+0
-42
include/architecture/armv8/armv8_tsc.h
include/architecture/armv8/armv8_tsc.h
+0
-110
include/architecture/rv32/rv32_cpu.h
include/architecture/rv32/rv32_cpu.h
+27
-6
include/architecture/rv64/rv64_cpu.h
include/architecture/rv64/rv64_cpu.h
+0
-388
include/architecture/rv64/rv64_mmu.h
include/architecture/rv64/rv64_mmu.h
+0
-431
include/architecture/rv64/rv64_traits.h
include/architecture/rv64/rv64_traits.h
+0
-37
include/architecture/rv64/rv64_tsc.h
include/architecture/rv64/rv64_tsc.h
+0
-48
include/machine/riscv/riscv_ic.h
include/machine/riscv/riscv_ic.h
+2
-0
include/process.h
include/process.h
+18
-7
src/api/thread.cc
src/api/thread.cc
+3
-1
src/architecture/armv7/armv7_cpu.cc
src/architecture/armv7/armv7_cpu.cc
+18
-0
src/architecture/armv7/armv7_cpu_syscall.cc
src/architecture/armv7/armv7_cpu_syscall.cc
+14
-0
No files found.
app/hello/hello_traits.h
View file @
3266e295
...
...
@@ -9,7 +9,7 @@ __BEGIN_SYS
template
<
>
struct
Traits
<
Build
>:
public
Traits_Tokens
{
// Basic configuration
static
const
unsigned
int
MODE
=
BUILTIN
;
static
const
unsigned
int
MODE
=
KERNEL
;
static
const
unsigned
int
ARCHITECTURE
=
ARMv7
;
static
const
unsigned
int
MACHINE
=
Cortex
;
static
const
unsigned
int
MODEL
=
Raspberry_Pi3
;
...
...
app/philosophers_dinner/philosophers_dinner.cc
View file @
3266e295
// EPOS Semaphore Component Test Program
#include <machine/display.h>
#include <time.h>
#include <synchronizer.h>
#include <process.h>
...
...
@@ -21,8 +20,6 @@ int philosopher(int n, int l, int c);
int
main
()
{
table
.
lock
();
Display
::
clear
();
Display
::
position
(
0
,
0
);
cout
<<
"The Philosopher's Dinner:"
<<
endl
;
for
(
int
i
=
0
;
i
<
5
;
i
++
)
...
...
@@ -36,25 +33,12 @@ int main()
cout
<<
"Philosophers are alive and hungry!"
<<
endl
;
Display
::
position
(
7
,
44
);
cout
<<
'/'
;
Display
::
position
(
13
,
44
);
cout
<<
'\\'
;
Display
::
position
(
16
,
35
);
cout
<<
'|'
;
Display
::
position
(
13
,
27
);
cout
<<
'/'
;
Display
::
position
(
7
,
27
);
cout
<<
'\\'
;
Display
::
position
(
19
,
0
);
cout
<<
"The dinner is served ..."
<<
endl
;
table
.
unlock
();
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
int
ret
=
phil
[
i
]
->
join
();
table
.
lock
();
Display
::
position
(
20
+
i
,
0
);
cout
<<
"Philosopher "
<<
i
<<
" ate "
<<
ret
<<
" times "
<<
endl
;
table
.
unlock
();
}
...
...
@@ -77,30 +61,26 @@ int philosopher(int n, int l, int c)
for
(
int
i
=
iterations
;
i
>
0
;
i
--
)
{
table
.
lock
();
Display
::
position
(
l
,
c
);
cout
<<
"thinking"
;
cout
<<
n
<<
" thinking"
;
table
.
unlock
();
Delay
thinking
(
1000000
);
table
.
lock
();
Display
::
position
(
l
,
c
);
cout
<<
" hungry "
;
cout
<<
n
<<
" hungry "
;
table
.
unlock
();
chopstick
[
first
]
->
p
();
// get first chopstick
chopstick
[
second
]
->
p
();
// get second chopstick
table
.
lock
();
Display
::
position
(
l
,
c
);
cout
<<
" eating "
;
cout
<<
n
<<
" eating "
;
table
.
unlock
();
Delay
eating
(
500000
);
table
.
lock
();
Display
::
position
(
l
,
c
);
cout
<<
" sate "
;
cout
<<
n
<<
" sate "
;
table
.
unlock
();
chopstick
[
first
]
->
v
();
// release first chopstick
...
...
@@ -108,7 +88,6 @@ int philosopher(int n, int l, int c)
}
table
.
lock
();
Display
::
position
(
l
,
c
);
cout
<<
" done "
;
table
.
unlock
();
...
...
app/philosophers_dinner/philosophers_dinner_traits.h
View file @
3266e295
...
...
@@ -9,7 +9,7 @@ __BEGIN_SYS
template
<
>
struct
Traits
<
Build
>:
public
Traits_Tokens
{
// Basic configuration
static
const
unsigned
int
MODE
=
BUILTIN
;
static
const
unsigned
int
MODE
=
KERNEL
;
static
const
unsigned
int
ARCHITECTURE
=
ARMv7
;
static
const
unsigned
int
MACHINE
=
Cortex
;
static
const
unsigned
int
MODEL
=
Raspberry_Pi3
;
...
...
app/producer_consumer/producer_consumer_traits.h
View file @
3266e295
...
...
@@ -9,7 +9,7 @@ __BEGIN_SYS
template
<
>
struct
Traits
<
Build
>:
public
Traits_Tokens
{
// Basic configuration
static
const
unsigned
int
MODE
=
BUILTIN
;
static
const
unsigned
int
MODE
=
KERNEL
;
static
const
unsigned
int
ARCHITECTURE
=
ARMv7
;
static
const
unsigned
int
MACHINE
=
Cortex
;
static
const
unsigned
int
MODEL
=
Raspberry_Pi3
;
...
...
include/architecture/armv7/armv7_cpu.h
View file @
3266e295
...
...
@@ -536,10 +536,15 @@ public:
static
void
switch_context
(
Context
**
o
,
Context
*
n
)
__attribute__
((
naked
));
template
<
typename
...
Tn
>
static
Context
*
init_stack
(
Log_Addr
usp
,
Log_Addr
sp
,
void
(
*
exit
)(),
int
(
*
entry
)(
Tn
...),
Tn
...
an
)
{
sp
-=
sizeof
(
Context
);
Context
*
ctx
=
new
(
sp
)
Context
(
entry
,
exit
,
usp
);
// init_stack is called with usp = 0 for kernel threads
static
Context
*
init_stack
(
Log_Addr
usp
,
Log_Addr
k
sp
,
void
(
*
exit
)(),
int
(
*
entry
)(
Tn
...),
Tn
...
an
)
{
k
sp
-=
sizeof
(
Context
);
Context
*
ctx
=
new
(
k
sp
)
Context
(
entry
,
exit
,
usp
);
// init_stack is called with usp = 0 for kernel threads
init_stack_helper
(
&
ctx
->
_r0
,
an
...);
if
(
multitask
)
{
// handle trampoline context here
}
return
ctx
;
}
...
...
include/architecture/armv8/armv8_cpu.h
deleted
100644 → 0
View file @
7311811a
// EPOS ARMv8 CPU Mediator Declarations
#ifndef __armv8_h
#define __armv8_h
#define __cpu_common_only__
#include <architecture/cpu.h>
#include <architecture/armv7/armv7_cpu.h>
#undef __cpu_common_only__
__BEGIN_SYS
class
ARMv8_A
:
public
ARMv7_A
{
protected:
ARMv8_A
()
{};
public:
static
unsigned
int
cores
()
{
// Cortex A53 cannot execute "mrc p15, 4, r0, c15, c0, 0".
// The amount of cores booted is equal to the Traits value (defined at Raspberry_Pi3::pre_init::pre_init for instance, up to four)
return
Traits
<
Build
>::
CPUS
;
}
// We need to redefine because we also redefined cores()
static
void
smp_barrier
(
unsigned
long
cores
=
cores
())
{
CPU_Common
::
smp_barrier
<&
finc
>
(
cores
,
id
());
}
};
class
CPU
:
private
ARMv8_A
{
friend
class
Init_System
;
private:
typedef
ARMv8_A
Base
;
public:
// CPU Native Data Types
using
CPU_Common
::
Reg8
;
using
CPU_Common
::
Reg16
;
using
CPU_Common
::
Reg32
;
using
CPU_Common
::
Reg64
;
using
Reg
=
CPU_Common
::
Reg32
;
using
Log_Addr
=
CPU_Common
::
Log_Addr
<
Reg
>
;
using
Phy_Addr
=
CPU_Common
::
Phy_Addr
<
Reg
>
;
// CPU Context
class
Context
{
public:
Context
(){}
Context
(
Log_Addr
entry
,
Log_Addr
exit
,
Log_Addr
usp
)
:
_flags
(
FLAG_DEFAULTS
),
_lr
(
exit
|
(
thumb
?
1
:
0
)),
_pc
(
entry
|
(
thumb
?
1
:
0
))
{
if
(
Traits
<
Build
>::
hysterically_debugged
||
Traits
<
Thread
>::
trace_idle
)
{
_r0
=
0
;
_r1
=
1
;
_r2
=
2
;
_r3
=
3
;
_r4
=
4
;
_r5
=
5
;
_r6
=
6
;
_r7
=
7
;
_r8
=
8
;
_r9
=
9
;
_r10
=
10
;
_r11
=
11
;
_r12
=
12
;
}
}
void
save
()
volatile
__attribute__
((
naked
));
void
load
()
const
volatile
;
friend
Debug
&
operator
<<
(
Debug
&
db
,
const
Context
&
c
)
{
db
<<
hex
<<
"{r0="
<<
c
.
_r0
<<
",r1="
<<
c
.
_r1
<<
",r2="
<<
c
.
_r2
<<
",r3="
<<
c
.
_r3
<<
",r4="
<<
c
.
_r4
<<
",r5="
<<
c
.
_r5
<<
",r6="
<<
c
.
_r6
<<
",r7="
<<
c
.
_r7
<<
",r8="
<<
c
.
_r8
<<
",r9="
<<
c
.
_r9
<<
",r10="
<<
c
.
_r10
<<
",r11="
<<
c
.
_r11
<<
",r12="
<<
c
.
_r12
<<
",sp="
<<
&
c
<<
",lr="
<<
c
.
_lr
<<
",pc="
<<
c
.
_pc
<<
",psr="
<<
c
.
_flags
<<
"}"
<<
dec
;
return
db
;
}
public:
Reg32
_flags
;
Reg32
_r0
;
Reg32
_r1
;
Reg32
_r2
;
Reg32
_r3
;
Reg32
_r4
;
Reg32
_r5
;
Reg32
_r6
;
Reg32
_r7
;
Reg32
_r8
;
Reg32
_r9
;
Reg32
_r10
;
Reg32
_r11
;
Reg32
_r12
;
Reg32
_lr
;
Reg32
_pc
;
};
// I/O ports
typedef
Reg16
IO_Irq
;
// Interrupt Service Routines
typedef
void
(
ISR
)();
// Fault Service Routines (exception handlers)
typedef
void
(
FSR
)();
public:
CPU
()
{}
using
Base
::
pc
;
using
Base
::
lr
;
using
Base
::
flags
;
using
Base
::
sp
;
using
Base
::
fr
;
using
Base
::
pdp
;
using
Base
::
id
;
using
Base
::
cores
;
static
Hertz
clock
()
{
return
_cpu_clock
;
}
static
void
clock
(
const
Hertz
&
frequency
);
// defined along with each machine's IOCtrl
static
Hertz
max_clock
();
static
Hertz
min_clock
();
static
Hertz
bus_clock
()
{
return
_bus_clock
;
}
using
Base
::
int_enable
;
using
Base
::
int_disable
;
using
Base
::
int_enabled
;
using
Base
::
int_disabled
;
using
Base
::
halt
;
using
Base
::
tsl
;
using
Base
::
finc
;
using
Base
::
fdec
;
using
Base
::
cas
;
using
Base
::
smp_barrier
;
using
Base
::
msr12
;
using
Base
::
mrs12
;
using
Base
::
cpsr
;
using
Base
::
cpsrc
;
using
Base
::
spsr_cxsf
;
using
Base
::
elr_hyp
;
using
Base
::
r0
;
using
Base
::
r1
;
using
Base
::
ldmia
;
using
Base
::
stmia
;
using
Base
::
enable_fpu
;
static
void
fpu_save
()
{
if
(
Traits
<
Build
>::
MODEL
==
Traits
<
Build
>::
Raspberry_Pi3
)
ASM
(
" vpush {s0-s15}
\n
"
" vpush {s16-s31}
\n
"
);
}
static
void
fpu_restore
()
{
if
(
Traits
<
Build
>::
MODEL
==
Traits
<
Build
>::
Raspberry_Pi3
)
ASM
(
" vpop {s0-s15}
\n
"
" vpop {s16-s31}
\n
"
);
}
static
void
switch_context
(
Context
**
o
,
Context
*
n
)
__attribute__
((
naked
));
template
<
typename
...
Tn
>
static
Context
*
init_stack
(
Log_Addr
usp
,
Log_Addr
ksp
,
void
(
*
exit
)(),
int
(
*
entry
)(
Tn
...),
Tn
...
an
)
{
ksp
-=
sizeof
(
Context
);
Context
*
ctx
=
new
(
ksp
)
Context
(
entry
,
exit
,
usp
);
init_stack_helper
(
&
ctx
->
_r0
,
an
...);
return
ctx
;
}
template
<
typename
...
Tn
>
static
Log_Addr
init_user_stack
(
Log_Addr
usp
,
void
(
*
exit
)(),
Tn
...
an
)
{
usp
-=
sizeof
(
Context
);
Context
*
ctx
=
new
(
usp
)
Context
(
0
,
exit
,
0
);
init_stack_helper
(
&
ctx
->
_r0
,
an
...);
return
usp
;
}
static
int
syscall
(
void
*
message
);
static
void
syscalled
();
using
CPU_Common
::
htole64
;
using
CPU_Common
::
htole32
;
using
CPU_Common
::
htole16
;
using
CPU_Common
::
letoh64
;
using
CPU_Common
::
letoh32
;
using
CPU_Common
::
letoh16
;
using
CPU_Common
::
htobe64
;
using
CPU_Common
::
htobe32
;
using
CPU_Common
::
htobe16
;
using
CPU_Common
::
betoh64
;
using
CPU_Common
::
betoh32
;
using
CPU_Common
::
betoh16
;
using
CPU_Common
::
htonl
;
using
CPU_Common
::
htons
;
using
CPU_Common
::
ntohl
;
using
CPU_Common
::
ntohs
;
private:
template
<
typename
Head
,
typename
...
Tail
>
static
void
init_stack_helper
(
Log_Addr
sp
,
Head
head
,
Tail
...
tail
)
{
*
static_cast
<
Head
*>
(
sp
)
=
head
;
init_stack_helper
(
sp
+
sizeof
(
Head
),
tail
...);
}
static
void
init_stack_helper
(
Log_Addr
sp
)
{}
static
void
init
();
private:
static
unsigned
int
_cpu_clock
;
static
unsigned
int
_bus_clock
;
};
inline
CPU
::
Reg64
htole64
(
CPU
::
Reg64
v
)
{
return
CPU
::
htole64
(
v
);
}
inline
CPU
::
Reg32
htole32
(
CPU
::
Reg32
v
)
{
return
CPU
::
htole32
(
v
);
}
inline
CPU
::
Reg16
htole16
(
CPU
::
Reg16
v
)
{
return
CPU
::
htole16
(
v
);
}
inline
CPU
::
Reg64
letoh64
(
CPU
::
Reg64
v
)
{
return
CPU
::
letoh64
(
v
);
}
inline
CPU
::
Reg32
letoh32
(
CPU
::
Reg32
v
)
{
return
CPU
::
letoh32
(
v
);
}
inline
CPU
::
Reg16
letoh16
(
CPU
::
Reg16
v
)
{
return
CPU
::
letoh16
(
v
);
}
inline
CPU
::
Reg64
htobe64
(
CPU
::
Reg64
v
)
{
return
CPU
::
htobe64
(
v
);
}
inline
CPU
::
Reg32
htobe32
(
CPU
::
Reg32
v
)
{
return
CPU
::
htobe32
(
v
);
}
inline
CPU
::
Reg16
htobe16
(
CPU
::
Reg16
v
)
{
return
CPU
::
htobe16
(
v
);
}
inline
CPU
::
Reg64
betoh64
(
CPU
::
Reg64
v
)
{
return
CPU
::
betoh64
(
v
);
}
inline
CPU
::
Reg32
betoh32
(
CPU
::
Reg32
v
)
{
return
CPU
::
betoh32
(
v
);
}
inline
CPU
::
Reg16
betoh16
(
CPU
::
Reg16
v
)
{
return
CPU
::
betoh16
(
v
);
}
inline
CPU
::
Reg32
htonl
(
CPU
::
Reg32
v
)
{
return
CPU
::
htonl
(
v
);
}
inline
CPU
::
Reg16
htons
(
CPU
::
Reg16
v
)
{
return
CPU
::
htons
(
v
);
}
inline
CPU
::
Reg32
ntohl
(
CPU
::
Reg32
v
)
{
return
CPU
::
ntohl
(
v
);
}
inline
CPU
::
Reg16
ntohs
(
CPU
::
Reg16
v
)
{
return
CPU
::
ntohs
(
v
);
}
__END_SYS
#endif
include/architecture/armv8/armv8_mmu.h
deleted
100644 → 0
View file @
7311811a
// EPOS ARMv8 MMU Mediator Declarations
#ifndef __armv8_mmu_h
#define __armv8_mmu_h
#include <architecture/mmu.h>
#include <system/memory_map.h>
__BEGIN_SYS
class
ARMv8_MMU
:
public
MMU_Common
<
10
,
10
,
12
>
{
friend
class
CPU
;
private:
typedef
Grouping_List
<
Frame
>
List
;
static
const
bool
colorful
=
Traits
<
MMU
>::
colorful
;
static
const
unsigned
int
COLORS
=
Traits
<
MMU
>::
COLORS
;
static
const
unsigned
int
MEM_BASE
=
Memory_Map
::
MEM_BASE
;
static
const
unsigned
int
APP_LOW
=
Memory_Map
::
APP_LOW
;
static
const
unsigned
int
PHY_MEM
=
Memory_Map
::
PHY_MEM
;
public:
// Page Flags
class
Page_Flags
;
// Page_Table
class
Page_Table
;
// Page Directory
class
Page_Directory
;
// Chunk (for Segment)
class
Chunk
;
// Directory (for Address_Space)
class
Directory
;
// DMA_Buffer
class
DMA_Buffer
;
// Class Translation performs manual logical to physical address translations for debugging purposes only
class
Translation
;
public:
ARMv8_MMU
()
{}
static
Phy_Addr
alloc
(
unsigned
int
frames
=
1
,
Color
color
=
WHITE
);
static
Phy_Addr
calloc
(
unsigned
int
frames
=
1
,
Color
color
=
WHITE
);
static
void
free
(
Phy_Addr
frame
,
int
n
=
1
);
static
void
white_free
(
Phy_Addr
frame
,
int
n
);
static
unsigned
int
allocable
(
Color
color
=
WHITE
);
static
Page_Directory
*
volatile
current
();
static
Phy_Addr
physical
(
Log_Addr
addr
);
static
PT_Entry
phy2pte
(
Phy_Addr
frame
,
Page_Flags
flags
);
static
Phy_Addr
pte2phy
(
PT_Entry
entry
);
static
PD_Entry
phy2pde
(
Phy_Addr
frame
);
static
Phy_Addr
pde2phy
(
PD_Entry
entry
);
static
void
flush_tlb
();
static
void
flush_tlb
(
Log_Addr
addr
);
static
Log_Addr
phy2log
(
Phy_Addr
phy
)
{
return
Log_Addr
((
MEM_BASE
==
PHY_MEM
)
?
phy
:
(
MEM_BASE
>
PHY_MEM
)
?
phy
-
(
MEM_BASE
-
PHY_MEM
)
:
phy
+
(
PHY_MEM
-
MEM_BASE
));
}
static
Phy_Addr
log2phy
(
Log_Addr
log
)
{
return
Phy_Addr
((
MEM_BASE
==
PHY_MEM
)
?
log
:
(
MEM_BASE
>
PHY_MEM
)
?
log
+
(
MEM_BASE
-
PHY_MEM
)
:
log
-
(
PHY_MEM
-
MEM_BASE
));
}
static
Color
phy2color
(
Phy_Addr
phy
);
static
Color
log2color
(
Log_Addr
log
);
private:
static
void
init
();
private:
static
List
_free
[
colorful
*
COLORS
+
1
];
// +1 for WHITE
static
Page_Directory
*
_master
;
};
class
MMU
:
public
IF
<
Traits
<
System
>::
multitask
,
ARMv8_MMU
,
No_MMU
>::
Result
{};
__END_SYS
#endif
include/architecture/armv8/armv8_pmu.h
deleted
100644 → 0
View file @
7311811a
// EPOS ARMv8 PMU Mediator Declarations
#ifndef __armv8_pmu_h
#define __armv8_pmu_h
#include <architecture/cpu.h>
#define __common_only__
#include <architecture/pmu.h>
#undef __common_only__
__BEGIN_SYS
class
ARMv8_A_PMU
:
public
PMU_Common
{
private:
typedef
CPU
::
Reg32
Reg32
;
protected:
static
const
unsigned
int
CHANNELS
=
6
;
static
const
unsigned
int
FIXED
=
0
;
static
const
unsigned
int
EVENTS
=
54
;
public:
// Useful bits in the PMCR register
enum
{
// Description Type Value after reset
PMCR_E
=
1
<<
0
,
// Enable all counters r/w
PMCR_P
=
1
<<
1
,
// Reset event counters r/w
PMCR_C
=
1
<<
2
,
// Cycle counter reset r/w
PMCR_D
=
1
<<
3
,
// Enable cycle counter prescale (1/64) r/w
PMCR_X
=
1
<<
4
,
// Export events r/w
};
// Useful bits in the PMCNTENSET register
enum
{
// Description Type Value after reset
PMCNTENSET_C
=
1
<<
31
,
// Cycle counter enable r/w
};
// Useful bits in the PMOVSR register
enum
{
// Description Type Value after reset
PMOVSR_C
=
1
<<
31
,
// Cycle counter overflow clear r/w
};
// Predefined architectural performance events
enum
{
// Event
L1I_REFILL
=
0x01
,
L1I_TLB_REFILL
=
0x02
,
L1D_REFILL
=
0x03
,
L1D_ACCESS
=
0x04
,
L1D_TLB_REFILL
=
0x05
,
INSTRUCTIONS_ARCHITECTURALLY_EXECUTED
=
0x08
,
EXCEPTION_TAKEN
=
0x09
,
BRANCHES_ARCHITECTURALLY_EXECUTED
=
0x0c
,
IMMEDIATE_BRANCH
=
0X0d
,
UNALIGNED_LOAD_STORE
=
0X0f
,
MISPREDICTED_BRANCH
=
0x10
,
CYCLE
=
0x11
,
PREDICTABLE_BRANCH_EXECUTED
=
0x12
,
DATA_MEMORY_ACCESS
=
0x13
,
L1I_ACCESS
=
0x14
,
L1D_WRITEBACK
=
0x15
,
L2D_ACCESS
=
0x16
,
L2D_REFILL
=
0x17
,
L2D_WRITEBACK
=
0x18
,
BUS_ACCESS
=
0x19
,
LOCAL_MEMORY_ERROR
=
0x1a
,
INSTRUCTION_SPECULATIVELY_EXECUTED
=
0x1b
,
BUS_CYCLE
=
0x1d
,
CHAIN
=
0x1e
,
// Cortex A-53 specific events
BUS_ACCESS_LD
=
0x60
,
BUS_ACCESS_ST
=
0x61
,
BR_INDIRECT_SPEC
=
0x7a
,
EXC_IRQ
=
0x86
,
EXC_FIQ
=
0x87
,
EXTERNAL_MEM_REQUEST
=
0xc0
,
EXTERNAL_MEM_REQUEST_NON_CACHEABLE
=
0xc1
,
PREFETCH_LINEFILL
=
0xc2
,
ICACHE_THROTTLE
=
0xc3
,
ENTER_READ_ALLOC_MODE
=
0xc4
,
READ_ALLOC_MODE
=
0xc5
,
PRE_DECODE_ERROR
=
0xc6
,
DATA_WRITE_STALL_ST_BUFFER_FULL
=
0xc7
,
SCU_SNOOPED_DATA_FROM_OTHER_CPU
=
0xc8
,
CONDITIONAL_BRANCH_EXECUTED
=
0xc9
,
IND_BR_MISP
=
0xca
,
IND_BR_MISP_ADDRESS_MISCOMPARE
=
0xcb
,
CONDITIONAL_BRANCH_MISP
=
0xcc
,
L1_ICACHE_MEM_ERROR
=
0xd0
,
L1_DCACHE_MEM_ERROR
=
0xd1
,
TLB_MEM_ERROR
=
0xd2
,
EMPTY_DPU_IQ_NOT_GUILTY
=
0xe0
,
EMPTY_DPU_IQ_ICACHE_MISS
=
0xe1
,
EMPTY_DPU_IQ_IMICRO_TLB_MISS
=
0xe2
,
EMPTY_DPU_IQ_PRE_DECODE_ERROR
=
0xe3
,
INTERLOCK_CYCLE_NOT_GUILTY
=
0xe4
,
INTERLOCK_CYCLE_LD_ST_WAIT_AGU_ADDRESS
=
0xe5
,
INTERLOCK_CYCLE_ADV_SIMD_FP_INST
=
0xe6
,
INTERLOCK_CYCLE_WR_STAGE_STALL_BC_MISS
=
0xe7
,
INTERLOCK_CYCLE_WR_STAGE_STALL_BC_STR
=
0xe8
};
public:
ARMv8_A_PMU
()
{}
static
void
config
(
Channel
channel
,
Event
event
,
Flags
flags
=
NONE
)
{
assert
((
static_cast
<
unsigned
int
>
(
channel
)
<
CHANNELS
)
&&
(
static_cast
<
unsigned
int
>
(
event
)
<
EVENTS
));
db
<
PMU
>
(
TRC
)
<<
"PMU::config(c="
<<
channel
<<
",e="
<<
event
<<
",f="
<<
flags
<<
")"
<<
endl
;
pmselr
(
channel
);
pmxevtyper
(
_events
[
event
]);
start
(
channel
);
}
static
Count
read
(
Channel
channel
)
{
db
<
PMU
>
(
TRC
)
<<
"PMU::read(c="
<<
channel
<<
")"
<<
endl
;
pmselr
(
channel
);
return
pmxevcntr
();
}
static
void
write
(
Channel
channel
,
Count
count
)
{
db
<
PMU
>
(
TRC
)
<<
"PMU::write(ch="
<<
channel
<<
",ct="
<<
count
<<
")"
<<
endl
;
pmselr
(
channel
);
pmxevcntr
(
count
);
}
static
void
start
(
Channel
channel
)
{
db
<
PMU
>
(
TRC
)
<<
"PMU::start(c="
<<
channel
<<
")"
<<
endl
;
pmcntenset
(
pmcntenset
()
|
(
1
<<
channel
));
}
static
void
stop
(
Channel
channel
)
{
db
<
PMU
>
(
TRC
)
<<
"PMU::stop(c="
<<
channel
<<
")"
<<
endl
;