From 782778cbea180064cafaa41d51758d36c58ca908 Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Sat, 16 Dec 2017 08:19:22 +0000 Subject: [PATCH] acpi: move parser opcode table into the parser pkg --- src/gopheros/device/acpi/aml/opcode.go | 269 -------------- src/gopheros/device/acpi/aml/opcode_table.go | 317 ---------------- src/gopheros/device/acpi/aml/opcode_test.go | 187 ---------- .../device/acpi/aml/parser/opcode_table.go | 339 ++++++++++++++++++ .../device/acpi/aml/parser/opcode_test.go | 35 ++ 5 files changed, 374 insertions(+), 773 deletions(-) delete mode 100644 src/gopheros/device/acpi/aml/opcode.go delete mode 100644 src/gopheros/device/acpi/aml/opcode_table.go delete mode 100644 src/gopheros/device/acpi/aml/opcode_test.go create mode 100644 src/gopheros/device/acpi/aml/parser/opcode_table.go create mode 100644 src/gopheros/device/acpi/aml/parser/opcode_test.go diff --git a/src/gopheros/device/acpi/aml/opcode.go b/src/gopheros/device/acpi/aml/opcode.go deleted file mode 100644 index 617fc7a..0000000 --- a/src/gopheros/device/acpi/aml/opcode.go +++ /dev/null @@ -1,269 +0,0 @@ -package aml - -// opcode describes an AML opcode. While AML supports 256 opcodes, some of them -// are specified using a combination of an extension prefix and a code. To map -// each opcode into a single unique value the parser uses an uint16 -// representation of the opcode values. -type opcode uint16 - -// String implements fmt.Stringer for opcode. -func (op opcode) String() string { - for _, entry := range opcodeTable { - if entry.op == op { - return entry.name - } - } - - return "unknown" -} - -// opIsLocalArg returns true if this opcode represents any of the supported local -// function args 0 to 7. -func opIsLocalArg(op opcode) bool { - return op >= opLocal0 && op <= opLocal7 -} - -// opIsMethodArg returns true if this opcode represents any of the supported -// input function args 0 to 6. -func opIsMethodArg(op opcode) bool { - return op >= opArg0 && op <= opArg6 -} - -// opIsArg returns true if this opcode is either a local or a method arg. -func opIsArg(op opcode) bool { - return opIsLocalArg(op) || opIsMethodArg(op) -} - -// opIsDataObject returns true if this opcode is part of a DataObject definition -// -// Grammar: -// DataObject := ComputationalData | DefPackage | DefVarPackage -// ComputationalData := ByteConst | WordConst | DWordConst | QWordConst | String | ConstObj | RevisionOp | DefBuffer -// ConstObj := ZeroOp | OneOp | OnesOp -func opIsDataObject(op opcode) bool { - switch op { - case opBytePrefix, opWordPrefix, opDwordPrefix, opQwordPrefix, opStringPrefix, - opZero, opOne, opOnes, opRevision, opBuffer, opPackage, opVarPackage: - return true - default: - return false - } -} - -// opIsType2 returns true if this is a Type2Opcode. -// -// Grammar: -// Type2Opcode := DefAcquire | DefAdd | DefAnd | DefBuffer | DefConcat | -// DefConcatRes | DefCondRefOf | DefCopyObject | DefDecrement | -// DefDerefOf | DefDivide | DefFindSetLeftBit | DefFindSetRightBit | -// DefFromBCD | DefIncrement | DefIndex | DefLAnd | DefLEqual | -// DefLGreater | DefLGreaterEqual | DefLLess | DefLLessEqual | DefMid | -// DefLNot | DefLNotEqual | DefLoadTable | DefLOr | DefMatch | DefMod | -// DefMultiply | DefNAnd | DefNOr | DefNot | DefObjectType | DefOr | -// DefPackage | DefVarPackage | DefRefOf | DefShiftLeft | DefShiftRight | -// DefSizeOf | DefStore | DefSubtract | DefTimer | DefToBCD | DefToBuffer | -// DefToDecimalString | DefToHexString | DefToInteger | DefToString | -// DefWait | DefXOr -func opIsType2(op opcode) bool { - switch op { - case opAcquire, opAdd, opAnd, opBuffer, opConcat, - opConcatRes, opCondRefOf, opCopyObject, opDecrement, - opDerefOf, opDivide, opFindSetLeftBit, opFindSetRightBit, - opFromBCD, opIncrement, opIndex, opLand, opLEqual, - opLGreater, opLLess, opMid, - opLnot, opLoadTable, opLor, opMatch, opMod, - opMultiply, opNand, opNor, opNot, opObjectType, opOr, - opPackage, opVarPackage, opRefOf, opShiftLeft, opShiftRight, - opSizeOf, opStore, opSubtract, opTimer, opToBCD, opToBuffer, - opToDecimalString, opToHexString, opToInteger, opToString, - opWait, opXor: - return true - default: - return false - } -} - -// opIsBufferField returens true if this opcode describes a -// buffer field creation operation. -func opIsBufferField(op opcode) bool { - switch op { - case opCreateField, opCreateBitField, opCreateByteField, opCreateWordField, opCreateDWordField, opCreateQWordField: - return true - default: - return false - } -} - -// objType represents the object types that are supported by the AML parser. -type objType uint8 - -// The list of AML object types. -const ( - objTypeAny objType = iota - objTypeInteger - objTypeString - objTypeBuffer - objTypePackage - objTypeDevice - objTypeEvent - objTypeMethod - objTypeMutex - objTypeRegion - objTypePower - objTypeProcessor - objTypeThermal - objTypeBufferField - objTypeLocalRegionField - objTypeLocalBankField - objTypeLocalReference - objTypeLocalAlias - objTypeLocalScope - objTypeLocalVariable - objTypeMethodArgument -) - -// opFlag specifies a list of OR-able flags that describe the object -// type/attributes generated by a particular opcode. -type opFlag uint16 - -const ( - opFlagNone opFlag = 1 << iota - opFlagHasPkgLen - opFlagNamed - opFlagConstant - opFlagReference - opFlagArithmetic - opFlagCreate - opFlagReturn - opFlagExecutable - opFlagNoOp - opFlagScoped -) - -// is returns true if f is set in this opFlag. -func (fl opFlag) is(f opFlag) bool { - return (fl & f) != 0 -} - -// opArgFlags encodes up to 7 opArgFlag values in a uint64 value. -type opArgFlags uint64 - -// argCount returns the number of encoded args in the given flag. -func (fl opArgFlags) argCount() (count uint8) { - // Each argument is specified using 8 bits with 0x0 indicating the end of the - // argument list - for ; fl&0xf != 0; fl, count = fl>>8, count+1 { - } - - return count -} - -// arg returns the arg flags for argument "num" where num is the 0-based index -// of the argument to return. The allowed values for num are 0-6. -func (fl opArgFlags) arg(num uint8) opArgFlag { - return opArgFlag((fl >> (num * 8)) & 0xf) -} - -// contains returns true if the arg flags contain any argument with type x. -func (fl opArgFlags) contains(x opArgFlag) bool { - // Each argument is specified using 8 bits with 0x0 indicating the end of the - // argument list - for ; fl&0xf != 0; fl >>= 8 { - if opArgFlag(fl&0xf) == x { - return true - } - } - - return false -} - -// opArgFlag represents the type of an argument expected by a particular opcode. -type opArgFlag uint8 - -// The list of supported opArgFlag values. -const ( - _ opArgFlag = iota - opArgTermList - opArgTermObj - opArgByteList - opArgPackage - opArgString - opArgByteData - opArgWord - opArgDword - opArgQword - opArgNameString - opArgSuperName - opArgSimpleName - opArgDataRefObj - opArgTarget - opArgFieldList -) - -// String implements fmt.Stringer for opArgFlag. -func (fl opArgFlag) String() string { - switch fl { - case opArgTermList: - return "opArgTermList" - case opArgTermObj: - return "opArgTermObj" - case opArgByteList: - return "opArgByteList" - case opArgPackage: - return "opArgPackage" - case opArgString: - return "opArgString" - case opArgByteData: - return "opArgByteData" - case opArgWord: - return "opArgWord" - case opArgDword: - return "opArgDword" - case opArgQword: - return "opArgQword" - case opArgNameString: - return "opArgNameString" - case opArgSuperName: - return "opArgSuperName" - case opArgSimpleName: - return "opArgSimpleName" - case opArgDataRefObj: - return "opArgDataRefObj" - case opArgTarget: - return "opArgTarget" - case opArgFieldList: - return "opArgFieldList" - } - return "" -} - -func makeArg0() opArgFlags { return 0 } -func makeArg1(arg0 opArgFlag) opArgFlags { return opArgFlags(arg0) } -func makeArg2(arg0, arg1 opArgFlag) opArgFlags { return opArgFlags(arg1)<<8 | opArgFlags(arg0) } -func makeArg3(arg0, arg1, arg2 opArgFlag) opArgFlags { - return opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) -} -func makeArg4(arg0, arg1, arg2, arg3 opArgFlag) opArgFlags { - return opArgFlags(arg3)<<24 | opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) -} -func makeArg5(arg0, arg1, arg2, arg3, arg4 opArgFlag) opArgFlags { - return opArgFlags(arg4)<<32 | opArgFlags(arg3)<<24 | opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) -} -func makeArg6(arg0, arg1, arg2, arg3, arg4, arg5 opArgFlag) opArgFlags { - return opArgFlags(arg5)<<40 | opArgFlags(arg4)<<32 | opArgFlags(arg3)<<24 | opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) -} -func makeArg7(arg0, arg1, arg2, arg3, arg4, arg5, arg6 opArgFlag) opArgFlags { - return opArgFlags(arg6)<<48 | opArgFlags(arg5)<<40 | opArgFlags(arg4)<<32 | opArgFlags(arg3)<<24 | opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) -} - -// opcodeInfo contains all known information about an opcode, -// its argument count and types as well as the type of object -// represented by it. -type opcodeInfo struct { - op opcode - name string - objType objType - - flags opFlag - argFlags opArgFlags -} diff --git a/src/gopheros/device/acpi/aml/opcode_table.go b/src/gopheros/device/acpi/aml/opcode_table.go deleted file mode 100644 index ba8e500..0000000 --- a/src/gopheros/device/acpi/aml/opcode_table.go +++ /dev/null @@ -1,317 +0,0 @@ -package aml - -const ( - badOpcode = 0xff - extOpPrefix = 0x5b - - // Regular opcode list - opZero = opcode(0x00) - opOne = opcode(0x01) - opAlias = opcode(0x06) - opName = opcode(0x08) - opBytePrefix = opcode(0x0a) - opWordPrefix = opcode(0x0b) - opDwordPrefix = opcode(0x0c) - opStringPrefix = opcode(0x0d) - opQwordPrefix = opcode(0x0e) - opScope = opcode(0x10) - opBuffer = opcode(0x11) - opPackage = opcode(0x12) - opVarPackage = opcode(0x13) - opMethod = opcode(0x14) - opExternal = opcode(0x15) - opLocal0 = opcode(0x60) - opLocal1 = opcode(0x61) - opLocal2 = opcode(0x62) - opLocal3 = opcode(0x63) - opLocal4 = opcode(0x64) - opLocal5 = opcode(0x65) - opLocal6 = opcode(0x66) - opLocal7 = opcode(0x67) - opArg0 = opcode(0x68) - opArg1 = opcode(0x69) - opArg2 = opcode(0x6a) - opArg3 = opcode(0x6b) - opArg4 = opcode(0x6c) - opArg5 = opcode(0x6d) - opArg6 = opcode(0x6e) - opStore = opcode(0x70) - opRefOf = opcode(0x71) - opAdd = opcode(0x72) - opConcat = opcode(0x73) - opSubtract = opcode(0x74) - opIncrement = opcode(0x75) - opDecrement = opcode(0x76) - opMultiply = opcode(0x77) - opDivide = opcode(0x78) - opShiftLeft = opcode(0x79) - opShiftRight = opcode(0x7a) - opAnd = opcode(0x7b) - opNand = opcode(0x7c) - opOr = opcode(0x7d) - opNor = opcode(0x7e) - opXor = opcode(0x7f) - opNot = opcode(0x80) - opFindSetLeftBit = opcode(0x81) - opFindSetRightBit = opcode(0x82) - opDerefOf = opcode(0x83) - opConcatRes = opcode(0x84) - opMod = opcode(0x85) - opNotify = opcode(0x86) - opSizeOf = opcode(0x87) - opIndex = opcode(0x88) - opMatch = opcode(0x89) - opCreateDWordField = opcode(0x8a) - opCreateWordField = opcode(0x8b) - opCreateByteField = opcode(0x8c) - opCreateBitField = opcode(0x8d) - opObjectType = opcode(0x8e) - opCreateQWordField = opcode(0x8f) - opLand = opcode(0x90) - opLor = opcode(0x91) - opLnot = opcode(0x92) - opLEqual = opcode(0x93) - opLGreater = opcode(0x94) - opLLess = opcode(0x95) - opToBuffer = opcode(0x96) - opToDecimalString = opcode(0x97) - opToHexString = opcode(0x98) - opToInteger = opcode(0x99) - opToString = opcode(0x9c) - opCopyObject = opcode(0x9d) - opMid = opcode(0x9e) - opContinue = opcode(0x9f) - opIf = opcode(0xa0) - opElse = opcode(0xa1) - opWhile = opcode(0xa2) - opNoop = opcode(0xa3) - opReturn = opcode(0xa4) - opBreak = opcode(0xa5) - opBreakPoint = opcode(0xcc) - opOnes = opcode(0xff) - // Extended opcodes - opMutex = opcode(0xff + 0x01) - opEvent = opcode(0xff + 0x02) - opCondRefOf = opcode(0xff + 0x12) - opCreateField = opcode(0xff + 0x13) - opLoadTable = opcode(0xff + 0x1f) - opLoad = opcode(0xff + 0x20) - opStall = opcode(0xff + 0x21) - opSleep = opcode(0xff + 0x22) - opAcquire = opcode(0xff + 0x23) - opSignal = opcode(0xff + 0x24) - opWait = opcode(0xff + 0x25) - opReset = opcode(0xff + 0x26) - opRelease = opcode(0xff + 0x27) - opFromBCD = opcode(0xff + 0x28) - opToBCD = opcode(0xff + 0x29) - opUnload = opcode(0xff + 0x2a) - opRevision = opcode(0xff + 0x30) - opDebug = opcode(0xff + 0x31) - opFatal = opcode(0xff + 0x32) - opTimer = opcode(0xff + 0x33) - opOpRegion = opcode(0xff + 0x80) - opField = opcode(0xff + 0x81) - opDevice = opcode(0xff + 0x82) - opProcessor = opcode(0xff + 0x83) - opPowerRes = opcode(0xff + 0x84) - opThermalZone = opcode(0xff + 0x85) - opIndexField = opcode(0xff + 0x86) - opBankField = opcode(0xff + 0x87) - opDataRegion = opcode(0xff + 0x88) -) - -// The opcode table contains all opcode-related information that the parser knows. -// This table is modeled after a similar table used in the acpica implementation. -var opcodeTable = []opcodeInfo{ - /*0x00*/ {opZero, "Zero", objTypeInteger, opFlagConstant, makeArg0()}, - /*0x01*/ {opOne, "One", objTypeInteger, opFlagConstant, makeArg0()}, - /*0x02*/ {opAlias, "Alias", objTypeLocalAlias, opFlagNamed, makeArg2(opArgNameString, opArgNameString)}, - /*0x03*/ {opName, "Name", objTypeAny, opFlagNamed, makeArg2(opArgNameString, opArgDataRefObj)}, - /*0x04*/ {opBytePrefix, "Byte", objTypeInteger, opFlagConstant, makeArg1(opArgByteData)}, - /*0x05*/ {opWordPrefix, "Word", objTypeInteger, opFlagConstant, makeArg1(opArgWord)}, - /*0x06*/ {opDwordPrefix, "Dword", objTypeInteger, opFlagConstant, makeArg1(opArgDword)}, - /*0x07*/ {opStringPrefix, "String", objTypeString, opFlagConstant, makeArg1(opArgString)}, - /*0x08*/ {opQwordPrefix, "Qword", objTypeInteger, opFlagConstant, makeArg1(opArgQword)}, - /*0x09*/ {opScope, "Scope", objTypeLocalScope, opFlagNamed, makeArg2(opArgNameString, opArgTermList)}, - /*0x0a*/ {opBuffer, "Buffer", objTypeBuffer, opFlagHasPkgLen, makeArg2(opArgTermObj, opArgByteList)}, - /*0x0b*/ {opPackage, "Package", objTypePackage, opFlagNone, makeArg2(opArgByteData, opArgTermList)}, - /*0x0c*/ {opVarPackage, "VarPackage", objTypePackage, opFlagNone, makeArg2(opArgByteData, opArgTermList)}, - /*0x0d*/ {opMethod, "Method", objTypeMethod, opFlagNamed | opFlagScoped, makeArg3(opArgNameString, opArgByteData, opArgTermList)}, - /*0x0e*/ {opExternal, "External", objTypeAny, opFlagNamed, makeArg3(opArgNameString, opArgByteData, opArgByteData)}, - /*0x0f*/ {opLocal0, "Local0", objTypeLocalVariable, opFlagExecutable, makeArg0()}, - /*0x10*/ {opLocal1, "Local1", objTypeLocalVariable, opFlagExecutable, makeArg0()}, - /*0x11*/ {opLocal2, "Local2", objTypeLocalVariable, opFlagExecutable, makeArg0()}, - /*0x12*/ {opLocal3, "Local3", objTypeLocalVariable, opFlagExecutable, makeArg0()}, - /*0x13*/ {opLocal4, "Local4", objTypeLocalVariable, opFlagExecutable, makeArg0()}, - /*0120*/ {opLocal5, "Local5", objTypeLocalVariable, opFlagExecutable, makeArg0()}, - /*0x15*/ {opLocal6, "Local6", objTypeLocalVariable, opFlagExecutable, makeArg0()}, - /*0x16*/ {opLocal7, "Local7", objTypeLocalVariable, opFlagExecutable, makeArg0()}, - /*0x17*/ {opArg0, "Arg0", objTypeMethodArgument, opFlagExecutable, makeArg0()}, - /*0x18*/ {opArg1, "Arg1", objTypeMethodArgument, opFlagExecutable, makeArg0()}, - /*0x19*/ {opArg2, "Arg2", objTypeMethodArgument, opFlagExecutable, makeArg0()}, - /*0x1a*/ {opArg3, "Arg3", objTypeMethodArgument, opFlagExecutable, makeArg0()}, - /*0x1b*/ {opArg4, "Arg4", objTypeMethodArgument, opFlagExecutable, makeArg0()}, - /*0x1c*/ {opArg5, "Arg5", objTypeMethodArgument, opFlagExecutable, makeArg0()}, - /*0x1d*/ {opArg6, "Arg6", objTypeMethodArgument, opFlagExecutable, makeArg0()}, - /*0x1e*/ {opStore, "Store", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgSuperName)}, - /*0x1f*/ {opRefOf, "RefOf", objTypeAny, opFlagReference | opFlagExecutable, makeArg1(opArgSuperName)}, - /*0x20*/ {opAdd, "Add", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x21*/ {opConcat, "Concat", objTypeAny, opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x22*/ {opSubtract, "Subtract", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x23*/ {opIncrement, "Increment", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg1(opArgSuperName)}, - /*0x24*/ {opDecrement, "Decrement", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg1(opArgSuperName)}, - /*0x25*/ {opMultiply, "Multiply", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x26*/ {opDivide, "Divide", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg4(opArgTermObj, opArgTermObj, opArgTarget, opArgTarget)}, - /*0x27*/ {opShiftLeft, "ShiftLeft", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x28*/ {opShiftRight, "ShiftRight", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x29*/ {opAnd, "And", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x2a*/ {opNand, "Nand", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x2b*/ {opOr, "Or", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x2c*/ {opNor, "Nor", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x2d*/ {opXor, "Xor", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x2e*/ {opNot, "Not", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x2f*/ {opFindSetLeftBit, "FindSetLeftBit", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x30*/ {opFindSetRightBit, "FindSetRightBit", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x31*/ {opDerefOf, "DerefOf", objTypeAny, opFlagExecutable, makeArg1(opArgTermObj)}, - /*0x32*/ {opConcatRes, "ConcatRes", objTypeAny, opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x33*/ {opMod, "Mod", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x34*/ {opNotify, "Notify", objTypeAny, opFlagExecutable, makeArg2(opArgSuperName, opArgTermObj)}, - /*0x35*/ {opSizeOf, "SizeOf", objTypeAny, opFlagExecutable, makeArg1(opArgSuperName)}, - /*0x36*/ {opIndex, "Index", objTypeAny, opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x37*/ {opMatch, "Match", objTypeAny, opFlagExecutable, makeArg6(opArgTermObj, opArgByteData, opArgTermObj, opArgByteData, opArgTermObj, opArgTermObj)}, - /*0x38*/ {opCreateDWordField, "CreateDWordField", objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, - /*0x39*/ {opCreateWordField, "CreateWordField", objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, - /*0x3a*/ {opCreateByteField, "CreateByteField", objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, - /*0x3b*/ {opCreateBitField, "CreateBitField", objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, - /*0x3c*/ {opObjectType, "ObjectType", objTypeAny, opFlagNone, makeArg1(opArgSuperName)}, - /*0x3d*/ {opCreateQWordField, "CreateQWordField", objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, - /*0x3e*/ {opLand, "Land", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, - /*0x3f*/ {opLor, "Lor", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, - /*0x40*/ {opLnot, "Lnot", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg1(opArgTermObj)}, - /*0x41*/ {opLEqual, "LEqual", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, - /*0x42*/ {opLGreater, "LGreater", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, - /*0x43*/ {opLLess, "LLess", objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, - /*0x44*/ {opToBuffer, "ToBuffer", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x45*/ {opToDecimalString, "ToDecimalString", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x46*/ {opToHexString, "ToHexString", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x47*/ {opToInteger, "ToInteger", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x48*/ {opToString, "ToString", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x49*/ {opCopyObject, "CopyObject", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgSimpleName)}, - /*0x4a*/ {opMid, "Mid", objTypeAny, opFlagExecutable, makeArg4(opArgTermObj, opArgTermObj, opArgTermObj, opArgTarget)}, - /*0x4b*/ {opContinue, "Continue", objTypeAny, opFlagExecutable, makeArg0()}, - /*0x4c*/ {opIf, "If", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTermList)}, - /*0x4d*/ {opElse, "Else", objTypeAny, opFlagExecutable | opFlagScoped, makeArg1(opArgTermList)}, - /*0x4e*/ {opWhile, "While", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTermList)}, - /*0x4f*/ {opNoop, "Noop", objTypeAny, opFlagNoOp, makeArg0()}, - /*0x50*/ {opReturn, "Return", objTypeAny, opFlagReturn, makeArg1(opArgTermObj)}, - /*0x51*/ {opBreak, "Break", objTypeAny, opFlagExecutable, makeArg0()}, - /*0x52*/ {opBreakPoint, "BreakPoint", objTypeAny, opFlagNoOp, makeArg0()}, - /*0x53*/ {opOnes, "Ones", objTypeInteger, opFlagConstant, makeArg0()}, - /*0x54*/ {opMutex, "Mutex", objTypeMutex, opFlagNamed, makeArg2(opArgNameString, opArgByteData)}, - /*0x55*/ {opEvent, "Event", objTypeEvent, opFlagNamed, makeArg1(opArgNameString)}, - /*0x56*/ {opCondRefOf, "CondRefOf", objTypeAny, opFlagExecutable, makeArg2(opArgSuperName, opArgSuperName)}, - /*0x57*/ {opCreateField, "CreateField", objTypeBufferField, opFlagExecutable, makeArg4(opArgTermObj, opArgTermObj, opArgTermObj, opArgNameString)}, - /*0x58*/ {opLoadTable, "LoadTable", objTypeAny, opFlagExecutable, makeArg7(opArgTermObj, opArgTermObj, opArgTermObj, opArgTermObj, opArgTermObj, opArgTermObj, opArgTermObj)}, - /*0x59*/ {opLoad, "Load", objTypeAny, opFlagExecutable, makeArg2(opArgNameString, opArgSuperName)}, - /*0x5a*/ {opStall, "Stall", objTypeAny, opFlagExecutable, makeArg1(opArgTermObj)}, - /*0x5b*/ {opSleep, "Sleep", objTypeAny, opFlagExecutable, makeArg1(opArgTermObj)}, - /*0x5c*/ {opAcquire, "Acquire", objTypeAny, opFlagExecutable, makeArg2(opArgNameString, opArgSuperName)}, - /*0x5d*/ {opSignal, "Signal", objTypeAny, opFlagExecutable, makeArg1(opArgTermObj)}, - /*0x5e*/ {opWait, "Wait", objTypeAny, opFlagExecutable, makeArg2(opArgSuperName, opArgTermObj)}, - /*0x5f*/ {opReset, "Reset", objTypeAny, opFlagExecutable, makeArg1(opArgSuperName)}, - /*0x60*/ {opRelease, "Release", objTypeAny, opFlagExecutable, makeArg1(opArgSuperName)}, - /*0x61*/ {opFromBCD, "FromBCD", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x62*/ {opToBCD, "ToBCD", objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, - /*0x63*/ {opUnload, "Unload", objTypeAny, opFlagExecutable, makeArg1(opArgSuperName)}, - /*0x64*/ {opRevision, "Revision", objTypeInteger, opFlagConstant | opFlagExecutable, makeArg0()}, - /*0x65*/ {opDebug, "Debug", objTypeLocalReference, opFlagExecutable, makeArg0()}, - /*0x66*/ {opFatal, "Fatal", objTypeAny, opFlagExecutable, makeArg3(opArgByteData, opArgDword, opArgTermObj)}, - /*0x67*/ {opTimer, "Timer", objTypeAny, opFlagNone, makeArg0()}, - /*0x68*/ {opOpRegion, "OpRegion", objTypeRegion, opFlagNamed, makeArg4(opArgNameString, opArgByteData, opArgTermObj, opArgTermObj)}, - /*0x69*/ {opField, "Field", objTypeAny, opFlagNone, makeArg3(opArgNameString, opArgByteData, opArgFieldList)}, - /*0x6a*/ {opDevice, "Device", objTypeDevice, opFlagNamed | opFlagScoped, makeArg2(opArgNameString, opArgTermList)}, - /*0x6b*/ {opProcessor, "Processor", objTypeProcessor, opFlagNamed | opFlagScoped, makeArg5(opArgNameString, opArgByteData, opArgDword, opArgByteData, opArgTermList)}, - /*0x6c*/ {opPowerRes, "PowerRes", objTypePower, opFlagNamed | opFlagScoped, makeArg4(opArgNameString, opArgByteData, opArgWord, opArgTermList)}, - /*0x6d*/ {opThermalZone, "ThermalZone", objTypeThermal, opFlagNamed | opFlagScoped, makeArg2(opArgNameString, opArgTermList)}, - /*0x6e*/ {opIndexField, "IndexField", objTypeAny, opFlagNone, makeArg4(opArgNameString, opArgNameString, opArgByteData, opArgFieldList)}, - /*0x6f*/ {opBankField, "BankField", objTypeLocalBankField, opFlagNamed, makeArg5(opArgNameString, opArgNameString, opArgTermObj, opArgByteData, opArgFieldList)}, - /*0x70*/ {opDataRegion, "DataRegion", objTypeLocalRegionField, opFlagNamed, makeArg4(opArgNameString, opArgTermObj, opArgTermObj, opArgTermObj)}, -} - -// opcodeMap maps an AML opcode to an entry in the opcode table. Entries with -// the value 0xff indicate an invalid/unsupported opcode. -var opcodeMap = [256]uint8{ - /* 0 1 2 3 4 5 6 7*/ - /*0x00 - 0x07*/ 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x02, 0xff, - /*0x08 - 0x0f*/ 0x03, 0xff, 0x04, 0x05, 0x06, 0x07, 0x08, 0xff, - /*0x10 - 0x17*/ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xff, 0xff, - /*0x18 - 0x1f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x20 - 0x27*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x28 - 0x2f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x30 - 0x37*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x38 - 0x3f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x40 - 0x47*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x48 - 0x4f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x50 - 0x57*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x58 - 0x5f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x60 - 0x67*/ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - /*0x68 - 0x6f*/ 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0xff, - /*0x70 - 0x77*/ 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, - /*0x78 - 0x7f*/ 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, - /*0x80 - 0x87*/ 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, - /*0x88 - 0x8f*/ 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, - /*0x90 - 0x97*/ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - /*0x98 - 0x9f*/ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x49, 0x4a, 0x4b, - /*0xa0 - 0xa7*/ 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0xff, 0xff, - /*0xa8 - 0xaf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xb0 - 0xb7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xb8 - 0xbf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xc0 - 0xc7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xc8 - 0xcf*/ 0xff, 0xff, 0xff, 0xff, 0x52, 0xff, 0xff, 0xff, - /*0xd0 - 0xd7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xd8 - 0xdf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xe0 - 0xe7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xe8 - 0xef*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xf0 - 0xf7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xf8 - 0xff*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x53, -} - -// extendedOpcodeMap maps an AML extended opcode (extOpPrefix + code) to an -// entry in the opcode table. Entries with the value 0xff indicate an -// invalid/unsupported opcode. -var extendedOpcodeMap = [256]uint8{ - /* 0 1 2 3 4 5 6 7*/ - /*0x00 - 0x07*/ 0xff, 0x54, 0x55, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x08 - 0x0f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x10 - 0x17*/ 0xff, 0xff, 0x56, 0x57, 0xff, 0xff, 0xff, 0xff, - /*0x18 - 0x1f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x58, - /*0x20 - 0x27*/ 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, - /*0x28 - 0x2f*/ 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x30 - 0x37*/ 0x64, 0x65, 0x66, 0x67, 0xff, 0xff, 0xff, 0xff, - /*0x38 - 0x3f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x40 - 0x47*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x48 - 0x4f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x50 - 0x57*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x58 - 0x5f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x60 - 0x67*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x68 - 0x6f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x70 - 0x77*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x78 - 0x7f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x80 - 0x87*/ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - /*0x88 - 0x8f*/ 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x90 - 0x97*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0x98 - 0x9f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xa0 - 0xa7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xa8 - 0xaf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xb0 - 0xb7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xb8 - 0xbf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xc0 - 0xc7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xc8 - 0xcf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xd0 - 0xd7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xd8 - 0xdf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xe0 - 0xe7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xe8 - 0xef*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xf0 - 0xf7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /*0xf8 - 0xff*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x53, -} diff --git a/src/gopheros/device/acpi/aml/opcode_test.go b/src/gopheros/device/acpi/aml/opcode_test.go deleted file mode 100644 index 7258759..0000000 --- a/src/gopheros/device/acpi/aml/opcode_test.go +++ /dev/null @@ -1,187 +0,0 @@ -package aml - -import "testing" - -func TestOpcodeToString(t *testing.T) { - if exp, got := "Acquire", opAcquire.String(); got != exp { - t.Fatalf("expected opAcquire.toString() to return %q; got %q", exp, got) - } - - if exp, got := "unknown", opcode(0xffff).String(); got != exp { - t.Fatalf("expected opcode.String() to return %q; got %q", exp, got) - } -} - -func TestOpcodeIsX(t *testing.T) { - specs := []struct { - op opcode - testFn func(opcode) bool - want bool - }{ - // opIsLocalArg - {opLocal0, opIsLocalArg, true}, - {opLocal1, opIsLocalArg, true}, - {opLocal2, opIsLocalArg, true}, - {opLocal3, opIsLocalArg, true}, - {opLocal4, opIsLocalArg, true}, - {opLocal5, opIsLocalArg, true}, - {opLocal6, opIsLocalArg, true}, - {opLocal7, opIsLocalArg, true}, - {opArg0, opIsLocalArg, false}, - {opDivide, opIsLocalArg, false}, - // opIsMethodArg - {opArg0, opIsMethodArg, true}, - {opArg1, opIsMethodArg, true}, - {opArg2, opIsMethodArg, true}, - {opArg3, opIsMethodArg, true}, - {opArg4, opIsMethodArg, true}, - {opArg5, opIsMethodArg, true}, - {opArg6, opIsMethodArg, true}, - {opLocal7, opIsMethodArg, false}, - {opIf, opIsMethodArg, false}, - // opIsArg - {opLocal5, opIsArg, true}, - {opArg1, opIsArg, true}, - {opDivide, opIsArg, false}, - // opIsType2 - {opAcquire, opIsType2, true}, - {opAdd, opIsType2, true}, - {opAnd, opIsType2, true}, - {opBuffer, opIsType2, true}, - {opConcat, opIsType2, true}, - {opConcatRes, opIsType2, true}, - {opCondRefOf, opIsType2, true}, - {opCopyObject, opIsType2, true}, - {opDecrement, opIsType2, true}, - {opDerefOf, opIsType2, true}, - {opDivide, opIsType2, true}, - {opFindSetLeftBit, opIsType2, true}, - {opFindSetRightBit, opIsType2, true}, - {opFromBCD, opIsType2, true}, - {opIncrement, opIsType2, true}, - {opIndex, opIsType2, true}, - {opLand, opIsType2, true}, - {opLEqual, opIsType2, true}, - {opLGreater, opIsType2, true}, - {opLLess, opIsType2, true}, - {opMid, opIsType2, true}, - {opLnot, opIsType2, true}, - {opLoadTable, opIsType2, true}, - {opLor, opIsType2, true}, - {opMatch, opIsType2, true}, - {opMod, opIsType2, true}, - {opMultiply, opIsType2, true}, - {opNand, opIsType2, true}, - {opNor, opIsType2, true}, - {opNot, opIsType2, true}, - {opObjectType, opIsType2, true}, - {opOr, opIsType2, true}, - {opPackage, opIsType2, true}, - {opVarPackage, opIsType2, true}, - {opRefOf, opIsType2, true}, - {opShiftLeft, opIsType2, true}, - {opShiftRight, opIsType2, true}, - {opSizeOf, opIsType2, true}, - {opStore, opIsType2, true}, - {opSubtract, opIsType2, true}, - {opTimer, opIsType2, true}, - {opToBCD, opIsType2, true}, - {opToBuffer, opIsType2, true}, - {opToDecimalString, opIsType2, true}, - {opToHexString, opIsType2, true}, - {opToInteger, opIsType2, true}, - {opToString, opIsType2, true}, - {opWait, opIsType2, true}, - {opXor, opIsType2, true}, - {opBytePrefix, opIsType2, false}, - // opIsDataObject - {opBytePrefix, opIsDataObject, true}, - {opWordPrefix, opIsDataObject, true}, - {opDwordPrefix, opIsDataObject, true}, - {opQwordPrefix, opIsDataObject, true}, - {opStringPrefix, opIsDataObject, true}, - {opZero, opIsDataObject, true}, - {opOne, opIsDataObject, true}, - {opOnes, opIsDataObject, true}, - {opRevision, opIsDataObject, true}, - {opBuffer, opIsDataObject, true}, - {opPackage, opIsDataObject, true}, - {opVarPackage, opIsDataObject, true}, - {opLor, opIsDataObject, false}, - // opIsBufferField - {opCreateField, opIsBufferField, true}, - {opCreateBitField, opIsBufferField, true}, - {opCreateByteField, opIsBufferField, true}, - {opCreateWordField, opIsBufferField, true}, - {opCreateDWordField, opIsBufferField, true}, - {opCreateQWordField, opIsBufferField, true}, - {opRevision, opIsBufferField, false}, - } - - for specIndex, spec := range specs { - if got := spec.testFn(spec.op); got != spec.want { - t.Errorf("[spec %d] opcode %q: expected to get %t; got %t", specIndex, spec.op, spec.want, got) - } - } -} - -func TestOpArgFlagToString(t *testing.T) { - specs := map[opArgFlag]string{ - opArgTermList: "opArgTermList", - opArgTermObj: "opArgTermObj", - opArgByteList: "opArgByteList", - opArgPackage: "opArgPackage", - opArgString: "opArgString", - opArgByteData: "opArgByteData", - opArgWord: "opArgWord", - opArgDword: "opArgDword", - opArgQword: "opArgQword", - opArgNameString: "opArgNameString", - opArgSuperName: "opArgSuperName", - opArgSimpleName: "opArgSimpleName", - opArgDataRefObj: "opArgDataRefObj", - opArgTarget: "opArgTarget", - opArgFieldList: "opArgFieldList", - opArgFlag(0xff): "", - } - - for flag, want := range specs { - if got := flag.String(); got != want { - t.Errorf("expected %q; got %q", want, got) - } - } -} - -// TestFindUnmappedOpcodes is a helper test that pinpoints opcodes that have -// not yet been mapped via an opcode table. This test will be removed once all -// opcodes are supported. -func TestFindUnmappedOpcodes(t *testing.T) { - //t.SkipNow() - for opIndex, opRef := range opcodeMap { - if opRef != badOpcode { - continue - } - - for tabIndex, info := range opcodeTable { - if uint16(info.op) == uint16(opIndex) { - t.Errorf("set opcodeMap[0x%02x] = 0x%02x // %s\n", opIndex, tabIndex, info.op.String()) - break - } - } - } - - for opIndex, opRef := range extendedOpcodeMap { - // 0xff (opOnes) is defined in opcodeTable - if opRef != badOpcode || opIndex == 0 { - continue - } - - opIndex += 0xff - for tabIndex, info := range opcodeTable { - if uint16(info.op) == uint16(opIndex) { - t.Errorf("set extendedOpcodeMap[0x%02x] = 0x%02x // %s\n", opIndex-0xff, tabIndex, info.op.String()) - break - } - } - } -} diff --git a/src/gopheros/device/acpi/aml/parser/opcode_table.go b/src/gopheros/device/acpi/aml/parser/opcode_table.go new file mode 100644 index 0000000..df983dc --- /dev/null +++ b/src/gopheros/device/acpi/aml/parser/opcode_table.go @@ -0,0 +1,339 @@ +package parser + +import "gopheros/device/acpi/aml/entity" + +const ( + badOpcode = 0xff + extOpPrefix = 0x5b +) + +// objType represents the object types that are supported by the AML parser. +type objType uint8 + +// The list of AML object types. +const ( + objTypeAny objType = iota + objTypeInteger + objTypeString + objTypeBuffer + objTypePackage + objTypeDevice + objTypeEvent + objTypeMethod + objTypeMutex + objTypeRegion + objTypePower + objTypeProcessor + objTypeThermal + objTypeBufferField + objTypeLocalRegionField + objTypeLocalBankField + objTypeLocalReference + objTypeLocalAlias + objTypeLocalScope + objTypeLocalVariable + objTypeMethodArgument +) + +// opFlag specifies a list of OR-able flags that describe the object +// type/attributes generated by a particular opcode. +type opFlag uint16 + +const ( + opFlagNone opFlag = 1 << iota + opFlagHasPkgLen + opFlagNamed + opFlagConstant + opFlagReference + opFlagArithmetic + opFlagCreate + opFlagReturn + opFlagExecutable + opFlagNoOp + opFlagScoped +) + +// is returns true if f is set in this opFlag. +func (fl opFlag) is(f opFlag) bool { + return (fl & f) != 0 +} + +// opArgFlags encodes up to 7 opArgFlag values in a uint64 value. +type opArgFlags uint64 + +// argCount returns the number of encoded args in the given flag. +func (fl opArgFlags) argCount() (count uint8) { + // Each argument is specified using 8 bits with 0x0 indicating the end of the + // argument list + for ; fl&0xf != 0; fl, count = fl>>8, count+1 { + } + + return count +} + +// arg returns the arg flags for argument "num" where num is the 0-based index +// of the argument to return. The allowed values for num are 0-6. +func (fl opArgFlags) arg(num uint8) opArgFlag { + return opArgFlag((fl >> (num * 8)) & 0xf) +} + +// contains returns true if the arg flags contain any argument with type x. +func (fl opArgFlags) contains(x opArgFlag) bool { + // Each argument is specified using 8 bits with 0x0 indicating the end of the + // argument list + for ; fl&0xf != 0; fl >>= 8 { + if opArgFlag(fl&0xf) == x { + return true + } + } + + return false +} + +// opArgFlag represents the type of an argument expected by a particular opcode. +type opArgFlag uint8 + +// The list of supported opArgFlag values. +const ( + _ opArgFlag = iota + opArgTermList + opArgTermObj + opArgByteList + opArgPackage + opArgString + opArgByteData + opArgWord + opArgDword + opArgQword + opArgNameString + opArgSuperName + opArgSimpleName + opArgDataRefObj + opArgTarget + opArgFieldList +) + +func makeArg0() opArgFlags { return 0 } +func makeArg1(arg0 opArgFlag) opArgFlags { return opArgFlags(arg0) } +func makeArg2(arg0, arg1 opArgFlag) opArgFlags { return opArgFlags(arg1)<<8 | opArgFlags(arg0) } +func makeArg3(arg0, arg1, arg2 opArgFlag) opArgFlags { + return opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) +} +func makeArg4(arg0, arg1, arg2, arg3 opArgFlag) opArgFlags { + return opArgFlags(arg3)<<24 | opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) +} +func makeArg5(arg0, arg1, arg2, arg3, arg4 opArgFlag) opArgFlags { + return opArgFlags(arg4)<<32 | opArgFlags(arg3)<<24 | opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) +} +func makeArg6(arg0, arg1, arg2, arg3, arg4, arg5 opArgFlag) opArgFlags { + return opArgFlags(arg5)<<40 | opArgFlags(arg4)<<32 | opArgFlags(arg3)<<24 | opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) +} +func makeArg7(arg0, arg1, arg2, arg3, arg4, arg5, arg6 opArgFlag) opArgFlags { + return opArgFlags(arg6)<<48 | opArgFlags(arg5)<<40 | opArgFlags(arg4)<<32 | opArgFlags(arg3)<<24 | opArgFlags(arg2)<<16 | opArgFlags(arg1)<<8 | opArgFlags(arg0) +} + +// opcodeInfo contains all known information about an opcode, +// its argument count and types as well as the type of object +// represented by it. +type opcodeInfo struct { + op entity.AMLOpcode + objType objType + + flags opFlag + argFlags opArgFlags +} + +// The opcode table contains all opcode-related information that the parser knows. +// This table is modeled after a similar table used in the acpica implementation. +var opcodeTable = []opcodeInfo{ + /*0x00*/ {entity.OpZero, objTypeInteger, opFlagConstant, makeArg0()}, + /*0x01*/ {entity.OpOne, objTypeInteger, opFlagConstant, makeArg0()}, + /*0x02*/ {entity.OpAlias, objTypeLocalAlias, opFlagNamed, makeArg2(opArgNameString, opArgNameString)}, + /*0x03*/ {entity.OpName, objTypeAny, opFlagNamed, makeArg2(opArgNameString, opArgDataRefObj)}, + /*0x04*/ {entity.OpBytePrefix, objTypeInteger, opFlagConstant, makeArg1(opArgByteData)}, + /*0x05*/ {entity.OpWordPrefix, objTypeInteger, opFlagConstant, makeArg1(opArgWord)}, + /*0x06*/ {entity.OpDwordPrefix, objTypeInteger, opFlagConstant, makeArg1(opArgDword)}, + /*0x07*/ {entity.OpStringPrefix, objTypeString, opFlagConstant, makeArg1(opArgString)}, + /*0x08*/ {entity.OpQwordPrefix, objTypeInteger, opFlagConstant, makeArg1(opArgQword)}, + /*0x09*/ {entity.OpScope, objTypeLocalScope, opFlagNamed, makeArg2(opArgNameString, opArgTermList)}, + /*0x0a*/ {entity.OpBuffer, objTypeBuffer, opFlagHasPkgLen, makeArg2(opArgTermObj, opArgByteList)}, + /*0x0b*/ {entity.OpPackage, objTypePackage, opFlagNone, makeArg2(opArgByteData, opArgTermList)}, + /*0x0c*/ {entity.OpVarPackage, objTypePackage, opFlagNone, makeArg2(opArgByteData, opArgTermList)}, + /*0x0d*/ {entity.OpMethod, objTypeMethod, opFlagNamed | opFlagScoped, makeArg3(opArgNameString, opArgByteData, opArgTermList)}, + /*0x0e*/ {entity.OpExternal, objTypeAny, opFlagNamed, makeArg3(opArgNameString, opArgByteData, opArgByteData)}, + /*0x0f*/ {entity.OpLocal0, objTypeLocalVariable, opFlagExecutable, makeArg0()}, + /*0x10*/ {entity.OpLocal1, objTypeLocalVariable, opFlagExecutable, makeArg0()}, + /*0x11*/ {entity.OpLocal2, objTypeLocalVariable, opFlagExecutable, makeArg0()}, + /*0x12*/ {entity.OpLocal3, objTypeLocalVariable, opFlagExecutable, makeArg0()}, + /*0x13*/ {entity.OpLocal4, objTypeLocalVariable, opFlagExecutable, makeArg0()}, + /*0120*/ {entity.OpLocal5, objTypeLocalVariable, opFlagExecutable, makeArg0()}, + /*0x15*/ {entity.OpLocal6, objTypeLocalVariable, opFlagExecutable, makeArg0()}, + /*0x16*/ {entity.OpLocal7, objTypeLocalVariable, opFlagExecutable, makeArg0()}, + /*0x17*/ {entity.OpArg0, objTypeMethodArgument, opFlagExecutable, makeArg0()}, + /*0x18*/ {entity.OpArg1, objTypeMethodArgument, opFlagExecutable, makeArg0()}, + /*0x19*/ {entity.OpArg2, objTypeMethodArgument, opFlagExecutable, makeArg0()}, + /*0x1a*/ {entity.OpArg3, objTypeMethodArgument, opFlagExecutable, makeArg0()}, + /*0x1b*/ {entity.OpArg4, objTypeMethodArgument, opFlagExecutable, makeArg0()}, + /*0x1c*/ {entity.OpArg5, objTypeMethodArgument, opFlagExecutable, makeArg0()}, + /*0x1d*/ {entity.OpArg6, objTypeMethodArgument, opFlagExecutable, makeArg0()}, + /*0x1e*/ {entity.OpStore, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgSuperName)}, + /*0x1f*/ {entity.OpRefOf, objTypeAny, opFlagReference | opFlagExecutable, makeArg1(opArgSuperName)}, + /*0x20*/ {entity.OpAdd, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x21*/ {entity.OpConcat, objTypeAny, opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x22*/ {entity.OpSubtract, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x23*/ {entity.OpIncrement, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg1(opArgSuperName)}, + /*0x24*/ {entity.OpDecrement, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg1(opArgSuperName)}, + /*0x25*/ {entity.OpMultiply, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x26*/ {entity.OpDivide, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg4(opArgTermObj, opArgTermObj, opArgTarget, opArgTarget)}, + /*0x27*/ {entity.OpShiftLeft, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x28*/ {entity.OpShiftRight, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x29*/ {entity.OpAnd, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x2a*/ {entity.OpNand, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x2b*/ {entity.OpOr, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x2c*/ {entity.OpNor, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x2d*/ {entity.OpXor, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x2e*/ {entity.OpNot, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x2f*/ {entity.OpFindSetLeftBit, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x30*/ {entity.OpFindSetRightBit, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x31*/ {entity.OpDerefOf, objTypeAny, opFlagExecutable, makeArg1(opArgTermObj)}, + /*0x32*/ {entity.OpConcatRes, objTypeAny, opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x33*/ {entity.OpMod, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x34*/ {entity.OpNotify, objTypeAny, opFlagExecutable, makeArg2(opArgSuperName, opArgTermObj)}, + /*0x35*/ {entity.OpSizeOf, objTypeAny, opFlagExecutable, makeArg1(opArgSuperName)}, + /*0x36*/ {entity.OpIndex, objTypeAny, opFlagExecutable, makeArg3(opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x37*/ {entity.OpMatch, objTypeAny, opFlagExecutable, makeArg6(opArgTermObj, opArgByteData, opArgTermObj, opArgByteData, opArgTermObj, opArgTermObj)}, + /*0x38*/ {entity.OpCreateDWordField, objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, + /*0x39*/ {entity.OpCreateWordField, objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, + /*0x3a*/ {entity.OpCreateByteField, objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, + /*0x3b*/ {entity.OpCreateBitField, objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, + /*0x3c*/ {entity.OpObjectType, objTypeAny, opFlagNone, makeArg1(opArgSuperName)}, + /*0x3d*/ {entity.OpCreateQWordField, objTypeBufferField, opFlagNamed | opFlagCreate, makeArg3(opArgTermObj, opArgTermObj, opArgNameString)}, + /*0x3e*/ {entity.OpLand, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, + /*0x3f*/ {entity.OpLor, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, + /*0x40*/ {entity.OpLnot, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg1(opArgTermObj)}, + /*0x41*/ {entity.OpLEqual, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, + /*0x42*/ {entity.OpLGreater, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, + /*0x43*/ {entity.OpLLess, objTypeAny, opFlagArithmetic | opFlagExecutable, makeArg2(opArgTermObj, opArgTermObj)}, + /*0x44*/ {entity.OpToBuffer, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x45*/ {entity.OpToDecimalString, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x46*/ {entity.OpToHexString, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x47*/ {entity.OpToInteger, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x48*/ {entity.OpToString, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x49*/ {entity.OpCopyObject, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgSimpleName)}, + /*0x4a*/ {entity.OpMid, objTypeAny, opFlagExecutable, makeArg4(opArgTermObj, opArgTermObj, opArgTermObj, opArgTarget)}, + /*0x4b*/ {entity.OpContinue, objTypeAny, opFlagExecutable, makeArg0()}, + /*0x4c*/ {entity.OpIf, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTermList)}, + /*0x4d*/ {entity.OpElse, objTypeAny, opFlagExecutable | opFlagScoped, makeArg1(opArgTermList)}, + /*0x4e*/ {entity.OpWhile, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTermList)}, + /*0x4f*/ {entity.OpNoop, objTypeAny, opFlagNoOp, makeArg0()}, + /*0x50*/ {entity.OpReturn, objTypeAny, opFlagReturn, makeArg1(opArgTermObj)}, + /*0x51*/ {entity.OpBreak, objTypeAny, opFlagExecutable, makeArg0()}, + /*0x52*/ {entity.OpBreakPoint, objTypeAny, opFlagNoOp, makeArg0()}, + /*0x53*/ {entity.OpOnes, objTypeInteger, opFlagConstant, makeArg0()}, + /*0x54*/ {entity.OpMutex, objTypeMutex, opFlagNamed, makeArg2(opArgNameString, opArgByteData)}, + /*0x55*/ {entity.OpEvent, objTypeEvent, opFlagNamed, makeArg1(opArgNameString)}, + /*0x56*/ {entity.OpCondRefOf, objTypeAny, opFlagExecutable, makeArg2(opArgSuperName, opArgSuperName)}, + /*0x57*/ {entity.OpCreateField, objTypeBufferField, opFlagExecutable, makeArg4(opArgTermObj, opArgTermObj, opArgTermObj, opArgNameString)}, + /*0x58*/ {entity.OpLoadTable, objTypeAny, opFlagExecutable, makeArg7(opArgTermObj, opArgTermObj, opArgTermObj, opArgTermObj, opArgTermObj, opArgTermObj, opArgTermObj)}, + /*0x59*/ {entity.OpLoad, objTypeAny, opFlagExecutable, makeArg2(opArgNameString, opArgSuperName)}, + /*0x5a*/ {entity.OpStall, objTypeAny, opFlagExecutable, makeArg1(opArgTermObj)}, + /*0x5b*/ {entity.OpSleep, objTypeAny, opFlagExecutable, makeArg1(opArgTermObj)}, + /*0x5c*/ {entity.OpAcquire, objTypeAny, opFlagExecutable, makeArg2(opArgNameString, opArgSuperName)}, + /*0x5d*/ {entity.OpSignal, objTypeAny, opFlagExecutable, makeArg1(opArgTermObj)}, + /*0x5e*/ {entity.OpWait, objTypeAny, opFlagExecutable, makeArg2(opArgSuperName, opArgTermObj)}, + /*0x5f*/ {entity.OpReset, objTypeAny, opFlagExecutable, makeArg1(opArgSuperName)}, + /*0x60*/ {entity.OpRelease, objTypeAny, opFlagExecutable, makeArg1(opArgSuperName)}, + /*0x61*/ {entity.OpFromBCD, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x62*/ {entity.OpToBCD, objTypeAny, opFlagExecutable, makeArg2(opArgTermObj, opArgTarget)}, + /*0x63*/ {entity.OpUnload, objTypeAny, opFlagExecutable, makeArg1(opArgSuperName)}, + /*0x64*/ {entity.OpRevision, objTypeInteger, opFlagConstant | opFlagExecutable, makeArg0()}, + /*0x65*/ {entity.OpDebug, objTypeLocalReference, opFlagExecutable, makeArg0()}, + /*0x66*/ {entity.OpFatal, objTypeAny, opFlagExecutable, makeArg3(opArgByteData, opArgDword, opArgTermObj)}, + /*0x67*/ {entity.OpTimer, objTypeAny, opFlagNone, makeArg0()}, + /*0x68*/ {entity.OpOpRegion, objTypeRegion, opFlagNamed, makeArg4(opArgNameString, opArgByteData, opArgTermObj, opArgTermObj)}, + /*0x69*/ {entity.OpField, objTypeAny, opFlagNone, makeArg3(opArgNameString, opArgByteData, opArgFieldList)}, + /*0x6a*/ {entity.OpDevice, objTypeDevice, opFlagNamed | opFlagScoped, makeArg2(opArgNameString, opArgTermList)}, + /*0x6b*/ {entity.OpProcessor, objTypeProcessor, opFlagNamed | opFlagScoped, makeArg5(opArgNameString, opArgByteData, opArgDword, opArgByteData, opArgTermList)}, + /*0x6c*/ {entity.OpPowerRes, objTypePower, opFlagNamed | opFlagScoped, makeArg4(opArgNameString, opArgByteData, opArgWord, opArgTermList)}, + /*0x6d*/ {entity.OpThermalZone, objTypeThermal, opFlagNamed | opFlagScoped, makeArg2(opArgNameString, opArgTermList)}, + /*0x6e*/ {entity.OpIndexField, objTypeAny, opFlagNone, makeArg4(opArgNameString, opArgNameString, opArgByteData, opArgFieldList)}, + /*0x6f*/ {entity.OpBankField, objTypeLocalBankField, opFlagNamed, makeArg5(opArgNameString, opArgNameString, opArgTermObj, opArgByteData, opArgFieldList)}, + /*0x70*/ {entity.OpDataRegion, objTypeLocalRegionField, opFlagNamed, makeArg4(opArgNameString, opArgTermObj, opArgTermObj, opArgTermObj)}, +} + +// opcodeMap maps an AML opcode to an entry in the opcode table. Entries with +// the value 0xff indicate an invalid/unsupported opcode. +var opcodeMap = [256]uint8{ + /* 0 1 2 3 4 5 6 7*/ + /*0x00 - 0x07*/ 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x02, 0xff, + /*0x08 - 0x0f*/ 0x03, 0xff, 0x04, 0x05, 0x06, 0x07, 0x08, 0xff, + /*0x10 - 0x17*/ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xff, 0xff, + /*0x18 - 0x1f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x20 - 0x27*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x28 - 0x2f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x30 - 0x37*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x38 - 0x3f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x40 - 0x47*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x48 - 0x4f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x50 - 0x57*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x58 - 0x5f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x60 - 0x67*/ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + /*0x68 - 0x6f*/ 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0xff, + /*0x70 - 0x77*/ 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + /*0x78 - 0x7f*/ 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + /*0x80 - 0x87*/ 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + /*0x88 - 0x8f*/ 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + /*0x90 - 0x97*/ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + /*0x98 - 0x9f*/ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x49, 0x4a, 0x4b, + /*0xa0 - 0xa7*/ 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0xff, 0xff, + /*0xa8 - 0xaf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xb0 - 0xb7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xb8 - 0xbf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xc0 - 0xc7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xc8 - 0xcf*/ 0xff, 0xff, 0xff, 0xff, 0x52, 0xff, 0xff, 0xff, + /*0xd0 - 0xd7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xd8 - 0xdf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xe0 - 0xe7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xe8 - 0xef*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xf0 - 0xf7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xf8 - 0xff*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x53, +} + +// extendedOpcodeMap maps an AML extended opcode (extOpPrefix + code) to an +// entry in the opcode table. Entries with the value 0xff indicate an +// invalid/unsupported opcode. +var extendedOpcodeMap = [256]uint8{ + /* 0 1 2 3 4 5 6 7*/ + /*0x00 - 0x07*/ 0xff, 0x54, 0x55, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x08 - 0x0f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x10 - 0x17*/ 0xff, 0xff, 0x56, 0x57, 0xff, 0xff, 0xff, 0xff, + /*0x18 - 0x1f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x58, + /*0x20 - 0x27*/ 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, + /*0x28 - 0x2f*/ 0x61, 0x62, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x30 - 0x37*/ 0x64, 0x65, 0x66, 0x67, 0xff, 0xff, 0xff, 0xff, + /*0x38 - 0x3f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x40 - 0x47*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x48 - 0x4f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x50 - 0x57*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x58 - 0x5f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x60 - 0x67*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x68 - 0x6f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x70 - 0x77*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x78 - 0x7f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x80 - 0x87*/ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + /*0x88 - 0x8f*/ 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x90 - 0x97*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0x98 - 0x9f*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xa0 - 0xa7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xa8 - 0xaf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xb0 - 0xb7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xb8 - 0xbf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xc0 - 0xc7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xc8 - 0xcf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xd0 - 0xd7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xd8 - 0xdf*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xe0 - 0xe7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xe8 - 0xef*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xf0 - 0xf7*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /*0xf8 - 0xff*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x53, +} diff --git a/src/gopheros/device/acpi/aml/parser/opcode_test.go b/src/gopheros/device/acpi/aml/parser/opcode_test.go new file mode 100644 index 0000000..ee5bdd5 --- /dev/null +++ b/src/gopheros/device/acpi/aml/parser/opcode_test.go @@ -0,0 +1,35 @@ +package parser + +import "testing" + +// TestFindUnmappedOpcodes is a helper test that pinpoints opcodes that have +// not yet been mapped via an opcode table. +func TestFindUnmappedOpcodes(t *testing.T) { + for opIndex, opRef := range opcodeMap { + if opRef != badOpcode { + continue + } + + for tabIndex, info := range opcodeTable { + if uint16(info.op) == uint16(opIndex) { + t.Errorf("set opcodeMap[0x%02x] = 0x%02x // %s\n", opIndex, tabIndex, info.op.String()) + break + } + } + } + + for opIndex, opRef := range extendedOpcodeMap { + // 0xff (opOnes) is defined in opcodeTable + if opRef != badOpcode || opIndex == 0 { + continue + } + + opIndex += 0xff + for tabIndex, info := range opcodeTable { + if uint16(info.op) == uint16(opIndex) { + t.Errorf("set extendedOpcodeMap[0x%02x] = 0x%02x // %s\n", opIndex-0xff, tabIndex, info.op.String()) + break + } + } + } +}