1 /**
2   ******************************************************************************
3   * @file    rtl_trace.c
4   * @author
5   * @version V1.0.0
6   * @date    2016-05-17
7   * @brief   This file contains all the functions for log print and mask.
8   ******************************************************************************
9   * @attention
10   *
11   * This module is a confidential and proprietary property of RealTek and
12   * possession or use of this module requires written permission of RealTek.
13   *
14   * Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
15   ******************************************************************************
16   */
17 
18 #include "ameba_soc.h"
19 
20 SRAM_NOCACHE_DATA_SECTION u32 log_buffer_start;
21 SRAM_NOCACHE_DATA_SECTION u32 log_buffer_end;
22 SRAM_NOCACHE_DATA_SECTION TaskHandle_t log_buffer_thread_handle;
23 
24 #if defined (ARM_CORE_CM4)
LOG_PRINTF_BUFFER(const char * fmt)25 u32 LOG_PRINTF_BUFFER(const char *fmt)
26 {
27 	/* To avoid gcc warnings */
28 	( void ) fmt;
29 
30 	IPC_TypeDef *IPC0 = IPCM0_DEV;
31 	u32 write_pointer = IPC0->IPCx_USR[IPC_USER_BUF_LOG_WP];
32 	u32 read_pointer = IPC0->IPCx_USR[IPC_USER_BUF_LOG_RP];
33 	u32 write_pointer_next = 0;
34 
35 	write_pointer_next = write_pointer + sizeof(log_buffer_t);
36 	if (write_pointer_next > log_buffer_end) {
37 		write_pointer_next = log_buffer_start;
38 	}
39 
40 	/* write pointer catch up with read pointer, wait */
41 	while (1) {
42 		read_pointer = IPC0->IPCx_USR[IPC_USER_BUF_LOG_RP];
43 
44 		if (write_pointer_next != read_pointer)
45 			break;
46 	}
47 
48 	/* make sure write pointer buffer is empty */
49 	IPC0->IPCx_USR[IPC_USER_BUF_LOG_WP] = write_pointer_next;
50 
51 	//DiagPrintfD("LOG_PRINTF_BUFFER: %x\n", IPC0->IPCx_USR[IPC_USER_BUF_LOG_WP]);
52 
53 	return (write_pointer);
54 }
55 
LOG_PRINTF_BUFFER_INIT(u32 thread_init)56 u32 LOG_PRINTF_BUFFER_INIT(u32 thread_init)
57 {
58 	/* To avoid gcc wanrings */
59 	( void ) thread_init;
60 
61 	IPC_TypeDef *IPC0 = IPCM0_DEV;
62 
63 	log_buffer_start = IPC0->IPCx_USR[IPC_USER_BUF_LOG_RP];
64 
65 	if (log_buffer_start == 0) {
66 		DBG_8195A("KM0 dont open logbuf \n");
67 		return 0;
68 	}
69 
70 	log_buffer_end = log_buffer_start + (LOG_BUFFER_NUM - 1) * sizeof(log_buffer_t);
71 	ConfigDebugBufferGet = LOG_PRINTF_BUFFER;
72 
73 	DBG_8195A("LOG_PRINTF_BUFFER_INIT KM4 %x %x\n", log_buffer_start, log_buffer_end);
74 
75 	/* open/close in CmdLogBuf */
76 	ConfigDebugBuffer = 1;
77 
78 	return 0;
79 }
80 #else
81 /* reserve one to avoid memory overflow */
82 SRAM_NOCACHE_DATA_SECTION log_buffer_t log_buffer[LOG_BUFFER_NUM + 1];
LOG_BUFF_TASK(VOID * Data)83 static VOID LOG_BUFF_TASK(VOID *Data)
84 {
85 	/* To avoid gcc warnings */
86 	( void ) Data;
87 
88 	IPC_TypeDef *IPC0 = IPCM0_DEV;
89 	u32 write_pointer = IPC0->IPCx_USR[IPC_USER_BUF_LOG_WP];
90 	u32 read_pointer = IPC0->IPCx_USR[IPC_USER_BUF_LOG_RP];
91 
92 	do {
93 		//DBG_8195A("write_pointer:%x read_pointer:%x \n", IPC0->IPCx_USR[IPC_USER_BUF_LOG_WP],
94 		//	IPC0->IPCx_USR[IPC_USER_BUF_LOG_RP]);
95 
96 		/* read pointer catch up with write pointer, wait */
97 		while (1) {
98 			write_pointer = IPC0->IPCx_USR[IPC_USER_BUF_LOG_WP];
99 
100 			if ((write_pointer != read_pointer) && (write_pointer != 0))
101 				break;
102 
103 			taskYIELD();
104 		}
105 		DiagPrintf((const char *)read_pointer);
106 
107 		read_pointer = (read_pointer + sizeof(log_buffer_t));
108 		if (read_pointer > log_buffer_end) {
109 			read_pointer = log_buffer_start;
110 		}
111 
112 		IPC0->IPCx_USR[IPC_USER_BUF_LOG_RP] = read_pointer;
113 	} while(1);
114 }
115 
LOG_PRINTF_BUFFER_INIT(u32 thread_init)116 u32 LOG_PRINTF_BUFFER_INIT(u32 thread_init)
117 {
118 	IPC_TypeDef *IPC0 = IPCM0_DEV;
119 
120 	log_buffer_thread_handle = NULL;
121 
122 	return 0;
123 
124 	/* init read/write pointer */
125 	IPC0->IPCx_USR[IPC_USER_BUF_LOG_WP] = (u32)&log_buffer[0]; /* write_pointer */
126 	IPC0->IPCx_USR[IPC_USER_BUF_LOG_RP] = (u32)&log_buffer[0]; /* read_pointer */
127 	log_buffer_end = (u32)&log_buffer[LOG_BUFFER_NUM-1];
128 	log_buffer_start = (u32)&log_buffer[0];
129 	log_buffer[0].buffer[0]='\0';
130 
131 	DBG_8195A("LOG_PRINTF_BUFFER_INIT %x %x %x\n", IPC0->IPCx_USR[IPC_USER_BUF_LOG_WP], \
132 		IPC0->IPCx_USR[IPC_USER_BUF_LOG_RP], log_buffer_end);
133 
134 	if (!thread_init)
135 		return 0;
136 
137 	/* init thread, low-priority */
138 	if (pdTRUE != xTaskCreate(LOG_BUFF_TASK, (const char * const)"LOGBUFF_TASK", 128,
139 		NULL, tskIDLE_PRIORITY + 3 , &log_buffer_thread_handle))
140 	{
141 		DiagPrintf("CreateLOGBUFF_TASK Err!!\n");
142 	}
143 
144 	return 0;
145 }
146 
LOG_BUFF_SUSPEND(void)147 u32 LOG_BUFF_SUSPEND(void)
148 {
149 	if (log_buffer_thread_handle) {
150 		vTaskSuspend(log_buffer_thread_handle);
151 	}
152 	return TRUE;
153 }
154 
LOG_BUFF_RESUME(void)155 u32 LOG_BUFF_RESUME(void)
156 {
157 	if (log_buffer_thread_handle) {
158 		vTaskResume(log_buffer_thread_handle);
159 	}
160 	return TRUE;
161 }
162 #endif
163 /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/
164