asahi: Add a shared library interface for decode

Add a simple API so that decode can be used as a shared library by the
Python hypervisor. Note that this is not thread-safe. If we ever want to
use this in other contexts with thread safety, it will need a refactor
(along with the core decode code anyway).

Signed-off-by: Asahi Lina <lina@asahilina.net>
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24258>
This commit is contained in:
Asahi Lina 2023-07-11 00:45:17 +09:00 committed by Marge Bot
parent 55d363e02e
commit ee83453f69
3 changed files with 85 additions and 9 deletions

View file

@ -28,6 +28,8 @@ struct drm_asahi_params_global {
int num_clusters_total;
};
struct libagxdecode_config lib_config;
UNUSED static const char *agx_alloc_types[AGX_NUM_ALLOC] = {"mem", "map",
"cmd"};
@ -213,6 +215,9 @@ __agxdecode_fetch_gpu_mem(const struct agx_bo *mem, uint64_t gpu_va,
size_t size, void *buf, int line,
const char *filename)
{
if (lib_config.read_gpu_mem)
return lib_config.read_gpu_mem(gpu_va, size, buf);
if (!mem)
mem = agxdecode_find_mapped_gpu_mem_containing(gpu_va);
@ -282,10 +287,14 @@ agxdecode_stateful(uint64_t va, const char *label, decode_cmd decoder,
bool verbose, decoder_params *params, void *data)
{
uint8_t buf[1024];
struct agx_bo *alloc = agxdecode_find_mapped_gpu_mem_containing(va);
assert(alloc != NULL && "nonexistent object");
fprintf(agxdecode_dump_stream, "%s (%" PRIx64 ", handle %u)\n", label, va,
alloc->handle);
if (!lib_config.read_gpu_mem) {
struct agx_bo *alloc = agxdecode_find_mapped_gpu_mem_containing(va);
assert(alloc != NULL && "nonexistent object");
fprintf(agxdecode_dump_stream, "%s (%" PRIx64 ", handle %u)\n", label, va,
alloc->handle);
} else {
fprintf(agxdecode_dump_stream, "%s (%" PRIx64 ")\n", label, va);
}
fflush(agxdecode_dump_stream);
int len = agxdecode_fetch_gpu_array(va, buf);
@ -608,13 +617,17 @@ agxdecode_vdm(const uint8_t *map, uint64_t *link, bool verbose,
agx_unpack(agxdecode_dump_stream, map, PPP_STATE, cmd);
uint64_t address = (((uint64_t)cmd.pointer_hi) << 32) | cmd.pointer_lo;
struct agx_bo *mem = agxdecode_find_mapped_gpu_mem_containing(address);
if (mem)
agxdecode_record(address, cmd.size_words * 4, verbose, params);
else
DUMP_UNPACKED(PPP_STATE, cmd, "Non-existent record (XXX)\n");
if (!lib_config.read_gpu_mem) {
struct agx_bo *mem = agxdecode_find_mapped_gpu_mem_containing(address);
if (!mem) {
DUMP_UNPACKED(PPP_STATE, cmd, "Non-existent record (XXX)\n");
return AGX_PPP_STATE_LENGTH;
}
}
agxdecode_record(address, cmd.size_words * 4, verbose, params);
return AGX_PPP_STATE_LENGTH;
}
@ -951,3 +964,44 @@ agxdecode_close(void)
{
agxdecode_dump_file_close();
}
static ssize_t
libagxdecode_writer(void *cookie, const char *buffer, size_t size)
{
return lib_config.stream_write(buffer, size);
}
static cookie_io_functions_t funcs = {.write = libagxdecode_writer};
static decoder_params lib_params;
void
libagxdecode_init(struct libagxdecode_config *config)
{
lib_config = *config;
agxdecode_dump_stream = fopencookie(NULL, "w", funcs);
chip_id_to_params(&lib_params, config->chip_id);
}
void
libagxdecode_vdm(uint64_t addr, const char *label, bool verbose)
{
agxdecode_stateful(addr, label, agxdecode_vdm, verbose, &lib_params, NULL);
}
void
libagxdecode_cdm(uint64_t addr, const char *label, bool verbose)
{
agxdecode_stateful(addr, label, agxdecode_cdm, verbose, &lib_params, NULL);
}
void
libagxdecode_usc(uint64_t addr, const char *label, bool verbose)
{
agxdecode_stateful(addr, label, agxdecode_usc, verbose, &lib_params, NULL);
}
void
libagxdecode_shutdown(void)
{
agxdecode_dump_file_close();
}

View file

@ -8,6 +8,7 @@
#ifndef __AGX_DECODE_H__
#define __AGX_DECODE_H__
#include <sys/types.h>
#include "agx_bo.h"
void agxdecode_next_frame(void);
@ -25,4 +26,16 @@ void agxdecode_dump_mappings(unsigned map_index);
void agxdecode_track_free(struct agx_bo *bo);
struct libagxdecode_config {
uint32_t chip_id;
size_t (*read_gpu_mem)(uint64_t addr, size_t size, void *data);
ssize_t (*stream_write)(const char *buffer, size_t size);
};
void libagxdecode_init(struct libagxdecode_config *config);
void libagxdecode_vdm(uint64_t addr, const char *label, bool verbose);
void libagxdecode_cdm(uint64_t addr, const char *label, bool verbose);
void libagxdecode_usc(uint64_t addr, const char *label, bool verbose);
void libagxdecode_shutdown(void);
#endif /* __AGX_DECODE_H__ */

View file

@ -48,6 +48,15 @@ libasahi_decode = static_library(
build_by_default : false,
)
libasahi_decode_shared = shared_library(
'asahi_decode',
[libasahi_decode_files, agx_pack],
include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_asahi],
dependencies : [dep_valgrind, idep_mesautil],
c_args : [no_override_init_args],
build_by_default : with_tools.contains('asahi'),
)
libasahi_lib = static_library(
'asahi_lib',
[libasahi_lib_files, agx_pack],