/********************************************************************************/ /* */ /* Nuvoton Preconfig */ /* Written by Ken Goldman */ /* IBM Thomas J. Watson Research Center */ /* */ /* (c) Copyright IBM Corporation 2015 - 2019 */ /* */ /* All rights reserved. */ /* */ /* 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 names of the IBM Corporation 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 */ /* HOLDER 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. */ /********************************************************************************/ /* The function permits configuring either standard manufacturing values or individual registers. The hard coded values are in ../src/ntc2lib.h. They are configured as a set. That file also has certain required values that cannot be changed. To override the standard manufacturing values, cautiously use -override. This can brick the TPM, since it's setting up the bus interface. Override does a red-modify-write, reading the registers and substiuting the new values. */ #include #include #include #include #include #include #include #include "ntc2lib.h" static void printUsage(void); static TPM_RC fixedConfig(NTC2_CFG_STRUCT *preConfig); static void mergeConfig(NTC2_CFG_STRUCT *preConfigOut, const NTC2_CFG_STRUCT *preConfigIn, const NTC2_CFG_STRUCT *preConfigSet); extern int tssUtilsVerbose; int main(int argc, char *argv[]) { TPM_RC rc = 0; int i; /* argc iterator */ TSS_CONTEXT *tssContext = NULL; NTC2_GetConfig_Out out; NTC2_PreConfig_In in; NTC2_CFG_STRUCT preConfigSet; /* flags mark values to change */ NTC2_CFG_STRUCT preConfigIn; /* values to change */ int p8 = FALSE; int p9 = FALSE; int override = FALSE; /* TRUE to override P required values */ setvbuf(stdout, 0, _IONBF, 0); /* output may be going through pipe to log file */ TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "1"); tssUtilsVerbose = FALSE; memset(&preConfigSet, 0, sizeof(NTC2_CFG_STRUCT)); /* default nothing to change */ memset(&preConfigIn, 0, sizeof(NTC2_CFG_STRUCT)); /* initialized to suppress false gcc -O3 warning */ /* command line argument defaults */ for (i=1 ; (iDirection != FIXED_Direction) { printf("Direction is not the required value %02x\n", FIXED_Direction); return TPM_RC_RANGE; } if (preConfig->PullUp != FIXED_PullUp) { printf("PullUp is not the required value %02x\n", FIXED_PullUp); return TPM_RC_RANGE; } if (preConfig->PushPull != FIXED_PushPull) { printf("PushPull is not the required value %02x\n", FIXED_PushPull); return TPM_RC_RANGE; } if (preConfig->CFG_F != FIXED_CFG_F) { printf("CFG_F is not the required value %02x\n", FIXED_CFG_F); return TPM_RC_RANGE; } if (preConfig->CFG_I != FIXED_CFG_I) { printf("CFG_I is not the required value %02x\n", FIXED_CFG_I); return TPM_RC_RANGE; } if (preConfig->CFG_J != FIXED_CFG_J) { printf("CFG_J is not the required value %02x\n", FIXED_CFG_J); return TPM_RC_RANGE; } if (preConfig->IsValid != FIXED_IsValid) { printf("IsValid is not the required value %02x\n", FIXED_IsValid); return TPM_RC_RANGE; } return 0; } /* mergeConfig() handles the read modify write setup. preConfigIn are the new values preConfigSet are booleans, true for the new values preConfigOut at input are the current values, at output are the merged values */ static void mergeConfig(NTC2_CFG_STRUCT *preConfigOut, const NTC2_CFG_STRUCT *preConfigIn, const NTC2_CFG_STRUCT *preConfigSet) { if (preConfigSet->i2cLoc1_2) { preConfigOut->i2cLoc1_2 = preConfigIn->i2cLoc1_2; } if (preConfigSet->i2cLoc3_4) { preConfigOut->i2cLoc3_4 = preConfigIn->i2cLoc3_4; } if (preConfigSet->AltCfg) { preConfigOut->AltCfg = preConfigIn->AltCfg; } if (preConfigSet->Direction) { preConfigOut->Direction = preConfigIn->Direction; } if (preConfigSet->PullUp) { preConfigOut->PullUp = preConfigIn->PullUp; } if (preConfigSet->PushPull) { preConfigOut->PushPull = preConfigIn->PushPull; } if (preConfigSet->CFG_A) { preConfigOut->CFG_A = preConfigIn->CFG_A; } if (preConfigSet->CFG_B) { preConfigOut->CFG_B = preConfigIn->CFG_B; } if (preConfigSet->CFG_C) { preConfigOut->CFG_C = preConfigIn->CFG_C; } if (preConfigSet->CFG_D) { preConfigOut->CFG_D = preConfigIn->CFG_D; } if (preConfigSet->CFG_E) { preConfigOut->CFG_E = preConfigIn->CFG_E; } if (preConfigSet->CFG_F) { preConfigOut->CFG_F = preConfigIn->CFG_F; } if (preConfigSet->CFG_G) { preConfigOut->CFG_G = preConfigIn->CFG_G; } if (preConfigSet->CFG_H) { preConfigOut->CFG_H = preConfigIn->CFG_H; } if (preConfigSet->CFG_I) { preConfigOut->CFG_I = preConfigIn->CFG_I; } if (preConfigSet->CFG_J) { preConfigOut->CFG_J = preConfigIn->CFG_J; } if (preConfigSet->IsValid) { preConfigOut->IsValid = preConfigIn->IsValid; } return; } static void printUsage(void) { printf("\n"); printf("ntc2preconfig\n"); printf("\n"); printf("Runs NTC2_PreConfig\n"); printf("\n"); printf("\t-p8 or -p9\tConfigure Nuvoton TPM for P8 or P9\n"); printf("\t-override\tpermits individual register values, read-modify-write\n"); printf("\n"); printf("Values to set, each is a hex byte, (default do not change)\n"); printf("\n"); printf("\t[-i2cLoc1_2\tbyte]\n"); printf("\t[-i2cLoc3_4\tbyte]\n"); printf("\t[-AltCfg\tbyte]\n"); printf("\t[-Direction\tbyte]\n"); printf("\t[-PullUp\tbyte]\n"); printf("\t[-PushPull\tbyte]\n"); printf("\t[-CFG_A\t\tbyte]\n"); printf("\t[-CFG_B\t\tbyte]\n"); printf("\t[-CFG_C\t\tbyte]\n"); printf("\t[-CFG_D\t\tbyte]\n"); printf("\t[-CFG_E\t\tbyte]\n"); printf("\t[-CFG_F\t\tbyte]\n"); printf("\t[-CFG_G\t\tbyte]\n"); printf("\t[-CFG_H\t\tbyte]\n"); printf("\t[-CFG_I\t\tbyte]\n"); printf("\t[-CFG_J\t\tbyte]\n"); printf("\t[-IsValid\tbyte]\n"); exit(1); }