Lines Matching +full:block +full:- +full:size

7  * Copyright (c) 2003-2008 Cavium Networks
14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37 #include <asm/octeon/cvmx-spinlock.h>
38 #include <asm/octeon/cvmx-bootmem.h>
71 * @param size Size of the structure member.
76 int size) in __cvmx_bootmem_desc_get() argument
79 switch (size) { in __cvmx_bootmem_desc_get()
90 * Wrapper functions are provided for reading/writing the size and
91 * next block values as these may not be directly addressible (in 32
98 static void cvmx_bootmem_phy_set_size(uint64_t addr, uint64_t size) in cvmx_bootmem_phy_set_size() argument
100 cvmx_write64_uint64((addr + SIZE_OFFSET) | (1ull << 63), size); in cvmx_bootmem_phy_set_size()
119 * Allocate a block of memory from the free list that was
121 * address range. This is an allocate-only algorithm, so
125 * @size: Size in bytes of block to allocate
128 * @alignment: Alignment required - must be power of 2
129 * Returns pointer to block of memory, NULL on error
131 static void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment, in cvmx_bootmem_alloc_range() argument
136 cvmx_bootmem_phy_alloc(size, min_addr, max_addr, alignment, 0); in cvmx_bootmem_alloc_range()
144 void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address, in cvmx_bootmem_alloc_address() argument
147 return cvmx_bootmem_alloc_range(size, alignment, address, in cvmx_bootmem_alloc_address()
148 address + size); in cvmx_bootmem_alloc_address()
151 void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, in cvmx_bootmem_alloc_named_range() argument
157 addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, in cvmx_bootmem_alloc_named_range()
165 void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name) in cvmx_bootmem_alloc_named() argument
167 return cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name); in cvmx_bootmem_alloc_named()
173 cvmx_spinlock_lock((cvmx_spinlock_t *) &(cvmx_bootmem_desc->lock)); in cvmx_bootmem_lock()
178 cvmx_spinlock_unlock((cvmx_spinlock_t *) &(cvmx_bootmem_desc->lock)); in cvmx_bootmem_unlock()
184 * block. This pointer will be used directly, so we will set in cvmx_bootmem_init()
193 * Note that the CVMX environment assumes the use of 1-1 TLB in cvmx_bootmem_init()
238 if (cvmx_bootmem_desc->major_version > 3) { in cvmx_bootmem_phy_alloc()
241 (int)cvmx_bootmem_desc->major_version, in cvmx_bootmem_phy_alloc()
242 (int)cvmx_bootmem_desc->minor_version, in cvmx_bootmem_phy_alloc()
251 * not self-contradictory before we look through the list of in cvmx_bootmem_phy_alloc()
260 req_size = (req_size + (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1)) & in cvmx_bootmem_phy_alloc()
261 ~(CVMX_BOOTMEM_ALIGNMENT_SIZE - 1); in cvmx_bootmem_phy_alloc()
265 * range that specifies an exact memory block to allocate. Do in cvmx_bootmem_phy_alloc()
276 * Enforce minimum alignment (this also keeps the minimum free block in cvmx_bootmem_phy_alloc()
295 if (req_size > address_max - address_min) in cvmx_bootmem_phy_alloc()
298 /* Walk through the list entries - first fit found is returned */ in cvmx_bootmem_phy_alloc()
302 head_addr = cvmx_bootmem_desc->head_addr; in cvmx_bootmem_phy_alloc()
329 * We should be able to allocate block at address in cvmx_bootmem_phy_alloc()
340 && req_size <= usable_max - usable_base)) in cvmx_bootmem_phy_alloc()
346 * the end of this block rather than the beginning. in cvmx_bootmem_phy_alloc()
349 desired_min_addr = usable_max - req_size; in cvmx_bootmem_phy_alloc()
354 desired_min_addr &= ~(alignment - 1); in cvmx_bootmem_phy_alloc()
361 * big enough to create a new block in cvmx_bootmem_phy_alloc()
362 * from top portion of block. in cvmx_bootmem_phy_alloc()
368 ent_size - in cvmx_bootmem_phy_alloc()
391 cvmx_bootmem_desc->head_addr = in cvmx_bootmem_phy_alloc()
399 * block returned doesn't start at beginning of entry, in cvmx_bootmem_phy_alloc()
400 * so we know that we will be splitting a block off in cvmx_bootmem_phy_alloc()
401 * the front of this one. Create a new block from the in cvmx_bootmem_phy_alloc()
405 * create new block from high portion of in cvmx_bootmem_phy_alloc()
406 * block, so that top block starts at desired in cvmx_bootmem_phy_alloc()
415 (ent_addr) - in cvmx_bootmem_phy_alloc()
416 (desired_min_addr - in cvmx_bootmem_phy_alloc()
419 desired_min_addr - ent_addr); in cvmx_bootmem_phy_alloc()
421 /* Loop again to handle actual alloc from new block */ in cvmx_bootmem_phy_alloc()
427 return -1; in cvmx_bootmem_phy_alloc()
430 int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags) in __cvmx_bootmem_phy_free() argument
437 cvmx_dprintf("__cvmx_bootmem_phy_free addr: 0x%llx, size: 0x%llx\n", in __cvmx_bootmem_phy_free()
438 (unsigned long long)phy_addr, (unsigned long long)size); in __cvmx_bootmem_phy_free()
440 if (cvmx_bootmem_desc->major_version > 3) { in __cvmx_bootmem_phy_free()
443 (int)cvmx_bootmem_desc->major_version, in __cvmx_bootmem_phy_free()
444 (int)cvmx_bootmem_desc->minor_version, in __cvmx_bootmem_phy_free()
449 /* 0 is not a valid size for this allocator */ in __cvmx_bootmem_phy_free()
450 if (!size) in __cvmx_bootmem_phy_free()
455 cur_addr = cvmx_bootmem_desc->head_addr; in __cvmx_bootmem_phy_free()
457 /* add at front of list - special case with changing head ptr */ in __cvmx_bootmem_phy_free()
458 if (cur_addr && phy_addr + size > cur_addr) in __cvmx_bootmem_phy_free()
460 else if (phy_addr + size == cur_addr) { in __cvmx_bootmem_phy_free()
461 /* Add to front of existing first block */ in __cvmx_bootmem_phy_free()
467 (cur_addr) + size); in __cvmx_bootmem_phy_free()
468 cvmx_bootmem_desc->head_addr = phy_addr; in __cvmx_bootmem_phy_free()
471 /* New block before first block. OK if cur_addr is 0 */ in __cvmx_bootmem_phy_free()
473 cvmx_bootmem_phy_set_size(phy_addr, size); in __cvmx_bootmem_phy_free()
474 cvmx_bootmem_desc->head_addr = phy_addr; in __cvmx_bootmem_phy_free()
480 /* Find place in list to add block */ in __cvmx_bootmem_phy_free()
490 * block in __cvmx_bootmem_phy_free()
496 (prev_addr) + size); in __cvmx_bootmem_phy_free()
499 cvmx_bootmem_phy_set_size(phy_addr, size); in __cvmx_bootmem_phy_free()
514 (prev_addr) + size); in __cvmx_bootmem_phy_free()
515 if (phy_addr + size == cur_addr) { in __cvmx_bootmem_phy_free()
525 } else if (phy_addr + size == cur_addr) { in __cvmx_bootmem_phy_free()
529 (cur_addr) + size); in __cvmx_bootmem_phy_free()
538 /* It is a standalone block, add in between prev and cur */ in __cvmx_bootmem_phy_free()
539 cvmx_bootmem_phy_set_size(phy_addr, size); in __cvmx_bootmem_phy_free()
554 * Finds a named memory block by name.
555 * Also used for finding an unused entry in the named block table.
557 * @name: Name of memory block to find. If NULL pointer given, then
562 * Returns Pointer to memory block descriptor, NULL if not found.
564 * block descriptors are available.
584 cvmx_phys_to_ptr(cvmx_bootmem_desc->named_block_array_addr); in cvmx_bootmem_phy_named_block_find()
591 if (cvmx_bootmem_desc->major_version == 3) { in cvmx_bootmem_phy_named_block_find()
593 i < cvmx_bootmem_desc->named_block_num_blocks; i++) { in cvmx_bootmem_phy_named_block_find()
594 if ((name && named_block_array_ptr[i].size in cvmx_bootmem_phy_named_block_find()
596 cvmx_bootmem_desc->named_block_name_len in cvmx_bootmem_phy_named_block_find()
597 - 1)) in cvmx_bootmem_phy_named_block_find()
598 || (!name && !named_block_array_ptr[i].size)) { in cvmx_bootmem_phy_named_block_find()
608 (int)cvmx_bootmem_desc->major_version, in cvmx_bootmem_phy_named_block_find()
609 (int)cvmx_bootmem_desc->minor_version, in cvmx_bootmem_phy_named_block_find()
618 void *cvmx_bootmem_alloc_named_range_once(uint64_t size, uint64_t min_addr, in cvmx_bootmem_alloc_named_range_once() argument
637 addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, in cvmx_bootmem_alloc_named_range_once()
648 memset(ptr, 0, size); in cvmx_bootmem_alloc_named_range_once()
661 * Frees a named block.
663 * @name: name of block to free
673 if (cvmx_bootmem_desc->major_version != 3) { in cvmx_bootmem_phy_named_block_free()
676 (int)cvmx_bootmem_desc->major_version, in cvmx_bootmem_phy_named_block_free()
677 (int)cvmx_bootmem_desc->minor_version, in cvmx_bootmem_phy_named_block_free()
686 * Take lock here, as name lookup/block free/name free need to in cvmx_bootmem_phy_named_block_free()
697 "%s, base: 0x%llx, size: 0x%llx\n", in cvmx_bootmem_phy_named_block_free()
699 (unsigned long long)named_block_ptr->base_addr, in cvmx_bootmem_phy_named_block_free()
700 (unsigned long long)named_block_ptr->size); in cvmx_bootmem_phy_named_block_free()
702 __cvmx_bootmem_phy_free(named_block_ptr->base_addr, in cvmx_bootmem_phy_named_block_free()
703 named_block_ptr->size, in cvmx_bootmem_phy_named_block_free()
705 named_block_ptr->size = 0; in cvmx_bootmem_phy_named_block_free()
706 /* Set size to zero to indicate block not used. */ in cvmx_bootmem_phy_named_block_free()
718 int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, in cvmx_bootmem_phy_named_block_alloc() argument
728 cvmx_dprintf("cvmx_bootmem_phy_named_block_alloc: size: 0x%llx, min: " in cvmx_bootmem_phy_named_block_alloc()
730 (unsigned long long)size, in cvmx_bootmem_phy_named_block_alloc()
736 if (cvmx_bootmem_desc->major_version != 3) { in cvmx_bootmem_phy_named_block_alloc()
739 (int)cvmx_bootmem_desc->major_version, in cvmx_bootmem_phy_named_block_alloc()
740 (int)cvmx_bootmem_desc->minor_version, in cvmx_bootmem_phy_named_block_alloc()
742 return -1; in cvmx_bootmem_phy_named_block_alloc()
746 * Take lock here, as name lookup/block alloc/name add need to in cvmx_bootmem_phy_named_block_alloc()
750 cvmx_spinlock_lock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock)); in cvmx_bootmem_phy_named_block_alloc()
752 /* Get pointer to first available named block descriptor */ in cvmx_bootmem_phy_named_block_alloc()
764 cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock)); in cvmx_bootmem_phy_named_block_alloc()
765 return -1; in cvmx_bootmem_phy_named_block_alloc()
770 * Round size up to mult of minimum alignment bytes We need in cvmx_bootmem_phy_named_block_alloc()
771 * the actual size allocated to allow for blocks to be in cvmx_bootmem_phy_named_block_alloc()
775 size = ALIGN(size, CVMX_BOOTMEM_ALIGNMENT_SIZE); in cvmx_bootmem_phy_named_block_alloc()
777 addr_allocated = cvmx_bootmem_phy_alloc(size, min_addr, max_addr, in cvmx_bootmem_phy_named_block_alloc()
781 named_block_desc_ptr->base_addr = addr_allocated; in cvmx_bootmem_phy_named_block_alloc()
782 named_block_desc_ptr->size = size; in cvmx_bootmem_phy_named_block_alloc()
783 strscpy(named_block_desc_ptr->name, name, in cvmx_bootmem_phy_named_block_alloc()
784 cvmx_bootmem_desc->named_block_name_len); in cvmx_bootmem_phy_named_block_alloc()
788 cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock)); in cvmx_bootmem_phy_named_block_alloc()