1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00

acpi: instanciate AML interpreter when the ACPI driver is initialized

This commit is contained in:
Achilleas Anagnostopoulos 2017-10-16 07:05:48 +01:00
parent 63c69fe8d3
commit fd2f4a72ad
3 changed files with 57 additions and 4 deletions

View File

@ -2,6 +2,7 @@ package acpi
import (
"gopheros/device"
"gopheros/device/acpi/aml"
"gopheros/device/acpi/table"
"gopheros/kernel"
"gopheros/kernel/kfmt"
@ -45,17 +46,33 @@ type acpiDriver struct {
// by the table name. All tables included in this map are mapped into
// memory.
tableMap map[string]*table.SDTHeader
// The AML interpreter used by the ACPI driver to execute various
// ACPI-related methods.
amlVM *aml.VM
}
// DriverInit initializes this driver.
func (drv *acpiDriver) DriverInit(w io.Writer) *kernel.Error {
if err := drv.enumerateTables(w); err != nil {
var err *kernel.Error
if err = drv.enumerateTables(w); err != nil {
return err
}
drv.printTableInfo(w)
return nil
// Now that we have enumerated the available ACPI tables we can
// initialize the AML interpreter passing the driver instance as
// a table.Resolver.
drv.amlVM = aml.NewVM(w, drv)
if vmErr := drv.amlVM.Init(); vmErr != nil {
return &kernel.Error{
Module: "acpi",
Message: vmErr.Error(),
}
}
return err
}
// DriverName returns the name of this driver.
@ -68,6 +85,11 @@ func (*acpiDriver) DriverVersion() (uint16, uint16, uint16) {
return 0, 0, 1
}
// LookupTable implements the table.Resolver interface.
func (drv *acpiDriver) LookupTable(name string) *table.SDTHeader {
return drv.tableMap[name]
}
func (drv *acpiDriver) printTableInfo(w io.Writer) {
for name, header := range drv.tableMap {
kfmt.Fprintf(w, "%s at 0x%16x %6x (%6s %8s)\n",
@ -84,6 +106,10 @@ func (drv *acpiDriver) printTableInfo(w io.Writer) {
// the table list defined by the RSDP, this method will also peek into the
// FADT (if found) looking for the address of DSDT.
func (drv *acpiDriver) enumerateTables(w io.Writer) *kernel.Error {
if len(drv.tableMap) != 0 {
return nil
}
header, sizeofHeader, err := mapACPITable(drv.rsdtAddr)
if err != nil {
return err

View File

@ -9,6 +9,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"runtime"
"testing"
"unsafe"
@ -237,6 +238,33 @@ func TestDriverInit(t *testing.T) {
}
})
t.Run("AML interpreter init error", func(t *testing.T) {
rsdtAddr, _ := genTestRDST(t, acpiRev2Plus)
identityMapFn = func(frame pmm.Frame, _ mem.Size, _ vmm.PageTableEntryFlag) (vmm.Page, *kernel.Error) {
return vmm.Page(frame), nil
}
drv := &acpiDriver{
rsdtAddr: rsdtAddr,
useXSDT: true,
}
// Patch the DSDT with an incomplete extOpPrefix opcode; this
// will trigger an error when trying to parse its AML contents
drv.enumerateTables(ioutil.Discard)
header := drv.LookupTable("DSDT")
rawData := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Len: int(header.Length),
Cap: int(header.Length),
Data: uintptr(unsafe.Pointer(header)) + unsafe.Sizeof(table.SDTHeader{}),
}))
rawData[0] = 0x1b // extOpPrefix
expErr := "acpi_aml_parser: could not parse AML bytecode"
if err := drv.DriverInit(os.Stderr); err == nil || err.Error() != expErr {
t.Fatalf("expected to get an AML parse error; got %v", err)
}
})
}
func TestEnumerateTables(t *testing.T) {

View File

@ -90,7 +90,6 @@ func (vm *VM) Init() *Error {
if header == nil {
continue
}
if err := vm.tableParser.ParseAML(uint8(tableHandle+1), tableName, header); err != nil {
return &Error{message: err.Module + ": " + err.Error()}
}