Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tighten up LowLevelHardwareInterfaces #6

Open
flanfly opened this issue Sep 23, 2021 · 0 comments
Open

Tighten up LowLevelHardwareInterfaces #6

flanfly opened this issue Sep 23, 2021 · 0 comments

Comments

@flanfly
Copy link
Contributor

flanfly commented Sep 23, 2021

Hi,

I'm implementing the LowLevelHardwareInterfaces interface and noticed that many of the functions don't seem to be strictly necessary. The most blatant example are PCIReadConfig* and PCIWriteConfig* as well as PCIReadVendorID and PCIReadDeviceID. If the interface would defined PCIReadConfig(address uint64) ([]byte, error) and PCIWriteConfig(address uint64, buf []byte) error all other functions could be implemented as free functions using the interface e.g.

func PCIReadConfig8(hwapi LowLevelHardwareInterfaces, d PCIDevice, off int) (uint8, error) {
    buf := make([]byte, 1)
    return buf[0], hwapi.PCIReadConfig(d, off)
}

Same applies IMO to ReadMSR vs. ReadMSRAllCores, all CPUID and SMBIOS functions, ReadPhys vs. ReadPhysBuf and both ACPI retrieval functions. In the latter case I don't see how the means of getting them matters to the consumer of the interface.

The second issue I have with the interface is performance. Especially the ReadPhysBuf function forces the implementation to copy the requested data into a user provided buffer. In my case the data is read ahead of time and it would improve memory and CPU consumption a lot if the function could just return a byte slice.

I think the following interface would suffice:

type MemoryRange struct
       Begin uint64 // included
       End uint64. // excluded
}

type LowLevelHardwareInterfaces interface {
	// cpuid.go
        CPUID(leaf uint32, sub uint32) (uint32, uint32, uint32, uint32, error)

	// e820.go
	GetReservedAreas() ([]MemoryRange, error)

	// iommu.go
	LookupIOAddress(addr uint64, regs VTdRegisters) ([]uint64, error)
	AddressRangesIsDMAProtected(first, end uint64) (bool, error)

	// msr.go
	ReadMSR(msr int64) ([]uint64, error) // value for each core

	// pci.go
	PCIDeviceList() ([]PCIDevice, error)
	PCIReadConfig(d PCIDevice, off uint64, size uint64) ([]byte, error)
	PCIWriteConfig(d PCIDevice, off int, val []byte) error

	// hostbridge.go
	ReadHostBridgeTseg() (uint32, uint32, error)
	ReadHostBridgeDPR() (DMAProtectedRange, error)

	// phys.go
	ReadPhys(addr uint64, size uint64) ([]byte, error)
	WritePhys(addr uint64, data []byte) error

	// tpm.go
	NewTPM() (*TPM, error)
	NVLocked(tpmCon *TPM) (bool, error)
	ReadNVPublic(tpmCon *TPM, index uint32) ([]byte, error)
	NVReadValue(tpmCon *TPM, index uint32, password string, size, offhandle uint32) ([]byte, error)
	ReadPCR(tpmCon *TPM, pcr uint32) ([]byte, error)

	// acpi.go
	GetACPITable(n string) ([]byte, error)

	// smbios.go
	IterateOverSMBIOSTables(n uint8, callback func(s *smbios.Structure) bool) (ret bool, err error)
}

What do you guys think? I'm willing to implement most of that as well as fix the CSS code depending on it.

@ChriMarMe ChriMarMe mentioned this issue Sep 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant