diff --git a/src/gopheros/device/acpi/aml/entity/opcode.go b/src/gopheros/device/acpi/aml/entity/opcode.go new file mode 100644 index 0000000..7c0bf67 --- /dev/null +++ b/src/gopheros/device/acpi/aml/entity/opcode.go @@ -0,0 +1,202 @@ +package entity + +// AMLOpcode 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 AMLOpcode uint16 + +const ( + // Regular opcode list + OpZero = AMLOpcode(0x00) + OpOne = AMLOpcode(0x01) + OpAlias = AMLOpcode(0x06) + OpName = AMLOpcode(0x08) + OpBytePrefix = AMLOpcode(0x0a) + OpWordPrefix = AMLOpcode(0x0b) + OpDwordPrefix = AMLOpcode(0x0c) + OpStringPrefix = AMLOpcode(0x0d) + OpQwordPrefix = AMLOpcode(0x0e) + OpScope = AMLOpcode(0x10) + OpBuffer = AMLOpcode(0x11) + OpPackage = AMLOpcode(0x12) + OpVarPackage = AMLOpcode(0x13) + OpMethod = AMLOpcode(0x14) + OpExternal = AMLOpcode(0x15) + OpLocal0 = AMLOpcode(0x60) + OpLocal1 = AMLOpcode(0x61) + OpLocal2 = AMLOpcode(0x62) + OpLocal3 = AMLOpcode(0x63) + OpLocal4 = AMLOpcode(0x64) + OpLocal5 = AMLOpcode(0x65) + OpLocal6 = AMLOpcode(0x66) + OpLocal7 = AMLOpcode(0x67) + OpArg0 = AMLOpcode(0x68) + OpArg1 = AMLOpcode(0x69) + OpArg2 = AMLOpcode(0x6a) + OpArg3 = AMLOpcode(0x6b) + OpArg4 = AMLOpcode(0x6c) + OpArg5 = AMLOpcode(0x6d) + OpArg6 = AMLOpcode(0x6e) + OpStore = AMLOpcode(0x70) + OpRefOf = AMLOpcode(0x71) + OpAdd = AMLOpcode(0x72) + OpConcat = AMLOpcode(0x73) + OpSubtract = AMLOpcode(0x74) + OpIncrement = AMLOpcode(0x75) + OpDecrement = AMLOpcode(0x76) + OpMultiply = AMLOpcode(0x77) + OpDivide = AMLOpcode(0x78) + OpShiftLeft = AMLOpcode(0x79) + OpShiftRight = AMLOpcode(0x7a) + OpAnd = AMLOpcode(0x7b) + OpNand = AMLOpcode(0x7c) + OpOr = AMLOpcode(0x7d) + OpNor = AMLOpcode(0x7e) + OpXor = AMLOpcode(0x7f) + OpNot = AMLOpcode(0x80) + OpFindSetLeftBit = AMLOpcode(0x81) + OpFindSetRightBit = AMLOpcode(0x82) + OpDerefOf = AMLOpcode(0x83) + OpConcatRes = AMLOpcode(0x84) + OpMod = AMLOpcode(0x85) + OpNotify = AMLOpcode(0x86) + OpSizeOf = AMLOpcode(0x87) + OpIndex = AMLOpcode(0x88) + OpMatch = AMLOpcode(0x89) + OpCreateDWordField = AMLOpcode(0x8a) + OpCreateWordField = AMLOpcode(0x8b) + OpCreateByteField = AMLOpcode(0x8c) + OpCreateBitField = AMLOpcode(0x8d) + OpObjectType = AMLOpcode(0x8e) + OpCreateQWordField = AMLOpcode(0x8f) + OpLand = AMLOpcode(0x90) + OpLor = AMLOpcode(0x91) + OpLnot = AMLOpcode(0x92) + OpLEqual = AMLOpcode(0x93) + OpLGreater = AMLOpcode(0x94) + OpLLess = AMLOpcode(0x95) + OpToBuffer = AMLOpcode(0x96) + OpToDecimalString = AMLOpcode(0x97) + OpToHexString = AMLOpcode(0x98) + OpToInteger = AMLOpcode(0x99) + OpToString = AMLOpcode(0x9c) + OpCopyObject = AMLOpcode(0x9d) + OpMid = AMLOpcode(0x9e) + OpContinue = AMLOpcode(0x9f) + OpIf = AMLOpcode(0xa0) + OpElse = AMLOpcode(0xa1) + OpWhile = AMLOpcode(0xa2) + OpNoop = AMLOpcode(0xa3) + OpReturn = AMLOpcode(0xa4) + OpBreak = AMLOpcode(0xa5) + OpBreakPoint = AMLOpcode(0xcc) + OpOnes = AMLOpcode(0xff) + // Extended opcodes + OpMutex = AMLOpcode(0xff + 0x01) + OpEvent = AMLOpcode(0xff + 0x02) + OpCondRefOf = AMLOpcode(0xff + 0x12) + OpCreateField = AMLOpcode(0xff + 0x13) + OpLoadTable = AMLOpcode(0xff + 0x1f) + OpLoad = AMLOpcode(0xff + 0x20) + OpStall = AMLOpcode(0xff + 0x21) + OpSleep = AMLOpcode(0xff + 0x22) + OpAcquire = AMLOpcode(0xff + 0x23) + OpSignal = AMLOpcode(0xff + 0x24) + OpWait = AMLOpcode(0xff + 0x25) + OpReset = AMLOpcode(0xff + 0x26) + OpRelease = AMLOpcode(0xff + 0x27) + OpFromBCD = AMLOpcode(0xff + 0x28) + OpToBCD = AMLOpcode(0xff + 0x29) + OpUnload = AMLOpcode(0xff + 0x2a) + OpRevision = AMLOpcode(0xff + 0x30) + OpDebug = AMLOpcode(0xff + 0x31) + OpFatal = AMLOpcode(0xff + 0x32) + OpTimer = AMLOpcode(0xff + 0x33) + OpOpRegion = AMLOpcode(0xff + 0x80) + OpField = AMLOpcode(0xff + 0x81) + OpDevice = AMLOpcode(0xff + 0x82) + OpProcessor = AMLOpcode(0xff + 0x83) + OpPowerRes = AMLOpcode(0xff + 0x84) + OpThermalZone = AMLOpcode(0xff + 0x85) + OpIndexField = AMLOpcode(0xff + 0x86) + OpBankField = AMLOpcode(0xff + 0x87) + OpDataRegion = AMLOpcode(0xff + 0x88) +) + +// OpIsLocalArg returns true if this opcode represents any of the supported local +// function args 0 to 7. +func OpIsLocalArg(op AMLOpcode) 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 AMLOpcode) bool { + return op >= OpArg0 && op <= OpArg6 +} + +// OpIsArg returns true if this opcode is either a local or a method arg. +func OpIsArg(op AMLOpcode) 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 AMLOpcode) 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 AMLOpcode) 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 AMLOpcode) bool { + switch op { + case OpCreateField, OpCreateBitField, OpCreateByteField, OpCreateWordField, OpCreateDWordField, OpCreateQWordField: + return true + default: + return false + } +} diff --git a/src/gopheros/device/acpi/aml/entity/opcode_test.go b/src/gopheros/device/acpi/aml/entity/opcode_test.go new file mode 100644 index 0000000..3cf0e4c --- /dev/null +++ b/src/gopheros/device/acpi/aml/entity/opcode_test.go @@ -0,0 +1,116 @@ +package entity + +import "testing" + +func TestOpcodeIsX(t *testing.T) { + specs := []struct { + op AMLOpcode + testFn func(AMLOpcode) 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) + } + } +}