github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/acpi/bios.go (about)

     1  // Copyright 2020 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package acpi
     6  
     7  import "fmt"
     8  
     9  const (
    10  	llDSDTAddr = 140
    11  	lDSDTAddr  = 40
    12  )
    13  
    14  // BiosTable contains the information needed to create table images for
    15  // firmware such as coreboot or oreboot. It hence includes the RSDP,
    16  // [XR]SDT, and the raw table data. The *SDT is always Tables[0]
    17  // as in the real tables.
    18  type BiosTable struct {
    19  	RSDP   *RSDP
    20  	Tables []Table
    21  }
    22  
    23  // ReadBiosTables reads tables that are not interpreted by the OS,
    24  // i.e. it goes straight to memory and gets them there. We optimistically
    25  // hope the bios has not stomped around in low memory messing around.
    26  func ReadBiosTables() (*BiosTable, error) {
    27  	r, err := GetRSDPEBDA()
    28  	if err != nil {
    29  		r, err = GetRSDPMem()
    30  		if err != nil {
    31  			return nil, err
    32  		}
    33  	}
    34  	Debug("Found an RSDP at %#x", r.base)
    35  	x, err := NewSDTAddr(r.SDTAddr())
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	Debug("Found an SDT: %s", String(x))
    40  	bios := &BiosTable{
    41  		RSDP:   r,
    42  		Tables: []Table{x},
    43  	}
    44  	for _, a := range x.Addrs {
    45  		Debug("Check Table at %#x", a)
    46  		t, err := ReadRawTable(a)
    47  		if err != nil {
    48  			return nil, fmt.Errorf("%#x:%v", a, err)
    49  		}
    50  		Debug("Add table %s", String(t))
    51  		bios.Tables = append(bios.Tables, t)
    52  		// What I love about ACPI is its unchanging
    53  		// consistency. One table, the FADT, points
    54  		// to another table, the DSDT. There are
    55  		// very good reasons for this:
    56  		// (1) ACPI is a bad design
    57  		// (2) see (1)
    58  		// The signature of the FADT is "FACP".
    59  		// Most appropriate that the names
    60  		// start with F. So does Failure Of Vision.
    61  		if t.Sig() != "FACP" {
    62  			continue
    63  		}
    64  		// 64-bit CPUs had been around for 30 years when ACPI
    65  		// was defined. Nevertheless, they filled it chock full
    66  		// of 32-bit pointers, and then had to go back and paste
    67  		// in 64-bit pointers. The mind reels.
    68  		dsdt, err := getaddr(t.Data(), llDSDTAddr, lDSDTAddr)
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  		// This is sometimes a kernel virtual address.
    73  		// Fix that.
    74  		t, err = ReadRawTable(int64(uint32(dsdt)))
    75  		if err != nil {
    76  			return nil, fmt.Errorf("%#x:%v", uint64(dsdt), err)
    77  		}
    78  		Debug("Add table %s", String(t))
    79  		bios.Tables = append(bios.Tables, t)
    80  
    81  	}
    82  	return bios, nil
    83  }
    84  
    85  // RawTablesFromMem reads all the tables from Mem, using the SDT.
    86  func RawTablesFromMem() ([]Table, error) {
    87  	x, err := ReadBiosTables()
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  	return x.Tables, err
    92  }