22
33#include <string.h>
44
5+ #include "adt.h"
6+ #include "akf.h"
57#include "asc.h"
8+ #include "malloc.h"
69#include "sep.h"
710#include "types.h"
811#include "utils.h"
1821
1922#define SEP_TIMEOUT 1000
2023
21- static asc_dev_t * sep_asc = NULL ;
24+ enum sep_mbox_type {
25+ SEP_MBOX_TYPE_AKF ,
26+ SEP_MBOX_TYPE_ASC ,
27+ };
28+
29+ static struct sep_dev {
30+ enum sep_mbox_type type ;
31+ enum sep_capabilities capabilities ;
32+ union {
33+ akf_dev_t * akf ;
34+ asc_dev_t * asc ;
35+ };
36+ } * sep_dev ;
2237
2338int sep_init (void )
2439{
25- if (!sep_asc )
26- sep_asc = asc_init ("/arm-io/sep" );
27- if (!sep_asc )
40+ const char * path = "/arm-io/sep" ;
41+ int sep_path [8 ];
42+
43+ int node = adt_path_offset_trace (adt , path , sep_path );
44+ if (node < 0 ) {
45+ printf ("sep: Error getting sep node %s\n" , path );
46+ return -1 ;
47+ }
48+
49+ u64 base ;
50+ if (adt_get_reg (adt , sep_path , "reg" , 0 , & base , NULL ) < 0 ) {
51+ printf ("sep: Error getting akf %s base address.\n" , path );
2852 return -1 ;
53+ }
54+
55+ sep_dev = calloc (0 , sizeof (* sep_dev ));
56+
57+ if (adt_is_compatible (adt , node , "iop,s5l8960x" ) || adt_is_compatible (adt , node , "iop,s8000" )) {
58+ sep_dev -> type = SEP_MBOX_TYPE_AKF ;
59+ } else {
60+ sep_dev -> type = SEP_MBOX_TYPE_ASC ;
61+ }
62+
63+ switch (sep_dev -> type ) {
64+ case SEP_MBOX_TYPE_AKF :
65+ sep_dev -> akf = akf_init (path );
66+ break ;
67+ case SEP_MBOX_TYPE_ASC :
68+ sep_dev -> asc = asc_init (path );
69+ break ;
70+ }
71+
72+ if (chip_id != 0x8960 && chip_id != 0x7000 && chip_id != 0x7001 && chip_id != 0x8000 &&
73+ chip_id != 0x8001 && chip_id != 0x8003 )
74+ sep_dev -> capabilities |= SEP_CAPABILITY_GETRAND ;
75+
2976 return 0 ;
3077}
3178
79+ bool sep_send (u64 msg )
80+ {
81+ switch (sep_dev -> type ) {
82+ case SEP_MBOX_TYPE_AKF : {
83+ const struct akf_message akf_msg = {.msg0 = FIELD_GET (msg , MASK (32 )),
84+ .msg1 = FIELD_GET (msg , GENMASK (63 , 32 ))};
85+ return akf_send (sep_dev -> akf , & akf_msg );
86+ }
87+ case SEP_MBOX_TYPE_ASC : {
88+ const struct asc_message asc_msg = {.msg0 = msg };
89+ return asc_send (sep_dev -> asc , & asc_msg );
90+ }
91+ }
92+ }
93+
94+ bool sep_recv (u64 * reply )
95+ {
96+ switch (sep_dev -> type ) {
97+ case SEP_MBOX_TYPE_ASC : {
98+ struct asc_message asc_reply ;
99+ int retval = asc_recv_timeout (sep_dev -> asc , & asc_reply , SEP_TIMEOUT );
100+ * reply = asc_reply .msg0 ;
101+ return retval ;
102+ }
103+ case SEP_MBOX_TYPE_AKF : {
104+ struct akf_message akf_reply ;
105+ int retval = akf_recv_timeout (sep_dev -> akf , & akf_reply , SEP_TIMEOUT );
106+ * reply =
107+ FIELD_PREP (MASK (32 ), akf_reply .msg0 ) | FIELD_PREP (GENMASK (63 , 32 ), akf_reply .msg1 );
108+ return retval ;
109+ }
110+ }
111+ }
112+
32113size_t sep_get_random (void * buffer , size_t len )
33114{
34- const struct asc_message msg_getrand = {.msg0 = FIELD_PREP (SEP_MSG_EP , SEP_EP_ROM ) |
35- FIELD_PREP (SEP_MSG_CMD , SEP_MSG_GETRAND )};
115+ if (!(sep_dev -> capabilities & SEP_CAPABILITY_GETRAND )) {
116+ printf ("sep: SEP does not support GETRAND\n" );
117+ return 0 ;
118+ }
119+
120+ const u64 msg_getrand =
121+ FIELD_PREP (SEP_MSG_EP , SEP_EP_ROM ) | FIELD_PREP (SEP_MSG_CMD , SEP_MSG_GETRAND );
36122 int ret ;
37123 size_t done = 0 ;
38124
@@ -41,20 +127,20 @@ size_t sep_get_random(void *buffer, size_t len)
41127 return 0 ;
42128
43129 while (len ) {
44- struct asc_message reply ;
130+ u64 reply ;
45131 u32 rng ;
46132 size_t copy ;
47133
48- if (!asc_send ( sep_asc , & msg_getrand ))
134+ if (!sep_send ( msg_getrand ))
49135 return done ;
50- if (!asc_recv_timeout ( sep_asc , & reply , SEP_TIMEOUT ))
136+ if (!sep_recv ( & reply ))
51137 return done ;
52- if (FIELD_GET (SEP_MSG_CMD , reply . msg0 ) != SEP_REPLY_GETRAND ) {
53- printf ("SEP: unexpected getrand reply: %016lx\n" , reply . msg0 );
138+ if (FIELD_GET (SEP_MSG_CMD , reply ) != SEP_REPLY_GETRAND ) {
139+ printf ("SEP: unexpected getrand reply: %016lx\n" , reply );
54140 return done ;
55141 }
56142
57- rng = FIELD_GET (SEP_MSG_DATA , reply . msg0 );
143+ rng = FIELD_GET (SEP_MSG_DATA , reply );
58144 copy = sizeof (rng );
59145 if (copy > len )
60146 copy = len ;
@@ -66,3 +152,8 @@ size_t sep_get_random(void *buffer, size_t len)
66152
67153 return done ;
68154}
155+
156+ enum sep_capabilities sep_get_capabilities (void )
157+ {
158+ return sep_dev -> capabilities ;
159+ }
0 commit comments