drivers/accel/ethosu/ethosu_gem.c

Source file repositories/reference/linux-study-clean/drivers/accel/ethosu/ethosu_gem.c

File Facts

System
Linux kernel
Corpus path
drivers/accel/ethosu/ethosu_gem.c
Extension
.c
Size
17840 bytes
Lines
728
Domain
Driver Families
Bucket
drivers/accel
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 dma {
	s8 region;
	u64 len;
	u64 offset;
	s64 stride[2];
};

struct dma_state {
	u16 size0;
	u16 size1;
	s8 mode;
	struct dma src;
	struct dma dst;
};

struct buffer {
	u64 base;
	u32 length;
	s8 region;
};

struct feat_matrix {
	u64 base[4];
	s64 stride_x;
	s64 stride_y;
	s64 stride_c;
	s8 region;
	u8 broadcast;
	u16 stride_kernel;
	u16 precision;
	u16 depth;
	u16 width;
	u16 width0;
	u16 height[3];
	u8 pad_top;
	u8 pad_left;
	u8 pad_bottom;
	u8 pad_right;
};

struct cmd_state {
	struct dma_state dma;
	struct buffer scale[2];
	struct buffer weight[4];
	struct feat_matrix ofm;
	struct feat_matrix ifm;
	struct feat_matrix ifm2;
};

static void cmd_state_init(struct cmd_state *st)
{
	/* Initialize to all 1s to detect missing setup */
	memset(st, 0xff, sizeof(*st));
}

static u64 cmd_to_addr(u32 *cmd)
{
	return (((u64)cmd[0] & 0xff0000) << 16) | cmd[1];
}

static u64 dma_length(struct ethosu_validated_cmdstream_info *info,
		      struct dma_state *dma_st, struct dma *dma)
{
	s8 mode = dma_st->mode;
	u64 len = dma->len;

	if (len == U64_MAX)
		return U64_MAX;

	if (mode >= 1) {
		if (dma->stride[0] < 0 && (u64)(-dma->stride[0]) > len)
			return U64_MAX;
		len += dma->stride[0];
		if (check_mul_overflow(len, (u64)dma_st->size0, &len))
			return U64_MAX;
	}
	if (mode == 2) {
		if (dma->stride[1] < 0 && (u64)(-dma->stride[1]) > len)
			return U64_MAX;
		len += dma->stride[1];
		if (check_mul_overflow(len, (u64)dma_st->size1, &len))
			return U64_MAX;
	}
	if (dma->region >= 0) {
		u64 end;

		if (check_add_overflow(len, dma->offset, &end))
			return U64_MAX;
		info->region_size[dma->region] = max(info->region_size[dma->region], end);
	}

Annotation

Implementation Notes