first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2010-11 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#include <AppleEffaceableStorageFormat.h>
|
||||
#include <AppleEffaceableStorageKeys.h>
|
||||
|
||||
#include <lib/effaceable.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <sys/menu.h>
|
||||
#include <drivers/sha1.h>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int do_effaceable(int argc, struct cmd_arg *args);
|
||||
static void printUsage(int argc, struct cmd_arg *args);
|
||||
static void effaceable_hexdump(const void * buf, uint32_t count);
|
||||
static int lockerList(void);
|
||||
|
||||
#if DEBUG_BUILD
|
||||
static int consumeNonce(void);
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int
|
||||
do_effaceable(int argc, struct cmd_arg *args)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (1 >= argc) {
|
||||
printUsage(argc, args);
|
||||
err = 0;
|
||||
} else if (0 == strcmp("lockers", args[1].str)) {
|
||||
err = lockerList();
|
||||
#if DEBUG_BUILD
|
||||
} else if (0 == strcmp("nonce", args[1].str)) {
|
||||
err = consumeNonce();
|
||||
#endif
|
||||
} else {
|
||||
printUsage(argc, args);
|
||||
printf("unrecognized subcommand\n");
|
||||
err = -1;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static void
|
||||
printUsage(int argc, struct cmd_arg *args)
|
||||
{
|
||||
printf("USAGE: %s <subcmd>\n\n", ((0 < argc) ? args[0].str : "?"));
|
||||
printf(" Where <subcmd> is one of following\n\n");
|
||||
printf(" lockers - list lockers and contents\n");
|
||||
|
||||
#if DEBUG_BUILD
|
||||
printf(" nonce - consume nonce; then, report its SHA1 hash and value\n");
|
||||
#endif
|
||||
|
||||
printf(" ...(more to come)...\n\n");
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static void
|
||||
effaceable_hexdump(const void * buf, uint32_t count)
|
||||
{
|
||||
uint32_t i, j;
|
||||
for (i = 0; i < count; i += 16) {
|
||||
printf("0x%08x:", ((uint32_t) buf) + i);
|
||||
for (j = 0; (j < 16) && ((i + j) < count); j++) {
|
||||
printf(" %02.2x", ((uint8_t*)buf)[i+j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#define UNTAG(x) \
|
||||
\
|
||||
(uint8_t)(((x) >> 24) & 0xff), \
|
||||
(uint8_t)(((x) >> 16) & 0xff), \
|
||||
(uint8_t)(((x) >> 8) & 0xff), \
|
||||
(uint8_t)((x) & 0xff)
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int
|
||||
lockerList(void)
|
||||
{
|
||||
uint8_t *buf, *cursor;
|
||||
uint32_t size;
|
||||
AppleEffaceableStorageLockerHeader *header;
|
||||
|
||||
size = effaceable_get_capacity();
|
||||
if (0 == size) {
|
||||
printf("ERROR: unable to get capacity\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = malloc(size);
|
||||
|
||||
if (!effaceable_get_bytes(buf, 0, size)) {
|
||||
printf("ERROR: unable to read\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cursor = buf;
|
||||
for (;;) {
|
||||
header = (AppleEffaceableStorageLockerHeader *)cursor;
|
||||
if (header->magic != kAppleEffaceableStorageLockerMagic) {
|
||||
printf("WARNING: unexpected magic 0x%04x at %u, expected 0x%04x\n",
|
||||
header->magic, cursor - buf, kAppleEffaceableStorageLockerMagic);
|
||||
break;
|
||||
}
|
||||
if (header->type_id == kAppleEffaceableStorageLockerSentinel) {
|
||||
printf("<END>\n");
|
||||
break;
|
||||
}
|
||||
printf("0x%08x/0x%04x %c%c%c%c %s\n",
|
||||
header->type_id,
|
||||
header->data_size,
|
||||
UNTAG(header->type_id & ~kAppleEffaceableStorageLockerProtected),
|
||||
(header->type_id & kAppleEffaceableStorageLockerProtected) ? "(protected)" : "");
|
||||
cursor += sizeof(*header);
|
||||
if (header->data_size > 0) {
|
||||
if ((cursor + header->data_size) > (buf + size)) {
|
||||
printf("WARNING: data overflows buffer\n");
|
||||
break;
|
||||
}
|
||||
effaceable_hexdump(cursor, header->data_size);
|
||||
cursor += header->data_size;
|
||||
}
|
||||
if ((cursor + sizeof(*header)) > (buf + size)) {
|
||||
printf("WARNING: header overflows buffer\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
// XXX correct hard-coding of SHA1 buffer size
|
||||
#define SHA1_HASH_SIZE 20
|
||||
|
||||
static int
|
||||
consumeNonce(void)
|
||||
{
|
||||
uint64_t nonce;
|
||||
uint8_t hash[SHA1_HASH_SIZE];
|
||||
int idx;
|
||||
|
||||
if (!effaceable_consume_nonce(&nonce)) {
|
||||
printf("ERROR: unable to consume nonce\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sha1_calculate(&nonce, sizeof(nonce), hash);
|
||||
|
||||
for (idx = 0; idx < SHA1_HASH_SIZE; idx++) {
|
||||
printf("%s%02X", (idx ? " " : ""), hash[idx]);
|
||||
}
|
||||
printf(" (0x%016llX)\n", nonce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
MENU_COMMAND_DEBUG(effaceable, do_effaceable, "effaceable storage utilities", NULL);
|
||||
|
||||
// =============================================================================
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#include <lib/effaceable.h>
|
||||
#include <lib/effaceable_impl.h>
|
||||
#include <lib/libc.h>
|
||||
|
||||
#include <effaceable_contract.h>
|
||||
#include <effaceable_debug.h>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int logf(void * ignored, const char * fmt, ...);
|
||||
|
||||
#define debug(...) dlogf((void*)0, __VA_ARGS__ )
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static effaceable_storage_t * gEffaceableStorage = (void*)0;
|
||||
|
||||
// =============================================================================
|
||||
|
||||
extern void registerEffaceableStorage(effaceable_storage_t * storage)
|
||||
{
|
||||
gEffaceableStorage = storage;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
effaceable_storage_t * locateEffaceableStorage(void)
|
||||
{
|
||||
if (0 == gEffaceableStorage) {
|
||||
debug(ERR, "no storage available");
|
||||
}
|
||||
|
||||
return gEffaceableStorage;
|
||||
}
|
||||
|
||||
bool trustEffaceableContext(void)
|
||||
{
|
||||
#if DEBUG_BUILD
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
bool effaceable_get_locker(uint32_t type_id, void * data, uint32_t * data_size)
|
||||
{
|
||||
bool trust = trustEffaceableContext();
|
||||
effaceable_storage_t * storage = locateEffaceableStorage();
|
||||
|
||||
if (0 == storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kEffaceableReturnSuccess != storage->getLocker(storage, type_id, data, data_size, !trust)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool effaceable_set_locker(uint32_t type_id, const void * data, uint32_t data_size)
|
||||
{
|
||||
bool trust = trustEffaceableContext();
|
||||
effaceable_storage_t * storage = locateEffaceableStorage();
|
||||
|
||||
if (0 == storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kEffaceableReturnSuccess != storage->setLocker(storage, type_id, data, data_size, !trust)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool effaceable_space_for_locker(uint32_t type_id, uint32_t * data_space)
|
||||
{
|
||||
effaceable_storage_t * storage = locateEffaceableStorage();
|
||||
|
||||
if (0 == storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kEffaceableReturnSuccess != storage->spaceForLocker(storage, type_id, data_space)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool effaceable_efface_locker(uint32_t type_id)
|
||||
{
|
||||
bool trust = trustEffaceableContext();
|
||||
effaceable_storage_t * storage = locateEffaceableStorage();
|
||||
|
||||
if (0 == storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kEffaceableReturnSuccess != storage->effaceLocker(storage, type_id, !trust)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool effaceable_consume_nonce(uint64_t * nonce)
|
||||
{
|
||||
effaceable_storage_t * storage = locateEffaceableStorage();
|
||||
|
||||
if (0 == storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kEffaceableReturnSuccess != storage->consumeNonce(storage, nonce)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#if DEBUG_BUILD
|
||||
|
||||
bool effaceable_get_bytes(void * client_buf, uint32_t offset, uint32_t count)
|
||||
{
|
||||
effaceable_storage_t * storage = locateEffaceableStorage();
|
||||
|
||||
if (0 == storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kEffaceableReturnSuccess != storage->getBytes(storage, client_buf, offset, count)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t effaceable_get_capacity(void)
|
||||
{
|
||||
effaceable_storage_t * storage = locateEffaceableStorage();
|
||||
uint32_t capacity = 0;
|
||||
|
||||
if (0 != storage) {
|
||||
capacity = storage->getCapacity(storage);
|
||||
}
|
||||
|
||||
debug(INFO, "capacity is %d bytes", capacity);
|
||||
|
||||
return capacity;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int logf(void * ignored, const char * fmt, ...)
|
||||
{
|
||||
int err;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
err = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2012 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#include <effaceable_contract.h>
|
||||
#include <effaceable_debug.h>
|
||||
#include <lib/effaceable_impl.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <lib/random.h>
|
||||
#include <lib/cksum.h>
|
||||
#include <lib/libc.h>
|
||||
#include <drivers/sha1.h>
|
||||
#include <sys.h>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#if DEBUG_BUILD
|
||||
# define USING_STRONG_SEED false
|
||||
#else
|
||||
# define USING_STRONG_SEED true
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int logf(void * ignored, const char * fmt, ...);
|
||||
|
||||
#define debug(...) dlogf((void*)0, __VA_ARGS__ )
|
||||
|
||||
// =============================================================================
|
||||
|
||||
void * allocMemIboot(effaceable_system_t * system, uint32_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void freeMemIboot(effaceable_system_t * system, void * buf, uint32_t size)
|
||||
{
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void * setMemIboot(effaceable_system_t * system, void * buf, uint8_t val, uint32_t size)
|
||||
{
|
||||
return memset(buf, val, size);
|
||||
}
|
||||
|
||||
void * moveMemIboot(effaceable_system_t * system, void * dst, const void * src, uint32_t size)
|
||||
{
|
||||
return memmove(dst, src, size);
|
||||
}
|
||||
|
||||
int cmpMemIboot(effaceable_system_t * system, const void * lhs, const void * rhs, uint32_t size)
|
||||
{
|
||||
return memcmp(lhs, rhs, size);
|
||||
}
|
||||
|
||||
void readRandomIboot(effaceable_system_t * system, void * buf, uint32_t size)
|
||||
{
|
||||
static bool is_seeded = false;
|
||||
const unsigned increment = sizeof(int);
|
||||
uint8_t * cursor = (uint8_t *)buf;
|
||||
unsigned idx;
|
||||
|
||||
// if we're using a strong seed, draw from the entropy pool to
|
||||
// re-seed psuedo-random generator the first time function is called
|
||||
if (!is_seeded && USING_STRONG_SEED) {
|
||||
unsigned int seed;
|
||||
random_get_bytes((u_int8_t*)&seed, sizeof(seed));
|
||||
srand(seed);
|
||||
is_seeded = true;
|
||||
}
|
||||
|
||||
// fill with psuedo-random values by 'int'-sized chunks as long as possible
|
||||
for (idx = 0; (idx + increment) <= size; idx += increment, cursor += increment) {
|
||||
*((int*)cursor) = rand();
|
||||
}
|
||||
|
||||
// if size doesn't divide evenly by increment, fill fringe bytewise
|
||||
for (; idx < size; idx++, cursor++) {
|
||||
*cursor = (uint8_t)rand();
|
||||
}
|
||||
}
|
||||
|
||||
void calcSHA1Iboot(effaceable_system_t * system, const void * buf, uint32_t size, void * hash)
|
||||
{
|
||||
sha1_calculate(buf, size, hash);
|
||||
}
|
||||
|
||||
uint32_t crc32Iboot(effaceable_system_t * system, uint32_t crc, const void * buf, uint32_t size, bool finish)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
if ((0 == crc) && (0 == buf) && (0 == size)) {
|
||||
val = update_crc32(0xffffffffL, 0, 0);
|
||||
} else {
|
||||
val = update_crc32(crc, (unsigned char *)buf, size);
|
||||
}
|
||||
|
||||
return (finish ? val ^ 0xffffffffL : val);
|
||||
}
|
||||
|
||||
bool setPropertyIboot(effaceable_system_t * system, const char * key, uint32_t value)
|
||||
{
|
||||
debug(INFO, "%s := %u", key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
void panicIboot(effaceable_system_t * system, const char * msg)
|
||||
{
|
||||
panic("%s", msg);
|
||||
}
|
||||
|
||||
int vlogfIboot(effaceable_system_t * system, const char * fmt, va_list ap)
|
||||
{
|
||||
return vprintf(fmt, ap);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
extern EffaceableReturn
|
||||
setupEffaceableSystemContract(effaceable_system_t * system)
|
||||
{
|
||||
system->opaque = 0;
|
||||
|
||||
system->allocMem = allocMemIboot;
|
||||
system->freeMem = freeMemIboot;
|
||||
system->setMem = setMemIboot;
|
||||
system->moveMem = moveMemIboot;
|
||||
system->cmpMem = cmpMemIboot;
|
||||
system->readRandom = readRandomIboot;
|
||||
system->calcSHA1 = calcSHA1Iboot;
|
||||
system->crc32 = crc32Iboot;
|
||||
system->setProperty = setPropertyIboot;
|
||||
system->panicSys = panicIboot;
|
||||
system->vlogf = vlogfIboot;
|
||||
|
||||
return kEffaceableReturnSuccess;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int logf(void * ignored, const char * fmt, ...)
|
||||
{
|
||||
int err;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
err = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#ifndef _EFFACEABLE_STORAGE_API_H_
|
||||
#define _EFFACEABLE_STORAGE_API_H_
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
// =============================================================================
|
||||
//
|
||||
// iBoot-specific presentation of the effaceable storage API for client use.
|
||||
//
|
||||
// =============================================================================
|
||||
|
||||
bool effaceable_get_locker(uint32_t type_id, void * data, uint32_t * data_size);
|
||||
bool effaceable_set_locker(uint32_t type_id, const void * data, uint32_t data_size);
|
||||
bool effaceable_space_for_locker(uint32_t type_id, uint32_t * data_space);
|
||||
bool effaceable_efface_locker(uint32_t type_id);
|
||||
bool effaceable_consume_nonce(uint64_t * nonce);
|
||||
|
||||
// =============================================================================
|
||||
//
|
||||
// iBoot-specific presentation of the effaceable storage API for util/devel.
|
||||
//
|
||||
// =============================================================================
|
||||
|
||||
bool effaceable_get_bytes(void * client_buf, uint32_t offset, uint32_t count);
|
||||
uint32_t effaceable_get_capacity(void);
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#endif /* _EFFACEABLE_STORAGE_API_H_ */
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#ifndef _EFFACEABLE_IMPL_H_
|
||||
#define _EFFACEABLE_IMPL_H_
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#include <effaceable_contract.h>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
extern EffaceableReturn setupEffaceableSystemContract(effaceable_system_t * system);
|
||||
extern void registerEffaceableStorage(effaceable_storage_t * storage);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
__END_DECLS
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#endif /* _EFFACEABLE_IMPL_H_ */
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#include <lib/effaceable.h>
|
||||
#include <lib/effaceable_impl.h>
|
||||
|
||||
#include <effaceable_contract.h>
|
||||
#include <effaceable_debug.h>
|
||||
|
||||
#include <nand_part.h>
|
||||
#include <nand_part_interface.h>
|
||||
|
||||
#include <lib/heap.h>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
struct _context
|
||||
{
|
||||
NandPartInterface * npi;
|
||||
uint32_t idx;
|
||||
};
|
||||
|
||||
typedef struct _context context_t;
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static inline context_t * context(effaceable_nand_hal_t * nand)
|
||||
{
|
||||
return (context_t*)nand->opaque;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#define delegateNPI(_me, _fn, ...) context(_me)->npi->_fn(context(_me)->npi->core, context(_me)->idx, ## __VA_ARGS__)
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static void initContext(effaceable_nand_hal_t * nand, NandPartInterface * npi, uint32_t idx)
|
||||
{
|
||||
context_t * ctx = (context_t*)malloc(sizeof(context_t));
|
||||
|
||||
ctx->npi = npi;
|
||||
ctx->idx = idx;
|
||||
|
||||
nand->opaque = ctx;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static uint32_t getPageSizeHook(effaceable_nand_hal_t * nand)
|
||||
{
|
||||
return delegateNPI(nand, get_bytes_per_page);
|
||||
}
|
||||
|
||||
static uint32_t getPageCountHook(effaceable_nand_hal_t * nand)
|
||||
{
|
||||
return delegateNPI(nand, get_pages_per_block);
|
||||
}
|
||||
|
||||
static uint32_t getBlockCountHook(effaceable_nand_hal_t * nand)
|
||||
{
|
||||
return delegateNPI(nand, get_block_depth);
|
||||
}
|
||||
|
||||
static uint32_t getBankCountHook(effaceable_nand_hal_t * nand)
|
||||
{
|
||||
return delegateNPI(nand, get_bank_width);
|
||||
}
|
||||
|
||||
static bool isBlockBadHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block)
|
||||
{
|
||||
return delegateNPI(nand, is_block_bad, bank, block);
|
||||
}
|
||||
|
||||
static EffaceableReturn eraseBlockHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block)
|
||||
{
|
||||
return (delegateNPI(nand, erase_block, bank, block) ? kEffaceableReturnSuccess : kEffaceableReturnError);
|
||||
}
|
||||
|
||||
static EffaceableReturn writePageHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, const void * buf, uint32_t length)
|
||||
{
|
||||
return (delegateNPI(nand, write_page, bank, block, page, (void*)buf) ? kEffaceableReturnSuccess : kEffaceableReturnError);
|
||||
}
|
||||
|
||||
static EffaceableReturn readPageHook(effaceable_nand_hal_t * nand, uint32_t bank, uint32_t block, uint32_t page, void * buf, uint32_t length)
|
||||
{
|
||||
return (delegateNPI(nand, read_page, bank, block, page, buf, (bool*)0) ? kEffaceableReturnSuccess : kEffaceableReturnError);
|
||||
}
|
||||
|
||||
static bool requestPartitionTableDiffHook(effaceable_nand_hal_t * nand, void * buf, uint32_t length)
|
||||
{
|
||||
return delegateNPI(nand, request_ptab_diff, buf, length);
|
||||
}
|
||||
|
||||
static bool providePartitionTableDiffHook(effaceable_nand_hal_t * nand, void * buf, uint32_t length)
|
||||
{
|
||||
return delegateNPI(nand, provide_ptab_diff, buf, length);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static void initContract(effaceable_nand_hal_t * nand)
|
||||
{
|
||||
nand->getPageSize = getPageSizeHook;
|
||||
nand->getPageCount = getPageCountHook;
|
||||
nand->getBlockCount = getBlockCountHook;
|
||||
nand->getBankCount = getBankCountHook;
|
||||
nand->isBlockBad = isBlockBadHook;
|
||||
nand->eraseBlock = eraseBlockHook;
|
||||
nand->writePage = writePageHook;
|
||||
nand->readPage = readPageHook;
|
||||
nand->requestPartitionTableDiff = requestPartitionTableDiffHook;
|
||||
nand->providePartitionTableDiff = providePartitionTableDiffHook;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
extern void
|
||||
effaceable_nand_init(NandPartInterface * npi, uint32_t idx)
|
||||
{
|
||||
effaceable_nand_hal_t * nand = (effaceable_nand_hal_t *)malloc(sizeof(effaceable_nand_hal_t));
|
||||
effaceable_device_t * device = (effaceable_device_t *)malloc(sizeof(effaceable_device_t));
|
||||
effaceable_system_t * system = (effaceable_system_t *)malloc(sizeof(effaceable_system_t));
|
||||
effaceable_storage_t * storage = (effaceable_storage_t *)malloc(sizeof(effaceable_storage_t));
|
||||
|
||||
initContext(nand, npi, idx);
|
||||
initContract(nand);
|
||||
|
||||
if (kEffaceableReturnSuccess == setupEffaceableSystemContract(system)) {
|
||||
|
||||
startEffaceableNAND(device, system, nand, storage);
|
||||
registerEffaceableStorage(storage);
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#ifndef _EFFACEABLE_NAND_H_
|
||||
#define _EFFACEABLE_NAND_H_
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
void effaceable_nand_init(NandPartInterface * npi, uint32_t idx);
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#endif /* _EFFACEABLE_NAND_H_ */
|
||||
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
# XXX Clean this kludge up when iBoot two-stage boot changes are submitted.
|
||||
ifneq ($(PRODUCT),iBSS)
|
||||
|
||||
OPTIONS += \
|
||||
WITH_EFFACEABLE_NAND=1
|
||||
|
||||
MODULES += \
|
||||
lib/effaceable/iboot
|
||||
|
||||
# XXX Clean this up when iBoot two-stage boot changes are submitted.
|
||||
GLOBAL_INCLUDES += \
|
||||
drivers/flash_nand/boot \
|
||||
$(LOCAL_DIR)/include
|
||||
|
||||
ALL_OBJS += \
|
||||
$(LOCAL_DIR)/effaceable_nand.o
|
||||
|
||||
endif
|
||||
|
||||
# XXX Consider relocating this directory to 'iBoot/drivers/apple/effaceable/nand'.
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#include <lib/effaceable.h>
|
||||
#include <lib/effaceable_impl.h>
|
||||
|
||||
#include <effaceable_contract.h>
|
||||
#include <effaceable_debug.h>
|
||||
|
||||
#include <sys.h>
|
||||
#include <AssertMacros.h>
|
||||
#include <lib/blockdev.h>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#define WITH_EFFACEABLE_NOR_DEBUG 0
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int logf(void * ignored, const char * fmt, ...);
|
||||
|
||||
#define debug(...) dlogf((void*)0, __VA_ARGS__ )
|
||||
|
||||
// =============================================================================
|
||||
//
|
||||
// Effaceable NOR region definition is currently only supplied by means
|
||||
// of publishing device tree up to iOS. Currently, in order to get this off
|
||||
// its feet, I'm about to hard code equivalent information here; however,
|
||||
// that's obviously not a very good solution going forward (for any of the
|
||||
// NOR memory map, honestly).
|
||||
//
|
||||
// =============================================================================
|
||||
|
||||
#define NOR_BDEV "nor0"
|
||||
#define REGION_SIZE ((uint32_t)0x1000)
|
||||
|
||||
static const uint32_t region_offsets[] = {0xFA000, 0xFB000};
|
||||
|
||||
// =============================================================================
|
||||
|
||||
void validate(effaceable_nor_hal_t * nor, uint32_t index, uint32_t length)
|
||||
{
|
||||
require(nor != 0, fail_contract);
|
||||
require(nor->opaque != 0, fail_context);
|
||||
require(index < sizeof(region_offsets)/sizeof(region_offsets[0]), fail_index);
|
||||
require(length <= REGION_SIZE, fail_length);
|
||||
return;
|
||||
|
||||
fail_contract:
|
||||
panic("contract missing");
|
||||
|
||||
fail_context:
|
||||
panic("context missing");
|
||||
|
||||
fail_index:
|
||||
panic("bad index");
|
||||
|
||||
fail_length:
|
||||
panic("bad length");
|
||||
}
|
||||
|
||||
uint32_t getNorOffset(uint32_t index)
|
||||
{
|
||||
return region_offsets[index];
|
||||
}
|
||||
|
||||
static void
|
||||
doHexdump(const void * buf, uint32_t count)
|
||||
{
|
||||
uint32_t i, j;
|
||||
for (i = 0; i < count; i += 16) {
|
||||
printf("0x%08x:", ((uint32_t) buf) + i);
|
||||
for (j = 0; (j < 16) && ((i + j) < count); j++) {
|
||||
printf(" %2.2x", ((uint8_t*)buf)[i+j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#define context(nor) ((struct blockdev *)nor->opaque)
|
||||
|
||||
// =============================================================================
|
||||
|
||||
uint32_t getRegionCountIboot(effaceable_nor_hal_t * nor)
|
||||
{
|
||||
validate(nor, 0, 0);
|
||||
return sizeof(region_offsets)/sizeof(region_offsets[0]);
|
||||
}
|
||||
|
||||
uint32_t getRegionSizeIboot(effaceable_nor_hal_t * nor, uint32_t index)
|
||||
{
|
||||
validate(nor, index, 0);
|
||||
return REGION_SIZE;
|
||||
}
|
||||
|
||||
EffaceableReturn eraseRegionIboot(effaceable_nor_hal_t * nor, uint32_t index, uint32_t length)
|
||||
{
|
||||
EffaceableReturn ok = kEffaceableReturnSuccess;
|
||||
int err;
|
||||
|
||||
validate(nor, index, length);
|
||||
|
||||
err = blockdev_erase(context(nor), getNorOffset(index), length);
|
||||
|
||||
if (err < 0) {
|
||||
ok = kEffaceableReturnIOError;
|
||||
}
|
||||
debug(INFO, "blockdev_erase on '%s' %s", NOR_BDEV, (kEffaceableReturnSuccess == ok) ? "succeeded" : "failed");
|
||||
return ok;
|
||||
}
|
||||
|
||||
uint32_t writeRegionIboot(effaceable_nor_hal_t * nor, uint32_t index, const void * buf, uint32_t length)
|
||||
{
|
||||
EffaceableReturn ok = kEffaceableReturnSuccess;
|
||||
int err;
|
||||
|
||||
validate(nor, index, length);
|
||||
|
||||
err = blockdev_write(context(nor), buf, getNorOffset(index), length);
|
||||
|
||||
if (err <= 0) {
|
||||
ok = kEffaceableReturnIOError;
|
||||
}
|
||||
debug(INFO, "blockdev_write to '%s' %s", NOR_BDEV, (kEffaceableReturnSuccess == ok) ? "succeeded" : "failed");
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool readRegionIboot(effaceable_nor_hal_t * nor, uint32_t index, void * buf, uint32_t length)
|
||||
{
|
||||
EffaceableReturn ok = kEffaceableReturnSuccess;
|
||||
int err;
|
||||
|
||||
validate(nor, index, length);
|
||||
|
||||
err = blockdev_read(context(nor), buf, getNorOffset(index), length);
|
||||
|
||||
if (err <= 0) {
|
||||
ok = kEffaceableReturnIOError;
|
||||
} else {
|
||||
#if WITH_EFFACEABLE_NOR_DEBUG
|
||||
doHexdump(buf, length);
|
||||
#endif
|
||||
}
|
||||
debug(INFO, "blockdev_read from '%s' %s", NOR_BDEV, (kEffaceableReturnSuccess == ok) ? "succeeded" : "failed");
|
||||
return kEffaceableReturnSuccess;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
EffaceableReturn
|
||||
setupEffaceableNorContract(effaceable_nor_hal_t * nor)
|
||||
{
|
||||
nor->opaque = lookup_blockdev(NOR_BDEV);
|
||||
|
||||
if (0 == nor->opaque) {
|
||||
debug(ERR, "unable to find '%s' blockdev", NOR_BDEV);
|
||||
return kEffaceableReturnBadMedia;
|
||||
}
|
||||
|
||||
nor->getRegionCount = getRegionCountIboot;
|
||||
nor->getRegionSize = getRegionSizeIboot;
|
||||
nor->eraseRegion = eraseRegionIboot;
|
||||
nor->writeRegion = writeRegionIboot;
|
||||
nor->readRegion = readRegionIboot;
|
||||
|
||||
debug(INFO, "nor contract setup complete");
|
||||
|
||||
return kEffaceableReturnSuccess;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
extern void
|
||||
effaceable_nor_init(void)
|
||||
{
|
||||
effaceable_nor_hal_t * nor = (effaceable_nor_hal_t *)malloc(sizeof(effaceable_nor_hal_t));
|
||||
effaceable_device_t * device = (effaceable_device_t *)malloc(sizeof(effaceable_device_t));
|
||||
effaceable_system_t * system = (effaceable_system_t *)malloc(sizeof(effaceable_system_t));
|
||||
effaceable_storage_t * storage = (effaceable_storage_t *)malloc(sizeof(effaceable_storage_t));
|
||||
|
||||
if ((kEffaceableReturnSuccess == setupEffaceableNorContract(nor)) &&
|
||||
(kEffaceableReturnSuccess == setupEffaceableSystemContract(system))) {
|
||||
|
||||
startEffaceableNOR(device, system, nor, storage);
|
||||
registerEffaceableStorage(storage);
|
||||
debug(INFO, "registered nor-backed effaceable storage");
|
||||
|
||||
} else {
|
||||
|
||||
debug(ERR, "failed to init nor-backed effaceable storage");
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static int logf(void * ignored, const char * fmt, ...)
|
||||
{
|
||||
int err;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
err = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#ifndef _EFFACEABLE_NOR_H_
|
||||
#define _EFFACEABLE_NOR_H_
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
void effaceable_nor_init(void);
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#endif /* _EFFACEABLE_NOR_H_ */
|
||||
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
# XXX Clean this kludge up when iBoot two-stage boot changes are submitted.
|
||||
ifneq ($(PRODUCT),iBSS)
|
||||
|
||||
OPTIONS += \
|
||||
WITH_EFFACEABLE_NOR=1
|
||||
|
||||
MODULES += \
|
||||
lib/effaceable/iboot
|
||||
|
||||
GLOBAL_INCLUDES += \
|
||||
$(LOCAL_DIR)/include
|
||||
|
||||
ALL_OBJS += \
|
||||
$(LOCAL_DIR)/effaceable_nor.o
|
||||
|
||||
endif
|
||||
|
||||
# XXX Consider relocating this directory to 'iBoot/drivers/apple/effaceable/nand'.
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
OPTIONS += \
|
||||
WITH_EFFACEABLE=1
|
||||
|
||||
MODULES += \
|
||||
lib/effaceable/common
|
||||
|
||||
GLOBAL_INCLUDES += \
|
||||
$(LOCAL_DIR)/include
|
||||
|
||||
ALL_OBJS += \
|
||||
$(LOCAL_DIR)/effaceable_system.o \
|
||||
$(LOCAL_DIR)/effaceable_storage.o \
|
||||
$(LOCAL_DIR)/effaceable_cmd.o
|
||||
Reference in new issue
Block a user