drivers/acpi/prmt.c

Source file repositories/reference/linux-study-clean/drivers/acpi/prmt.c

File Facts

System
Linux kernel
Corpus path
drivers/acpi/prmt.c
Extension
.c
Size
11612 bytes
Lines
425
Domain
Driver Families
Bucket
drivers/acpi
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 prm_mmio_addr_range {
	u64 phys_addr;
	u64 virt_addr;
	u32 length;
};

struct prm_mmio_info {
	u64 mmio_count;
	struct prm_mmio_addr_range addr_ranges[];
};

struct prm_buffer {
	u8 prm_status;
	u64 efi_status;
	u8 prm_cmd;
	guid_t handler_guid;
};

struct prm_context_buffer {
	char signature[ACPI_NAMESEG_SIZE];
	u16 revision;
	u16 reserved;
	guid_t identifier;
	u64 static_data_buffer;
	struct prm_mmio_info *mmio_ranges;
};
#pragma pack()

static LIST_HEAD(prm_module_list);

struct prm_handler_info {
	efi_guid_t guid;
	efi_status_t (__efiapi *handler_addr)(u64, void *);
	u64 static_data_buffer_addr;
	u64 acpi_param_buffer_addr;

	struct list_head handler_list;
};

struct prm_module_info {
	guid_t guid;
	u16 major_rev;
	u16 minor_rev;
	u16 handler_count;
	struct prm_mmio_info *mmio_info;
	bool updatable;

	struct list_head module_list;
	struct prm_handler_info handlers[] __counted_by(handler_count);
};

static u64 efi_pa_va_lookup(efi_guid_t *guid, u64 pa)
{
	efi_memory_desc_t *md;
	u64 pa_offset = pa & ~PAGE_MASK;
	u64 page = pa & PAGE_MASK;

	for_each_efi_memory_desc(md) {
		if ((md->attribute & EFI_MEMORY_RUNTIME) &&
		    (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages)) {
			return pa_offset + md->virt_addr + page - md->phys_addr;
		}
	}

	return 0;
}

#define get_first_handler(a) ((struct acpi_prmt_handler_info *) ((char *) (a) + a->handler_info_offset))
#define get_next_handler(a) ((struct acpi_prmt_handler_info *) (sizeof(struct acpi_prmt_handler_info) + (char *) a))

static int __init
acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
{
	struct acpi_prmt_module_info *module_info;
	struct acpi_prmt_handler_info *handler_info;
	struct prm_handler_info *th;
	struct prm_module_info *tm;
	u64 *mmio_count;
	u64 cur_handler = 0;
	u32 module_info_size = 0;
	u64 mmio_range_size = 0;
	void *temp_mmio;

	module_info = (struct acpi_prmt_module_info *) header;
	module_info_size = struct_size(tm, handlers, module_info->handler_info_count);
	tm = kmalloc(module_info_size, GFP_KERNEL);
	if (!tm)
		goto parse_prmt_out1;

	guid_copy(&tm->guid, (guid_t *) module_info->module_guid);

Annotation

Implementation Notes