iBoot/drivers/flash_nand/ppn/WhimoryPPN/Boot/ANDStats.c

257 lines
7.1 KiB
C

/*
* Copyright (c) 2008-2009 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 "ANDTypes.h"
#include "WMROAM.h"
#include "VFLBuffer.h"
#include "FPart.h"
#include "WMRConfig.h"
#include "WhimoryBoot.h"
#include "ANDStats.h"
#include "FTL.h"
#include "VFL.h"
static VFLFunctions *stVflFunctions;
static FTLFunctions *stFtlFunctions;
typedef BOOL32 (*GetStructFunc)(UInt32 dwStructType, void * pvoidStructBuffer, UInt32 * pdwStructSize);
typedef struct {
UInt32 dwStructLayer;
UInt32 dwStructType;
UInt32 dwStructVersion;
} ExportStructParameters;
static ExportStructParameters astrStructsToExport[] =
{
// header (must be first)
{ 0, AND_STRUCT_WMR_EXPORT_ALL, AND_EXPORT_STRUCTURE_VERSION},
// WMR Version (FTL & VFL types)
{AND_STRUCT_LAYER_WMR, AND_STRUCT_WMR_VERSION, 0},
// VFL_type
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_GET_TYPE, 0},
// FTL_type ( FTL/yaFTL)
{AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_TYPE, 0},
// All VFL Meta
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 0, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 1, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 2, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 3, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 4, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 5, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 6, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 7, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 8, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 9, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 10, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 11, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 12, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 13, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 14, 0},
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_VFLMETA | 15, 0},
//FTL geometry
{AND_STRUCT_LAYER_FTL,AND_STRUCT_FTL_GET_FTL_DEVICEINFO, 0},
// FTL
{AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_FTLCXT, 0},
// FTL counters
{AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_FTL_EC_BINS, 1},
{AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_GET_FTL_RC_BINS, 1},
// FTL - Stat
{AND_STRUCT_LAYER_FTL, AND_STRUCT_FTL_STATISTICS, 0},
// VFL - Stat
{AND_STRUCT_LAYER_VFL, AND_STRUCT_VFL_STATISTICS, 0},
// FIL - Device Info
{AND_STRUCT_LAYER_FIL, AND_STRUCT_FIL_DEVICE_INFO, 0},
// FIL - Stat
{AND_STRUCT_LAYER_FIL, AND_STRUCT_FIL_STATISTICS, 0},
// footer (must be last)
{0, AND_STRUCT_WMR_EXPORT_ALL_END, AND_EXPORT_STRUCTURE_VERSION},
};
#define AND_DUMP_DEBUG (0)
#if AND_DUMP_DEBUG
#define DUMP_VAR(variable) WMR_PRINT(ALWAYS, "%s : %u\n", #variable, (UInt32)(variable))
static void
hexdump(UInt8 *bytes, int count)
{
int i, j;
for (i = 0; i < count; i += 16) {
kprintf("%04x:", i);
for (j = 0; (j < 16) && ((i + j) < count); j++)
kprintf(" %02.2x", *bytes++);
kprintf("\n");
}
}
#else
#define DUMP_VAR(variable)
#endif //AND_DUMP_DEBUG
static GetStructFunc _translateStructLayer (UInt32 dwStructLayer)
{
switch (dwStructLayer)
{
case AND_STRUCT_LAYER_FTL:
return stFtlFunctions->GetStruct;
case AND_STRUCT_LAYER_VFL:
return stVflFunctions->GetStruct;
case AND_STRUCT_LAYER_FIL:
return FIL_GetStruct;
case AND_STRUCT_LAYER_WMR:
return WMR_PPNGetStruct;
default:
return NULL;
}
}
static BOOL32 _appendStructToBuffer(void *pvoidExportBuffer,
UInt32 *pdwBufferSize,
UInt32 dwStructLayer,
UInt32 dwStructType,
UInt32 dwStructVersion)
{
UInt32 dwDataSize;
BOOL32 boolResult;
GetStructFunc fGetStruct = _translateStructLayer(dwStructLayer);
UInt8 *cursor = (UInt8*) pvoidExportBuffer;
DUMP_VAR(pvoidExportBuffer);
if (pdwBufferSize)
{
DUMP_VAR(*pdwBufferSize);
}
DUMP_VAR(dwStructLayer);
DUMP_VAR(dwStructType);
DUMP_VAR(dwStructVersion);
if (fGetStruct)
{
if (pvoidExportBuffer)
{
// leave room for the struct header
cursor += sizeof(ANDExportStruct);
}
dwDataSize = pdwBufferSize ? (*pdwBufferSize - sizeof(ANDExportStruct)) : 0;
boolResult = fGetStruct(dwStructType, cursor, &dwDataSize);
DUMP_VAR(dwDataSize);
}
else
{
// for header and footer
boolResult = TRUE32;
dwDataSize = 0;
}
if (boolResult)
{
#if AND_DUMP_DEBUG
if (pvoidExportBuffer)
{
hexdump(pvoidExportBuffer, dwDataSize);
}
#endif
if (pdwBufferSize)
{
*pdwBufferSize = dwDataSize + sizeof(ANDExportStruct);
}
if (pvoidExportBuffer)
{
ANDExportStruct strExport;
strExport.dwStructID = dwStructType;
strExport.dwStructureVersion = dwStructVersion;
strExport.dwDataSize = dwDataSize;
strExport.dwIndex = 0; // What is this?
WMR_MEMCPY(pvoidExportBuffer, &strExport, sizeof(ANDExportStruct));
}
}
else if (pdwBufferSize)
{
*pdwBufferSize = 0;
}
DUMP_VAR(boolResult);
return boolResult;
}
#define SUB_MIN_ZERO(minuend, subtrahend) (((minuend) > (subtrahend)) ? ((minuend) - (subtrahend)) : 0)
BOOL32 ANDExportAllStructs(void * pvoidDataBuffer, UInt32 * pdwDataSize)
{
UInt32 idx;
ExportStructParameters *nextStruct;
const UInt32 dwNumStructures = sizeof(astrStructsToExport) / sizeof(astrStructsToExport[0]);
const UInt32 dwBufferSize = pdwDataSize ? *pdwDataSize : 0;
UInt8 *cursor = (UInt8*) pvoidDataBuffer;
UInt32 dwBufferRead = 0;
UInt32 dwTmpStructSize;
if (!pdwDataSize)
{
return FALSE32;
}
// Update globals
stVflFunctions = WMR_PPN_GetVFL();
stFtlFunctions = WMR_PPN_GetFTL();
nextStruct = &astrStructsToExport[0];
for (idx = 0; idx < dwNumStructures; ++idx)
{
dwTmpStructSize = SUB_MIN_ZERO(dwBufferSize, dwBufferRead);
_appendStructToBuffer(cursor,
&dwTmpStructSize,
nextStruct->dwStructLayer,
nextStruct->dwStructType,
nextStruct->dwStructVersion);
nextStruct++;
if (cursor)
{
cursor += dwTmpStructSize;
}
dwBufferRead += dwTmpStructSize;
}
if (pdwDataSize)
{
*pdwDataSize = dwBufferRead;
}
// pdwDataSize tells the whole story, always pass
return TRUE32;
}