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; }
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); }
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); }
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; }
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; }
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(); }
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; }
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; }