blob: e9d847d9a01beb9879e9a6b69493c2758714fad1 [file] [log] [blame]
Vladimir Serbinenko3129f792014-10-15 21:51:47 +02001/* This is just an experiment. Full automatic porting
2 is probably not possible but a lot can be automated. */
3package main
4
5import (
6 "bytes"
7 "flag"
8 "fmt"
9 "log"
10 "os"
11 "sort"
12 "strings"
13)
14
15type PCIAddr struct {
16 Bus int
17 Dev int
18 Func int
19}
20
21type PCIDevData struct {
22 PCIAddr
23 PCIVenID uint16
24 PCIDevID uint16
25 ConfigDump []uint8
26}
27
28type PCIDevice interface {
29 Scan(ctx Context, addr PCIDevData)
30}
31
32type InteltoolData struct {
33 GPIO map[uint16]uint32
34 RCBA map[uint16]uint32
35 IGD map[uint32]uint32
36}
37
38type DMIData struct {
39 Vendor string
40 Model string
41 Version string
42 IsLaptop bool
43}
44
45type AzaliaCodec struct {
46 Name string
47 VendorID uint32
48 SubsystemID uint32
49 CodecNo int
50 PinConfig map[int]uint32
51}
52
53type DevReader interface {
54 GetPCIList() []PCIDevData
55 GetDMI() DMIData
56 GetInteltool() InteltoolData
57 GetAzaliaCodecs() []AzaliaCodec
58 GetACPI() map[string][]byte
59 GetCPUModel() []uint32
60 GetEC() []byte
61 GetIOPorts() []IOPorts
62}
63
64type IOPorts struct {
65 Start uint16
66 End uint16
67 Usage string
68}
69
70type SouthBridger interface {
71 GetGPIOHeader() string
72 EncodeGPE(int) int
73 DecodeGPE(int) int
74 EnableGPE(int)
75 NeedRouteGPIOManually()
76}
77
78var SouthBridge SouthBridger
79var ROMStageFiles map[string]string = map[string]string{}
80var RAMStageFiles map[string]string = map[string]string{}
81var SMMFiles map[string]string = map[string]string{}
82var MainboardInit string
83var MainboardEnable string
84var MainboardIncludes []string
85
86type Context struct {
87 MoboID string
88 KconfigName string
89 Vendor string
90 Model string
91 BaseDirectory string
92 InfoSource DevReader
93}
94
95type IOAPICIRQ struct {
96 APICID int
97 IRQNO [4]int
98}
99
100var IOAPICIRQs map[PCIAddr]IOAPICIRQ = map[PCIAddr]IOAPICIRQ{}
101var KconfigBool map[string]bool = map[string]bool{}
102var KconfigComment map[string]string = map[string]string{}
103var KconfigString map[string]string = map[string]string{}
104var KconfigStringUnquoted map[string]string = map[string]string{}
105var KconfigHex map[string]uint32 = map[string]uint32{}
106var KconfigInt map[string]int = map[string]int{}
107var ROMSizeKB = 0
108var ROMProtocol = ""
109var FlashROMSupport = ""
110
111func GetLE16(inp []byte) uint16 {
112 return uint16(inp[0]) | (uint16(inp[1]) << 8)
113}
114
115func FormatHexLE16(inp []byte) string {
116 return fmt.Sprintf("0x%04x", GetLE16(inp))
117}
118
119func FormatHex32(u uint32) string {
120 return fmt.Sprintf("0x%08x", u)
121}
122
123func FormatHex8(u uint8) string {
124 return fmt.Sprintf("0x%02x", u)
125}
126
127func FormatInt32(u uint32) string {
128 return fmt.Sprintf("%d", u)
129}
130
131func FormatHexLE32(d []uint8) string {
132 u := uint32(d[0]) | (uint32(d[1]) << 8) | (uint32(d[2]) << 16) | (uint32(d[3]) << 24)
133 return FormatHex32(u)
134}
135
136func FormatBool(inp bool) string {
137 if inp {
138 return "1"
139 } else {
140 return "0"
141 }
142}
143
144func sanitize(inp string) string {
145 result := strings.ToLower(inp)
146 result = strings.Replace(result, " ", "_", -1)
147 result = strings.Replace(result, ",", "_", -1)
148 for strings.HasSuffix(result, ".") {
149 result = result[0 : len(result)-1]
150 }
151 return result
152}
153
154func AddROMStageFile(Name string, Condition string) {
155 ROMStageFiles[Name] = Condition
156}
157
158func AddRAMStageFile(Name string, Condition string) {
159 RAMStageFiles[Name] = Condition
160}
161
162func AddSMMFile(Name string, Condition string) {
163 SMMFiles[Name] = Condition
164}
165
166func IsIOPortUsedBy(ctx Context, port uint16, name string) bool {
167 for _, io := range ctx.InfoSource.GetIOPorts() {
168 if io.Start <= port && port <= io.End && io.Usage == name {
169 return true
170 }
171 }
172 return false
173}
174
175var FlagOutDir = flag.String("coreboot_dir", ".", "Resulting coreboot directory")
176
177func writeMF(mf *os.File, files map[string]string, category string) {
178 keys := []string{}
179 for file, _ := range files {
180 keys = append(keys, file)
181 }
182
183 sort.Strings(keys)
184
185 for _, file := range keys {
186 condition := files[file]
187 if condition == "" {
188 fmt.Fprintf(mf, "%s-y += %s\n", category, file)
189 } else {
190 fmt.Fprintf(mf, "%s-$(%s) += %s\n", category,
191 condition, file)
192 }
193 }
194}
195
196func Create(ctx Context, name string) *os.File {
197 li := strings.LastIndex(name, "/")
198 if li > 0 {
199 os.MkdirAll(ctx.BaseDirectory+"/"+name[0:li], 0700)
200 }
201 mf, err := os.Create(ctx.BaseDirectory + "/" + name)
202 if err != nil {
203 log.Fatal(err)
204 }
205 return mf
206}
207
208func RestorePCI16Simple(f *os.File, pcidev PCIDevData, addr uint16) {
209 fmt.Fprintf(f, " pci_write_config16(PCI_DEV(%d, 0x%02x, %d), 0x%02x, 0x%02x%02x);\n",
210 pcidev.Bus, pcidev.Dev, pcidev.Func, addr,
211 pcidev.ConfigDump[addr+1],
212 pcidev.ConfigDump[addr])
213}
214
215func RestorePCI32Simple(f *os.File, pcidev PCIDevData, addr uint16) {
216 fmt.Fprintf(f, " pci_write_config32(PCI_DEV(%d, 0x%02x, %d), 0x%02x, 0x%02x%02x%02x%02x);\n",
217 pcidev.Bus, pcidev.Dev, pcidev.Func, addr,
218 pcidev.ConfigDump[addr+3],
219 pcidev.ConfigDump[addr+2],
220 pcidev.ConfigDump[addr+1],
221 pcidev.ConfigDump[addr])
222}
223
224func RestoreRCBA32(f *os.File, inteltool InteltoolData, addr uint16) {
225 fmt.Fprintf(f, "\tRCBA32(0x%04x) = 0x%08x;\n", addr, inteltool.RCBA[addr])
226}
227
228type PCISlot struct {
229 PCIAddr
230 additionalComment string
231 writeEmpty bool
232}
233
234type DevTreeNode struct {
235 Bus int
236 Dev int
237 Func int
238 Disabled bool
239 Registers map[string]string
240 IOs map[uint16]uint16
241 Children []DevTreeNode
242 PCISlots []PCISlot
243 PCIController bool
244 ChildPCIBus int
245 MissingParent string
246 SubVendor uint16
247 SubSystem uint16
248 Chip string
249 Comment string
250}
251
252var DevTree DevTreeNode
253var MissingChildren map[string][]DevTreeNode = map[string][]DevTreeNode{}
254var unmatchedPCIChips map[PCIAddr]DevTreeNode = map[PCIAddr]DevTreeNode{}
255var unmatchedPCIDevices map[PCIAddr]DevTreeNode = map[PCIAddr]DevTreeNode{}
256
257func Offset(dt *os.File, offset int) {
258 for i := 0; i < offset; i++ {
259 fmt.Fprintf(dt, "\t")
260 }
261}
262
263func MatchDev(dev *DevTreeNode) {
264 for idx := range dev.Children {
265 MatchDev(&dev.Children[idx])
266 }
267
268 for _, slot := range dev.PCISlots {
269 slotChip, ok := unmatchedPCIChips[slot.PCIAddr]
270
271 if !ok {
272 continue
273 }
274
275 if slot.additionalComment != "" && slotChip.Comment != "" {
276 slotChip.Comment = slot.additionalComment + " " + slotChip.Comment
277 } else {
278 slotChip.Comment = slot.additionalComment + slotChip.Comment
279 }
280
281 delete(unmatchedPCIChips, slot.PCIAddr)
282 MatchDev(&slotChip)
283 dev.Children = append(dev.Children, slotChip)
284 }
285
286 if dev.PCIController {
287 for slot, slotDev := range unmatchedPCIChips {
288 if slot.Bus == dev.ChildPCIBus {
289 delete(unmatchedPCIChips, slot)
290 MatchDev(&slotDev)
291 dev.Children = append(dev.Children, slotDev)
292 }
293 }
294 }
295
296 for _, slot := range dev.PCISlots {
297 slotDev, ok := unmatchedPCIDevices[slot.PCIAddr]
298 if !ok {
299 if slot.writeEmpty {
300 dev.Children = append(dev.Children,
301 DevTreeNode{
302 Registers: map[string]string{},
303 Chip: "pci",
304 Bus: slot.Bus,
305 Dev: slot.Dev,
306 Func: slot.Func,
307 Comment: slot.additionalComment,
308 Disabled: true,
309 },
310 )
311 }
312 continue
313 }
314
315 if slot.additionalComment != "" && slotDev.Comment != "" {
316 slotDev.Comment = slot.additionalComment + " " + slotDev.Comment
317 } else {
318 slotDev.Comment = slot.additionalComment + slotDev.Comment
319 }
320
321 MatchDev(&slotDev)
322 dev.Children = append(dev.Children, slotDev)
323 delete(unmatchedPCIDevices, slot.PCIAddr)
324 }
325
326 if dev.MissingParent != "" {
327 for _, child := range MissingChildren[dev.MissingParent] {
328 MatchDev(&child)
329 dev.Children = append(dev.Children, child)
330 }
331 delete(MissingChildren, dev.MissingParent)
332 }
333
334 if dev.PCIController {
335 for slot, slotDev := range unmatchedPCIDevices {
336 if slot.Bus == dev.ChildPCIBus {
337 MatchDev(&slotDev)
338 dev.Children = append(dev.Children, slotDev)
339 delete(unmatchedPCIDevices, slot)
340 }
341 }
342 }
343}
344
345func writeOn(dt *os.File, dev DevTreeNode) {
346 if dev.Disabled {
347 fmt.Fprintf(dt, "off")
348 } else {
349 fmt.Fprintf(dt, "on")
350 }
351}
352
353func WriteDev(dt *os.File, offset int, dev DevTreeNode) {
354 Offset(dt, offset)
355 switch dev.Chip {
356 case "cpu_cluster", "lapic", "domain", "ioapic":
357 fmt.Fprintf(dt, "device %s 0x%x ", dev.Chip, dev.Dev)
358 writeOn(dt, dev)
359 case "pci", "pnp":
360 fmt.Fprintf(dt, "device %s %02x.%x ", dev.Chip, dev.Dev, dev.Func)
361 writeOn(dt, dev)
362 case "i2c":
363 fmt.Fprintf(dt, "device %s %02x ", dev.Chip, dev.Dev)
364 writeOn(dt, dev)
365 default:
366 fmt.Fprintf(dt, "chip %s", dev.Chip)
367 }
368 if dev.Comment != "" {
369 fmt.Fprintf(dt, " # %s", dev.Comment)
370 }
371 fmt.Fprintf(dt, "\n")
372 if dev.Chip == "pci" && dev.SubSystem != 0 && dev.SubVendor != 0 {
373 Offset(dt, offset+1)
374 fmt.Fprintf(dt, "subsystemid 0x%04x 0x%04x\n", dev.SubVendor, dev.SubSystem)
375 }
376
377 ioapic, ok := IOAPICIRQs[PCIAddr{Bus: dev.Bus, Dev: dev.Dev, Func: dev.Func}]
378 if dev.Chip == "pci" && ok {
379 for pin, irq := range ioapic.IRQNO {
380 if irq != 0 {
381 Offset(dt, offset+1)
382 fmt.Fprintf(dt, "ioapic_irq %d INT%c 0x%x\n", ioapic.APICID, 'A'+pin, irq)
383 }
384 }
385 }
386
387 keys := []string{}
388 for reg, _ := range dev.Registers {
389 keys = append(keys, reg)
390 }
391
392 sort.Strings(keys)
393
394 for _, reg := range keys {
395 val := dev.Registers[reg]
396 Offset(dt, offset+1)
397 fmt.Fprintf(dt, "register \"%s\" = \"%s\"\n", reg, val)
398 }
399
400 ios := []int{}
401 for reg, _ := range dev.IOs {
402 ios = append(ios, int(reg))
403 }
404
405 sort.Ints(ios)
406
407 for _, reg := range ios {
408 val := dev.IOs[uint16(reg)]
409 Offset(dt, offset+1)
410 fmt.Fprintf(dt, "io 0x%x = 0x%x\n", reg, val)
411 }
412
413 for _, child := range dev.Children {
414 WriteDev(dt, offset+1, child)
415 }
416
417 Offset(dt, offset)
418 fmt.Fprintf(dt, "end\n")
419}
420
421func PutChip(domain string, cur DevTreeNode) {
422 MissingChildren[domain] = append(MissingChildren[domain], cur)
423}
424
425func PutPCIChip(addr PCIDevData, cur DevTreeNode) {
426 unmatchedPCIChips[addr.PCIAddr] = cur
427}
428
429func PutPCIDevParent(addr PCIDevData, comment string, parent string) {
430 cur := DevTreeNode{
431 Registers: map[string]string{},
432 Chip: "pci",
433 Bus: addr.Bus,
434 Dev: addr.Dev,
435 Func: addr.Func,
436 MissingParent: parent,
437 Comment: comment,
438 }
439 if addr.ConfigDump[0xa] == 0x04 && addr.ConfigDump[0xb] == 0x06 {
440 cur.PCIController = true
441 cur.ChildPCIBus = int(addr.ConfigDump[0x19])
442
443 loopCtr := 0
444 for capPtr := addr.ConfigDump[0x34]; capPtr != 0; capPtr = addr.ConfigDump[capPtr+1] {
445 /* Avoid hangs. There are only 0x100 different possible values for capPtr.
446 If we iterate longer than that, we're in endless loop. */
447 loopCtr++
448 if loopCtr > 0x100 {
449 break
450 }
451 if addr.ConfigDump[capPtr] == 0x0d {
452 cur.SubVendor = GetLE16(addr.ConfigDump[capPtr+4 : capPtr+6])
453 cur.SubSystem = GetLE16(addr.ConfigDump[capPtr+6 : capPtr+8])
454 }
455 }
456 } else {
457 cur.SubVendor = GetLE16(addr.ConfigDump[0x2c:0x2e])
458 cur.SubSystem = GetLE16(addr.ConfigDump[0x2e:0x30])
459 }
460 unmatchedPCIDevices[addr.PCIAddr] = cur
461}
462
463func PutPCIDev(addr PCIDevData, comment string) {
464 PutPCIDevParent(addr, comment, "")
465}
466
467type GenericPCI struct {
468 Comment string
469 Bus0Subdiv string
470 MissingParent string
471}
472
473type GenericVGA struct {
474 GenericPCI
475}
476
477type DSDTInclude struct {
478 Comment string
479 File string
480}
481
482type DSDTDefine struct {
483 Key string
484 Comment string
485 Value string
486}
487
488var DSDTIncludes []DSDTInclude
489var DSDTPCI0Includes []DSDTInclude
490var DSDTDefines []DSDTDefine
491
492func (g GenericPCI) Scan(ctx Context, addr PCIDevData) {
493 PutPCIDevParent(addr, g.Comment, g.MissingParent)
494}
495
496func (g GenericVGA) Scan(ctx Context, addr PCIDevData) {
497 KconfigString["VGA_BIOS_ID"] = fmt.Sprintf("%04x,%04x",
498 addr.PCIVenID,
499 addr.PCIDevID)
500 KconfigString["VGA_BIOS_FILE"] = fmt.Sprintf("pci%04x,%04x.rom",
501 addr.PCIVenID,
502 addr.PCIDevID)
503 PutPCIDevParent(addr, g.Comment, g.MissingParent)
504}
505
506func makeKconfigName(ctx Context) {
507 kn := Create(ctx, "Kconfig.name")
508 defer kn.Close()
509
510 fmt.Fprintf(kn, "config %s\n\tbool \"%s\"\n", ctx.KconfigName, ctx.Model)
511}
512
513func makeComment(name string) string {
514 cmt, ok := KconfigComment[name]
515 if !ok {
516 return ""
517 }
518 return " # " + cmt
519}
520
521func makeKconfig(ctx Context) {
522 kc := Create(ctx, "Kconfig")
523 defer kc.Close()
524
525 fmt.Fprintf(kc, "if %s\n\n", ctx.KconfigName)
526
527 fmt.Fprintf(kc, "config BOARD_SPECIFIC_OPTIONS # dummy\n\tdef_bool y\n")
528 keys := []string{}
529 for name, val := range KconfigBool {
530 if val {
531 keys = append(keys, name)
532 }
533 }
534
535 sort.Strings(keys)
536
537 for _, name := range keys {
538 fmt.Fprintf(kc, "\tselect %s%s\n", name, makeComment(name))
539 }
540
541 keys = nil
542 for name, val := range KconfigBool {
543 if !val {
544 keys = append(keys, name)
545 }
546 }
547
548 sort.Strings(keys)
549
550 for _, name := range keys {
551 fmt.Fprintf(kc, `
552config %s%s
553 bool
554 default n
555`, name, makeComment(name))
556 }
557
558 keys = nil
559 for name, _ := range KconfigStringUnquoted {
560 keys = append(keys, name)
561 }
562
563 sort.Strings(keys)
564
565 for _, name := range keys {
566 fmt.Fprintf(kc, `
567config %s%s
568 string
569 default %s
570`, name, makeComment(name), KconfigStringUnquoted[name])
571 }
572
573 keys = nil
574 for name, _ := range KconfigString {
575 keys = append(keys, name)
576 }
577
578 sort.Strings(keys)
579
580 for _, name := range keys {
581 fmt.Fprintf(kc, `
582config %s%s
583 string
584 default "%s"
585`, name, makeComment(name), KconfigString[name])
586 }
587
588 keys = nil
589 for name, _ := range KconfigHex {
590 keys = append(keys, name)
591 }
592
593 sort.Strings(keys)
594
595 for _, name := range keys {
596 fmt.Fprintf(kc, `
597config %s%s
598 hex
599 default 0x%x
600`, name, makeComment(name), KconfigHex[name])
601 }
602
603 keys = nil
604 for name, _ := range KconfigInt {
605 keys = append(keys, name)
606 }
607
608 sort.Strings(keys)
609
610 for _, name := range keys {
611 fmt.Fprintf(kc, `
612config %s%s
613 int
614 default %d
615`, name, makeComment(name), KconfigInt[name])
616 }
617
618 fmt.Fprintf(kc, "endif\n")
619}
620
621const MoboDir = "/src/mainboard/"
622
623func makeVendor(ctx Context) {
624 vendor := ctx.Vendor
625 vendorSane := sanitize(ctx.Vendor)
626 vendorDir := *FlagOutDir + MoboDir + vendorSane
627 vendorUpper := strings.ToUpper(vendorSane)
628 kconfig := vendorDir + "/Kconfig"
629 if _, err := os.Stat(kconfig); os.IsNotExist(err) {
630 f, err := os.Create(kconfig)
631 if err != nil {
632 log.Fatal(err)
633 }
634 defer f.Close()
635 f.WriteString(`if VENDOR_` + vendorUpper + `
636
637choice
638 prompt "Mainboard model"
639
640source "src/mainboard/` + vendorSane + `/*/Kconfig.name"
641
642endchoice
643
644source "src/mainboard/` + vendorSane + `/*/Kconfig"
645
646config MAINBOARD_VENDOR
647 string
648 default "` + vendor + `"
649
650endif # VENDOR_` + vendorUpper + "\n")
651 }
652 kconfigName := vendorDir + "/Kconfig.name"
653 if _, err := os.Stat(kconfigName); os.IsNotExist(err) {
654 f, err := os.Create(kconfigName)
655 if err != nil {
656 log.Fatal(err)
657 }
658 defer f.Close()
659 f.WriteString(`config VENDOR_` + vendorUpper + `
660 bool "` + vendor + `"
661`)
662 }
663
664}
665
666func GuessECGPE(ctx Context) int {
667 /* FIXME:XX Use iasl -d and/or better parsing */
668 dsdt := ctx.InfoSource.GetACPI()["DSDT"]
669 idx := bytes.Index(dsdt, []byte{0x08, '_', 'G', 'P', 'E', 0x0a}) /* Name (_GPE, byte). */
670 if idx > 0 {
671 return int(dsdt[idx+6])
672 }
673 return -1
674}
675
676func GuessSPDMap(ctx Context) []uint8 {
677 dmi := ctx.InfoSource.GetDMI()
678
679 if dmi.Vendor == "LENOVO" {
680 return []uint8{0x50, 0x51, 0x52, 0x53}
681 }
682 return []uint8{0x50, 0x52, 0x51, 0x53}
683}
684
685func main() {
686 flag.Parse()
687
688 ctx := Context{}
689
690 ctx.InfoSource = MakeLogReader()
691
692 dmi := ctx.InfoSource.GetDMI()
693
694 ctx.Vendor = dmi.Vendor
695
696 if dmi.Vendor == "LENOVO" {
697 ctx.Model = dmi.Version
698 } else {
699 ctx.Model = dmi.Model
700 }
701
702 if dmi.IsLaptop {
703 KconfigBool["SYSTEM_TYPE_LAPTOP"] = true
704 }
705 ctx.MoboID = sanitize(ctx.Vendor) + "/" + sanitize(ctx.Model)
706 ctx.KconfigName = "BOARD_" + strings.ToUpper(sanitize(ctx.Vendor)+"_"+sanitize(ctx.Model))
707 ctx.BaseDirectory = *FlagOutDir + MoboDir + ctx.MoboID
708 KconfigStringUnquoted["MAINBOARD_DIR"] = ctx.MoboID
709 KconfigString["MAINBOARD_PART_NUMBER"] = ctx.Model
710
711 os.MkdirAll(ctx.BaseDirectory, 0700)
712
713 makeVendor(ctx)
714
715 ScanRoot(ctx)
716
717 if len(ROMStageFiles) > 0 || len(RAMStageFiles) > 0 || len(SMMFiles) > 0 {
718 mf := Create(ctx, "Makefile.inc")
719 defer mf.Close()
720 writeMF(mf, ROMStageFiles, "romstage")
721 writeMF(mf, RAMStageFiles, "ramstage")
722 writeMF(mf, SMMFiles, "smm")
723 }
724
725 devtree := Create(ctx, "devicetree.cb")
726 defer devtree.Close()
727
728 MatchDev(&DevTree)
729 WriteDev(devtree, 0, DevTree)
730
731 if MainboardInit != "" || MainboardEnable != "" || MainboardIncludes != nil {
732 mainboard := Create(ctx, "mainboard.c")
733 defer mainboard.Close()
734 mainboard.WriteString("#include <device/device.h>\n")
735 for _, include := range MainboardIncludes {
736 mainboard.WriteString("#include <" + include + ">\n")
737 }
738 mainboard.WriteString("\n")
739 if MainboardInit != "" {
740 mainboard.WriteString(`static void mainboard_init(device_t dev)
741{
742` + MainboardInit + "}\n\n")
743 }
744 if MainboardInit != "" || MainboardEnable != "" {
745 mainboard.WriteString("static void mainboard_enable(device_t dev)\n{\n")
746 if MainboardInit != "" {
747 mainboard.WriteString("\tdev->ops->init = mainboard_init;\n\n")
748 }
749 mainboard.WriteString(MainboardEnable)
750 mainboard.WriteString("}\n\n")
751 mainboard.WriteString(`struct chip_operations mainboard_ops = {
752 .enable_dev = mainboard_enable,
753};
754`)
755 }
756 }
757
758 at := Create(ctx, "acpi_tables.c")
759 defer at.Close()
760 at.WriteString("/* dummy */\n")
761
762 bi := Create(ctx, "board_info.txt")
763 defer bi.Close()
764
765 fixme := ""
766
767 if dmi.IsLaptop {
768 bi.WriteString("Category: laptop\n")
769 } else {
770 bi.WriteString("Category: desktop\n")
771 fixme += "check category, "
772 }
773
774 missing := "ROM package, ROM socketed"
775
776 if ROMProtocol != "" {
777 fmt.Fprintf(bi, "ROM protocol: %s\n", ROMProtocol)
778 } else {
779 missing += ", ROM protocol"
780 }
781
782 if FlashROMSupport != "" {
783 fmt.Fprintf(bi, "Flashrom support: %s\n", FlashROMSupport)
784 } else {
785 missing += ", Flashrom support"
786 }
787
788 missing += ", Release year"
789
790 if fixme != "" {
791 fmt.Fprintf(bi, "FIXME: %s, put %s\n", fixme, missing)
792 } else {
793 fmt.Fprintf(bi, "FIXME: put %s\n", missing)
794 }
795
796 rs := Create(ctx, "romstage.c")
797 defer rs.Close()
798 rs.WriteString("/* dummy file */\n")
799
800 if ROMSizeKB == 0 {
801 KconfigBool["BOARD_ROMSIZE_KB_2048"] = true
802 KconfigComment["BOARD_ROMSIZE_KB_2048"] = "FIXME: correct this"
803 } else {
804 KconfigBool[fmt.Sprintf("BOARD_ROMSIZE_KB_%d", ROMSizeKB)] = true
805 }
806
807 makeKconfig(ctx)
808 makeKconfigName(ctx)
809
810 dsdt := Create(ctx, "dsdt.asl")
811 defer dsdt.Close()
812
813 for _, define := range DSDTDefines {
814 if define.Comment != "" {
815 fmt.Fprintf(dsdt, "\t/* %s. */\n", define.Comment)
816 }
817 dsdt.WriteString("#define " + define.Key + " " + define.Value + "\n")
818 }
819
820 dsdt.WriteString(
821 `DefinitionBlock(
822 "dsdt.aml",
823 "DSDT",
824 0x03, // DSDT revision: ACPI v3.0
825 "COREv4", // OEM id
826 "COREBOOT", // OEM table id
827 0x20141018 // OEM revision
828)
829{
830 // Some generic macros
831 #include "acpi/platform.asl"
832`)
833
834 for _, x := range DSDTIncludes {
835 if x.Comment != "" {
836 fmt.Fprintf(dsdt, "\t/* %s. */\n", x.Comment)
837 }
838 fmt.Fprintf(dsdt, "\t#include <%s>\n", x.File)
839 }
840
841 dsdt.WriteString(`
842 Scope (\_SB) {
843 Device (PCI0)
844 {
845`)
846 for _, x := range DSDTPCI0Includes {
847 if x.Comment != "" {
848 fmt.Fprintf(dsdt, "\t/* %s. */\n", x.Comment)
849 }
850 fmt.Fprintf(dsdt, "\t\t#include <%s>\n", x.File)
851 }
852 dsdt.WriteString(
853 ` }
854 }
855}
856`)
857
858}