iBoot/lib/effaceable/iokit/AppleEffaceableNOR.cpp

159 lines
3.9 KiB
C++

/*
* 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 <IOKit/IOLib.h>
#include "AppleEffaceableNOR.h"
#include "effaceable_contract.h"
#include "effaceable_debug.h"
// =============================================================================
#define debug(...) dlogf((void*)0, __VA_ARGS__ )
// =============================================================================
#ifdef super
#undef super
#endif
#define super AppleEffaceableStorage
OSDefineMetaClassAndStructors(AppleEffaceableNOR, AppleEffaceableStorage);
// =============================================================================
bool
AppleEffaceableNOR::start(IOService *provider)
{
bool ok = false;
debug(INFO, "starting");
setupNorContract();
if (_is_started) {
debug(INFO, "already started");
ok = true;
} else if (0 == (_nor_flash = OSDynamicCast(AppleARMNORFlashDevice, provider))) {
debug(ERR, "bug in kext matching");
} else if (!super::start(provider)) {
debug(ERR, "super failed to start");
} else {
debug(INIT, "started");
_is_started = true;
ok = true;
}
return ok;
}
// =============================================================================
effaceable_nor_hal_t *
AppleEffaceableNOR::nor(void)
{
return &_nor_hal;
}
void
AppleEffaceableNOR::setupDeviceContract(void)
{
startEffaceableNOR(device(), system(), nor(), storage());
}
// =============================================================================
AppleEffaceableNOR * context(effaceable_nor_hal_t * nor)
{
AppleEffaceableNOR * context;
// XXX assert instead?
if (0 == (context = (AppleEffaceableNOR *)nor->opaque))
panic("null context");
return context;
}
uint32_t getRegionCountHook(effaceable_nor_hal_t * nor)
{
return context(nor)->getRegionCountNor();
}
uint32_t getRegionSizeHook(effaceable_nor_hal_t * nor, uint32_t index)
{
return context(nor)->getRegionSizeNor(index);
}
EffaceableReturn eraseRegionHook(effaceable_nor_hal_t * nor, uint32_t index, uint32_t length)
{
return context(nor)->eraseRegionNor(index, length);
}
uint32_t writeRegionHook(effaceable_nor_hal_t * nor, uint32_t index, const void * buf, uint32_t length)
{
return context(nor)->writeRegionNor(index, buf, length);
}
bool readRegionHook(effaceable_nor_hal_t * nor, uint32_t index, void * buf, uint32_t length)
{
return context(nor)->readRegionNor(index, buf, length);
}
// =============================================================================
void
AppleEffaceableNOR::setupNorContract(void)
{
nor()->opaque = this;
nor()->getRegionCount = getRegionCountHook;
nor()->getRegionSize = getRegionSizeHook;
nor()->eraseRegion = eraseRegionHook;
nor()->writeRegion = writeRegionHook;
nor()->readRegion = readRegionHook;
}
uint32_t
AppleEffaceableNOR::getRegionCountNor(void)
{
return _nor_flash->getRegionCount();
}
uint32_t
AppleEffaceableNOR::getRegionSizeNor(uint32_t index)
{
return _nor_flash->getRegionSize(index);
}
EffaceableReturn
AppleEffaceableNOR::eraseRegionNor(uint32_t index, uint32_t length)
{
return efReturn(_nor_flash->eraseRegion(index, 0, length));
}
uint32_t
AppleEffaceableNOR::writeRegionNor(uint32_t index, const void * buf, uint32_t length)
{
return _nor_flash->writeRegion(index, (const UInt8*)buf, length);
}
bool
AppleEffaceableNOR::readRegionNor(uint32_t index, void * buf, uint32_t length)
{
return _nor_flash->readRegion(index, (UInt8*)buf, length);
}
// =============================================================================