mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
acpi: add VM-support for AML arithmetic opcodes
This commit is contained in:
parent
a172621af7
commit
38b2a3e4e2
@ -18,6 +18,7 @@ var (
|
|||||||
errCopyFailed = &Error{message: "vmCopyObject: copy failed"}
|
errCopyFailed = &Error{message: "vmCopyObject: copy failed"}
|
||||||
errConversionFailed = &Error{message: "vmConvert: conversion failed"}
|
errConversionFailed = &Error{message: "vmConvert: conversion failed"}
|
||||||
errArgIndexOutOfBounds = &Error{message: "vm: arg index out of bounds"}
|
errArgIndexOutOfBounds = &Error{message: "vm: arg index out of bounds"}
|
||||||
|
errDivideByZero = &Error{message: "vm: division by zero"}
|
||||||
)
|
)
|
||||||
|
|
||||||
// objRef is a pointer to an argument (local or global) or a named AML object.
|
// objRef is a pointer to an argument (local or global) or a named AML object.
|
||||||
|
@ -167,7 +167,6 @@ func vmConvert(ctx *execContext, arg interface{}, toType valueType) (interface{}
|
|||||||
return strconv.FormatUint(argAsInt, 16), nil
|
return strconv.FormatUint(argAsInt, 16), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errConversionFailed
|
return nil, errConversionFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +284,13 @@ func TestVMToIntArgs2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestVMConvert(t *testing.T) {
|
func TestVMConvert(t *testing.T) {
|
||||||
|
vm := NewVM(nil, nil)
|
||||||
|
vm.populateJumpTable()
|
||||||
|
|
||||||
|
vm.jumpTable[0] = func(_ *execContext, ent Entity) *Error {
|
||||||
|
return &Error{message: "something went wrong"}
|
||||||
|
}
|
||||||
|
|
||||||
specs := []struct {
|
specs := []struct {
|
||||||
ctx *execContext
|
ctx *execContext
|
||||||
in interface{}
|
in interface{}
|
||||||
@ -347,15 +354,7 @@ func TestVMConvert(t *testing.T) {
|
|||||||
"feedfacedeadc0de",
|
"feedfacedeadc0de",
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
// vmLoad returns an error
|
// conversion to unsupported type
|
||||||
{
|
|
||||||
nil,
|
|
||||||
&unnamedEntity{op: opAdd},
|
|
||||||
valueTypeInteger,
|
|
||||||
nil,
|
|
||||||
&Error{message: "readArg: unsupported entity type: " + opAdd.String()},
|
|
||||||
},
|
|
||||||
// unsupported conversion
|
|
||||||
{
|
{
|
||||||
nil,
|
nil,
|
||||||
uint64(42),
|
uint64(42),
|
||||||
@ -363,6 +362,13 @@ func TestVMConvert(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
errConversionFailed,
|
errConversionFailed,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
&execContext{vm: vm},
|
||||||
|
&unnamedEntity{op: 0}, // uses our patched jumpTable[0] that always errors
|
||||||
|
valueTypeString,
|
||||||
|
nil,
|
||||||
|
&Error{message: "vmLoad: something went wrong"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for specIndex, spec := range specs {
|
for specIndex, spec := range specs {
|
||||||
|
@ -9,6 +9,21 @@ func (vm *VM) populateJumpTable() {
|
|||||||
for i := 0; i < len(vm.jumpTable); i++ {
|
for i := 0; i < len(vm.jumpTable); i++ {
|
||||||
vm.jumpTable[i] = opExecNotImplemented
|
vm.jumpTable[i] = opExecNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Control-flow opcodes
|
||||||
|
vm.jumpTable[opReturn] = vmOpReturn
|
||||||
|
|
||||||
|
// ALU opcodes
|
||||||
|
vm.jumpTable[opAdd] = vmOpAdd
|
||||||
|
vm.jumpTable[opSubtract] = vmOpSubtract
|
||||||
|
vm.jumpTable[opIncrement] = vmOpIncrement
|
||||||
|
vm.jumpTable[opDecrement] = vmOpDecrement
|
||||||
|
vm.jumpTable[opMultiply] = vmOpMultiply
|
||||||
|
vm.jumpTable[opDivide] = vmOpDivide
|
||||||
|
vm.jumpTable[opMod] = vmOpMod
|
||||||
|
|
||||||
|
// Store-related opcodes
|
||||||
|
vm.jumpTable[opStore] = vmOpStore
|
||||||
}
|
}
|
||||||
|
|
||||||
// opExecNotImplemented is a placeholder handler that returns a non-implemented
|
// opExecNotImplemented is a placeholder handler that returns a non-implemented
|
||||||
|
@ -19,7 +19,15 @@ func vmLoad(ctx *execContext, arg interface{}) (interface{}, *Error) {
|
|||||||
case opIsMethodArg(op):
|
case opIsMethodArg(op):
|
||||||
arg = ctx.methodArg[op-opArg0]
|
arg = ctx.methodArg[op-opArg0]
|
||||||
default:
|
default:
|
||||||
return nil, &Error{message: "readArg: unsupported entity type: " + op.String()}
|
// Val may be a nested opcode (e.g Add(Add(1,1), 2))
|
||||||
|
// In this case, try evaluating the opcode and replace arg with the
|
||||||
|
// output value that gets stored stored into ctx.retVal
|
||||||
|
if err := ctx.vm.jumpTable[typ.getOpcode()](ctx, typ); err != nil {
|
||||||
|
err.message = "vmLoad: " + err.message
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
arg = ctx.retVal
|
||||||
}
|
}
|
||||||
case bool:
|
case bool:
|
||||||
// Convert boolean results to ints so they can be used
|
// Convert boolean results to ints so they can be used
|
||||||
|
@ -6,6 +6,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestVMLoad(t *testing.T) {
|
func TestVMLoad(t *testing.T) {
|
||||||
|
vm := NewVM(nil, nil)
|
||||||
|
vm.populateJumpTable()
|
||||||
|
|
||||||
|
vm.jumpTable[0] = func(_ *execContext, ent Entity) *Error {
|
||||||
|
return &Error{message: "something went wrong"}
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.jumpTable[1] = func(ctx *execContext, ent Entity) *Error {
|
||||||
|
ctx.retVal = uint64(123)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Use a pointer to ensure that when we dereference an objRef we get
|
// Use a pointer to ensure that when we dereference an objRef we get
|
||||||
// back the same pointer
|
// back the same pointer
|
||||||
uniqueVal := &execContext{}
|
uniqueVal := &execContext{}
|
||||||
@ -74,12 +86,19 @@ func TestVMLoad(t *testing.T) {
|
|||||||
aRef,
|
aRef,
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
// Unsupported reads
|
// nested opcode which returns an error
|
||||||
{
|
{
|
||||||
|
&execContext{vm: vm},
|
||||||
|
&unnamedEntity{op: 0}, // uses our patched jumpTable[0] that always errors
|
||||||
nil,
|
nil,
|
||||||
&unnamedEntity{op: opBuffer},
|
&Error{message: "vmLoad: something went wrong"},
|
||||||
|
},
|
||||||
|
// nested opcode which does not return an error
|
||||||
|
{
|
||||||
|
&execContext{vm: vm},
|
||||||
|
&unnamedEntity{op: 1}, // uses our patched jumpTable[1]
|
||||||
|
uint64(123),
|
||||||
nil,
|
nil,
|
||||||
&Error{message: "readArg: unsupported entity type: Buffer"},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
136
src/gopheros/device/acpi/aml/vm_op_alu.go
Normal file
136
src/gopheros/device/acpi/aml/vm_op_alu.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
package aml
|
||||||
|
|
||||||
|
// Args: left, right, store?
|
||||||
|
// Returns: left + right
|
||||||
|
func vmOpAdd(ctx *execContext, ent Entity) *Error {
|
||||||
|
var (
|
||||||
|
left, right uint64
|
||||||
|
err *Error
|
||||||
|
)
|
||||||
|
|
||||||
|
if left, right, err = vmToIntArgs2(ctx, ent, 0, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.retVal = left + right
|
||||||
|
return vmCondStore(ctx, ctx.retVal, ent, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args: left, right, store?
|
||||||
|
// Returns: left - right
|
||||||
|
func vmOpSubtract(ctx *execContext, ent Entity) *Error {
|
||||||
|
var (
|
||||||
|
left, right uint64
|
||||||
|
err *Error
|
||||||
|
)
|
||||||
|
|
||||||
|
if left, right, err = vmToIntArgs2(ctx, ent, 0, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.retVal = left - right
|
||||||
|
return vmCondStore(ctx, ctx.retVal, ent, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args: left, store?
|
||||||
|
// Returns: left + 1
|
||||||
|
// Stores: left <= left + 1
|
||||||
|
func vmOpIncrement(ctx *execContext, ent Entity) *Error {
|
||||||
|
var (
|
||||||
|
left uint64
|
||||||
|
err *Error
|
||||||
|
)
|
||||||
|
|
||||||
|
if left, err = vmToIntArg(ctx, ent, 0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The result is stored back into the left operand
|
||||||
|
ctx.retVal = left + 1
|
||||||
|
if err := vmStore(ctx, ctx.retVal, ent.getArgs()[0]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return vmCondStore(ctx, ctx.retVal, ent, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args: left, store?
|
||||||
|
// Returns: left - 1
|
||||||
|
// Stores: left <= left - 1
|
||||||
|
func vmOpDecrement(ctx *execContext, ent Entity) *Error {
|
||||||
|
var (
|
||||||
|
left uint64
|
||||||
|
err *Error
|
||||||
|
)
|
||||||
|
|
||||||
|
if left, err = vmToIntArg(ctx, ent, 0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The result is stored back into the left operand
|
||||||
|
ctx.retVal = left - 1
|
||||||
|
if err := vmStore(ctx, ctx.retVal, ent.getArgs()[0]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return vmCondStore(ctx, ctx.retVal, ent, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args: left, right, store?
|
||||||
|
// Returns: left * right
|
||||||
|
func vmOpMultiply(ctx *execContext, ent Entity) *Error {
|
||||||
|
var (
|
||||||
|
left, right uint64
|
||||||
|
err *Error
|
||||||
|
)
|
||||||
|
|
||||||
|
if left, right, err = vmToIntArgs2(ctx, ent, 0, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.retVal = left * right
|
||||||
|
return vmCondStore(ctx, ctx.retVal, ent, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args: left, right, remainder_store?, quotient_store?
|
||||||
|
// Returns: left / right; errDivideByZero if right == 0
|
||||||
|
func vmOpDivide(ctx *execContext, ent Entity) *Error {
|
||||||
|
var (
|
||||||
|
left, right uint64
|
||||||
|
err *Error
|
||||||
|
)
|
||||||
|
|
||||||
|
if left, right, err = vmToIntArgs2(ctx, ent, 0, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if right == 0 {
|
||||||
|
return errDivideByZero
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.retVal = left / right
|
||||||
|
if err = vmCondStore(ctx, ctx.retVal, ent, 3); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// opDivide can also spefify a target for storing the remainder
|
||||||
|
return vmCondStore(ctx, left%right, ent, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args: left, right, remainder_store?
|
||||||
|
// Returns: left % right; errDivideByZero if right == 0
|
||||||
|
func vmOpMod(ctx *execContext, ent Entity) *Error {
|
||||||
|
var (
|
||||||
|
left, right uint64
|
||||||
|
err *Error
|
||||||
|
)
|
||||||
|
|
||||||
|
if left, right, err = vmToIntArgs2(ctx, ent, 0, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if right == 0 {
|
||||||
|
return errDivideByZero
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.retVal = left % right
|
||||||
|
return vmCondStore(ctx, ctx.retVal, ent, 2)
|
||||||
|
}
|
128
src/gopheros/device/acpi/aml/vm_op_alu_test.go
Normal file
128
src/gopheros/device/acpi/aml/vm_op_alu_test.go
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package aml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestArithmeticExpressions(t *testing.T) {
|
||||||
|
specs := []struct {
|
||||||
|
method string
|
||||||
|
input interface{}
|
||||||
|
exp uint64
|
||||||
|
}{
|
||||||
|
{`\AR00`, uint64(10), uint64(15)},
|
||||||
|
{`\ARI0`, uint64(10), uint64(15)},
|
||||||
|
{`\AR01`, uint64(6), uint64(1)},
|
||||||
|
{`\ARI1`, uint64(6), uint64(1)},
|
||||||
|
{`\AR02`, uint64(3), uint64(24)},
|
||||||
|
{`\ARI2`, uint64(3), uint64(24)},
|
||||||
|
{`\AR03`, uint64(42), uint64(41)},
|
||||||
|
{`\ARI3`, uint64(42), uint64(41)},
|
||||||
|
{`\AR04`, uint64(42), uint64(43)},
|
||||||
|
{`\ARI4`, uint64(42), uint64(43)},
|
||||||
|
{`\AR05`, uint64(100), uint64(0)},
|
||||||
|
{`\ARI5`, uint64(100), uint64(0)},
|
||||||
|
{`\AR06`, uint64(100), uint64(10)},
|
||||||
|
{`\ARI6`, uint64(100), uint64(10)},
|
||||||
|
{`\AR06`, uint64(101), uint64(11)},
|
||||||
|
{`\ARI6`, uint64(101), uint64(10)},
|
||||||
|
}
|
||||||
|
|
||||||
|
resolver := &mockResolver{
|
||||||
|
tableFiles: []string{"vm-testsuite-DSDT.aml"},
|
||||||
|
}
|
||||||
|
|
||||||
|
vm := NewVM(os.Stderr, resolver)
|
||||||
|
if err := vm.Init(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for specIndex, spec := range specs {
|
||||||
|
m := vm.Lookup(spec.method)
|
||||||
|
if m == nil {
|
||||||
|
t.Errorf("error looking up method: %q", spec.method)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
method := m.(*Method)
|
||||||
|
|
||||||
|
ctx := &execContext{
|
||||||
|
methodArg: [maxMethodArgs]interface{}{spec.input},
|
||||||
|
vm: vm,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vm.execBlock(ctx, method); err != nil {
|
||||||
|
t.Errorf("[spec %02d] %s: invocation failed: %v\n", specIndex, spec.method, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(ctx.retVal, spec.exp) {
|
||||||
|
t.Errorf("[spec %02d] %s: expected %d; got %v\n", specIndex, spec.method, spec.exp, ctx.retVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestArithmeticExpressionErrors(t *testing.T) {
|
||||||
|
t.Run("arg handling errors", func(t *testing.T) {
|
||||||
|
specs := []opHandler{
|
||||||
|
vmOpAdd,
|
||||||
|
vmOpSubtract,
|
||||||
|
vmOpIncrement,
|
||||||
|
vmOpDecrement,
|
||||||
|
vmOpMultiply,
|
||||||
|
vmOpDivide,
|
||||||
|
vmOpMod,
|
||||||
|
}
|
||||||
|
|
||||||
|
for specIndex, handler := range specs {
|
||||||
|
if err := handler(nil, new(unnamedEntity)); err == nil {
|
||||||
|
t.Errorf("[spec %d] expected opHandler to return an error", specIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("division by zero errors", func(t *testing.T) {
|
||||||
|
specs := []opHandler{
|
||||||
|
vmOpDivide,
|
||||||
|
vmOpMod,
|
||||||
|
}
|
||||||
|
|
||||||
|
ent := &unnamedEntity{
|
||||||
|
args: []interface{}{
|
||||||
|
&constEntity{val: uint64(1)},
|
||||||
|
&constEntity{val: uint64(0)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for specIndex, handler := range specs {
|
||||||
|
if err := handler(nil, ent); err != errDivideByZero {
|
||||||
|
t.Errorf("[spec %d] expected opHandler to return errDivideByZero; got %v", specIndex, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("secondary value store errors", func(t *testing.T) {
|
||||||
|
specs := []opHandler{
|
||||||
|
vmOpIncrement,
|
||||||
|
vmOpDecrement,
|
||||||
|
vmOpDivide,
|
||||||
|
vmOpMod,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := new(execContext)
|
||||||
|
ent := &unnamedEntity{
|
||||||
|
args: []interface{}{
|
||||||
|
uint64(64),
|
||||||
|
&constEntity{val: uint64(4)},
|
||||||
|
"foo", // error: store target must be an AML entity
|
||||||
|
"bar", // error: store target must be an AML entity
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for specIndex, handler := range specs {
|
||||||
|
if err := handler(ctx, ent); err != errInvalidStoreDestination {
|
||||||
|
t.Errorf("[spec %d] expected opHandler to return errInvalidStoreDestination; got %v", specIndex, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
16
src/gopheros/device/acpi/aml/vm_op_flow.go
Normal file
16
src/gopheros/device/acpi/aml/vm_op_flow.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package aml
|
||||||
|
|
||||||
|
// Args: val
|
||||||
|
// Set val as the return value in ctx and change the ctrlFlow
|
||||||
|
// type to ctrlFlowTypeFnReturn.
|
||||||
|
func vmOpReturn(ctx *execContext, ent Entity) *Error {
|
||||||
|
args := ent.getArgs()
|
||||||
|
if len(args) != 1 {
|
||||||
|
return errArgIndexOutOfBounds
|
||||||
|
}
|
||||||
|
|
||||||
|
var err *Error
|
||||||
|
ctx.ctrlFlow = ctrlFlowTypeFnReturn
|
||||||
|
ctx.retVal, err = vmLoad(ctx, args[0])
|
||||||
|
return err
|
||||||
|
}
|
12
src/gopheros/device/acpi/aml/vm_op_flow_test.go
Normal file
12
src/gopheros/device/acpi/aml/vm_op_flow_test.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package aml
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestFlowExpressionErrors(t *testing.T) {
|
||||||
|
t.Run("opReturn errors", func(t *testing.T) {
|
||||||
|
// opReturn expects an argument to evaluate as the return value
|
||||||
|
if err := vmOpReturn(nil, new(unnamedEntity)); err != errArgIndexOutOfBounds {
|
||||||
|
t.Errorf("expected to get errArgIndexOutOfBounds; got %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
17
src/gopheros/device/acpi/aml/vm_op_store.go
Normal file
17
src/gopheros/device/acpi/aml/vm_op_store.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package aml
|
||||||
|
|
||||||
|
// Args: src dst
|
||||||
|
// Store src into dst applying any required conversion.
|
||||||
|
func vmOpStore(ctx *execContext, ent Entity) *Error {
|
||||||
|
args := ent.getArgs()
|
||||||
|
if len(args) != 2 {
|
||||||
|
return errArgIndexOutOfBounds
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := vmLoad(ctx, args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return vmStore(ctx, val, args[1])
|
||||||
|
}
|
41
src/gopheros/device/acpi/aml/vm_op_store_test.go
Normal file
41
src/gopheros/device/acpi/aml/vm_op_store_test.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package aml
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestVMOpStoreErrors(t *testing.T) {
|
||||||
|
// Wrong arg count
|
||||||
|
if err := vmOpStore(nil, new(unnamedEntity)); err != errArgIndexOutOfBounds {
|
||||||
|
t.Errorf("expected to get errArgIndexOutOfBounds; got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error loading the value to be stored
|
||||||
|
expErr := &Error{message: "something went wrong"}
|
||||||
|
|
||||||
|
vm := NewVM(nil, nil)
|
||||||
|
vm.populateJumpTable()
|
||||||
|
vm.jumpTable[0] = func(_ *execContext, ent Entity) *Error {
|
||||||
|
return expErr
|
||||||
|
}
|
||||||
|
|
||||||
|
ent := &unnamedEntity{
|
||||||
|
args: []interface{}{
|
||||||
|
// vmLoad will try to eval jumptable[0] which we monkey-patched to return an error
|
||||||
|
&unnamedEntity{op: 0},
|
||||||
|
uint64(128),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vmOpStore(&execContext{vm: vm}, ent); err != expErr {
|
||||||
|
t.Errorf("expected to get error %q; got %v", expErr.Error(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error storing the value
|
||||||
|
ent.args = []interface{}{
|
||||||
|
uint64(128),
|
||||||
|
uint64(0xf00), // storing to a non-AML entity is an error
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vmOpStore(nil, ent); err != errInvalidStoreDestination {
|
||||||
|
t.Errorf("expected to get errInvalidStoreDestination; got %v", err)
|
||||||
|
}
|
||||||
|
}
|
BIN
src/gopheros/device/acpi/table/tabletest/vm-testsuite-DSDT.aml
Normal file
BIN
src/gopheros/device/acpi/table/tabletest/vm-testsuite-DSDT.aml
Normal file
Binary file not shown.
@ -0,0 +1,84 @@
|
|||||||
|
DefinitionBlock ("vm-testsuite-DSDT.aml", "DSDT", 2, "GOPHER", "GOPHEROS", 0x00000002)
|
||||||
|
{
|
||||||
|
// Arithmetic ops
|
||||||
|
Method (AR00, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Add(Arg0, 5, Local0)
|
||||||
|
Return(Local0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (ARI0, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Return(Arg0 + 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (AR01, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Subtract(Arg0, 5, Local0)
|
||||||
|
Return(Local0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (ARI1, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Return(Arg0 - 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (AR02, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Multiply(Arg0, 8, Local0)
|
||||||
|
Return(Local0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (ARI2, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Return(Arg0*8)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (AR03, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Local1 = Arg0
|
||||||
|
Local1--
|
||||||
|
Return(Local1)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (ARI3, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Return(Arg0--)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (AR04, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Local2 = Arg0
|
||||||
|
Local2++
|
||||||
|
Return(Local2)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (ARI4, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Return(Arg0++)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (AR05, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Mod(Arg0, 10, Local0)
|
||||||
|
Return(Local0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (ARI5, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Return(Arg0 % 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (AR06, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
// Local0: remainder
|
||||||
|
// Local1: quotient
|
||||||
|
Divide(Arg0, 10, Local0, Local1)
|
||||||
|
Return(Local0 + Local1)
|
||||||
|
}
|
||||||
|
|
||||||
|
Method (ARI6, 1, NotSerialized)
|
||||||
|
{
|
||||||
|
Return(Arg0 / 10)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user