blob: 3111c8fc9c71a7c4814e07d865bb0851a455c26d [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.
*
* 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.
*/
#include <common.h>
#include <cros/common.h>
/* Import the header files from vboot_reference. */
#include <vboot_api.h>
/*
* We had a discussion about the non-volatile storage device for keeping
* the cookies. Due to the lack of SPI flash driver in kernel, kernel cannot
* access cookies in SPI flash. So the final descision is to store the
* cookies in eMMC device where we are certain that kernel can access.
*/
/*
* Gets the first internal disk and caches the result in a static variable.
* Returns 0 for success, non-zero for failure.
*/
static int get_internal_disk(VbDiskInfo **disk_ptr)
{
static VbDiskInfo internal_disk;
if (internal_disk.handle == NULL) {
VbDiskInfo* disk_info;
uint32_t disk_count;
if (VbExDiskGetInfo(&disk_info, &disk_count,
VB_DISK_FLAG_FIXED) || disk_count == 0) {
VBDEBUG("No internal disk found!\n");
return 1;
}
internal_disk = disk_info[0];
VbExDiskFreeInfo(disk_info, internal_disk.handle);
}
*disk_ptr = &internal_disk;
return 0;
}
/*
* Allocates 1-block-sized memory to block_buf_ptr and fills it as the first
* block of the disk.
* Returns 0 for success, non-zero for failure.
*/
static int get_nvcxt_block_of_disk(const VbDiskInfo *disk,
uint8_t **block_buf_ptr)
{
uint8_t *block_buf = NULL;
block_buf = VbExMalloc(disk->bytes_per_lba);
if (VbExDiskRead(disk->handle,
CHROMEOS_VBNVCONTEXT_LBA, 1, block_buf)) {
VBDEBUG("Failed to read internal disk!\n");
VbExFree(block_buf);
return 1;
}
*block_buf_ptr = block_buf;
return 0;
}
VbError_t VbExNvStorageRead(uint8_t* buf)
{
VbDiskInfo *internal_disk;
uint8_t *block_buf;
if (get_internal_disk(&internal_disk))
return 1;
if (get_nvcxt_block_of_disk(internal_disk, &block_buf))
return 1;
memcpy(buf, block_buf, VBNV_BLOCK_SIZE);
VbExFree(block_buf);
return VBERROR_SUCCESS;
}
VbError_t VbExNvStorageWrite(const uint8_t* buf)
{
VbDiskInfo *internal_disk;
uint8_t *block_buf;
if (get_internal_disk(&internal_disk))
return 1;
if (get_nvcxt_block_of_disk(internal_disk, &block_buf))
return 1;
memcpy(block_buf, buf, VBNV_BLOCK_SIZE);
if (VbExDiskWrite(internal_disk->handle,
CHROMEOS_VBNVCONTEXT_LBA, 1, block_buf)) {
VBDEBUG("Failed to write internal disk!\n");
VbExFree(block_buf);
return 1;
}
VbExFree(block_buf);
return VBERROR_SUCCESS;
}