diff options
Diffstat (limited to 'cfe/cfe/main/cfe_mem.c')
-rw-r--r-- | cfe/cfe/main/cfe_mem.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/cfe/cfe/main/cfe_mem.c b/cfe/cfe/main/cfe_mem.c new file mode 100644 index 0000000..1c424e1 --- /dev/null +++ b/cfe/cfe/main/cfe_mem.c @@ -0,0 +1,256 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Physical Memory (arena) manager File: cfe_mem.c + * + * This module describes the physical memory available to the + * firmware. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" +#include "lib_arena.h" + +#include "cfe_error.h" + +#include "cfe.h" +#include "cfe_mem.h" + +#include "initdata.h" + +#define _NOPROTOS_ +#include "cfe_boot.h" +#undef _NOPROTOS_ + +#include "cpu_config.h" /* for definition of CPUCFG_ARENAINIT */ + +#include "addrspace.h" /* for macros dealing with addresses */ + + +/* ********************************************************************* + * Macros + ********************************************************************* */ + +#define ARENA_RANGE(bottom,top,type) arena_markrange(&cfe_arena,(uint64_t)(bottom), \ + (uint64_t)(top)-(uint64_t)bottom+1,(type),NULL) + +#define MEG (1024*1024) +#define KB 1024 +#define PAGESIZE 4096 +#define CFE_BOOTAREA_SIZE (256*KB) +#define CFE_BOOTAREA_ADDR 0x20000000 + +/* ********************************************************************* + * Globals + ********************************************************************* */ + +arena_t cfe_arena; +extern void _setcontext(int64_t); + +unsigned int mem_bootarea_start; +unsigned int mem_bootarea_size; + +extern void CPUCFG_ARENAINIT(void); +extern void cfe_bootarea_init(void); +extern void CPUCFG_PAGETBLINIT(uint64_t *ptaddr,unsigned int ptstart); + + + +/* ********************************************************************* + * cfe_arena_init() + * + * Create the initial map of physical memory + * + * Input parameters: + * nothing + * + * Return value: + * nothing + ********************************************************************* */ + +void cfe_arena_init(void) +{ + uint64_t memlo,memhi; + + /* + * This macro expands via cpu_config.h to an appropriate function + * name for creating an empty arena appropriately for our CPU + */ + + CPUCFG_ARENAINIT(); + + /* + * Round the area used by the firmware to a page boundary and + * mark it in use + */ + + memhi = PHYSADDR((mem_topofmem + 4095) & ~4095); + memlo = PHYSADDR(mem_bottomofmem) & ~4095; + + ARENA_RANGE(memlo,memhi-1,MEMTYPE_DRAM_USEDBYFIRMWARE); + + /* + * Create the initial page table + */ + + cfe_bootarea_init(); + +} + + +/* ********************************************************************* + * cfe_arena_enum(idx,type,start,size) + * + * Enumerate available memory. This is called by the user + * API dispatcher so that operating systems can determine what + * memory regions are available to them. + * + * Input parameters: + * idx - index. Start at zero and increment until an error + * is returned. + * type,start,size: pointers to variables to receive the + * arena entry's information + * allrecs - true to retrieve all records, false to retrieve + * only available DRAM + * + * Return value: + * 0 if ok + * CFE_ERR_NOMORE if idx is beyond the last entry + ********************************************************************* */ + +int cfe_arena_enum(int idx,int *type,uint64_t *start,uint64_t *size,int allrecs) +{ + arena_node_t *node; + queue_t *qb; + arena_t *arena = &cfe_arena; + + + for (qb = (arena->arena_list.q_next); qb != &(arena->arena_list); + qb = qb->q_next) { + node = (arena_node_t *) qb; + + if (allrecs || (!allrecs && (node->an_type == MEMTYPE_DRAM_AVAILABLE))) { + if (idx == 0) { + *type = node->an_type; + *start = node->an_address; + *size = node->an_length; + return 0; + } + idx--; + } + } + + return CFE_ERR_NOMORE; + +} + +/* ********************************************************************* + * cfe_arena_loadcheck(start,size) + * + * Determine if the specified memory area is within the available + * DRAM. This is used while loading executables to be sure we + * don't trash the firmware. + * + * Input parameters: + * start - starting physical address + * size - size of requested region + * + * Return value: + * true - ok to copy memory here + * false - not ok, memory overlaps firmware + ********************************************************************* */ + +int cfe_arena_loadcheck(uintptr_t start,unsigned int size) +{ + arena_node_t *node; + queue_t *qb; + arena_t *arena = &cfe_arena; + + /* + * If the address is in our boot area, it's okay + * for it to be a virtual address. + */ + + if ((start >= BOOT_START_ADDRESS) && + ((start+size) <= (BOOT_START_ADDRESS+BOOT_AREA_SIZE))) { + return TRUE; + } + + /* + * Otherwise, make a physical address. + */ + + start = PHYSADDR(start); + + /* + * Because all of the arena nodes of the same type are + * coalesced together, all we need to do is determine if the + * requested region is entirely within an arena node, + * so there's no need to look for things that span nodes. + */ + + for (qb = (arena->arena_list.q_next); qb != &(arena->arena_list); + qb = qb->q_next) { + node = (arena_node_t *) qb; + + /* If the memory is available, the region is OK. */ + + if ((start >= node->an_address) && + ((start+size) <= (node->an_address+node->an_length)) && + (node->an_type == MEMTYPE_DRAM_AVAILABLE)) { + return TRUE; + } + } + + /* + * Otherwise, it's not. We could go through the arena again and + * look for regions of other types that intersect the requested + * region, to get a more detailed error, but this'll do. + */ + + return FALSE; + +} + |