public static List <TpmNamedConstant> GetBifieldElements(TpmBitfield bf) { var elements = new List <TpmNamedConstant>(); foreach (var b in bf.Elements) { if (b.StartBit == b.EndBit) { AddBitfieldElt(elements, b.TranslatedName, 1 << b.StartBit, b.Comment, b.OldStyleName); } else // multibit members of a bitfield { string typeName = b.Name; if (TpmTypes.Contains(typeName)) { // Type typeName defines allowed values for this multi-bit field var e = TpmTypes.Lookup(typeName) as TpmEnum; if (e != null) { foreach (var v in e.Members) { AddBitfieldElt(elements, v.Name, v.NumericValue << b.EndBit, v.Comment); } } } // Multi-bit bitfield 'name' is additionally represented by several enumerators: // name_BIT_MASK - bit mask selecting all bits of the field // name_BIT_OFFSET - offset of the field's low order bit // name_BIT_LENGTH - number of bits in the field string nameBase = b.Name.Contains("_") ? TargetLang.NameToDotNet(b.Name) : b.Name; int len = b.StartBit - b.EndBit + 1; var suff = TargetLang.DotNet ? new string[] { "BitMask", "BitOffset", "BitLength" } : new string[] { "_BIT_MASK", "_BIT_OFFSET", "_BIT_LENGTH" }; AddBitfieldElt(elements, nameBase + suff[0], ((1 << len) - 1) << b.EndBit, b.Comment, null, true); AddBitfieldElt(elements, nameBase + suff[1], b.EndBit, null, null, true); AddBitfieldElt(elements, nameBase + suff[2], len, null, null, true); if (TargetLang.DotNet && bf.Name == "LocalityAttr") { // For backward compatibility for (int i = 0; i < len; ++i) { AddBitfieldElt(elements, $"{nameBase}Bit{i}", 1 << (b.EndBit + i), "", null, true); } } } // multibit members of a bitfield } return(elements); }
void GenCommands() { Write("//-----------------------------------------------------------------------------"); Write("//------------------------- COMMANDS -----------------------------------------"); Write("//-----------------------------------------------------------------------------"); Write(""); Write("public partial class Tpm2"); TabIn("{"); foreach (var req in TpmTypes.Get <TpmStruct>().Where(s => s.Info.IsRequest())) { string cmdName = GetCommandName(req); var resp = GetRespStruct(req); var reqFields = req.NonTagFields; var respFields = resp.NonTagFields; string outputType = "void"; int numRespParams = respFields.Count(); if (respFields.Count() != 0) { if (respFields.Last().Name == "name") { --numRespParams; } outputType = respFields[0].TypeName; } string annotation = req.Comment + "\n\n"; foreach (var f in reqFields) { annotation += GetParamComment(f) + "\n"; } annotation += GetReturnComment(respFields); WriteComment(annotation, false); // commmand prototype + parameters string transCmdName = TargetLang.NameToDotNet(cmdName); Write("[TpmCommand]"); TabIn($"public {outputType} {transCmdName}("); bool printComma = false; foreach (StructField f in reqFields) { WriteComma(ref printComma); Write($"{f.TypeName} {f.Name}", false); } for (int i = 1; i < numRespParams; ++i) { var f = respFields[i]; WriteComma(ref printComma); Write($"out {f.TypeName} {f.Name}", false); } TabOut(")"); TabIn("{"); // Create input struct string reqStructInitList = string.Join(", ", reqFields.Select(f => f.Name)); Write($"var req = new {req.Name}({reqStructInitList});"); // Dispatch the command string respType = !resp.Implement ? "EmptyResponse" : resp.Name; Write($"var resp = new {respType}();"); Write($"DispatchMethod(TpmCc.{transCmdName}, req, resp, {req.NumHandles}, {resp.NumHandles});"); if (numRespParams > 0) { if (numRespParams == 1) { Write($"return resp.{respFields[0].Name};"); } else { // Set the return parameters for (int i = 1; i < numRespParams; ++i) { string rfName = respFields[i].Name; Write($"{rfName} = resp.{rfName};"); } Write($"return resp.{respFields[0].Name};"); } } TabOut("}"); continue; } TabOut("}"); } // GenCommands()