|
30 | 30 | #include <sof/lib/dma.h> |
31 | 31 | #include <sof/lib/mailbox.h> |
32 | 32 | #include <sof/lib/memory.h> |
| 33 | +#include <sof/lib/mm_heap.h> |
33 | 34 | #include <sof/lib/pm_runtime.h> |
34 | 35 | #include <sof/list.h> |
35 | 36 | #include <sof/math/numbers.h> |
|
42 | 43 | #include <sof/trace/trace.h> |
43 | 44 | #include <ipc/control.h> |
44 | 45 | #include <ipc/dai.h> |
| 46 | +#include <ipc/debug.h> |
45 | 47 | #include <ipc/header.h> |
46 | 48 | #include <ipc/pm.h> |
47 | 49 | #include <ipc/stream.h> |
@@ -1281,6 +1283,70 @@ static int ipc_glb_tplg_message(uint32_t header) |
1281 | 1283 | } |
1282 | 1284 | } |
1283 | 1285 |
|
| 1286 | +static int fill_mem_usage_elems(int zone, int elem_number, |
| 1287 | + struct sof_ipc_dbg_mem_usage_elem *elems) |
| 1288 | +{ |
| 1289 | + struct mm_info info; |
| 1290 | + int ret; |
| 1291 | + int i; |
| 1292 | + |
| 1293 | + for (i = 0; i < elem_number; ++i) { |
| 1294 | + ret = heap_info(zone, i, &info); |
| 1295 | + elems[i].zone = zone; |
| 1296 | + elems[i].id = i; |
| 1297 | + elems[i].used = ret < 0 ? UINT32_MAX : info.used; |
| 1298 | + elems[i].free = ret < 0 ? 0 : info.free; |
| 1299 | + } |
| 1300 | + |
| 1301 | + return elem_number; |
| 1302 | +} |
| 1303 | + |
| 1304 | +static int ipc_glb_test_mem_usage(uint32_t header) |
| 1305 | +{ |
| 1306 | + /* count number heaps */ |
| 1307 | + int elem_cnt = PLATFORM_HEAP_SYSTEM + PLATFORM_HEAP_SYSTEM_RUNTIME + |
| 1308 | + PLATFORM_HEAP_RUNTIME + PLATFORM_HEAP_BUFFER; |
| 1309 | + size_t size = sizeof(struct sof_ipc_dbg_mem_usage) + |
| 1310 | + elem_cnt * sizeof(struct sof_ipc_dbg_mem_usage_elem); |
| 1311 | + struct sof_ipc_dbg_mem_usage_elem *elems; |
| 1312 | + struct sof_ipc_dbg_mem_usage *mem_usage; |
| 1313 | + |
| 1314 | + mem_usage = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, 0, size); |
| 1315 | + if (!mem_usage) |
| 1316 | + return -ENOMEM; |
| 1317 | + |
| 1318 | + mem_usage->rhdr.hdr.cmd = header; |
| 1319 | + mem_usage->rhdr.hdr.size = size; |
| 1320 | + mem_usage->num_elems = elem_cnt; |
| 1321 | + |
| 1322 | + /* fill list of elems */ |
| 1323 | + elems = mem_usage->elems; |
| 1324 | + elems += fill_mem_usage_elems(SOF_IPC_MEM_ZONE_SYS, PLATFORM_HEAP_SYSTEM, elems); |
| 1325 | + elems += fill_mem_usage_elems(SOF_IPC_MEM_ZONE_SYS_RUNTIME, PLATFORM_HEAP_SYSTEM_RUNTIME, |
| 1326 | + elems); |
| 1327 | + elems += fill_mem_usage_elems(SOF_IPC_MEM_ZONE_RUNTIME, PLATFORM_HEAP_RUNTIME, elems); |
| 1328 | + elems += fill_mem_usage_elems(SOF_IPC_MEM_ZONE_BUFFER, PLATFORM_HEAP_BUFFER, elems); |
| 1329 | + |
| 1330 | + /* write component values to the outbox */ |
| 1331 | + mailbox_hostbox_write(0, mem_usage, mem_usage->rhdr.hdr.size); |
| 1332 | + |
| 1333 | + rfree(mem_usage); |
| 1334 | + return 1; |
| 1335 | +} |
| 1336 | + |
| 1337 | +static int ipc_glb_debug_message(uint32_t header) |
| 1338 | +{ |
| 1339 | + uint32_t cmd = iCS(header); |
| 1340 | + |
| 1341 | + switch (cmd) { |
| 1342 | + case SOF_IPC_DEBUG_MEM_USAGE: |
| 1343 | + return ipc_glb_test_mem_usage(header); |
| 1344 | + default: |
| 1345 | + tr_err(&ipc_tr, "ipc: unknown debug header 0x%x", header); |
| 1346 | + return -EINVAL; |
| 1347 | + } |
| 1348 | +} |
| 1349 | + |
1284 | 1350 | #if CONFIG_DEBUG |
1285 | 1351 | static int ipc_glb_test_message(uint32_t header) |
1286 | 1352 | { |
@@ -1345,6 +1411,9 @@ void ipc_cmd(struct sof_ipc_cmd_hdr *hdr) |
1345 | 1411 | case SOF_IPC_GLB_PROBE: |
1346 | 1412 | ret = ipc_glb_probe(hdr->cmd); |
1347 | 1413 | break; |
| 1414 | + case SOF_IPC_GLB_DEBUG: |
| 1415 | + ret = ipc_glb_debug_message(hdr->cmd); |
| 1416 | + break; |
1348 | 1417 | #if CONFIG_DEBUG |
1349 | 1418 | case SOF_IPC_GLB_TEST: |
1350 | 1419 | ret = ipc_glb_test_message(hdr->cmd); |
|
0 commit comments