arch/mips/generic/yamon-dt.c

Source file repositories/reference/linux-study-clean/arch/mips/generic/yamon-dt.c

File Facts

System
Linux kernel
Corpus path
arch/mips/generic/yamon-dt.c
Extension
.c
Size
5751 bytes
Lines
233
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (entries >= max_entries) {
			pr_warn("Number of regions exceeds max %u\n",
				max_entries);
			break;
		}

		/* How much of the remaining RAM fits in the next region? */
		size = min_t(unsigned long, memsize, mr->size);
		memsize -= size;

		/* Emit a memory region */
		*(mem_array++) = cpu_to_be32(mr->start);
		*(mem_array++) = cpu_to_be32(size);
		++entries;

		/* Discard the next mr->discard bytes */
		memsize -= min_t(unsigned long, memsize, mr->discard);
	}
	return entries;
}

__init int yamon_dt_append_memory(void *fdt,
				  const struct yamon_mem_region *regions)
{
	unsigned long phys_memsize = 0, memsize;
	__be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES];
	unsigned int mem_entries;
	int i, err, mem_off;
	char *var, param_name[10], *var_names[] = {
		"ememsize", "memsize",
	};

	/* find memory size from the bootloader environment */
	for (i = 0; i < ARRAY_SIZE(var_names); i++) {
		var = fw_getenv(var_names[i]);
		if (!var)
			continue;

		err = kstrtoul(var, 0, &phys_memsize);
		if (!err)
			break;

		pr_warn("Failed to read the '%s' env variable '%s'\n",
			var_names[i], var);
	}

	if (!phys_memsize) {
		pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n");
		phys_memsize = 32 << 20;
	}

	/* default to using all available RAM */
	memsize = phys_memsize;

	/* allow the user to override the usable memory */
	for (i = 0; i < ARRAY_SIZE(var_names); i++) {
		snprintf(param_name, sizeof(param_name), "%s=", var_names[i]);
		var = strstr(arcs_cmdline, param_name);
		if (!var)
			continue;

		memsize = memparse(var + strlen(param_name), NULL);
	}

	/* if the user says there's more RAM than we thought, believe them */
	phys_memsize = max_t(unsigned long, phys_memsize, memsize);

	/* find or add a memory node */
	mem_off = fdt_path_offset(fdt, "/memory");
	if (mem_off == -FDT_ERR_NOTFOUND)
		mem_off = fdt_add_subnode(fdt, 0, "memory");
	if (mem_off < 0) {
		pr_err("Unable to find or add memory DT node: %d\n", mem_off);
		return mem_off;
	}

	err = fdt_setprop_string(fdt, mem_off, "device_type", "memory");
	if (err) {
		pr_err("Unable to set memory node device_type: %d\n", err);
		return err;
	}

	mem_entries = gen_fdt_mem_array(regions, mem_array,
					MAX_MEM_ARRAY_ENTRIES, phys_memsize);
	err = fdt_setprop(fdt, mem_off, "reg",
			  mem_array, mem_entries * 2 * sizeof(mem_array[0]));
	if (err) {
		pr_err("Unable to set memory regs property: %d\n", err);
		return err;
	}

Annotation

Implementation Notes