.. | .. |
---|
45 | 45 | /* See header file for descriptions of functions */ |
---|
46 | 46 | |
---|
47 | 47 | /** |
---|
48 | | - * This macro returns the size of a member of a structure. |
---|
49 | | - * Logically it is the same as "sizeof(s::field)" in C++, but |
---|
50 | | - * C lacks the "::" operator. |
---|
51 | | - */ |
---|
52 | | -#define SIZEOF_FIELD(s, field) sizeof(((s *)NULL)->field) |
---|
53 | | - |
---|
54 | | -/** |
---|
55 | 48 | * This macro returns a member of the |
---|
56 | 49 | * cvmx_bootmem_named_block_desc_t structure. These members can't |
---|
57 | 50 | * be directly addressed as they might be in memory not directly |
---|
.. | .. |
---|
65 | 58 | #define CVMX_BOOTMEM_NAMED_GET_FIELD(addr, field) \ |
---|
66 | 59 | __cvmx_bootmem_desc_get(addr, \ |
---|
67 | 60 | offsetof(struct cvmx_bootmem_named_block_desc, field), \ |
---|
68 | | - SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc, field)) |
---|
| 61 | + sizeof_field(struct cvmx_bootmem_named_block_desc, field)) |
---|
69 | 62 | |
---|
70 | 63 | /** |
---|
71 | 64 | * This function is the implementation of the get macros defined |
---|
.. | .. |
---|
122 | 115 | return cvmx_read64_uint64((addr + NEXT_OFFSET) | (1ull << 63)); |
---|
123 | 116 | } |
---|
124 | 117 | |
---|
125 | | -void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment, |
---|
126 | | - uint64_t min_addr, uint64_t max_addr) |
---|
| 118 | +/** |
---|
| 119 | + * Allocate a block of memory from the free list that was |
---|
| 120 | + * passed to the application by the bootloader within a specified |
---|
| 121 | + * address range. This is an allocate-only algorithm, so |
---|
| 122 | + * freeing memory is not possible. Allocation will fail if |
---|
| 123 | + * memory cannot be allocated in the requested range. |
---|
| 124 | + * |
---|
| 125 | + * @size: Size in bytes of block to allocate |
---|
| 126 | + * @min_addr: defines the minimum address of the range |
---|
| 127 | + * @max_addr: defines the maximum address of the range |
---|
| 128 | + * @alignment: Alignment required - must be power of 2 |
---|
| 129 | + * Returns pointer to block of memory, NULL on error |
---|
| 130 | + */ |
---|
| 131 | +static void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment, |
---|
| 132 | + uint64_t min_addr, uint64_t max_addr) |
---|
127 | 133 | { |
---|
128 | 134 | int64_t address; |
---|
129 | 135 | address = |
---|
.. | .. |
---|
142 | 148 | address + size); |
---|
143 | 149 | } |
---|
144 | 150 | |
---|
145 | | -void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment) |
---|
146 | | -{ |
---|
147 | | - return cvmx_bootmem_alloc_range(size, alignment, 0, 0); |
---|
148 | | -} |
---|
149 | | - |
---|
150 | | -void *cvmx_bootmem_alloc_named_range_once(uint64_t size, uint64_t min_addr, |
---|
151 | | - uint64_t max_addr, uint64_t align, |
---|
152 | | - char *name, |
---|
153 | | - void (*init) (void *)) |
---|
154 | | -{ |
---|
155 | | - int64_t addr; |
---|
156 | | - void *ptr; |
---|
157 | | - uint64_t named_block_desc_addr; |
---|
158 | | - |
---|
159 | | - named_block_desc_addr = (uint64_t) |
---|
160 | | - cvmx_bootmem_phy_named_block_find(name, |
---|
161 | | - (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING); |
---|
162 | | - |
---|
163 | | - if (named_block_desc_addr) { |
---|
164 | | - addr = CVMX_BOOTMEM_NAMED_GET_FIELD(named_block_desc_addr, |
---|
165 | | - base_addr); |
---|
166 | | - return cvmx_phys_to_ptr(addr); |
---|
167 | | - } |
---|
168 | | - |
---|
169 | | - addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, |
---|
170 | | - align, name, |
---|
171 | | - (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING); |
---|
172 | | - |
---|
173 | | - if (addr < 0) |
---|
174 | | - return NULL; |
---|
175 | | - ptr = cvmx_phys_to_ptr(addr); |
---|
176 | | - |
---|
177 | | - if (init) |
---|
178 | | - init(ptr); |
---|
179 | | - else |
---|
180 | | - memset(ptr, 0, size); |
---|
181 | | - |
---|
182 | | - return ptr; |
---|
183 | | -} |
---|
184 | | -EXPORT_SYMBOL(cvmx_bootmem_alloc_named_range_once); |
---|
185 | | - |
---|
186 | 151 | void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, |
---|
187 | 152 | uint64_t max_addr, uint64_t align, |
---|
188 | 153 | char *name) |
---|
.. | .. |
---|
197 | 162 | return NULL; |
---|
198 | 163 | } |
---|
199 | 164 | |
---|
200 | | -void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, |
---|
201 | | - char *name) |
---|
202 | | -{ |
---|
203 | | - return cvmx_bootmem_alloc_named_range(size, address, address + size, |
---|
204 | | - 0, name); |
---|
205 | | -} |
---|
206 | | - |
---|
207 | 165 | void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name) |
---|
208 | 166 | { |
---|
209 | 167 | return cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name); |
---|
210 | 168 | } |
---|
211 | 169 | EXPORT_SYMBOL(cvmx_bootmem_alloc_named); |
---|
212 | | - |
---|
213 | | -int cvmx_bootmem_free_named(char *name) |
---|
214 | | -{ |
---|
215 | | - return cvmx_bootmem_phy_named_block_free(name, 0); |
---|
216 | | -} |
---|
217 | | - |
---|
218 | | -struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name) |
---|
219 | | -{ |
---|
220 | | - return cvmx_bootmem_phy_named_block_find(name, 0); |
---|
221 | | -} |
---|
222 | | -EXPORT_SYMBOL(cvmx_bootmem_find_named_block); |
---|
223 | 170 | |
---|
224 | 171 | void cvmx_bootmem_lock(void) |
---|
225 | 172 | { |
---|
.. | .. |
---|
603 | 550 | |
---|
604 | 551 | } |
---|
605 | 552 | |
---|
606 | | -struct cvmx_bootmem_named_block_desc * |
---|
| 553 | +/** |
---|
| 554 | + * Finds a named memory block by name. |
---|
| 555 | + * Also used for finding an unused entry in the named block table. |
---|
| 556 | + * |
---|
| 557 | + * @name: Name of memory block to find. If NULL pointer given, then |
---|
| 558 | + * finds unused descriptor, if available. |
---|
| 559 | + * |
---|
| 560 | + * @flags: Flags to control options for the allocation. |
---|
| 561 | + * |
---|
| 562 | + * Returns Pointer to memory block descriptor, NULL if not found. |
---|
| 563 | + * If NULL returned when name parameter is NULL, then no memory |
---|
| 564 | + * block descriptors are available. |
---|
| 565 | + */ |
---|
| 566 | +static struct cvmx_bootmem_named_block_desc * |
---|
607 | 567 | cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags) |
---|
608 | 568 | { |
---|
609 | 569 | unsigned int i; |
---|
.. | .. |
---|
655 | 615 | return NULL; |
---|
656 | 616 | } |
---|
657 | 617 | |
---|
658 | | -int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags) |
---|
| 618 | +void *cvmx_bootmem_alloc_named_range_once(uint64_t size, uint64_t min_addr, |
---|
| 619 | + uint64_t max_addr, uint64_t align, |
---|
| 620 | + char *name, |
---|
| 621 | + void (*init) (void *)) |
---|
| 622 | +{ |
---|
| 623 | + int64_t addr; |
---|
| 624 | + void *ptr; |
---|
| 625 | + uint64_t named_block_desc_addr; |
---|
| 626 | + |
---|
| 627 | + named_block_desc_addr = (uint64_t) |
---|
| 628 | + cvmx_bootmem_phy_named_block_find(name, |
---|
| 629 | + (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING); |
---|
| 630 | + |
---|
| 631 | + if (named_block_desc_addr) { |
---|
| 632 | + addr = CVMX_BOOTMEM_NAMED_GET_FIELD(named_block_desc_addr, |
---|
| 633 | + base_addr); |
---|
| 634 | + return cvmx_phys_to_ptr(addr); |
---|
| 635 | + } |
---|
| 636 | + |
---|
| 637 | + addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, |
---|
| 638 | + align, name, |
---|
| 639 | + (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING); |
---|
| 640 | + |
---|
| 641 | + if (addr < 0) |
---|
| 642 | + return NULL; |
---|
| 643 | + ptr = cvmx_phys_to_ptr(addr); |
---|
| 644 | + |
---|
| 645 | + if (init) |
---|
| 646 | + init(ptr); |
---|
| 647 | + else |
---|
| 648 | + memset(ptr, 0, size); |
---|
| 649 | + |
---|
| 650 | + return ptr; |
---|
| 651 | +} |
---|
| 652 | +EXPORT_SYMBOL(cvmx_bootmem_alloc_named_range_once); |
---|
| 653 | + |
---|
| 654 | +struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name) |
---|
| 655 | +{ |
---|
| 656 | + return cvmx_bootmem_phy_named_block_find(name, 0); |
---|
| 657 | +} |
---|
| 658 | +EXPORT_SYMBOL(cvmx_bootmem_find_named_block); |
---|
| 659 | + |
---|
| 660 | +/** |
---|
| 661 | + * Frees a named block. |
---|
| 662 | + * |
---|
| 663 | + * @name: name of block to free |
---|
| 664 | + * @flags: flags for passing options |
---|
| 665 | + * |
---|
| 666 | + * Returns 0 on failure |
---|
| 667 | + * 1 on success |
---|
| 668 | + */ |
---|
| 669 | +static int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags) |
---|
659 | 670 | { |
---|
660 | 671 | struct cvmx_bootmem_named_block_desc *named_block_ptr; |
---|
661 | 672 | |
---|
.. | .. |
---|
699 | 710 | return named_block_ptr != NULL; /* 0 on failure, 1 on success */ |
---|
700 | 711 | } |
---|
701 | 712 | |
---|
| 713 | +int cvmx_bootmem_free_named(char *name) |
---|
| 714 | +{ |
---|
| 715 | + return cvmx_bootmem_phy_named_block_free(name, 0); |
---|
| 716 | +} |
---|
| 717 | + |
---|
702 | 718 | int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, |
---|
703 | 719 | uint64_t max_addr, |
---|
704 | 720 | uint64_t alignment, |
---|