1 /*
2  * Copyright 2022, Cypress Semiconductor Corporation (an Infineon company)
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdarg.h>
21 #include "whd_debug.h"
22 
23 #ifdef WHD_LOGGING_BUFFER_ENABLE
24 
25 #ifndef LOGGING_BUFFER_SIZE
26 #error LOGGING_BUFFER_SIZE is not defined
27 #endif  /* LOGGING_BUFFER_SIZE */
28 whd_logging_t logbuf;
29 
whd_buffer_printf(const char * format,...)30 int whd_buffer_printf(const char *format, ...)
31 {
32     int potential_num_written = 0;
33     va_list args;
34     va_start (args, format);
35 
36     potential_num_written = vsnprintf (&(logbuf.buffer[logbuf.buffer_write]),
37                                        (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write) ) + 1, format, args);
38 
39     if (potential_num_written > (int)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write) ) )
40     {
41         /* full print did not fit in buffer - wipe what was just written
42            and reprint at start of buffer
43          */
44         memset(&(logbuf.buffer[logbuf.buffer_write]), 0xf, (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write) ) );
45 
46         logbuf.buffer_write = 0;
47         potential_num_written = vsnprintf (&(logbuf.buffer[logbuf.buffer_write]),
48                                            (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write) ) + 1, format, args);
49 
50         logbuf.buffer_write += (unsigned)potential_num_written;
51         logbuf.buffer_write %= LOGGING_BUFFER_SIZE;
52 
53         if (logbuf.roll_over)
54             logbuf.over_write = WHD_TRUE;
55 
56         logbuf.roll_over = WHD_TRUE;
57 
58         if ( (logbuf.roll_over) && (logbuf.buffer_read < (logbuf.buffer_write) ) )
59         {
60             logbuf.buffer_read = logbuf.buffer_write;
61         }
62         if (logbuf.over_write && (logbuf.buffer_read != (logbuf.buffer_write) ) )
63         {
64             logbuf.buffer_read = (logbuf.buffer_write);
65         }
66     }
67     else
68     {
69         logbuf.buffer_write += (unsigned)potential_num_written;
70 
71         if ( (logbuf.buffer_write) >= LOGGING_BUFFER_SIZE )
72         {
73             logbuf.buffer_write %= LOGGING_BUFFER_SIZE;
74 
75             if (logbuf.roll_over)
76                 logbuf.over_write = WHD_TRUE;
77 
78             logbuf.roll_over = WHD_TRUE;
79         }
80 
81         if (logbuf.roll_over && (logbuf.buffer_read < logbuf.buffer_write) )
82         {
83             logbuf.buffer_read = logbuf.buffer_write;
84         }
85         if (logbuf.over_write && (logbuf.buffer_read != logbuf.buffer_write) )
86         {
87             logbuf.buffer_read = logbuf.buffer_write;
88         }
89     }
90 
91     va_end (args);
92     return potential_num_written;
93 }
94 
whd_print_logbuffer(void)95 void whd_print_logbuffer(void)
96 {
97     while (logbuf.roll_over || logbuf.over_write || (logbuf.buffer_read != logbuf.buffer_write) )
98     {
99         logbuf.roll_over = logbuf.over_write = WHD_FALSE;
100 
101         while (logbuf.buffer[logbuf.buffer_read] == 0xf)
102         {
103             logbuf.buffer_read = (logbuf.buffer_read + 1) % LOGGING_BUFFER_SIZE;
104         }
105 
106         putchar(logbuf.buffer[logbuf.buffer_read]);
107         logbuf.buffer_read = (logbuf.buffer_read + 1) % LOGGING_BUFFER_SIZE;
108     }
109 }
110 
111 #endif /* ifdef WHD_LOGGING_BUFFER_ENABLE */
112