| 98 | } |
| 99 | |
| 100 | static int imdr_create_empty(struct imdr *imdr, size_t root_size, |
| 101 | size_t entry_align) |
| 102 | { |
| 103 | struct imd_root_pointer *rp; |
| 104 | struct imd_root *r; |
| 105 | struct imd_entry *e; |
| 106 | ssize_t root_offset; |
| 107 | |
| 108 | if (!imdr->limit) |
| 109 | return -1; |
| 110 | |
| 111 | /* root_size and entry_align should be a power of 2. */ |
| 112 | assert(IS_POWER_OF_2(root_size)); |
| 113 | assert(IS_POWER_OF_2(entry_align)); |
| 114 | |
| 115 | /* |
| 116 | * root_size needs to be large enough to accommodate root pointer and |
| 117 | * root book keeping structure. Furthermore, there needs to be a space |
| 118 | * for at least one entry covering root region. The caller needs to |
| 119 | * ensure there's enough room for tracking individual allocations. |
| 120 | */ |
| 121 | if (root_size < (sizeof(*rp) + sizeof(*r) + sizeof(*e))) |
| 122 | return -1; |
| 123 | |
| 124 | /* For simplicity don't allow sizes or alignments to exceed LIMIT_ALIGN. |
| 125 | */ |
| 126 | if (root_size > LIMIT_ALIGN || entry_align > LIMIT_ALIGN) |
| 127 | return -1; |
| 128 | |
| 129 | /* Additionally, don't handle an entry alignment > root_size. */ |
| 130 | if (entry_align > root_size) |
| 131 | return -1; |
| 132 | |
| 133 | rp = imdr_get_root_pointer(imdr); |
| 134 | |
| 135 | root_offset = -(ssize_t)root_size; |
| 136 | /* Set root pointer. */ |
| 137 | imdr->r = relative_pointer((void *)imdr->limit, root_offset); |
| 138 | r = imdr_root(imdr); |
| 139 | imd_link_root(rp, r); |
| 140 | |
| 141 | memset(r, 0, sizeof(*r)); |
| 142 | r->entry_align = entry_align; |
| 143 | |
| 144 | /* Calculate size left for entries. */ |
| 145 | r->max_entries = root_num_entries(root_size); |
| 146 | |
| 147 | /* Fill in first entry covering the root region. */ |
| 148 | r->num_entries = 1; |
| 149 | e = &r->entries[0]; |
| 150 | imd_entry_assign(e, CBMEM_ID_IMD_ROOT, 0, root_size); |
| 151 | |
| 152 | printk(BIOS_DEBUG, "IMD: root @ %p %u entries.\n", r, r->max_entries); |
| 153 | |
| 154 | return 0; |
| 155 | } |
| 156 | |
| 157 | static int imdr_recover(struct imdr *imdr) |
no test coverage detected