drivers/firmware/memmap.c

Source file repositories/reference/linux-study-clean/drivers/firmware/memmap.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/memmap.c
Extension
.c
Size
11916 bytes
Lines
420
Domain
Driver Families
Bucket
drivers/firmware
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 firmware_map_entry {
	/*
	 * start and end must be u64 rather than resource_size_t, because e820
	 * resources can lie at addresses above 4G.
	 */
	u64			start;	/* start of the memory range */
	u64			end;	/* end of the memory range (incl.) */
	const char		*type;	/* type of the memory range */
	struct list_head	list;	/* entry for the linked list */
	struct kobject		kobj;   /* kobject for each entry */
};

/*
 * Forward declarations --------------------------------------------------------
 */
static ssize_t memmap_attr_show(struct kobject *kobj,
				struct attribute *attr, char *buf);
static ssize_t start_show(struct firmware_map_entry *entry, char *buf);
static ssize_t end_show(struct firmware_map_entry *entry, char *buf);
static ssize_t type_show(struct firmware_map_entry *entry, char *buf);

static struct firmware_map_entry * __meminit
firmware_map_find_entry(u64 start, u64 end, const char *type);

/*
 * Static data -----------------------------------------------------------------
 */

struct memmap_attribute {
	struct attribute attr;
	ssize_t (*show)(struct firmware_map_entry *entry, char *buf);
};

static struct memmap_attribute memmap_start_attr = __ATTR_RO(start);
static struct memmap_attribute memmap_end_attr   = __ATTR_RO(end);
static struct memmap_attribute memmap_type_attr  = __ATTR_RO(type);

/*
 * These are default attributes that are added for every memmap entry.
 */
static struct attribute *def_attrs[] = {
	&memmap_start_attr.attr,
	&memmap_end_attr.attr,
	&memmap_type_attr.attr,
	NULL
};
ATTRIBUTE_GROUPS(def);

static const struct sysfs_ops memmap_attr_ops = {
	.show = memmap_attr_show,
};

/* Firmware memory map entries. */
static LIST_HEAD(map_entries);
static DEFINE_SPINLOCK(map_entries_lock);

/*
 * For memory hotplug, there is no way to free memory map entries allocated
 * by boot mem after the system is up. So when we hot-remove memory whose
 * map entry is allocated by bootmem, we need to remember the storage and
 * reuse it when the memory is hot-added again.
 */
static LIST_HEAD(map_entries_bootmem);
static DEFINE_SPINLOCK(map_entries_bootmem_lock);


static inline struct firmware_map_entry *
to_memmap_entry(struct kobject *kobj)
{
	return container_of(kobj, struct firmware_map_entry, kobj);
}

static void __meminit release_firmware_map_entry(struct kobject *kobj)
{
	struct firmware_map_entry *entry = to_memmap_entry(kobj);

	if (PageReserved(virt_to_page(entry))) {
		/*
		 * Remember the storage allocated by bootmem, and reuse it when
		 * the memory is hot-added again. The entry will be added to
		 * map_entries_bootmem here, and deleted from &map_entries in
		 * firmware_map_remove_entry().
		 */
		spin_lock(&map_entries_bootmem_lock);
		list_add(&entry->list, &map_entries_bootmem);
		spin_unlock(&map_entries_bootmem_lock);

		return;
	}

Annotation

Implementation Notes