/* 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 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 KconfigStringUnquoted 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 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(fp *os.File) {
	fp.WriteString(`/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2008-2009 coresystems GmbH
 * Copyright (C) 2014 Vladimir Serbinenko
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of
 * the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

`)
}

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)
}

func (g GenericVGA) Scan(ctx Context, addr PCIDevData) {
	KconfigString["VGA_BIOS_ID"] = fmt.Sprintf("%04x,%04x",
		addr.PCIVenID,
		addr.PCIDevID)
	KconfigString["VGA_BIOS_FILE"] = fmt.Sprintf("pci%04x,%04x.rom",
		addr.PCIVenID,
		addr.PCIDevID)
	PutPCIDevParent(addr, g.Comment, g.MissingParent)
}

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 KconfigStringUnquoted {
		keys = append(keys, name)
	}

	sort.Strings(keys)

	for _, name := range keys {
		fmt.Fprintf(kc, `
config %s%s
	string
	default %s
`, name, makeComment(name), KconfigStringUnquoted[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
	KconfigStringUnquoted["MAINBOARD_DIR"] = ctx.MoboID
	KconfigString["MAINBOARD_PART_NUMBER"] = ctx.Model

	os.MkdirAll(ctx.BaseDirectory, 0700)

	makeVendor(ctx)

	ScanRoot(ctx)

	if len(ROMStageFiles) > 0 || len(RAMStageFiles) > 0 || len(SMMFiles) > 0 {
		mf := Create(ctx, "Makefile.inc")
		defer mf.Close()
		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()
		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,
};
`)
		}
	}

	at := Create(ctx, "acpi_tables.c")
	defer at.Close()
	at.WriteString("/* dummy */\n")

	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")
	}

	dsdt.WriteString(
		`#include <arch/acpi.h>
DefinitionBlock(
	"dsdt.aml",
	"DSDT",
	0x02,		// DSDT revision: ACPI 2.0 and up
	OEM_ID,
	ACPI_TABLE_CREATOR,
	0x20141018	// OEM revision
)
{
	// Some generic macros
	#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(`
	Scope (\_SB) {
		Device (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(
		`		}
	}
}
`)

}
