diff options
Diffstat (limited to 'util/autoport/main.go')
-rw-r--r-- | util/autoport/main.go | 915 |
1 files changed, 915 insertions, 0 deletions
diff --git a/util/autoport/main.go b/util/autoport/main.go new file mode 100644 index 00000000..3a2f0617 --- /dev/null +++ b/util/autoport/main.go @@ -0,0 +1,915 @@ +/* This is just an experiment. Full automatic porting + is probably not possible but a lot can be automated. */ +package main + +import ( + "bytes" + "flag" + "fmt" + "log" + "os" + "sort" + "strings" +) + +type PCIAddr struct { + Bus int + Dev int + Func int +} + +type PCIDevData struct { + PCIAddr + PCIVenID uint16 + PCIDevID uint16 + ConfigDump []uint8 +} + +type PCIDevice interface { + Scan(ctx Context, addr PCIDevData) +} + +type InteltoolData struct { + GPIO map[uint16]uint32 + RCBA map[uint16]uint32 + IOBP map[uint32]uint32 + IGD map[uint32]uint32 + MCHBAR map[uint16]uint32 + PMBASE map[uint16]uint32 +} + +type DMIData struct { + Vendor string + Model string + Version string + IsLaptop bool +} + +type AzaliaCodec struct { + Name string + VendorID uint32 + SubsystemID uint32 + CodecNo int + PinConfig map[int]uint32 +} + +type DevReader interface { + GetPCIList() []PCIDevData + GetDMI() DMIData + GetInteltool() InteltoolData + GetAzaliaCodecs() []AzaliaCodec + GetACPI() map[string][]byte + GetCPUModel() []uint32 + GetEC() []byte + GetIOPorts() []IOPorts + HasPS2() bool +} + +type IOPorts struct { + Start uint16 + End uint16 + Usage string +} + +type SouthBridger interface { + GetGPIOHeader() string + EncodeGPE(int) int + DecodeGPE(int) int + EnableGPE(int) + NeedRouteGPIOManually() +} + +var SouthBridge SouthBridger +var BootBlockFiles map[string]string = map[string]string{} +var ROMStageFiles map[string]string = map[string]string{} +var RAMStageFiles map[string]string = map[string]string{} +var SMMFiles map[string]string = map[string]string{} +var MainboardInit string +var MainboardEnable string +var MainboardIncludes []string + +type Context struct { + MoboID string + KconfigName string + Vendor string + Model string + BaseDirectory string + InfoSource DevReader + SaneVendor string +} + +type IOAPICIRQ struct { + APICID int + IRQNO [4]int +} + +var IOAPICIRQs map[PCIAddr]IOAPICIRQ = map[PCIAddr]IOAPICIRQ{} +var KconfigBool map[string]bool = map[string]bool{} +var KconfigComment map[string]string = map[string]string{} +var KconfigString map[string]string = map[string]string{} +var KconfigHex map[string]uint32 = map[string]uint32{} +var KconfigInt map[string]int = map[string]int{} +var ROMSizeKB = 0 +var ROMProtocol = "" +var FlashROMSupport = "" + +func GetLE16(inp []byte) uint16 { + return uint16(inp[0]) | (uint16(inp[1]) << 8) +} + +func FormatHexLE16(inp []byte) string { + return fmt.Sprintf("0x%04x", GetLE16(inp)) +} + +func FormatHex32(u uint32) string { + return fmt.Sprintf("0x%08x", u) +} + +func FormatHex8(u uint8) string { + return fmt.Sprintf("0x%02x", u) +} + +func FormatInt32(u uint32) string { + return fmt.Sprintf("%d", u) +} + +func FormatHexLE32(d []uint8) string { + u := uint32(d[0]) | (uint32(d[1]) << 8) | (uint32(d[2]) << 16) | (uint32(d[3]) << 24) + return FormatHex32(u) +} + +func FormatBool(inp bool) string { + if inp { + return "1" + } else { + return "0" + } +} + +func sanitize(inp string) string { + result := strings.ToLower(inp) + result = strings.Replace(result, " ", "_", -1) + result = strings.Replace(result, ",", "_", -1) + result = strings.Replace(result, "-", "_", -1) + for strings.HasSuffix(result, ".") { + result = result[0 : len(result)-1] + } + return result +} + +func AddBootBlockFile(Name string, Condition string) { + BootBlockFiles[Name] = Condition +} + +func AddROMStageFile(Name string, Condition string) { + ROMStageFiles[Name] = Condition +} + +func AddRAMStageFile(Name string, Condition string) { + RAMStageFiles[Name] = Condition +} + +func AddSMMFile(Name string, Condition string) { + SMMFiles[Name] = Condition +} + +func IsIOPortUsedBy(ctx Context, port uint16, name string) bool { + for _, io := range ctx.InfoSource.GetIOPorts() { + if io.Start <= port && port <= io.End && io.Usage == name { + return true + } + } + return false +} + +var FlagOutDir = flag.String("coreboot_dir", ".", "Resulting coreboot directory") + +func writeMF(mf *os.File, files map[string]string, category string) { + keys := []string{} + for file, _ := range files { + keys = append(keys, file) + } + + sort.Strings(keys) + + for _, file := range keys { + condition := files[file] + if condition == "" { + fmt.Fprintf(mf, "%s-y += %s\n", category, file) + } else { + fmt.Fprintf(mf, "%s-$(%s) += %s\n", category, condition, file) + } + } +} + +func Create(ctx Context, name string) *os.File { + li := strings.LastIndex(name, "/") + if li > 0 { + os.MkdirAll(ctx.BaseDirectory+"/"+name[0:li], 0700) + } + mf, err := os.Create(ctx.BaseDirectory + "/" + name) + if err != nil { + log.Fatal(err) + } + return mf +} + +func Add_gpl(f *os.File) { + fmt.Fprintln(f, "/* SPDX-License-Identifier: GPL-2.0-only */") + fmt.Fprintln(f) +} + +func RestorePCI16Simple(f *os.File, pcidev PCIDevData, addr uint16) { + fmt.Fprintf(f, " pci_write_config16(PCI_DEV(%d, 0x%02x, %d), 0x%02x, 0x%02x%02x);\n", + pcidev.Bus, pcidev.Dev, pcidev.Func, addr, + pcidev.ConfigDump[addr+1], + pcidev.ConfigDump[addr]) +} + +func RestorePCI32Simple(f *os.File, pcidev PCIDevData, addr uint16) { + fmt.Fprintf(f, " pci_write_config32(PCI_DEV(%d, 0x%02x, %d), 0x%02x, 0x%02x%02x%02x%02x);\n", + pcidev.Bus, pcidev.Dev, pcidev.Func, addr, + pcidev.ConfigDump[addr+3], + pcidev.ConfigDump[addr+2], + pcidev.ConfigDump[addr+1], + pcidev.ConfigDump[addr]) +} + +func RestoreRCBA32(f *os.File, inteltool InteltoolData, addr uint16) { + fmt.Fprintf(f, "\tRCBA32(0x%04x) = 0x%08x;\n", addr, inteltool.RCBA[addr]) +} + +type PCISlot struct { + PCIAddr + alias string + additionalComment string + writeEmpty bool +} + +type DevTreeNode struct { + Bus int + Dev int + Func int + Disabled bool + Registers map[string]string + IOs map[uint16]uint16 + Children []DevTreeNode + PCISlots []PCISlot + PCIController bool + ChildPCIBus int + MissingParent string + SubVendor uint16 + SubSystem uint16 + Chip string + Ops string + Comment string +} + +var DevTree DevTreeNode +var MissingChildren map[string][]DevTreeNode = map[string][]DevTreeNode{} +var unmatchedPCIChips map[PCIAddr]DevTreeNode = map[PCIAddr]DevTreeNode{} +var unmatchedPCIDevices map[PCIAddr]DevTreeNode = map[PCIAddr]DevTreeNode{} + +func Offset(dt *os.File, offset int) { + for i := 0; i < offset; i++ { + fmt.Fprintf(dt, "\t") + } +} + +func MatchDev(dev *DevTreeNode) { + for idx := range dev.Children { + MatchDev(&dev.Children[idx]) + } + + for _, slot := range dev.PCISlots { + slotChip, ok := unmatchedPCIChips[slot.PCIAddr] + + if !ok { + continue + } + + if slot.additionalComment != "" && slotChip.Comment != "" { + slotChip.Comment = slot.additionalComment + " " + slotChip.Comment + } else { + slotChip.Comment = slot.additionalComment + slotChip.Comment + } + + delete(unmatchedPCIChips, slot.PCIAddr) + MatchDev(&slotChip) + dev.Children = append(dev.Children, slotChip) + } + + if dev.PCIController { + for slot, slotDev := range unmatchedPCIChips { + if slot.Bus == dev.ChildPCIBus { + delete(unmatchedPCIChips, slot) + MatchDev(&slotDev) + dev.Children = append(dev.Children, slotDev) + } + } + } + + for _, slot := range dev.PCISlots { + slotDev, ok := unmatchedPCIDevices[slot.PCIAddr] + if !ok { + if slot.writeEmpty { + dev.Children = append(dev.Children, + DevTreeNode{ + Registers: map[string]string{}, + Chip: "pci", + Bus: slot.Bus, + Dev: slot.Dev, + Func: slot.Func, + Comment: slot.additionalComment, + Disabled: true, + }, + ) + } + continue + } + + if slot.additionalComment != "" && slotDev.Comment != "" { + slotDev.Comment = slot.additionalComment + " " + slotDev.Comment + } else { + slotDev.Comment = slot.additionalComment + slotDev.Comment + } + + MatchDev(&slotDev) + dev.Children = append(dev.Children, slotDev) + delete(unmatchedPCIDevices, slot.PCIAddr) + } + + if dev.MissingParent != "" { + for _, child := range MissingChildren[dev.MissingParent] { + MatchDev(&child) + dev.Children = append(dev.Children, child) + } + delete(MissingChildren, dev.MissingParent) + } + + if dev.PCIController { + for slot, slotDev := range unmatchedPCIDevices { + if slot.Bus == dev.ChildPCIBus { + MatchDev(&slotDev) + dev.Children = append(dev.Children, slotDev) + delete(unmatchedPCIDevices, slot) + } + } + } +} + +func writeOn(dt *os.File, dev DevTreeNode) { + if dev.Disabled { + fmt.Fprintf(dt, "off") + } else { + fmt.Fprintf(dt, "on") + } +} + +func WriteDev(dt *os.File, offset int, alias string, dev DevTreeNode) { + Offset(dt, offset) + switch dev.Chip { + case "cpu_cluster", "lapic", "domain", "ioapic": + fmt.Fprintf(dt, "device %s 0x%x ", dev.Chip, dev.Dev) + writeOn(dt, dev) + case "pci", "pnp": + if alias != "" { + fmt.Fprintf(dt, "device ref %s ", alias) + } else { + fmt.Fprintf(dt, "device %s %02x.%x ", dev.Chip, dev.Dev, dev.Func) + } + writeOn(dt, dev) + case "i2c": + fmt.Fprintf(dt, "device %s %02x ", dev.Chip, dev.Dev) + writeOn(dt, dev) + default: + fmt.Fprintf(dt, "chip %s", dev.Chip) + } + if dev.Comment != "" { + fmt.Fprintf(dt, " # %s", dev.Comment) + } + fmt.Fprintf(dt, "\n") + if dev.Ops != "" { + Offset(dt, offset+1) + fmt.Fprintf(dt, "ops %s\n", dev.Ops) + } + if dev.Chip == "pci" && dev.SubSystem != 0 && dev.SubVendor != 0 { + Offset(dt, offset+1) + fmt.Fprintf(dt, "subsystemid 0x%04x 0x%04x\n", dev.SubVendor, dev.SubSystem) + } + + ioapic, ok := IOAPICIRQs[PCIAddr{Bus: dev.Bus, Dev: dev.Dev, Func: dev.Func}] + if dev.Chip == "pci" && ok { + for pin, irq := range ioapic.IRQNO { + if irq != 0 { + Offset(dt, offset+1) + fmt.Fprintf(dt, "ioapic_irq %d INT%c 0x%x\n", ioapic.APICID, 'A'+pin, irq) + } + } + } + + keys := []string{} + for reg, _ := range dev.Registers { + keys = append(keys, reg) + } + + sort.Strings(keys) + + for _, reg := range keys { + val := dev.Registers[reg] + Offset(dt, offset+1) + fmt.Fprintf(dt, "register \"%s\" = \"%s\"\n", reg, val) + } + + ios := []int{} + for reg, _ := range dev.IOs { + ios = append(ios, int(reg)) + } + + sort.Ints(ios) + + for _, reg := range ios { + val := dev.IOs[uint16(reg)] + Offset(dt, offset+1) + fmt.Fprintf(dt, "io 0x%x = 0x%x\n", reg, val) + } + + for _, child := range dev.Children { + alias = "" + for _, slot := range dev.PCISlots { + if slot.PCIAddr.Bus == child.Bus && + slot.PCIAddr.Dev == child.Dev && slot.PCIAddr.Func == child.Func { + alias = slot.alias + } + } + WriteDev(dt, offset+1, alias, child) + } + + Offset(dt, offset) + fmt.Fprintf(dt, "end\n") +} + +func PutChip(domain string, cur DevTreeNode) { + MissingChildren[domain] = append(MissingChildren[domain], cur) +} + +func PutPCIChip(addr PCIDevData, cur DevTreeNode) { + unmatchedPCIChips[addr.PCIAddr] = cur +} + +func PutPCIDevParent(addr PCIDevData, comment string, parent string) { + cur := DevTreeNode{ + Registers: map[string]string{}, + Chip: "pci", + Bus: addr.Bus, + Dev: addr.Dev, + Func: addr.Func, + MissingParent: parent, + Comment: comment, + } + if addr.ConfigDump[0xa] == 0x04 && addr.ConfigDump[0xb] == 0x06 { + cur.PCIController = true + cur.ChildPCIBus = int(addr.ConfigDump[0x19]) + + loopCtr := 0 + for capPtr := addr.ConfigDump[0x34]; capPtr != 0; capPtr = addr.ConfigDump[capPtr+1] { + /* Avoid hangs. There are only 0x100 different possible values for capPtr. + If we iterate longer than that, we're in endless loop. */ + loopCtr++ + if loopCtr > 0x100 { + break + } + if addr.ConfigDump[capPtr] == 0x0d { + cur.SubVendor = GetLE16(addr.ConfigDump[capPtr+4 : capPtr+6]) + cur.SubSystem = GetLE16(addr.ConfigDump[capPtr+6 : capPtr+8]) + } + } + } else { + cur.SubVendor = GetLE16(addr.ConfigDump[0x2c:0x2e]) + cur.SubSystem = GetLE16(addr.ConfigDump[0x2e:0x30]) + } + unmatchedPCIDevices[addr.PCIAddr] = cur +} + +func PutPCIDev(addr PCIDevData, comment string) { + PutPCIDevParent(addr, comment, "") +} + +type GenericPCI struct { + Comment string + Bus0Subdiv string + MissingParent string +} + +type GenericVGA struct { + GenericPCI +} + +type DSDTInclude struct { + Comment string + File string +} + +type DSDTDefine struct { + Key string + Comment string + Value string +} + +var DSDTIncludes []DSDTInclude +var DSDTPCI0Includes []DSDTInclude +var DSDTDefines []DSDTDefine + +func (g GenericPCI) Scan(ctx Context, addr PCIDevData) { + PutPCIDevParent(addr, g.Comment, g.MissingParent) +} + +var IGDEnabled bool = false + +func (g GenericVGA) Scan(ctx Context, addr PCIDevData) { + KconfigString["VGA_BIOS_ID"] = fmt.Sprintf("%04x,%04x", + addr.PCIVenID, + addr.PCIDevID) + PutPCIDevParent(addr, g.Comment, g.MissingParent) + IGDEnabled = true +} + +func makeKconfigName(ctx Context) { + kn := Create(ctx, "Kconfig.name") + defer kn.Close() + + fmt.Fprintf(kn, "config %s\n\tbool \"%s\"\n", ctx.KconfigName, ctx.Model) +} + +func makeComment(name string) string { + cmt, ok := KconfigComment[name] + if !ok { + return "" + } + return " # " + cmt +} + +func makeKconfig(ctx Context) { + kc := Create(ctx, "Kconfig") + defer kc.Close() + + fmt.Fprintf(kc, "if %s\n\n", ctx.KconfigName) + + fmt.Fprintf(kc, "config BOARD_SPECIFIC_OPTIONS\n\tdef_bool y\n") + keys := []string{} + for name, val := range KconfigBool { + if val { + keys = append(keys, name) + } + } + + sort.Strings(keys) + + for _, name := range keys { + fmt.Fprintf(kc, "\tselect %s%s\n", name, makeComment(name)) + } + + keys = nil + for name, val := range KconfigBool { + if !val { + keys = append(keys, name) + } + } + + sort.Strings(keys) + + for _, name := range keys { + fmt.Fprintf(kc, ` +config %s%s + bool + default n +`, name, makeComment(name)) + } + + keys = nil + for name, _ := range KconfigString { + keys = append(keys, name) + } + + sort.Strings(keys) + + for _, name := range keys { + fmt.Fprintf(kc, ` +config %s%s + string + default "%s" +`, name, makeComment(name), KconfigString[name]) + } + + keys = nil + for name, _ := range KconfigHex { + keys = append(keys, name) + } + + sort.Strings(keys) + + for _, name := range keys { + fmt.Fprintf(kc, ` +config %s%s + hex + default 0x%x +`, name, makeComment(name), KconfigHex[name]) + } + + keys = nil + for name, _ := range KconfigInt { + keys = append(keys, name) + } + + sort.Strings(keys) + + for _, name := range keys { + fmt.Fprintf(kc, ` +config %s%s + int + default %d +`, name, makeComment(name), KconfigInt[name]) + } + + fmt.Fprintf(kc, "endif\n") +} + +const MoboDir = "/src/mainboard/" + +func makeVendor(ctx Context) { + vendor := ctx.Vendor + vendorSane := ctx.SaneVendor + vendorDir := *FlagOutDir + MoboDir + vendorSane + vendorUpper := strings.ToUpper(vendorSane) + kconfig := vendorDir + "/Kconfig" + if _, err := os.Stat(kconfig); os.IsNotExist(err) { + f, err := os.Create(kconfig) + if err != nil { + log.Fatal(err) + } + defer f.Close() + f.WriteString(`if VENDOR_` + vendorUpper + ` + +choice + prompt "Mainboard model" + +source "src/mainboard/` + vendorSane + `/*/Kconfig.name" + +endchoice + +source "src/mainboard/` + vendorSane + `/*/Kconfig" + +config MAINBOARD_VENDOR + string + default "` + vendor + `" + +endif # VENDOR_` + vendorUpper + "\n") + } + kconfigName := vendorDir + "/Kconfig.name" + if _, err := os.Stat(kconfigName); os.IsNotExist(err) { + f, err := os.Create(kconfigName) + if err != nil { + log.Fatal(err) + } + defer f.Close() + f.WriteString(`config VENDOR_` + vendorUpper + ` + bool "` + vendor + `" +`) + } + +} + +func GuessECGPE(ctx Context) int { + /* FIXME:XX Use iasl -d and/or better parsing */ + dsdt := ctx.InfoSource.GetACPI()["DSDT"] + idx := bytes.Index(dsdt, []byte{0x08, '_', 'G', 'P', 'E', 0x0a}) /* Name (_GPE, byte). */ + if idx > 0 { + return int(dsdt[idx+6]) + } + return -1 +} + +func GuessSPDMap(ctx Context) []uint8 { + dmi := ctx.InfoSource.GetDMI() + + if dmi.Vendor == "LENOVO" { + return []uint8{0x50, 0x52, 0x51, 0x53} + } + return []uint8{0x50, 0x51, 0x52, 0x53} +} + +func main() { + flag.Parse() + + ctx := Context{} + + ctx.InfoSource = MakeLogReader() + + dmi := ctx.InfoSource.GetDMI() + + ctx.Vendor = dmi.Vendor + + if dmi.Vendor == "LENOVO" { + ctx.Model = dmi.Version + } else { + ctx.Model = dmi.Model + } + + if dmi.IsLaptop { + KconfigBool["SYSTEM_TYPE_LAPTOP"] = true + } + ctx.SaneVendor = sanitize(ctx.Vendor) + for { + last := ctx.SaneVendor + for _, suf := range []string{"_inc", "_co", "_corp"} { + ctx.SaneVendor = strings.TrimSuffix(ctx.SaneVendor, suf) + } + if last == ctx.SaneVendor { + break + } + } + ctx.MoboID = ctx.SaneVendor + "/" + sanitize(ctx.Model) + ctx.KconfigName = "BOARD_" + strings.ToUpper(ctx.SaneVendor+"_"+sanitize(ctx.Model)) + ctx.BaseDirectory = *FlagOutDir + MoboDir + ctx.MoboID + KconfigString["MAINBOARD_DIR"] = ctx.MoboID + KconfigString["MAINBOARD_PART_NUMBER"] = ctx.Model + + os.MkdirAll(ctx.BaseDirectory, 0700) + + makeVendor(ctx) + + ScanRoot(ctx) + + if IGDEnabled { + KconfigBool["MAINBOARD_HAS_LIBGFXINIT"] = true + KconfigComment["MAINBOARD_HAS_LIBGFXINIT"] = "FIXME: check this" + AddRAMStageFile("gma-mainboard.ads", "CONFIG_MAINBOARD_USE_LIBGFXINIT") + } + + if len(BootBlockFiles) > 0 || len(ROMStageFiles) > 0 || len(RAMStageFiles) > 0 || len(SMMFiles) > 0 { + mf := Create(ctx, "Makefile.mk") + defer mf.Close() + writeMF(mf, BootBlockFiles, "bootblock") + writeMF(mf, ROMStageFiles, "romstage") + writeMF(mf, RAMStageFiles, "ramstage") + writeMF(mf, SMMFiles, "smm") + } + + devtree := Create(ctx, "devicetree.cb") + defer devtree.Close() + + MatchDev(&DevTree) + WriteDev(devtree, 0, "", DevTree) + + if MainboardInit != "" || MainboardEnable != "" || MainboardIncludes != nil { + mainboard := Create(ctx, "mainboard.c") + defer mainboard.Close() + Add_gpl(mainboard) + mainboard.WriteString("#include <device/device.h>\n") + for _, include := range MainboardIncludes { + mainboard.WriteString("#include <" + include + ">\n") + } + mainboard.WriteString("\n") + if MainboardInit != "" { + mainboard.WriteString(`static void mainboard_init(struct device *dev) +{ +` + MainboardInit + "}\n\n") + } + if MainboardInit != "" || MainboardEnable != "" { + mainboard.WriteString("static void mainboard_enable(struct device *dev)\n{\n") + if MainboardInit != "" { + mainboard.WriteString("\tdev->ops->init = mainboard_init;\n\n") + } + mainboard.WriteString(MainboardEnable) + mainboard.WriteString("}\n\n") + mainboard.WriteString(`struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; +`) + } + } + + bi := Create(ctx, "board_info.txt") + defer bi.Close() + + fixme := "" + + if dmi.IsLaptop { + bi.WriteString("Category: laptop\n") + } else { + bi.WriteString("Category: desktop\n") + fixme += "check category, " + } + + missing := "ROM package, ROM socketed" + + if ROMProtocol != "" { + fmt.Fprintf(bi, "ROM protocol: %s\n", ROMProtocol) + } else { + missing += ", ROM protocol" + } + + if FlashROMSupport != "" { + fmt.Fprintf(bi, "Flashrom support: %s\n", FlashROMSupport) + } else { + missing += ", Flashrom support" + } + + missing += ", Release year" + + if fixme != "" { + fmt.Fprintf(bi, "FIXME: %s, put %s\n", fixme, missing) + } else { + fmt.Fprintf(bi, "FIXME: put %s\n", missing) + } + + if ROMSizeKB == 0 { + KconfigBool["BOARD_ROMSIZE_KB_2048"] = true + KconfigComment["BOARD_ROMSIZE_KB_2048"] = "FIXME: correct this" + } else { + KconfigBool[fmt.Sprintf("BOARD_ROMSIZE_KB_%d", ROMSizeKB)] = true + } + + makeKconfig(ctx) + makeKconfigName(ctx) + + dsdt := Create(ctx, "dsdt.asl") + defer dsdt.Close() + + for _, define := range DSDTDefines { + if define.Comment != "" { + fmt.Fprintf(dsdt, "\t/* %s. */\n", define.Comment) + } + dsdt.WriteString("#define " + define.Key + " " + define.Value + "\n") + } + + Add_gpl(dsdt) + dsdt.WriteString( + ` +#include <acpi/acpi.h> + +DefinitionBlock( + "dsdt.aml", + "DSDT", + ACPI_DSDT_REV_2, + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20141018 /* OEM revision */ +) +{ + #include <acpi/dsdt_top.asl> + #include "acpi/platform.asl" +`) + + for _, x := range DSDTIncludes { + if x.Comment != "" { + fmt.Fprintf(dsdt, "\t/* %s. */\n", x.Comment) + } + fmt.Fprintf(dsdt, "\t#include <%s>\n", x.File) + } + + dsdt.WriteString(` + Device (\_SB.PCI0) + { +`) + for _, x := range DSDTPCI0Includes { + if x.Comment != "" { + fmt.Fprintf(dsdt, "\t/* %s. */\n", x.Comment) + } + fmt.Fprintf(dsdt, "\t\t#include <%s>\n", x.File) + } + dsdt.WriteString( + ` } +} +`) + + if IGDEnabled { + gma := Create(ctx, "gma-mainboard.ads") + defer gma.Close() + + gma.WriteString(`-- SPDX-License-Identifier: GPL-2.0-or-later + +with HW.GFX.GMA; +with HW.GFX.GMA.Display_Probing; + +use HW.GFX.GMA; +use HW.GFX.GMA.Display_Probing; + +private package GMA.Mainboard is + + -- FIXME: check this + ports : constant Port_List := + (DP1, + DP2, + DP3, + HDMI1, + HDMI2, + HDMI3, + Analog, + LVDS, + eDP); + +end GMA.Mainboard; +`) + } +} |