Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
051cf889
Unverified
Commit
051cf889
authored
Nov 29, 2018
by
Antonio Niño Díaz
Committed by
GitHub
Nov 29, 2018
Browse files
Merge pull request #1679 from pangupta/master
ccn: Introduce API to set and read value of node register
parents
9345d9a0
6f7dba4b
Changes
2
Hide whitespace changes
Inline
Side-by-side
drivers/arm/ccn/ccn.c
View file @
051cf889
...
...
@@ -11,6 +11,7 @@
#include <debug.h>
#include <errno.h>
#include <mmio.h>
#include <stdbool.h>
#include "ccn_private.h"
static
const
ccn_desc_t
*
ccn_plat_desc
;
...
...
@@ -490,3 +491,123 @@ int ccn_get_part0_id(uintptr_t periphbase)
return
(
int
)(
mmio_read_64
(
periphbase
+
MN_PERIPH_ID_0_1_OFFSET
)
&
0xFF
);
}
/*******************************************************************************
* This function returns the region id corresponding to a node_id of node_type.
******************************************************************************/
static
unsigned
int
get_region_id_for_node
(
node_types_t
node_type
,
unsigned
int
node_id
)
{
unsigned
int
mn_reg_off
,
region_id
;
unsigned
long
long
node_bitmap
;
unsigned
int
loc_node_id
,
node_pos_in_map
=
0
;
assert
(
node_type
<
NUM_NODE_TYPES
);
assert
(
node_id
<
MAX_RN_NODES
);
switch
(
node_type
)
{
case
NODE_TYPE_RNI
:
region_id
=
RNI_REGION_ID_START
;
break
;
case
NODE_TYPE_HNF
:
region_id
=
HNF_REGION_ID_START
;
break
;
case
NODE_TYPE_HNI
:
region_id
=
HNI_REGION_ID_START
;
break
;
case
NODE_TYPE_SN
:
region_id
=
SBSX_REGION_ID_START
;
break
;
default:
ERROR
(
"Un-supported Node Type = %d.
\n
"
,
node_type
);
assert
(
false
);
return
REGION_ID_LIMIT
;
}
/*
* RN-I, HN-F, HN-I, SN node registers in the MN region
* occupy contiguous 16 byte apart offsets.
*
* RN-F and RN-D node are not supported as
* none of them exposes any memory map to
* configure any of their offset registers.
*/
mn_reg_off
=
MN_RNF_NODEID_OFFSET
+
(
node_type
<<
4
);
node_bitmap
=
ccn_reg_read
(
ccn_plat_desc
->
periphbase
,
MN_REGION_ID
,
mn_reg_off
);
assert
((
node_bitmap
&
(
1ULL
<<
(
node_id
)))
!=
0U
);
FOR_EACH_PRESENT_NODE_ID
(
loc_node_id
,
node_bitmap
)
{
INFO
(
"Index = %u with loc_nod=%u and input nod=%u
\n
"
,
node_pos_in_map
,
loc_node_id
,
node_id
);
if
(
loc_node_id
==
node_id
)
break
;
node_pos_in_map
++
;
}
if
(
node_pos_in_map
==
CCN_MAX_RN_MASTERS
)
{
ERROR
(
"Node Id = %d, is not found.
\n
"
,
node_id
);
assert
(
false
);
return
REGION_ID_LIMIT
;
}
region_id
+=
node_pos_in_map
;
return
region_id
;
}
/*******************************************************************************
* This function sets the value 'val' to the register at register_offset from
* the base address pointed to by the region_id.
* where, region id is mapped to a node_id of node_type.
******************************************************************************/
void
ccn_write_node_reg
(
node_types_t
node_type
,
unsigned
int
node_id
,
unsigned
int
reg_offset
,
unsigned
long
long
val
)
{
unsigned
int
region_id
=
get_region_id_for_node
(
node_type
,
node_id
);
if
(
reg_offset
>
REGION_ID_OFFSET
)
{
ERROR
(
"Invalid Register offset 0x%x is provided.
\n
"
,
reg_offset
);
assert
(
false
);
return
;
}
/* Setting the value of Auxilary Control Register of the Node */
ccn_reg_write
(
ccn_plat_desc
->
periphbase
,
region_id
,
reg_offset
,
val
);
VERBOSE
(
"Value is successfully written at address 0x%lx.
\n
"
,
(
ccn_plat_desc
->
periphbase
+
region_id_to_base
(
region_id
))
+
reg_offset
);
}
/*******************************************************************************
* This function read the value 'val' stored in the register at register_offset
* from the base address pointed to by the region_id.
* where, region id is mapped to a node_id of node_type.
******************************************************************************/
unsigned
long
long
ccn_read_node_reg
(
node_types_t
node_type
,
unsigned
int
node_id
,
unsigned
int
reg_offset
)
{
unsigned
long
long
val
;
unsigned
int
region_id
=
get_region_id_for_node
(
node_type
,
node_id
);
if
(
reg_offset
>
REGION_ID_OFFSET
)
{
ERROR
(
"Invalid Register offset 0x%x is provided.
\n
"
,
reg_offset
);
assert
(
false
);
return
ULL
(
0
);
}
/* Setting the value of Auxilary Control Register of the Node */
val
=
ccn_reg_read
(
ccn_plat_desc
->
periphbase
,
region_id
,
reg_offset
);
VERBOSE
(
"Value is successfully read from address 0x%lx.
\n
"
,
(
ccn_plat_desc
->
periphbase
+
region_id_to_base
(
region_id
))
+
reg_offset
);
return
val
;
}
include/drivers/arm/ccn.h
View file @
051cf889
...
...
@@ -76,6 +76,16 @@ typedef struct ccn_desc {
uintptr_t
periphbase
;
}
ccn_desc_t
;
/* Enum used to loop through all types of nodes in CCN*/
typedef
enum
node_types
{
NODE_TYPE_RNF
=
0
,
NODE_TYPE_RNI
,
NODE_TYPE_RND
,
NODE_TYPE_HNF
,
NODE_TYPE_HNI
,
NODE_TYPE_SN
,
NUM_NODE_TYPES
}
node_types_t
;
void
ccn_init
(
const
ccn_desc_t
*
plat_ccn_desc
);
void
ccn_enter_snoop_dvm_domain
(
unsigned
long
long
master_iface_map
);
...
...
@@ -92,5 +102,12 @@ void ccn_program_sys_addrmap(unsigned int sn0_id,
unsigned
int
ccn_get_l3_run_mode
(
void
);
int
ccn_get_part0_id
(
uintptr_t
periphbase
);
void
ccn_write_node_reg
(
node_types_t
node_type
,
unsigned
int
node_id
,
unsigned
int
reg_offset
,
unsigned
long
long
val
);
unsigned
long
long
ccn_read_node_reg
(
node_types_t
node_type
,
unsigned
int
node_id
,
unsigned
int
reg_offset
);
#endif
/* __ASSEMBLY__ */
#endif
/* CCN_H */
Write
Preview
Markdown
is supported
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