drivers/gpu/drm/i915/gt/uc/intel_guc_log.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
Extension
.c
Size
24974 bytes
Lines
938
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct guc_log_section {
	u32 max;
	u32 flag;
	u32 default_val;
	const char *name;
};

static void _guc_log_init_sizes(struct intel_guc_log *log)
{
	struct intel_guc *guc = log_to_guc(log);
	static const struct guc_log_section sections[GUC_LOG_SECTIONS_LIMIT] = {
		{
			GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT,
			GUC_LOG_LOG_ALLOC_UNITS,
			GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE,
			"crash dump"
		},
		{
			GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT,
			GUC_LOG_LOG_ALLOC_UNITS,
			GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE,
			"debug",
		},
		{
			GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT,
			GUC_LOG_CAPTURE_ALLOC_UNITS,
			GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE,
			"capture",
		}
	};
	int i;

	for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++)
		log->sizes[i].bytes = sections[i].default_val;

	/* If debug size > 1MB then bump default crash size to keep the same units */
	if (log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes >= SZ_1M &&
	    GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE < SZ_1M)
		log->sizes[GUC_LOG_SECTIONS_CRASH].bytes = SZ_1M;

	/* Prepare the GuC API structure fields: */
	for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++) {
		/* Convert to correct units */
		if ((log->sizes[i].bytes % SZ_1M) == 0) {
			log->sizes[i].units = SZ_1M;
			log->sizes[i].flag = sections[i].flag;
		} else {
			log->sizes[i].units = SZ_4K;
			log->sizes[i].flag = 0;
		}

		if (!IS_ALIGNED(log->sizes[i].bytes, log->sizes[i].units))
			guc_err(guc, "Mis-aligned log %s size: 0x%X vs 0x%X!\n",
				sections[i].name, log->sizes[i].bytes, log->sizes[i].units);
		log->sizes[i].count = log->sizes[i].bytes / log->sizes[i].units;

		if (!log->sizes[i].count) {
			guc_err(guc, "Zero log %s size!\n", sections[i].name);
		} else {
			/* Size is +1 unit */
			log->sizes[i].count--;
		}

		/* Clip to field size */
		if (log->sizes[i].count > sections[i].max) {
			guc_err(guc, "log %s size too large: %d vs %d!\n",
				sections[i].name, log->sizes[i].count + 1, sections[i].max + 1);
			log->sizes[i].count = sections[i].max;
		}
	}

	if (log->sizes[GUC_LOG_SECTIONS_CRASH].units != log->sizes[GUC_LOG_SECTIONS_DEBUG].units) {
		guc_err(guc, "Unit mismatch for crash and debug sections: %d vs %d!\n",
			log->sizes[GUC_LOG_SECTIONS_CRASH].units,
			log->sizes[GUC_LOG_SECTIONS_DEBUG].units);
		log->sizes[GUC_LOG_SECTIONS_CRASH].units = log->sizes[GUC_LOG_SECTIONS_DEBUG].units;
		log->sizes[GUC_LOG_SECTIONS_CRASH].count = 0;
	}

	log->sizes_initialised = true;
}

static void guc_log_init_sizes(struct intel_guc_log *log)
{
	if (log->sizes_initialised)
		return;

	_guc_log_init_sizes(log);
}

Annotation

Implementation Notes