From 718006f4e46cb9d421a5eef73170e4630ca5564b Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Mon, 16 Oct 2017 06:58:05 +0100 Subject: [PATCH] acpi: define AML opcode jumptable and populate with placeholder function Due to the large number of opcodes that the AML VM needs to support, using a long switch statement will not be as performant as setting up a jump table due to the way that the go compiler generates code for long switch statements on integer values (asm code indicates that binary search is used to select the switch target). For the time being, the populateJumpTable method will assign a placeholder function to each jump table entry that just returns a "opcode X not implemented error". --- src/gopheros/device/acpi/aml/opcode_table.go | 2 ++ src/gopheros/device/acpi/aml/vm.go | 5 ++++- src/gopheros/device/acpi/aml/vm_jumptable.go | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/gopheros/device/acpi/aml/vm_jumptable.go diff --git a/src/gopheros/device/acpi/aml/opcode_table.go b/src/gopheros/device/acpi/aml/opcode_table.go index ba8e500..27d9d94 100644 --- a/src/gopheros/device/acpi/aml/opcode_table.go +++ b/src/gopheros/device/acpi/aml/opcode_table.go @@ -119,6 +119,8 @@ const ( opIndexField = opcode(0xff + 0x86) opBankField = opcode(0xff + 0x87) opDataRegion = opcode(0xff + 0x88) + // + numOpcodes = 0xff + 0x89 ) // The opcode table contains all opcode-related information that the parser knows. diff --git a/src/gopheros/device/acpi/aml/vm.go b/src/gopheros/device/acpi/aml/vm.go index 9dae0d6..59d1a94 100644 --- a/src/gopheros/device/acpi/aml/vm.go +++ b/src/gopheros/device/acpi/aml/vm.go @@ -24,7 +24,7 @@ const ( ctrlFlowTypeFnReturn ) -// execContext encapsulates +// execContext holds the AML interpreter state while an AML method executes. type execContext struct { localArg [maxLocalArgs]interface{} methodArg [maxMethodArgs]interface{} @@ -65,6 +65,8 @@ type VM struct { // whether integers are treated as 32 or 64-bits. The VM memoizes this // value so that it can be used by the data conversion helpers. sizeOfIntInBits int + + jumpTable [numOpcodes]opHandler } // NewVM creates a new AML VM and initializes it with the default scope @@ -101,6 +103,7 @@ func (vm *VM) Init() *Error { } } + vm.populateJumpTable() return nil } diff --git a/src/gopheros/device/acpi/aml/vm_jumptable.go b/src/gopheros/device/acpi/aml/vm_jumptable.go new file mode 100644 index 0000000..25f91bb --- /dev/null +++ b/src/gopheros/device/acpi/aml/vm_jumptable.go @@ -0,0 +1,20 @@ +package aml + +// opHandler is a function that implements an AML opcode. +type opHandler func(*execContext, Entity) *Error + +// populateJumpTable assigns the functions that implement the various AML +// opcodes to the VM's jump table. +func (vm *VM) populateJumpTable() { + for i := 0; i < len(vm.jumpTable); i++ { + vm.jumpTable[i] = opExecNotImplemented + } +} + +// opExecNotImplemented is a placeholder handler that returns a non-implemented +// opcode error. +func opExecNotImplemented(_ *execContext, ent Entity) *Error { + return &Error{ + message: "opcode " + ent.getOpcode().String() + " not implemented", + } +}