autoport: Drop ioapic, ioapic_irq, and lapic handling for devicetree
[coreboot.git] / util / autoport / main.go
blob21dbbf07abfeeacdad920cb7dd3c04a4361099de
1 /* This is just an experiment. Full automatic porting
2 is probably not possible but a lot can be automated. */
3 package main
5 import (
6 "bytes"
7 "flag"
8 "fmt"
9 "log"
10 "os"
11 "path/filepath"
12 "sort"
13 "strings"
16 type PCIAddr struct {
17 Bus int
18 Dev int
19 Func int
22 type PCIDevData struct {
23 PCIAddr
24 PCIVenID uint16
25 PCIDevID uint16
26 ConfigDump []uint8
29 type PCIDevice interface {
30 Scan(ctx Context, addr PCIDevData)
33 type InteltoolData struct {
34 GPIO map[uint16]uint32
35 RCBA map[uint16]uint32
36 IGD map[uint32]uint32
39 type DMIData struct {
40 Vendor string
41 Model string
42 Version string
43 IsLaptop bool
46 type AzaliaCodec struct {
47 Name string
48 VendorID uint32
49 SubsystemID uint32
50 CodecNo int
51 PinConfig map[int]uint32
54 type DevReader interface {
55 GetPCIList() []PCIDevData
56 GetDMI() DMIData
57 GetInteltool() InteltoolData
58 GetAzaliaCodecs() []AzaliaCodec
59 GetACPI() map[string][]byte
60 GetCPUModel() []uint32
61 GetEC() []byte
62 GetIOPorts() []IOPorts
63 HasPS2() bool
66 type IOPorts struct {
67 Start uint16
68 End uint16
69 Usage string
72 type SouthBridger interface {
73 GetGPIOHeader() string
74 EncodeGPE(int) int
75 DecodeGPE(int) int
76 EnableGPE(int)
77 NeedRouteGPIOManually()
80 var SouthBridge SouthBridger
81 var BootBlockFiles map[string]string = map[string]string{}
82 var ROMStageFiles map[string]string = map[string]string{}
83 var RAMStageFiles map[string]string = map[string]string{}
84 var SMMFiles map[string]string = map[string]string{}
85 var MainboardInit string
86 var MainboardEnable string
87 var MainboardIncludes []string
89 type Context struct {
90 MoboID string
91 KconfigName string
92 Vendor string
93 Model string
94 BaseDirectory string
95 InfoSource DevReader
96 SaneVendor string
99 var KconfigBool map[string]bool = map[string]bool{}
100 var KconfigComment map[string]string = map[string]string{}
101 var KconfigString map[string]string = map[string]string{}
102 var KconfigHex map[string]uint32 = map[string]uint32{}
103 var KconfigInt map[string]int = map[string]int{}
104 var ROMSizeKB = 0
105 var ROMProtocol = ""
106 var FlashROMSupport = ""
108 func GetLE16(inp []byte) uint16 {
109 return uint16(inp[0]) | (uint16(inp[1]) << 8)
112 func FormatHexLE16(inp []byte) string {
113 return fmt.Sprintf("0x%04x", GetLE16(inp))
116 func FormatHex32(u uint32) string {
117 return fmt.Sprintf("0x%08x", u)
120 func FormatHex8(u uint8) string {
121 return fmt.Sprintf("0x%02x", u)
124 func FormatInt32(u uint32) string {
125 return fmt.Sprintf("%d", u)
128 func FormatHexLE32(d []uint8) string {
129 u := uint32(d[0]) | (uint32(d[1]) << 8) | (uint32(d[2]) << 16) | (uint32(d[3]) << 24)
130 return FormatHex32(u)
133 func FormatBool(inp bool) string {
134 if inp {
135 return "1"
136 } else {
137 return "0"
141 func sanitize(inp string) string {
142 result := strings.ToLower(inp)
143 result = strings.Replace(result, " ", "_", -1)
144 result = strings.Replace(result, ",", "_", -1)
145 result = strings.Replace(result, "-", "_", -1)
146 for strings.HasSuffix(result, ".") {
147 result = result[0 : len(result)-1]
149 return result
152 func AddBootBlockFile(Name string, Condition string) {
153 BootBlockFiles[Name] = Condition
156 func AddROMStageFile(Name string, Condition string) {
157 ROMStageFiles[Name] = Condition
160 func AddRAMStageFile(Name string, Condition string) {
161 RAMStageFiles[Name] = Condition
164 func AddSMMFile(Name string, Condition string) {
165 SMMFiles[Name] = Condition
168 func IsIOPortUsedBy(ctx Context, port uint16, name string) bool {
169 for _, io := range ctx.InfoSource.GetIOPorts() {
170 if io.Start <= port && port <= io.End && io.Usage == name {
171 return true
174 return false
177 var FlagOutDir = flag.String("coreboot_dir", ".", "Resulting coreboot directory")
179 func writeMF(mf *os.File, files map[string]string, category string) {
180 keys := []string{}
181 for file, _ := range files {
182 keys = append(keys, file)
185 sort.Strings(keys)
187 for _, file := range keys {
188 condition := files[file]
189 if condition == "" {
190 fmt.Fprintf(mf, "%s-y += %s\n", category, file)
191 } else {
192 fmt.Fprintf(mf, "%s-$(%s) += %s\n", category, condition, file)
197 func Create(ctx Context, name string) *os.File {
198 li := strings.LastIndex(name, "/")
199 if li > 0 {
200 os.MkdirAll(ctx.BaseDirectory+"/"+name[0:li], 0700)
202 mf, err := os.Create(ctx.BaseDirectory + "/" + name)
203 if err != nil {
204 log.Fatal(err)
206 return mf
209 func Add_gpl(f *os.File) {
210 fmt.Fprintln(f, "/* SPDX-License-Identifier: GPL-2.0-only */")
211 fmt.Fprintln(f)
214 func RestorePCI16Simple(f *os.File, pcidev PCIDevData, addr uint16) {
215 fmt.Fprintf(f, " pci_write_config16(PCI_DEV(%d, 0x%02x, %d), 0x%02x, 0x%02x%02x);\n",
216 pcidev.Bus, pcidev.Dev, pcidev.Func, addr,
217 pcidev.ConfigDump[addr+1],
218 pcidev.ConfigDump[addr])
221 func RestorePCI32Simple(f *os.File, pcidev PCIDevData, addr uint16) {
222 fmt.Fprintf(f, " pci_write_config32(PCI_DEV(%d, 0x%02x, %d), 0x%02x, 0x%02x%02x%02x%02x);\n",
223 pcidev.Bus, pcidev.Dev, pcidev.Func, addr,
224 pcidev.ConfigDump[addr+3],
225 pcidev.ConfigDump[addr+2],
226 pcidev.ConfigDump[addr+1],
227 pcidev.ConfigDump[addr])
230 func RestoreRCBA32(f *os.File, inteltool InteltoolData, addr uint16) {
231 fmt.Fprintf(f, "\tRCBA32(0x%04x) = 0x%08x;\n", addr, inteltool.RCBA[addr])
234 type PCISlot struct {
235 PCIAddr
236 alias string
237 additionalComment string
238 writeEmpty bool
241 type DevTreeNode struct {
242 Bus int
243 Dev int
244 Func int
245 Disabled bool
246 Registers map[string]string
247 IOs map[uint16]uint16
248 Children []DevTreeNode
249 PCISlots []PCISlot
250 PCIController bool
251 ChildPCIBus int
252 MissingParent string
253 SubVendor uint16
254 SubSystem uint16
255 Chip string
256 Comment string
259 var DevTree DevTreeNode
260 var MissingChildren map[string][]DevTreeNode = map[string][]DevTreeNode{}
261 var unmatchedPCIChips map[PCIAddr]DevTreeNode = map[PCIAddr]DevTreeNode{}
262 var unmatchedPCIDevices map[PCIAddr]DevTreeNode = map[PCIAddr]DevTreeNode{}
264 func Offset(dt *os.File, offset int) {
265 for i := 0; i < offset; i++ {
266 fmt.Fprintf(dt, "\t")
270 func MatchDev(dev *DevTreeNode) {
271 for idx := range dev.Children {
272 MatchDev(&dev.Children[idx])
275 for _, slot := range dev.PCISlots {
276 slotChip, ok := unmatchedPCIChips[slot.PCIAddr]
278 if !ok {
279 continue
282 if slot.additionalComment != "" && slotChip.Comment != "" {
283 slotChip.Comment = slot.additionalComment + " " + slotChip.Comment
284 } else {
285 slotChip.Comment = slot.additionalComment + slotChip.Comment
288 delete(unmatchedPCIChips, slot.PCIAddr)
289 MatchDev(&slotChip)
290 dev.Children = append(dev.Children, slotChip)
293 if dev.PCIController {
294 for slot, slotDev := range unmatchedPCIChips {
295 if slot.Bus == dev.ChildPCIBus {
296 delete(unmatchedPCIChips, slot)
297 MatchDev(&slotDev)
298 dev.Children = append(dev.Children, slotDev)
303 for _, slot := range dev.PCISlots {
304 slotDev, ok := unmatchedPCIDevices[slot.PCIAddr]
305 if !ok {
306 if slot.writeEmpty {
307 dev.Children = append(dev.Children,
308 DevTreeNode{
309 Registers: map[string]string{},
310 Chip: "pci",
311 Bus: slot.Bus,
312 Dev: slot.Dev,
313 Func: slot.Func,
314 Comment: slot.additionalComment,
315 Disabled: true,
319 continue
322 if slot.additionalComment != "" && slotDev.Comment != "" {
323 slotDev.Comment = slot.additionalComment + " " + slotDev.Comment
324 } else {
325 slotDev.Comment = slot.additionalComment + slotDev.Comment
328 MatchDev(&slotDev)
329 dev.Children = append(dev.Children, slotDev)
330 delete(unmatchedPCIDevices, slot.PCIAddr)
333 if dev.MissingParent != "" {
334 for _, child := range MissingChildren[dev.MissingParent] {
335 MatchDev(&child)
336 dev.Children = append(dev.Children, child)
338 delete(MissingChildren, dev.MissingParent)
341 if dev.PCIController {
342 for slot, slotDev := range unmatchedPCIDevices {
343 if slot.Bus == dev.ChildPCIBus {
344 MatchDev(&slotDev)
345 dev.Children = append(dev.Children, slotDev)
346 delete(unmatchedPCIDevices, slot)
352 func writeOn(dt *os.File, dev DevTreeNode) {
353 if dev.Disabled {
354 fmt.Fprintf(dt, "off")
355 } else {
356 fmt.Fprintf(dt, "on")
360 func WriteDev(dt *os.File, offset int, alias string, dev DevTreeNode) {
361 Offset(dt, offset)
362 switch dev.Chip {
363 case "cpu_cluster", "domain":
364 fmt.Fprintf(dt, "device %s 0x%x ", dev.Chip, dev.Dev)
365 writeOn(dt, dev)
366 case "pci", "pnp":
367 if alias != "" {
368 fmt.Fprintf(dt, "device ref %s ", alias)
369 } else {
370 fmt.Fprintf(dt, "device %s %02x.%x ", dev.Chip, dev.Dev, dev.Func)
372 writeOn(dt, dev)
373 case "i2c":
374 fmt.Fprintf(dt, "device %s %02x ", dev.Chip, dev.Dev)
375 writeOn(dt, dev)
376 default:
377 fmt.Fprintf(dt, "chip %s", dev.Chip)
379 if dev.Comment != "" {
380 fmt.Fprintf(dt, " # %s", dev.Comment)
382 fmt.Fprintf(dt, "\n")
383 if dev.Chip == "pci" && dev.SubSystem != 0 && dev.SubVendor != 0 {
384 Offset(dt, offset+1)
385 fmt.Fprintf(dt, "subsystemid 0x%04x 0x%04x\n", dev.SubVendor, dev.SubSystem)
388 keys := []string{}
389 for reg, _ := range dev.Registers {
390 keys = append(keys, reg)
393 sort.Strings(keys)
395 for _, reg := range keys {
396 val := dev.Registers[reg]
397 Offset(dt, offset+1)
398 fmt.Fprintf(dt, "register \"%s\" = \"%s\"\n", reg, val)
401 ios := []int{}
402 for reg, _ := range dev.IOs {
403 ios = append(ios, int(reg))
406 sort.Ints(ios)
408 for _, reg := range ios {
409 val := dev.IOs[uint16(reg)]
410 Offset(dt, offset+1)
411 fmt.Fprintf(dt, "io 0x%x = 0x%x\n", reg, val)
414 for _, child := range dev.Children {
415 alias = ""
416 for _, slot := range dev.PCISlots {
417 if slot.PCIAddr.Bus == child.Bus &&
418 slot.PCIAddr.Dev == child.Dev && slot.PCIAddr.Func == child.Func {
419 alias = slot.alias
422 WriteDev(dt, offset+1, alias, child)
425 Offset(dt, offset)
426 fmt.Fprintf(dt, "end\n")
429 func PutChip(domain string, cur DevTreeNode) {
430 MissingChildren[domain] = append(MissingChildren[domain], cur)
433 func PutPCIChip(addr PCIDevData, cur DevTreeNode) {
434 unmatchedPCIChips[addr.PCIAddr] = cur
437 func PutPCIDevParent(addr PCIDevData, comment string, parent string) {
438 cur := DevTreeNode{
439 Registers: map[string]string{},
440 Chip: "pci",
441 Bus: addr.Bus,
442 Dev: addr.Dev,
443 Func: addr.Func,
444 MissingParent: parent,
445 Comment: comment,
447 if addr.ConfigDump[0xa] == 0x04 && addr.ConfigDump[0xb] == 0x06 {
448 cur.PCIController = true
449 cur.ChildPCIBus = int(addr.ConfigDump[0x19])
451 loopCtr := 0
452 for capPtr := addr.ConfigDump[0x34]; capPtr != 0; capPtr = addr.ConfigDump[capPtr+1] {
453 /* Avoid hangs. There are only 0x100 different possible values for capPtr.
454 If we iterate longer than that, we're in endless loop. */
455 loopCtr++
456 if loopCtr > 0x100 {
457 break
459 if addr.ConfigDump[capPtr] == 0x0d {
460 cur.SubVendor = GetLE16(addr.ConfigDump[capPtr+4 : capPtr+6])
461 cur.SubSystem = GetLE16(addr.ConfigDump[capPtr+6 : capPtr+8])
464 } else {
465 cur.SubVendor = GetLE16(addr.ConfigDump[0x2c:0x2e])
466 cur.SubSystem = GetLE16(addr.ConfigDump[0x2e:0x30])
468 unmatchedPCIDevices[addr.PCIAddr] = cur
471 func PutPCIDev(addr PCIDevData, comment string) {
472 PutPCIDevParent(addr, comment, "")
475 type GenericPCI struct {
476 Comment string
477 Bus0Subdiv string
478 MissingParent string
481 type GenericVGA struct {
482 GenericPCI
485 type DSDTInclude struct {
486 Comment string
487 File string
490 type DSDTDefine struct {
491 Key string
492 Comment string
493 Value string
496 var DSDTIncludes []DSDTInclude
497 var DSDTPCI0Includes []DSDTInclude
498 var DSDTDefines []DSDTDefine
500 func (g GenericPCI) Scan(ctx Context, addr PCIDevData) {
501 PutPCIDevParent(addr, g.Comment, g.MissingParent)
504 var IGDEnabled bool = false
506 func (g GenericVGA) Scan(ctx Context, addr PCIDevData) {
507 KconfigString["VGA_BIOS_ID"] = fmt.Sprintf("%04x,%04x",
508 addr.PCIVenID,
509 addr.PCIDevID)
510 PutPCIDevParent(addr, g.Comment, g.MissingParent)
511 IGDEnabled = true
514 func makeKconfigName(ctx Context) {
515 kn := Create(ctx, "Kconfig.name")
516 defer kn.Close()
518 fmt.Fprintf(kn, "config %s\n\tbool \"%s\"\n", ctx.KconfigName, ctx.Model)
521 func makeComment(name string) string {
522 cmt, ok := KconfigComment[name]
523 if !ok {
524 return ""
526 return " # " + cmt
529 func makeKconfig(ctx Context) {
530 kc := Create(ctx, "Kconfig")
531 defer kc.Close()
533 fmt.Fprintf(kc, "if %s\n\n", ctx.KconfigName)
535 fmt.Fprintf(kc, "config BOARD_SPECIFIC_OPTIONS\n\tdef_bool y\n")
536 keys := []string{}
537 for name, val := range KconfigBool {
538 if val {
539 keys = append(keys, name)
543 sort.Strings(keys)
545 for _, name := range keys {
546 fmt.Fprintf(kc, "\tselect %s%s\n", name, makeComment(name))
549 keys = nil
550 for name, val := range KconfigBool {
551 if !val {
552 keys = append(keys, name)
556 sort.Strings(keys)
558 for _, name := range keys {
559 fmt.Fprintf(kc, `
560 config %s%s
561 bool
562 default n
563 `, name, makeComment(name))
566 keys = nil
567 for name, _ := range KconfigString {
568 keys = append(keys, name)
571 sort.Strings(keys)
573 for _, name := range keys {
574 fmt.Fprintf(kc, `
575 config %s%s
576 string
577 default "%s"
578 `, name, makeComment(name), KconfigString[name])
581 keys = nil
582 for name, _ := range KconfigHex {
583 keys = append(keys, name)
586 sort.Strings(keys)
588 for _, name := range keys {
589 fmt.Fprintf(kc, `
590 config %s%s
592 default 0x%x
593 `, name, makeComment(name), KconfigHex[name])
596 keys = nil
597 for name, _ := range KconfigInt {
598 keys = append(keys, name)
601 sort.Strings(keys)
603 for _, name := range keys {
604 fmt.Fprintf(kc, `
605 config %s%s
607 default %d
608 `, name, makeComment(name), KconfigInt[name])
611 fmt.Fprintf(kc, "endif\n")
614 const MoboDir = "/src/mainboard/"
616 func makeVendor(ctx Context) {
617 vendor := ctx.Vendor
618 vendorSane := ctx.SaneVendor
619 vendorDir := *FlagOutDir + MoboDir + vendorSane
620 vendorUpper := strings.ToUpper(vendorSane)
621 kconfig := vendorDir + "/Kconfig"
622 if _, err := os.Stat(kconfig); os.IsNotExist(err) {
623 f, err := os.Create(kconfig)
624 if err != nil {
625 log.Fatal(err)
627 defer f.Close()
628 f.WriteString(`if VENDOR_` + vendorUpper + `
630 choice
631 prompt "Mainboard model"
633 source "src/mainboard/` + vendorSane + `/*/Kconfig.name"
635 endchoice
637 source "src/mainboard/` + vendorSane + `/*/Kconfig"
639 config MAINBOARD_VENDOR
640 string
641 default "` + vendor + `"
643 endif # VENDOR_` + vendorUpper + "\n")
645 kconfigName := vendorDir + "/Kconfig.name"
646 if _, err := os.Stat(kconfigName); os.IsNotExist(err) {
647 f, err := os.Create(kconfigName)
648 if err != nil {
649 log.Fatal(err)
651 defer f.Close()
652 f.WriteString(`config VENDOR_` + vendorUpper + `
653 bool "` + vendor + `"
659 func GuessECGPE(ctx Context) int {
660 /* FIXME:XX Use iasl -d and/or better parsing */
661 dsdt := ctx.InfoSource.GetACPI()["DSDT"]
662 idx := bytes.Index(dsdt, []byte{0x08, '_', 'G', 'P', 'E', 0x0a}) /* Name (_GPE, byte). */
663 if idx > 0 {
664 return int(dsdt[idx+6])
666 return -1
669 func GuessSPDMap(ctx Context) []uint8 {
670 dmi := ctx.InfoSource.GetDMI()
672 if dmi.Vendor == "LENOVO" {
673 return []uint8{0x50, 0x52, 0x51, 0x53}
675 return []uint8{0x50, 0x51, 0x52, 0x53}
678 func main() {
679 flag.Parse()
681 ctx := Context{}
683 ctx.InfoSource = MakeLogReader()
685 dmi := ctx.InfoSource.GetDMI()
687 ctx.Vendor = dmi.Vendor
689 if dmi.Vendor == "LENOVO" {
690 ctx.Model = dmi.Version
691 } else {
692 ctx.Model = dmi.Model
695 if dmi.IsLaptop {
696 KconfigBool["SYSTEM_TYPE_LAPTOP"] = true
698 ctx.SaneVendor = sanitize(ctx.Vendor)
699 for {
700 last := ctx.SaneVendor
701 for _, suf := range []string{"_inc", "_co", "_corp"} {
702 ctx.SaneVendor = strings.TrimSuffix(ctx.SaneVendor, suf)
704 if last == ctx.SaneVendor {
705 break
708 ctx.MoboID = ctx.SaneVendor + "/" + sanitize(ctx.Model)
709 ctx.KconfigName = "BOARD_" + strings.ToUpper(ctx.SaneVendor+"_"+sanitize(ctx.Model))
710 ctx.BaseDirectory = *FlagOutDir + MoboDir + ctx.MoboID
711 KconfigString["MAINBOARD_DIR"] = ctx.MoboID
712 KconfigString["MAINBOARD_PART_NUMBER"] = ctx.Model
714 os.MkdirAll(ctx.BaseDirectory, 0700)
716 makeVendor(ctx)
718 ScanRoot(ctx)
720 if IGDEnabled {
721 KconfigBool["MAINBOARD_HAS_LIBGFXINIT"] = true
722 KconfigComment["MAINBOARD_HAS_LIBGFXINIT"] = "FIXME: check this"
723 AddRAMStageFile("gma-mainboard.ads", "CONFIG_MAINBOARD_USE_LIBGFXINIT")
726 if len(BootBlockFiles) > 0 || len(ROMStageFiles) > 0 || len(RAMStageFiles) > 0 || len(SMMFiles) > 0 {
727 mf := Create(ctx, "Makefile.mk")
728 defer mf.Close()
729 writeMF(mf, BootBlockFiles, "bootblock")
730 writeMF(mf, ROMStageFiles, "romstage")
731 writeMF(mf, RAMStageFiles, "ramstage")
732 writeMF(mf, SMMFiles, "smm")
735 devtree := Create(ctx, "devicetree.cb")
736 defer devtree.Close()
738 MatchDev(&DevTree)
739 WriteDev(devtree, 0, "", DevTree)
741 if MainboardInit != "" || MainboardEnable != "" || MainboardIncludes != nil {
742 mainboard := Create(ctx, "mainboard.c")
743 defer mainboard.Close()
744 Add_gpl(mainboard)
745 mainboard.WriteString("#include <device/device.h>\n")
746 for _, include := range MainboardIncludes {
747 mainboard.WriteString("#include <" + include + ">\n")
749 mainboard.WriteString("\n")
750 if MainboardInit != "" {
751 mainboard.WriteString(`static void mainboard_init(struct device *dev)
753 ` + MainboardInit + "}\n\n")
755 if MainboardInit != "" || MainboardEnable != "" {
756 mainboard.WriteString("static void mainboard_enable(struct device *dev)\n{\n")
757 if MainboardInit != "" {
758 mainboard.WriteString("\tdev->ops->init = mainboard_init;\n\n")
760 mainboard.WriteString(MainboardEnable)
761 mainboard.WriteString("}\n\n")
762 mainboard.WriteString(`struct chip_operations mainboard_ops = {
763 .enable_dev = mainboard_enable,
769 bi := Create(ctx, "board_info.txt")
770 defer bi.Close()
772 fixme := ""
774 if dmi.IsLaptop {
775 bi.WriteString("Category: laptop\n")
776 } else {
777 bi.WriteString("Category: desktop\n")
778 fixme += "check category, "
781 missing := "ROM package, ROM socketed"
783 if ROMProtocol != "" {
784 fmt.Fprintf(bi, "ROM protocol: %s\n", ROMProtocol)
785 } else {
786 missing += ", ROM protocol"
789 if FlashROMSupport != "" {
790 fmt.Fprintf(bi, "Flashrom support: %s\n", FlashROMSupport)
791 } else {
792 missing += ", Flashrom support"
795 missing += ", Release year"
797 if fixme != "" {
798 fmt.Fprintf(bi, "FIXME: %s, put %s\n", fixme, missing)
799 } else {
800 fmt.Fprintf(bi, "FIXME: put %s\n", missing)
803 if ROMSizeKB == 0 {
804 KconfigBool["BOARD_ROMSIZE_KB_2048"] = true
805 KconfigComment["BOARD_ROMSIZE_KB_2048"] = "FIXME: correct this"
806 } else {
807 KconfigBool[fmt.Sprintf("BOARD_ROMSIZE_KB_%d", ROMSizeKB)] = true
810 makeKconfig(ctx)
811 makeKconfigName(ctx)
813 dsdt := Create(ctx, "dsdt.asl")
814 defer dsdt.Close()
815 Add_gpl(dsdt)
817 for _, define := range DSDTDefines {
818 if define.Comment != "" {
819 fmt.Fprintf(dsdt, "\t/* %s. */\n", define.Comment)
821 dsdt.WriteString("#define " + define.Key + " " + define.Value + "\n")
824 dsdt.WriteString(
825 `#include <acpi/acpi.h>
827 DefinitionBlock(
828 "dsdt.aml",
829 "DSDT",
830 ACPI_DSDT_REV_2,
831 OEM_ID,
832 ACPI_TABLE_CREATOR,
833 0x20141018
836 #include <acpi/dsdt_top.asl>
837 #include "acpi/platform.asl"
840 for _, x := range DSDTIncludes {
841 if x.Comment != "" {
842 fmt.Fprintf(dsdt, "\t/* %s. */\n", x.Comment)
844 fmt.Fprintf(dsdt, "\t#include <%s>\n", x.File)
847 dsdt.WriteString(`
848 Device (\_SB.PCI0)
851 for _, x := range DSDTPCI0Includes {
852 if x.Comment != "" {
853 fmt.Fprintf(dsdt, "\t/* %s. */\n", x.Comment)
855 fmt.Fprintf(dsdt, "\t\t#include <%s>\n", x.File)
857 dsdt.WriteString(
862 if IGDEnabled {
863 gma := Create(ctx, "gma-mainboard.ads")
864 defer gma.Close()
866 gma.WriteString(`-- SPDX-License-Identifier: GPL-2.0-or-later
868 with HW.GFX.GMA;
869 with HW.GFX.GMA.Display_Probing;
871 use HW.GFX.GMA;
872 use HW.GFX.GMA.Display_Probing;
874 private package GMA.Mainboard is
876 -- FIXME: check this
877 ports : constant Port_List :=
878 (DP1,
879 DP2,
880 DP3,
881 HDMI1,
882 HDMI2,
883 HDMI3,
884 Analog,
885 LVDS,
886 eDP);
888 end GMA.Mainboard;
891 outputPath, _ := filepath.Abs(ctx.BaseDirectory)
892 fmt.Printf("Done! Generated sources are in %s\n", outputPath)