diff options
Diffstat (limited to 'cvmx-bootmem.c')
-rw-r--r-- | cvmx-bootmem.c | 90 |
1 files changed, 61 insertions, 29 deletions
diff --git a/cvmx-bootmem.c b/cvmx-bootmem.c index bb373fbaa0ea..a5f4e0c786ae 100644 --- a/cvmx-bootmem.c +++ b/cvmx-bootmem.c @@ -1,5 +1,5 @@ /***********************license start*************** - * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights + * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights * reserved. * * @@ -15,7 +15,7 @@ * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of Cavium Networks nor the names of + * * Neither the name of Cavium Inc. nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. @@ -26,7 +26,7 @@ * countries. * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR + * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM @@ -47,7 +47,7 @@ * Simple allocate only memory allocator. Used to allocate memory at application * start time. * - * <hr>$Revision: 52119 $<hr> + * <hr>$Revision: 70030 $<hr> * */ #ifdef CVMX_BUILD_FOR_LINUX_KERNEL @@ -300,7 +300,7 @@ static int __cvmx_bootmem_check_version(int exact_match) int major_version; #ifdef CVMX_BUILD_FOR_LINUX_HOST if (!cvmx_bootmem_desc_addr) - cvmx_bootmem_desc_addr = cvmx_read64_uint64(0x24100); + cvmx_bootmem_desc_addr = cvmx_read64_uint64(0x48100); #endif major_version = CVMX_BOOTMEM_DESC_GET_FIELD(major_version); if ((major_version > 3) || (exact_match && major_version != exact_match)) @@ -457,27 +457,70 @@ void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment) EXPORT_SYMBOL(cvmx_bootmem_alloc); #endif -void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, const char *name) +void *cvmx_bootmem_alloc_named_range_once(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, const char *name, void (*init)(void*)) { int64_t addr; + void *ptr; + uint64_t named_block_desc_addr; + + __cvmx_bootmem_lock(0); __cvmx_validate_mem_range(&min_addr, &max_addr); - addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, align, name, 0); - if (addr >= 0) + named_block_desc_addr = cvmx_bootmem_phy_named_block_find(name, CVMX_BOOTMEM_FLAG_NO_LOCKING); + + if (named_block_desc_addr) + { + addr = CVMX_BOOTMEM_NAMED_GET_FIELD(named_block_desc_addr, base_addr); + __cvmx_bootmem_unlock(0); return cvmx_phys_to_ptr(addr); - else + } + + addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, align, name, CVMX_BOOTMEM_FLAG_NO_LOCKING); + + if (addr < 0) + { + __cvmx_bootmem_unlock(0); return NULL; + } + ptr = cvmx_phys_to_ptr(addr); + init(ptr); + __cvmx_bootmem_unlock(0); + return ptr; +} + +void *cvmx_bootmem_alloc_named_range_flags(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, const char *name, uint32_t flags) +{ + int64_t addr; + + __cvmx_validate_mem_range(&min_addr, &max_addr); + addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, align, name, flags); + if (addr >= 0) + return cvmx_phys_to_ptr(addr); + else + return NULL; + +} +void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, const char *name) +{ + return cvmx_bootmem_alloc_named_range_flags(size, min_addr, max_addr, align, name, 0); } + void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, const 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, const char *name) { return(cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name)); } +void *cvmx_bootmem_alloc_named_flags(uint64_t size, uint64_t alignment, const char *name, uint32_t flags) +{ + return cvmx_bootmem_alloc_named_range_flags(size, 0, 0, alignment, name, flags); +} + int cvmx_bootmem_free_named(const char *name) { return(cvmx_bootmem_phy_named_block_free(name, 0)); @@ -569,16 +612,7 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, uint64_t /* Round req_size up to mult of minimum alignment bytes */ req_size = (req_size + (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1)) & ~(CVMX_BOOTMEM_ALIGNMENT_SIZE - 1); - /* Convert !0 address_min and 0 address_max to special case of range that specifies an exact - ** memory block to allocate. Do this before other checks and adjustments so that this tranformation will be validated */ - if (address_min && !address_max) - address_max = address_min + req_size; - else if (!address_min && !address_max) - address_max = ~0ull; /* If no limits given, use max limits */ - - - - + /* Enforce minimum alignment (this also keeps the minimum free block ** req_size the same as the alignment req_size */ if (alignment < CVMX_BOOTMEM_ALIGNMENT_SIZE) @@ -592,6 +626,12 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min, uint64_t if (alignment) address_min = (address_min + (alignment - 1)) & ~(alignment - 1); + /* Convert !0 address_min and 0 address_max to special case of range that specifies an exact + ** memory block to allocate. Do this before other checks and adjustments so that this tranformation will be validated */ + if (address_min && !address_max) + address_max = address_min + req_size; + else if (!address_min && !address_max) + address_max = ~0ull; /* If no limits given, use max limits */ /* Reject inconsistent args. We have adjusted these, so this may fail due to our internal changes ** even if this check would pass for the values the user supplied. */ @@ -825,7 +865,7 @@ void cvmx_bootmem_phy_list_print(void) } while (addr) { - cvmx_dprintf("Block address: 0x%08qx, size: 0x%08qx, next: 0x%08qx\n", + cvmx_dprintf("Block address: 0x%08llx, size: 0x%08llx, next: 0x%08llx\n", (ULL)addr, (ULL)cvmx_bootmem_phy_get_size(addr), (ULL)cvmx_bootmem_phy_get_next(addr)); @@ -1014,7 +1054,7 @@ void cvmx_bootmem_phy_named_block_print(void) uint64_t named_addr = CVMX_BOOTMEM_NAMED_GET_FIELD(named_block_addr, base_addr); CVMX_BOOTMEM_NAMED_GET_NAME(named_block_addr, name_tmp, name_length); printed++; - cvmx_dprintf("Name: %s, address: 0x%08qx, size: 0x%08qx, index: %d\n", + cvmx_dprintf("Name: %s, address: 0x%08llx, size: 0x%08llx, index: %d\n", name_tmp, (ULL)named_addr, (ULL)named_size, i); } named_block_addr += sizeof(cvmx_bootmem_named_block_desc_t); @@ -1027,14 +1067,6 @@ void cvmx_bootmem_phy_named_block_print(void) } -/* Real physical addresses of memory regions */ -#define OCTEON_DDR0_BASE (0x0ULL) -#define OCTEON_DDR0_SIZE (0x010000000ULL) -#define OCTEON_DDR1_BASE (OCTEON_IS_MODEL(OCTEON_CN6XXX) ? 0x20000000ULL : 0x410000000ULL) -#define OCTEON_DDR1_SIZE (0x010000000ULL) -#define OCTEON_DDR2_BASE (OCTEON_IS_MODEL(OCTEON_CN6XXX) ? 0x30000000ULL : 0x20000000ULL) -#define OCTEON_DDR2_SIZE (OCTEON_IS_MODEL(OCTEON_CN6XXX) ? 0x7d0000000ULL : 0x3e0000000ULL) -#define OCTEON_MAX_PHY_MEM_SIZE (OCTEON_IS_MODEL(OCTEON_CN63XX) ? 32*1024*1024*1024ULL : 16*1024*1024*1024ULL) int64_t cvmx_bootmem_phy_mem_list_init(uint64_t mem_size, uint32_t low_reserved_bytes, cvmx_bootmem_desc_t *desc_buffer) { uint64_t cur_block_addr; |