drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_cmd.c
Extension
.c
Size
9025 bytes
Lines
288
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

if (amdgpu_ras_mgr_check_retired_addr(adev, req->address)) {
			RAS_DEV_WARN(ras_core->dev,
				"RAS WARN: inject: 0x%llx has already been marked as bad!\n",
				req->address);
			return RAS_CMD__ERROR_ACCESS_DENIED;
		}

		if ((req->address >= adev->gmc.mc_vram_size &&
			adev->gmc.mc_vram_size) ||
			(req->address >= RAS_UMC_INJECT_ADDR_LIMIT)) {
			RAS_DEV_WARN(adev, "RAS WARN: input address 0x%llx is invalid.",
					req->address);
			return RAS_CMD__ERROR_INVALID_INPUT_DATA;
		}

		/* Calculate XGMI relative offset */
		if (adev->gmc.xgmi.num_physical_nodes > 1 &&
			req->block_id != RAS_BLOCK_ID__GFX) {
			req->address = local_addr_to_xgmi_global_addr(ras_core, req->address);
		}
	}

	amdgpu_ras_trigger_error_prepare(ras_core, req);
	ret = rascore_handle_cmd(ras_core, cmd, data);
	amdgpu_ras_trigger_error_end(ras_core, req);

	return ret;
}

static int amdgpu_ras_get_ras_safe_fb_addr_ranges(struct ras_core_context *ras_core,
	struct ras_cmd_ctx *cmd, void *data)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)ras_core->dev;
	struct ras_cmd_dev_handle *input_data =
			(struct ras_cmd_dev_handle *)cmd->input_buff_raw;
	struct ras_cmd_ras_safe_fb_address_ranges_rsp *ranges =
			(struct ras_cmd_ras_safe_fb_address_ranges_rsp *)cmd->output_buff_raw;
	struct amdgpu_mem_partition_info *mem_ranges;
	uint32_t i = 0;

	if ((cmd->input_size != sizeof(*input_data)) ||
		(cmd->output_buf_size < sizeof(*ranges)))
		return RAS_CMD__ERROR_INVALID_INPUT_DATA;

	mem_ranges = adev->gmc.mem_partitions;
	for (i = 0; i < adev->gmc.num_mem_partitions; i++) {
		ranges->range[i].start = mem_ranges[i].range.fpfn << AMDGPU_GPU_PAGE_SHIFT;
		ranges->range[i].size = mem_ranges[i].size;
		ranges->range[i].idx = i;
	}

	ranges->num_ranges = adev->gmc.num_mem_partitions;

	ranges->version = 0;
	cmd->output_size = sizeof(struct ras_cmd_ras_safe_fb_address_ranges_rsp);

	return RAS_CMD__SUCCESS;
}

static int ras_translate_fb_address(struct ras_core_context *ras_core,
		enum ras_fb_addr_type src_type,
		enum ras_fb_addr_type dest_type,
		union ras_translate_fb_address *src_addr,
		union ras_translate_fb_address *dest_addr)
{
	uint64_t soc_phy_addr;
	int ret = RAS_CMD__SUCCESS;

	/* Does not need to be queued as event as this is a SW translation */
	switch (src_type) {
	case RAS_FB_ADDR_SOC_PHY:
		soc_phy_addr = src_addr->soc_phy_addr;
		break;
	case RAS_FB_ADDR_BANK:
		ret = ras_cmd_translate_bank_to_soc_pa(ras_core,
					src_addr->bank_addr, &soc_phy_addr);
		if (ret)
			return RAS_CMD__ERROR_GENERIC;
		break;
	default:
		return RAS_CMD__ERROR_INVALID_CMD;
	}

	switch (dest_type) {
	case RAS_FB_ADDR_SOC_PHY:
		dest_addr->soc_phy_addr = soc_phy_addr;
		break;
	case RAS_FB_ADDR_BANK:
		ret = ras_cmd_translate_soc_pa_to_bank(ras_core,
				soc_phy_addr, &dest_addr->bank_addr);

Annotation

Implementation Notes