/* 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
	IGD  map[uint32]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
	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
	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, 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":
		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.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 {
		WriteDev(dt, offset+1, 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.inc")
		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;
`)
	}
}
