14 #include "soc_watch.h"
15 #include "qm_common.h"
16 #include "qm_soc_regs.h"
22 #include <x86intrin.h>
24 #define get_ticks() _rdtsc()
26 #include "qm_sensor_regs.h"
28 #define get_ticks() __builtin_arc_lr(QM_SS_TSC_BASE + QM_SS_TIMER_COUNT)
39 #define NONUTSTATIC static
59 NONUTSTATIC
const char *ev_strs[] = {
77 static const uint32_t *platform_regs[] = {
78 (uint32_t *)(&QM_SCSS_CCU->osc0_cfg1),
79 (uint32_t *)(&QM_SCSS_CCU->ccu_lp_clk_ctl),
80 (uint32_t *)(&QM_SCSS_CCU->ccu_sys_clk_ctl),
82 (uint32_t *)(&QM_SCSS_CCU->ccu_periph_clk_gate_ctl),
83 (uint32_t *)(&QM_SCSS_CCU->ccu_ext_clock_ctl),
85 (uint32_t *)(&QM_SCSS_CMP->cmp_pwr),
86 (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup),
87 (uint32_t *)(&QM_SCSS_PMUX->pmux_slew),
88 (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en)};
90 static const uint32_t *platform_regs[] = {
91 (uint32_t *)(&QM_SCSS_CCU->osc0_cfg1),
92 (uint32_t *)(&QM_SCSS_CCU->ccu_lp_clk_ctl),
93 (uint32_t *)(&QM_SCSS_CCU->ccu_sys_clk_ctl),
95 (uint32_t *)(&QM_SCSS_CCU->ccu_periph_clk_gate_ctl),
96 (uint32_t *)(&QM_SCSS_CCU->ccu_ss_periph_clk_gate_ctl),
97 (uint32_t *)(&QM_SCSS_CCU->ccu_ext_clock_ctl),
99 (uint32_t *)(&QM_SCSS_CMP->cmp_pwr), (uint32_t *)(&QM_SCSS_PMU->slp_cfg),
100 (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup),
101 (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup[1]),
102 (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup[2]),
103 (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup[3]),
104 (uint32_t *)(&QM_SCSS_PMUX->pmux_slew),
105 (uint32_t *)(&QM_SCSS_PMUX->pmux_slew[1]),
106 (uint32_t *)(&QM_SCSS_PMUX->pmux_slew[2]),
107 (uint32_t *)(&QM_SCSS_PMUX->pmux_slew[3]),
108 (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en),
109 (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en[1]),
110 (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en[2]),
111 (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en[3])};
116 #define SOC_WATCH_TRACE QM_PRINTF
118 #define SOC_WATCH_TRACE(...)
126 #define MLOG(e) mlog(e)
127 #define MLOG_BYTE(b) mlog_byte(b)
128 #define MLOG_SIZE 512
129 static uint8_t mlog_events[MLOG_SIZE];
130 static uint16_t mlog_idx = 0;
131 void mlog(uint8_t event)
133 mlog_events[++mlog_idx % (MLOG_SIZE)] = event;
135 void mlog_byte(uint8_t byte)
137 const char c[] = {
"0123456789ABCDEF"};
149 #define SW_OSC0_CFG1 (0)
150 #define SW_SYS_CLK_CTL (2)
158 #define SOC_WATCH_EVENT_BUFFER_SIZE (256)
164 struct sw_profiling_event_buffer {
167 uint8_t event_data[SOC_WATCH_EVENT_BUFFER_SIZE - 2];
169 } soc_watch_event_buffer = {0, SOC_WATCH_EVENT_BUFFER_SIZE - 1, {0}};
172 #define SW_EB_HIGH_WATER (((SOC_WATCH_EVENT_BUFFER_SIZE - 2) * 7) >> 3)
174 NONUTSTATIC
int soc_watch_buffer_full(
void)
176 return (soc_watch_event_buffer.eb_idx >= SW_EB_HIGH_WATER);
186 volatile uint8_t soc_watch_flush_flag = 0;
191 static void soc_watch_event_buffer_flush(
void)
206 if (QM_SCSS_PMU->aon_vr & QM_AON_VR_VREG_SEL) {
212 soc_watch_flush_flag = 1;
213 soc_watch_event_buffer.eb_idx = 0;
218 static void eb_write_char(uint8_t data)
220 SOC_WATCH_TRACE(
"c%d:0x%x [0]=%x\n", soc_watch_event_buffer.eb_idx,
221 data, soc_watch_event_buffer.event_data[0]);
222 soc_watch_event_buffer.event_data[soc_watch_event_buffer.eb_idx++] =
227 static void eb_write_uint32(uint32_t *data)
229 uint32_t dst_data = *data;
230 uint8_t byte_count = 0;
231 SOC_WATCH_TRACE(
"I%d:0x%x\n", soc_watch_event_buffer.eb_idx, *data);
232 while (byte_count <
sizeof(uint32_t)) {
233 soc_watch_event_buffer
234 .event_data[soc_watch_event_buffer.eb_idx++] =
236 dst_data = dst_data >> 8;
252 static inline unsigned int soc_watch_irq_lock(
void)
254 unsigned int key = 0;
260 __asm__ __volatile__(
"clri %0" :
"=r"(key));
265 static inline void soc_watch_irq_unlock(
unsigned int key)
271 __asm__ __volatile__(
"seti %0" : :
"ir"(key));
278 #define X86_FLAGS_IF BIT(9)
287 static inline unsigned int soc_watch_irq_lock(
void)
289 unsigned int key = 0;
295 __asm__ __volatile__(
"pushfl;\n\t"
313 static inline void soc_watch_irq_unlock(
unsigned int key)
319 if (!(key & X86_FLAGS_IF)) {
329 __asm__ __volatile__(
"sti;\n\t" : :);
347 static uint8_t record_rtc = 0;
348 const uint32_t *rtc_ctr = (uint32_t *)&QM_RTC[QM_RTC_0]->rtc_ccvr;
350 unsigned int irq_flag = 0;
356 uint32_t rtc_val = *rtc_ctr;
358 #define AVG_EVENT_SIZE 8
361 irq_flag = soc_watch_irq_lock();
366 if ((soc_watch_event_buffer.eb_idx + AVG_EVENT_SIZE) <=
367 soc_watch_event_buffer.eb_size) {
372 if (QM_SCSS_PMU->aon_vr & QM_AON_VR_VREG_SEL) {
382 eb_write_uint32((uint32_t *)(&rtc_val));
387 SOC_WATCH_TRACE(
"Unknown event id: 0x%x\n", event_id);
389 soc_watch_irq_unlock(irq_flag);
392 cp = ev_strs[event_id];
393 SOC_WATCH_TRACE(
"%c", *cp);
400 eb_write_uint32((uint32_t *)(&tsc));
405 (uint32_t *)(&rtc_val));
413 (uint32_t *)platform_regs[ev_data]);
416 eb_write_uint32((uint32_t *)&ev_data);
420 eb_write_char(((uint32_t)ev_data) & 0xff);
424 eb_write_char(((uint32_t)ev_subtype) & 0xff);
428 (uint32_t *)platform_regs[SW_OSC0_CFG1]);
430 (uint32_t *)platform_regs[SW_SYS_CLK_CTL]);
434 "Unknown string char: 0x%x on string "
449 SOC_WATCH_TRACE(
"\n --- FLUSH: idx= %d ---\n",
450 soc_watch_event_buffer.eb_idx);
451 soc_watch_event_buffer_flush();
454 MLOG_BYTE(soc_watch_event_buffer.eb_idx);
455 soc_watch_irq_unlock(irq_flag);
469 soc_watch_event_buffer_flush();
void soc_watch_log_event(soc_watch_event_t event_id, uintptr_t ev_data)
Log a power profile event.
void soc_watch_trigger_flush()
Trigger a buffer flush via watchpoint.
soc_watch_event_t
Power profiling events enumeration.
void soc_watch_log_app_event(soc_watch_event_t event_id, uint8_t ev_subtype, uintptr_t ev_data)
Log an application event via the power profile logger.