MIPS: Add named alloc functions to OCTEON boot monitor memory allocator.
The various Octeon ethernet drivers use these new functions. Signed-off-by: David Daney <ddaney@caviumnetworks.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
committed by
Ralf Baechle
parent
ce65cc8fe2
commit
6fa044ab8a
@@ -31,6 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include <asm/octeon/cvmx.h>
|
#include <asm/octeon/cvmx.h>
|
||||||
#include <asm/octeon/cvmx-spinlock.h>
|
#include <asm/octeon/cvmx-spinlock.h>
|
||||||
@@ -97,6 +98,33 @@ void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment)
|
|||||||
return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
|
return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
|
||||||
|
uint64_t max_addr, uint64_t align,
|
||||||
|
char *name)
|
||||||
|
{
|
||||||
|
int64_t addr;
|
||||||
|
|
||||||
|
addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr,
|
||||||
|
align, name, 0);
|
||||||
|
if (addr >= 0)
|
||||||
|
return cvmx_phys_to_ptr(addr);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
|
||||||
|
char *name)
|
||||||
|
{
|
||||||
|
return cvmx_bootmem_alloc_named_range(size, address, address + size,
|
||||||
|
0, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name)
|
||||||
|
{
|
||||||
|
return cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cvmx_bootmem_alloc_named);
|
||||||
|
|
||||||
int cvmx_bootmem_free_named(char *name)
|
int cvmx_bootmem_free_named(char *name)
|
||||||
{
|
{
|
||||||
return cvmx_bootmem_phy_named_block_free(name, 0);
|
return cvmx_bootmem_phy_named_block_free(name, 0);
|
||||||
@@ -106,6 +134,7 @@ struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name)
|
|||||||
{
|
{
|
||||||
return cvmx_bootmem_phy_named_block_find(name, 0);
|
return cvmx_bootmem_phy_named_block_find(name, 0);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(cvmx_bootmem_find_named_block);
|
||||||
|
|
||||||
void cvmx_bootmem_lock(void)
|
void cvmx_bootmem_lock(void)
|
||||||
{
|
{
|
||||||
@@ -584,3 +613,78 @@ int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags)
|
|||||||
cvmx_bootmem_unlock();
|
cvmx_bootmem_unlock();
|
||||||
return named_block_ptr != NULL; /* 0 on failure, 1 on success */
|
return named_block_ptr != NULL; /* 0 on failure, 1 on success */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
|
||||||
|
uint64_t max_addr,
|
||||||
|
uint64_t alignment,
|
||||||
|
char *name,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
int64_t addr_allocated;
|
||||||
|
struct cvmx_bootmem_named_block_desc *named_block_desc_ptr;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
cvmx_dprintf("cvmx_bootmem_phy_named_block_alloc: size: 0x%llx, min: "
|
||||||
|
"0x%llx, max: 0x%llx, align: 0x%llx, name: %s\n",
|
||||||
|
(unsigned long long)size,
|
||||||
|
(unsigned long long)min_addr,
|
||||||
|
(unsigned long long)max_addr,
|
||||||
|
(unsigned long long)alignment,
|
||||||
|
name);
|
||||||
|
#endif
|
||||||
|
if (cvmx_bootmem_desc->major_version != 3) {
|
||||||
|
cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: "
|
||||||
|
"%d.%d at addr: %p\n",
|
||||||
|
(int)cvmx_bootmem_desc->major_version,
|
||||||
|
(int)cvmx_bootmem_desc->minor_version,
|
||||||
|
cvmx_bootmem_desc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Take lock here, as name lookup/block alloc/name add need to
|
||||||
|
* be atomic.
|
||||||
|
*/
|
||||||
|
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
|
||||||
|
cvmx_spinlock_lock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
|
||||||
|
|
||||||
|
/* Get pointer to first available named block descriptor */
|
||||||
|
named_block_desc_ptr =
|
||||||
|
cvmx_bootmem_phy_named_block_find(NULL,
|
||||||
|
flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see if name already in use, return error if name
|
||||||
|
* not available or no more room for blocks.
|
||||||
|
*/
|
||||||
|
if (cvmx_bootmem_phy_named_block_find(name,
|
||||||
|
flags | CVMX_BOOTMEM_FLAG_NO_LOCKING) || !named_block_desc_ptr) {
|
||||||
|
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
|
||||||
|
cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Round size up to mult of minimum alignment bytes We need
|
||||||
|
* the actual size allocated to allow for blocks to be
|
||||||
|
* coallesced when they are freed. The alloc routine does the
|
||||||
|
* same rounding up on all allocations.
|
||||||
|
*/
|
||||||
|
size = __ALIGN_MASK(size, (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1));
|
||||||
|
|
||||||
|
addr_allocated = cvmx_bootmem_phy_alloc(size, min_addr, max_addr,
|
||||||
|
alignment,
|
||||||
|
flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
|
||||||
|
if (addr_allocated >= 0) {
|
||||||
|
named_block_desc_ptr->base_addr = addr_allocated;
|
||||||
|
named_block_desc_ptr->size = size;
|
||||||
|
strncpy(named_block_desc_ptr->name, name,
|
||||||
|
cvmx_bootmem_desc->named_block_name_len);
|
||||||
|
named_block_desc_ptr->name[cvmx_bootmem_desc->named_block_name_len - 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
|
||||||
|
cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
|
||||||
|
return addr_allocated;
|
||||||
|
}
|
||||||
|
@@ -183,6 +183,64 @@ extern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment,
|
|||||||
* Returns 0 on failure,
|
* Returns 0 on failure,
|
||||||
* !0 on success
|
* !0 on success
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a block of memory from the free list that was passed
|
||||||
|
* to the application by the bootloader, and assign it a name in the
|
||||||
|
* global named block table. (part of the cvmx_bootmem_descriptor_t structure)
|
||||||
|
* Named blocks can later be freed.
|
||||||
|
*
|
||||||
|
* @size: Size in bytes of block to allocate
|
||||||
|
* @alignment: Alignment required - must be power of 2
|
||||||
|
* @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
|
||||||
|
*
|
||||||
|
* Returns a pointer to block of memory, NULL on error
|
||||||
|
*/
|
||||||
|
extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment,
|
||||||
|
char *name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a block of memory from the free list that was passed
|
||||||
|
* to the application by the bootloader, and assign it a name in the
|
||||||
|
* global named block table. (part of the cvmx_bootmem_descriptor_t structure)
|
||||||
|
* Named blocks can later be freed.
|
||||||
|
*
|
||||||
|
* @size: Size in bytes of block to allocate
|
||||||
|
* @address: Physical address to allocate memory at. If this
|
||||||
|
* memory is not available, the allocation fails.
|
||||||
|
* @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN
|
||||||
|
* bytes
|
||||||
|
*
|
||||||
|
* Returns a pointer to block of memory, NULL on error
|
||||||
|
*/
|
||||||
|
extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
|
||||||
|
char *name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a block of memory from a specific range of the free list
|
||||||
|
* that was passed to the application by the bootloader, and assign it
|
||||||
|
* a name in the global named block table. (part of the
|
||||||
|
* cvmx_bootmem_descriptor_t structure) Named blocks can later be
|
||||||
|
* freed. If request cannot be satisfied within the address range
|
||||||
|
* specified, NULL is returned
|
||||||
|
*
|
||||||
|
* @size: Size in bytes of block to allocate
|
||||||
|
* @min_addr: minimum address of range
|
||||||
|
* @max_addr: maximum address of range
|
||||||
|
* @align: Alignment of memory to be allocated. (must be a power of 2)
|
||||||
|
* @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
|
||||||
|
*
|
||||||
|
* Returns a pointer to block of memory, NULL on error
|
||||||
|
*/
|
||||||
|
extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
|
||||||
|
uint64_t max_addr, uint64_t align,
|
||||||
|
char *name);
|
||||||
|
|
||||||
extern int cvmx_bootmem_free_named(char *name);
|
extern int cvmx_bootmem_free_named(char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,6 +281,33 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min,
|
|||||||
uint64_t address_max, uint64_t alignment,
|
uint64_t address_max, uint64_t alignment,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a named block of physical memory from the free list, at
|
||||||
|
* (optional) requested address and alignment.
|
||||||
|
*
|
||||||
|
* @param size size of region to allocate. All requests are rounded
|
||||||
|
* up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE
|
||||||
|
* bytes size
|
||||||
|
* @param min_addr Minimum address that block can occupy.
|
||||||
|
* @param max_addr Specifies the maximum address_min (inclusive) that
|
||||||
|
* the allocation can use.
|
||||||
|
* @param alignment Requested alignment of the block. If this
|
||||||
|
* alignment cannot be met, the allocation fails.
|
||||||
|
* This must be a power of 2. (Note: Alignment of
|
||||||
|
* CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
|
||||||
|
* internally enforced. Requested alignments of less
|
||||||
|
* than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
|
||||||
|
* CVMX_BOOTMEM_ALIGNMENT_SIZE.)
|
||||||
|
* @param name name to assign to named block
|
||||||
|
* @param flags Flags to control options for the allocation.
|
||||||
|
*
|
||||||
|
* @return physical address of block allocated, or -1 on failure
|
||||||
|
*/
|
||||||
|
int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
|
||||||
|
uint64_t max_addr,
|
||||||
|
uint64_t alignment,
|
||||||
|
char *name, uint32_t flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a named memory block by name.
|
* Finds a named memory block by name.
|
||||||
* Also used for finding an unused entry in the named block table.
|
* Also used for finding an unused entry in the named block table.
|
||||||
|
Reference in New Issue
Block a user