blob: dc1b1415a182025fbe452e2bac10dba13798f93f [file] [log] [blame]
/*
* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY 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) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <debug.h>
#include <reg.h>
#include <sys/types.h>
#include <platform/iomap.h>
#include "smem.h"
static struct smem *smem;
/* buf MUST be 4byte aligned, and len MUST be a multiple of 8. */
unsigned smem_read_alloc_entry(smem_mem_type_t type, void *buf, int len)
{
struct smem_alloc_info *ainfo;
unsigned *dest = buf;
unsigned src;
unsigned size;
uint32_t smem_addr = 0;
smem_addr = platform_get_smem_base_addr();
smem = (struct smem *)smem_addr;
if (((len & 0x3) != 0) || (((unsigned)buf & 0x3) != 0))
return 1;
if (type < SMEM_FIRST_VALID_TYPE || type > SMEM_LAST_VALID_TYPE)
return 1;
/* TODO: Use smem spinlocks */
ainfo = &smem->alloc_info[type];
if (readl(&ainfo->allocated) == 0)
return 1;
size = readl(&ainfo->size);
if (size != (unsigned)((len + 7) & ~0x00000007))
return 1;
src = smem_addr + readl(&ainfo->offset);
for (; len > 0; src += 4, len -= 4)
*(dest++) = readl(src);
return 0;
}
unsigned
smem_read_alloc_entry_offset(smem_mem_type_t type, void *buf, int len,
int offset)
{
struct smem_alloc_info *ainfo;
unsigned *dest = buf;
unsigned src;
unsigned size = len;
uint32_t smem_addr = 0;
smem_addr = platform_get_smem_base_addr();
smem = (struct smem *)smem_addr;
if (((len & 0x3) != 0) || (((unsigned)buf & 0x3) != 0))
return 1;
if (type < SMEM_FIRST_VALID_TYPE || type > SMEM_LAST_VALID_TYPE)
return 1;
ainfo = &smem->alloc_info[type];
if (readl(&ainfo->allocated) == 0)
return 1;
src = smem_addr + readl(&ainfo->offset) + offset;
for (; size > 0; src += 4, size -= 4)
*(dest++) = readl(src);
return 0;
}