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:
parent
63c69fe8d3
commit
fd2f4a72ad
@ -2,6 +2,7 @@ package acpi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gopheros/device"
|
"gopheros/device"
|
||||||
|
"gopheros/device/acpi/aml"
|
||||||
"gopheros/device/acpi/table"
|
"gopheros/device/acpi/table"
|
||||||
"gopheros/kernel"
|
"gopheros/kernel"
|
||||||
"gopheros/kernel/kfmt"
|
"gopheros/kernel/kfmt"
|
||||||
@ -45,17 +46,33 @@ type acpiDriver struct {
|
|||||||
// by the table name. All tables included in this map are mapped into
|
// by the table name. All tables included in this map are mapped into
|
||||||
// memory.
|
// memory.
|
||||||
tableMap map[string]*table.SDTHeader
|
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.
|
// DriverInit initializes this driver.
|
||||||
func (drv *acpiDriver) DriverInit(w io.Writer) *kernel.Error {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
drv.printTableInfo(w)
|
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.
|
// DriverName returns the name of this driver.
|
||||||
@ -68,6 +85,11 @@ func (*acpiDriver) DriverVersion() (uint16, uint16, uint16) {
|
|||||||
return 0, 0, 1
|
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) {
|
func (drv *acpiDriver) printTableInfo(w io.Writer) {
|
||||||
for name, header := range drv.tableMap {
|
for name, header := range drv.tableMap {
|
||||||
kfmt.Fprintf(w, "%s at 0x%16x %6x (%6s %8s)\n",
|
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
|
// the table list defined by the RSDP, this method will also peek into the
|
||||||
// FADT (if found) looking for the address of DSDT.
|
// FADT (if found) looking for the address of DSDT.
|
||||||
func (drv *acpiDriver) enumerateTables(w io.Writer) *kernel.Error {
|
func (drv *acpiDriver) enumerateTables(w io.Writer) *kernel.Error {
|
||||||
|
if len(drv.tableMap) != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
header, sizeofHeader, err := mapACPITable(drv.rsdtAddr)
|
header, sizeofHeader, err := mapACPITable(drv.rsdtAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
"unsafe"
|
"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) {
|
func TestEnumerateTables(t *testing.T) {
|
||||||
|
@ -90,7 +90,6 @@ func (vm *VM) Init() *Error {
|
|||||||
if header == nil {
|
if header == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := vm.tableParser.ParseAML(uint8(tableHandle+1), tableName, header); err != nil {
|
if err := vm.tableParser.ParseAML(uint8(tableHandle+1), tableName, header); err != nil {
|
||||||
return &Error{message: err.Module + ": " + err.Error()}
|
return &Error{message: err.Module + ": " + err.Error()}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user