Пример #1
0
static int validate_entries(struct cbmem_root *root)
{
	unsigned int i;
	u32 current_end;

	current_end = (u32)get_top_aligned();

	printk(BIOS_DEBUG, "CBMEM: recovering %d/%d entries from root @ %p\n",
	       root->num_entries, root->max_entries, root);

	/* Check that all regions are properly aligned and are just below
	 * the previous entry */
	for (i = 0; i < root->num_entries; i++) {
		struct cbmem_entry *entry = &root->entries[i];

		if (entry->magic != CBMEM_ENTRY_MAGIC)
			return -1;

		if (entry->start & (DYN_CBMEM_ALIGN_SIZE - 1))
			return -1;

		if (entry->start + entry->size != current_end)
			return -1;

		current_end = entry->start;
	}

	return 0;
}
Пример #2
0
void cbmem_add_lb_mem(struct lb_memory *mem)
{
	unsigned long base;
	unsigned long top;

	base = (unsigned long)cbmem_base();
	top = (unsigned long)get_top_aligned();
	lb_add_memory_range(mem, LB_MEM_TABLE, base, top - base);
}
Пример #3
0
void cbmem_add_bootmem(void)
{
	uintptr_t base;
	uintptr_t top;

	base = cbmem_base();
	top = get_top_aligned();
	bootmem_add_range(base, top - base, LB_MEM_TABLE);
}
Пример #4
0
static inline void *get_root(void)
{
	unsigned long pointer_addr;
	struct cbmem_root_pointer *pointer;

	pointer_addr = (unsigned long)get_top_aligned();
	pointer_addr -= sizeof(struct cbmem_root_pointer);

	pointer = (void *)pointer_addr;
	if (pointer->magic != CBMEM_POINTER_MAGIC)
		return NULL;

	return (void *)pointer->root;
}
Пример #5
0
static inline void *get_root(void)
{
	uintptr_t pointer_addr;
	struct cbmem_root_pointer *pointer;

	pointer_addr = get_top_aligned();
	if (pointer_addr == 0)
		return NULL;

	pointer_addr -= sizeof(struct cbmem_root_pointer);

	pointer = (void *)pointer_addr;
	if (pointer->magic != CBMEM_POINTER_MAGIC)
		return NULL;

	pointer_addr = pointer->root;
	return (void *)pointer_addr;
}
Пример #6
0
void cbmem_initialize_empty(void)
{
	uintptr_t pointer_addr;
	uintptr_t root_addr;
	unsigned long max_entries;
	struct cbmem_root *root;
	struct cbmem_root_pointer *pointer;

	/* Place the root pointer and the root. The number of entries is
	 * dictated by difference between the root address and the pointer
	 * where the root address is aligned down to
	 * DYN_CBMEM_ALIGN_SIZE. The pointer falls just below the
	 * address returned by get_top_aligned(). */
	pointer_addr = get_top_aligned();
	if (pointer_addr == 0)
		return;

	root_addr = pointer_addr - ROOT_MIN_SIZE;
	root_addr &= ~(DYN_CBMEM_ALIGN_SIZE - 1);
	pointer_addr -= sizeof(struct cbmem_root_pointer);

	max_entries = (pointer_addr - (root_addr + sizeof(*root))) /
	              sizeof(struct cbmem_entry);

	pointer = (void *)pointer_addr;
	pointer->magic = CBMEM_POINTER_MAGIC;
	pointer->root = root_addr;

	root = (void *)root_addr;
	root->max_entries = max_entries;
	root->num_entries = 0;
	root->locked = 0;
	root->size = pointer_addr - root_addr +
	             sizeof(struct cbmem_root_pointer);

	/* Add an entry covering the root region. */
	cbmem_entry_append(root, CBMEM_ID_ROOT, root_addr, root->size);

	printk(BIOS_DEBUG, "CBMEM: root @ %p %d entries.\n",
	       root, root->max_entries);

	/* Complete migration to CBMEM. */
	cbmem_run_init_hooks();
}
Пример #7
0
int cbmem_initialize(void)
{
	struct cbmem_root *root;
	void *top_according_to_root;

	root = get_root();

	/* No recovery possible since root couldn't be recovered. */
	if (root == NULL)
		return cbmem_fail_recovery();

	/* Sanity check the root. */
	top_according_to_root = (void *)(root->size + (unsigned long)root);
	if (get_top_aligned() != top_according_to_root)
		return cbmem_fail_recovery();

	if (root->num_entries > root->max_entries)
		return cbmem_fail_recovery();

	if ((root->max_entries * sizeof(struct cbmem_entry)) >
	    (root->size - sizeof(struct cbmem_root_pointer) - sizeof(*root)))
		return cbmem_fail_recovery();

	/* Validate current entries. */
	if (validate_entries(root))
		return cbmem_fail_recovery();

#if defined(__PRE_RAM__)
	/* Lock the root in the romstage on a recovery. The assumption is that
	 * recovery is called during romstage on the S3 resume path. */
	root->locked = 1;
#endif

	cbmem_arch_init();

	/* Migrate cache-as-ram variables. */
	car_migrate_variables();

	/* Recovery successful. */
	return 0;
}
Пример #8
0
int cbmem_initialize(void)
{
	struct cbmem_root *root;
	uintptr_t top_according_to_root;

	root = get_root();

	/* No recovery possible since root couldn't be recovered. */
	if (root == NULL)
		return cbmem_fail_recovery();

	/* Sanity check the root. */
	top_according_to_root = (root->size + (uintptr_t)root);
	if (get_top_aligned() != top_according_to_root)
		return cbmem_fail_recovery();

	if (root->num_entries > root->max_entries)
		return cbmem_fail_recovery();

	if ((root->max_entries * sizeof(struct cbmem_entry)) >
	    (root->size - sizeof(struct cbmem_root_pointer) - sizeof(*root)))
		return cbmem_fail_recovery();

	/* Validate current entries. */
	if (validate_entries(root))
		return cbmem_fail_recovery();

#if defined(__PRE_RAM__)
	/* Lock the root in the romstage on a recovery. The assumption is that
	 * recovery is called during romstage on the S3 resume path. */
	root->locked = 1;
#endif

	/* Complete migration to CBMEM. */
	cbmem_run_init_hooks();

	/* Recovery successful. */
	return 0;
}