aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/octeon/patches/004-named_alloc_function.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/octeon/patches/004-named_alloc_function.patch')
-rw-r--r--target/linux/octeon/patches/004-named_alloc_function.patch223
1 files changed, 223 insertions, 0 deletions
diff --git a/target/linux/octeon/patches/004-named_alloc_function.patch b/target/linux/octeon/patches/004-named_alloc_function.patch
new file mode 100644
index 0000000000..a3135f0a8a
--- /dev/null
+++ b/target/linux/octeon/patches/004-named_alloc_function.patch
@@ -0,0 +1,223 @@
+The MGMT ethernet driver uses these new functions.
+
+Signed-off-by: David Daney <ddaney@caviumnetworks.com>
+---
+ arch/mips/cavium-octeon/executive/cvmx-bootmem.c | 101 ++++++++++++++++++++++
+ arch/mips/include/asm/octeon/cvmx-bootmem.h | 85 ++++++++++++++++++
+ 2 files changed, 186 insertions(+), 0 deletions(-)
+
+--- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
+@@ -97,6 +97,32 @@ void *cvmx_bootmem_alloc(uint64_t size,
+ 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);
++}
++
+ int cvmx_bootmem_free_named(char *name)
+ {
+ return cvmx_bootmem_phy_named_block_free(name, 0);
+@@ -584,3 +610,78 @@ int cvmx_bootmem_phy_named_block_free(ch
+ cvmx_bootmem_unlock();
+ 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;
++}
+--- a/arch/mips/include/asm/octeon/cvmx-bootmem.h
++++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h
+@@ -183,6 +183,64 @@ extern void *cvmx_bootmem_alloc_range(ui
+ * Returns 0 on failure,
+ * !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);
+
+ /**
+@@ -224,6 +282,33 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t
+ 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.
+ * Also used for finding an unused entry in the named block table.
+ *