blob: ef3f620032572f1f3a8453f94c00a7696c3a4636 [file] [log] [blame]
/*
* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* 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.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*/
/* Implementation of per-board EEPROM driver functions */
#include <common.h>
#include <malloc.h>
#include <chromeos/firmware_storage.h>
/* TODO Replace mem_seek/read with spi_seek/read when moving firmware storage
* from NAND to SPI Flash */
struct context_t {
void *begin, *cur, *end;
};
static off_t mem_seek(void *context, off_t offset, enum whence_t whence)
{
void *begin, *cur, *end;
begin = ((struct context_t *) context)->begin;
cur = ((struct context_t *) context)->cur;
end = ((struct context_t *) context)->end;
if (whence == SEEK_SET)
cur = begin + offset;
else if (whence == SEEK_CUR)
cur = cur + offset;
else if (whence == SEEK_END)
cur = end + offset;
else {
debug("mem_seek: unknown whence value: %d\n", whence);
return -1;
}
if (cur < begin) {
debug("mem_seek: offset underflow: %p < %p\n", cur, begin);
return -1;
}
if (cur >= end) {
debug("mem_seek: offset exceeds size: %p >= %p\n", cur, end);
return -1;
}
((struct context_t *) context)->cur = cur;
return cur - begin;
}
static ssize_t mem_read(void *context, void *buf, size_t count)
{
void *begin, *cur, *end;
if (count == 0)
return 0;
begin = ((struct context_t *) context)->begin;
cur = ((struct context_t *) context)->cur;
end = ((struct context_t *) context)->end;
if (count > end - cur)
count = end - cur;
memcpy(buf, cur, count);
((struct context_t *) context)->cur += count;
return count;
}
int init_firmware_storage(firmware_storage_t *f)
{
struct context_t *context;
context = (struct context_t *) malloc(sizeof(struct context_t));
context->begin = (void *) TEXT_BASE;
context->cur = (void *) TEXT_BASE;
context->end = (void *) TEXT_BASE + CONFIG_FIRMWARE_SIZE;
f->seek = mem_seek;
f->read = mem_read;
f->context = (void *) context;
return 0;
}
int release_firmware_storage(firmware_storage_t *f)
{
free(f->context);
return 0;
}