41
41
*/
42
42
#define LOG_MESSAGE_MAX_SIZE (4 * LOG_ENTRY_SIZE)
43
43
44
+ /* buf size should be identical to the size in hvlog option, which is
45
+ * transfered to SOS:
46
+ * bsp/uefi/clearlinux/acrn.conf: hvlog=2M@0x1FE00000
47
+ */
48
+ #define HVLOG_BUF_SIZE (2*1024*1024)
49
+
44
50
DEFINE_CPU_DATA (char [LOG_MESSAGE_MAX_SIZE ], logbuf );
51
+ DEFINE_CPU_DATA (struct shared_buf * , earlylog_sbuf );
45
52
46
53
struct logmsg {
47
54
uint32_t flags ;
@@ -51,10 +58,63 @@ struct logmsg {
51
58
52
59
static struct logmsg logmsg ;
53
60
61
+ static inline void alloc_earlylog_sbuf (uint32_t cpu_id )
62
+ {
63
+ uint32_t ele_size = LOG_ENTRY_SIZE ;
64
+ uint32_t ele_num = ((HVLOG_BUF_SIZE >> 1 ) / phy_cpu_num
65
+ - SBUF_HEAD_SIZE ) / ele_size ;
66
+
67
+ per_cpu (earlylog_sbuf , cpu_id ) = sbuf_allocate (ele_num , ele_size );
68
+ if (!per_cpu (earlylog_sbuf ,cpu_id ))
69
+ printf ("failed to allcate sbuf for hvlog - %d\n" , cpu_id );
70
+ }
71
+
72
+ static inline void free_earlylog_sbuf (uint32_t cpu_id )
73
+ {
74
+ if (!per_cpu (earlylog_sbuf , cpu_id ))
75
+ return ;
76
+
77
+ free (per_cpu (earlylog_sbuf , cpu_id ));
78
+ per_cpu (earlylog_sbuf , cpu_id ) = NULL ;
79
+ }
80
+
81
+ static int do_copy_earlylog (struct shared_buf * dst_sbuf ,
82
+ struct shared_buf * src_sbuf )
83
+ {
84
+ uint32_t buf_size , valid_size ;
85
+ uint32_t cur_tail ;
86
+ spinlock_rflags ;
87
+
88
+ if (src_sbuf -> ele_size != dst_sbuf -> ele_size
89
+ && src_sbuf -> ele_num != dst_sbuf -> ele_num ) {
90
+ spinlock_irqsave_obtain (& (logmsg .lock ));
91
+ printf ("Error to copy early hvlog: size mismatch\n" );
92
+ spinlock_irqrestore_release (& (logmsg .lock ));
93
+ return - EINVAL ;
94
+ }
95
+
96
+ cur_tail = src_sbuf -> tail ;
97
+ buf_size = SBUF_HEAD_SIZE + dst_sbuf -> size ;
98
+ valid_size = SBUF_HEAD_SIZE + cur_tail ;
99
+
100
+ memcpy_s ((void * )dst_sbuf , buf_size , (void * )src_sbuf , valid_size );
101
+ if (dst_sbuf -> tail != cur_tail )
102
+ /* there is chance to lose new log from certain pcpu */
103
+ dst_sbuf -> tail = cur_tail ;
104
+
105
+ return 0 ;
106
+ }
107
+
54
108
void init_logmsg (__unused uint32_t mem_size , uint32_t flags )
55
109
{
110
+ int32_t idx ;
111
+
56
112
logmsg .flags = flags ;
57
113
logmsg .seq = 0 ;
114
+
115
+ /* allocate sbuf for log before sos booting */
116
+ for (idx = 0 ; idx < phy_cpu_num ; idx ++ )
117
+ alloc_earlylog_sbuf (idx );
58
118
}
59
119
60
120
void do_logmsg (uint32_t severity , const char * fmt , ...)
@@ -114,6 +174,18 @@ void do_logmsg(uint32_t severity, const char *fmt, ...)
114
174
int i , msg_len ;
115
175
struct shared_buf * sbuf = (struct shared_buf * )
116
176
per_cpu (sbuf , cpu_id )[ACRN_HVLOG ];
177
+ struct shared_buf * early_sbuf = per_cpu (earlylog_sbuf , cpu_id );
178
+
179
+ if (early_sbuf ) {
180
+ if (sbuf ) {
181
+ /* switch to sbuf from sos */
182
+ do_copy_earlylog (sbuf , early_sbuf );
183
+ free_earlylog_sbuf (cpu_id );
184
+ } else
185
+ /* use earlylog sbuf if no sbuf from sos */
186
+ sbuf = early_sbuf ;
187
+ }
188
+
117
189
if (sbuf != NULL ) {
118
190
msg_len = strnlen_s (buffer , LOG_MESSAGE_MAX_SIZE );
119
191
@@ -131,31 +203,43 @@ void print_logmsg_buffer(uint32_t cpu_id)
131
203
spinlock_rflags ;
132
204
char buffer [LOG_ENTRY_SIZE + 1 ];
133
205
int read_cnt ;
134
- struct shared_buf * sbuf ;
206
+ struct shared_buf * * sbuf ;
207
+ int is_earlylog = 0 ;
135
208
136
209
if (cpu_id >= (uint32_t )phy_cpu_num )
137
210
return ;
138
211
139
- sbuf = (struct shared_buf * )per_cpu (sbuf , cpu_id )[ACRN_HVLOG ];
140
- if (sbuf != NULL ) {
212
+ if (per_cpu (earlylog_sbuf , cpu_id )) {
213
+ sbuf = & per_cpu (earlylog_sbuf , cpu_id );
214
+ is_earlylog = 1 ;
215
+ } else
216
+ sbuf = (struct shared_buf * * )
217
+ & per_cpu (sbuf , cpu_id )[ACRN_HVLOG ];
218
+
219
+ spinlock_irqsave_obtain (& (logmsg .lock ));
220
+ if (* sbuf )
221
+ printf ("CPU%d: head: 0x%x, tail: 0x%x %s\n\r" ,
222
+ cpu_id , (* sbuf )-> head , (* sbuf )-> tail ,
223
+ is_earlylog ? "[earlylog]" : "" );
224
+ spinlock_irqrestore_release (& (logmsg .lock ));
225
+
226
+ do {
227
+ uint32_t idx ;
228
+ memset (buffer , 0 , LOG_ENTRY_SIZE + 1 );
229
+
230
+ if (* sbuf == NULL )
231
+ return ;
232
+
233
+ read_cnt = sbuf_get (* sbuf , (uint8_t * )buffer );
234
+
235
+ if (read_cnt <= 0 )
236
+ return ;
237
+
238
+ idx = (read_cnt < LOG_ENTRY_SIZE ) ? read_cnt : LOG_ENTRY_SIZE ;
239
+ buffer [idx ] = '\0' ;
240
+
141
241
spinlock_irqsave_obtain (& (logmsg .lock ));
142
- printf ("CPU%d: head: 0x%x, tail: 0x%x\n\r" ,
143
- cpu_id , sbuf -> head , sbuf -> tail );
242
+ printf ("%s\n\r" , buffer );
144
243
spinlock_irqrestore_release (& (logmsg .lock ));
145
- do {
146
- memset (buffer , 0 , LOG_ENTRY_SIZE + 1 );
147
- read_cnt = sbuf_get (sbuf , (uint8_t * )buffer );
148
- if (read_cnt > 0 ) {
149
- uint32_t idx ;
150
-
151
- idx = (read_cnt < LOG_ENTRY_SIZE ) ?
152
- read_cnt : LOG_ENTRY_SIZE ;
153
- buffer [idx ] = '\0' ;
154
-
155
- spinlock_irqsave_obtain (& (logmsg .lock ));
156
- printf ("%s\n\r" , buffer );
157
- spinlock_irqrestore_release (& (logmsg .lock ));
158
- }
159
- } while (read_cnt > 0 );
160
- }
244
+ } while (read_cnt > 0 );
161
245
}
0 commit comments