main.go 20 KB

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