autoport: Add support for Haswell-Lynx Point platform
Tested with the following devices (not exhaustive): - Dell Latitude E7240 - Dell Precision M6800 and M4800 - Asrock Z87E-ITX - Asrock Z87M OC Formula - Asrock Fatal1ty Z87 Professional Change-Id: I4f6e8c97b5122101de2f36bba8ba9f8ddd5b813a Signed-off-by: Iru Cai <mytbk920423@gmail.com> Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/30890 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
@ -61,4 +61,7 @@ func init() {
|
||||
RegisterPCI(0x8086, 0x1c20, azalia{})
|
||||
/* C216/ivybridge */
|
||||
RegisterPCI(0x8086, 0x1e20, azalia{})
|
||||
/* Lynx Point */
|
||||
RegisterPCI(0x8086, 0x8c20, azalia{})
|
||||
RegisterPCI(0x8086, 0x9c20, azalia{})
|
||||
}
|
||||
|
140
util/autoport/haswell.go
Normal file
140
util/autoport/haswell.go
Normal file
@ -0,0 +1,140 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type haswellmc struct {
|
||||
variant string
|
||||
}
|
||||
|
||||
func divceil(a uint32, b uint32) uint32 {
|
||||
return (a + b - 1) / b
|
||||
}
|
||||
|
||||
func getPanelCfg(inteltool InteltoolData, isULT bool) string {
|
||||
var refclk uint32
|
||||
var pwm_hz uint32
|
||||
|
||||
if isULT {
|
||||
refclk = 24000000
|
||||
} else {
|
||||
refclk = 135000000
|
||||
}
|
||||
if (inteltool.IGD[0xc8254] >> 16) != 0 {
|
||||
pwm_hz = refclk / 128 / (inteltool.IGD[0xc8254] >> 16)
|
||||
} else {
|
||||
pwm_hz = 0
|
||||
}
|
||||
|
||||
gpu_panel_power_up_delay := (inteltool.IGD[0xc7208] >> 16) & 0x1fff
|
||||
gpu_panel_power_backlight_on_delay := inteltool.IGD[0xc7208] & 0x1fff
|
||||
gpu_panel_power_down_delay := (inteltool.IGD[0xc720c] >> 16) & 0x1fff
|
||||
gpu_panel_power_backlight_off_delay := inteltool.IGD[0xc720c] & 0x1fff
|
||||
gpu_panel_power_cycle_delay := inteltool.IGD[0xc7210] & 0x1f
|
||||
|
||||
return fmt.Sprintf(`{
|
||||
.up_delay_ms = %3d,
|
||||
.down_delay_ms = %3d,
|
||||
.cycle_delay_ms = %3d,
|
||||
.backlight_on_delay_ms = %3d,
|
||||
.backlight_off_delay_ms = %3d,
|
||||
.backlight_pwm_hz = %3d,
|
||||
}`,
|
||||
divceil(gpu_panel_power_up_delay, 10),
|
||||
divceil(gpu_panel_power_down_delay, 10),
|
||||
(gpu_panel_power_cycle_delay-1)*100,
|
||||
divceil(gpu_panel_power_backlight_on_delay, 10),
|
||||
divceil(gpu_panel_power_backlight_off_delay, 10),
|
||||
pwm_hz)
|
||||
}
|
||||
|
||||
func (i haswellmc) Scan(ctx Context, addr PCIDevData) {
|
||||
inteltool := ctx.InfoSource.GetInteltool()
|
||||
|
||||
isULT := (i.variant == "ULT")
|
||||
DevTree = DevTreeNode{
|
||||
Chip: "northbridge/intel/haswell",
|
||||
MissingParent: "northbridge",
|
||||
Comment: "FIXME: check ec_present, usb_xhci_on_resume, gfx",
|
||||
Registers: map[string]string{
|
||||
"gpu_dp_b_hotplug": FormatInt32((inteltool.IGD[0xc4030] >> 2) & 4),
|
||||
"gpu_dp_c_hotplug": FormatInt32((inteltool.IGD[0xc4030] >> 10) & 4),
|
||||
"gpu_dp_d_hotplug": FormatInt32((inteltool.IGD[0xc4030] >> 18) & 4),
|
||||
"panel_cfg": getPanelCfg(inteltool, isULT),
|
||||
"gpu_ddi_e_connected": FormatBool(((inteltool.IGD[0x64000] >> 4) & 1) == 0),
|
||||
"ec_present": "false",
|
||||
"usb_xhci_on_resume": "false",
|
||||
/* FIXME:XX hardcoded. */
|
||||
"gfx": "GMA_STATIC_DISPLAYS(0)",
|
||||
},
|
||||
Children: []DevTreeNode{
|
||||
{
|
||||
Chip: "cpu/intel/haswell",
|
||||
Children: []DevTreeNode{
|
||||
{
|
||||
Chip: "cpu_cluster",
|
||||
Dev: 0,
|
||||
Ops: "haswell_cpu_bus_ops",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Chip: "domain",
|
||||
Dev: 0,
|
||||
Ops: "haswell_pci_domain_ops",
|
||||
PCIController: true,
|
||||
ChildPCIBus: 0,
|
||||
PCISlots: []PCISlot{
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x0, Func: 0}, writeEmpty: true, additionalComment: i.variant},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1, Func: 0}, writeEmpty: !isULT, additionalComment: "PCIe Bridge for discrete graphics"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x2, Func: 0}, writeEmpty: true, additionalComment: "Internal graphics"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x3, Func: 0}, writeEmpty: true, additionalComment: "Mini-HD audio"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if isULT {
|
||||
DevTree.Registers["dq_pins_interleaved"] = FormatBool(((inteltool.MCHBAR[0x2008] >> 10) & 1) == 0)
|
||||
}
|
||||
|
||||
PutPCIDev(addr, "Host bridge")
|
||||
|
||||
KconfigBool["NORTHBRIDGE_INTEL_HASWELL"] = true
|
||||
KconfigBool["HAVE_ACPI_TABLES"] = true
|
||||
KconfigBool["HAVE_ACPI_RESUME"] = true
|
||||
|
||||
DSDTIncludes = append(DSDTIncludes, DSDTInclude{
|
||||
File: "cpu/intel/common/acpi/cpu.asl",
|
||||
})
|
||||
|
||||
DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{
|
||||
File: "northbridge/intel/haswell/acpi/hostbridge.asl",
|
||||
}, DSDTInclude{
|
||||
File: "drivers/intel/gma/acpi/default_brightness_levels.asl",
|
||||
Comment: "FIXME: remove this if the board doesn't have backlight",
|
||||
})
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterPCI(0x8086, 0x0c00, haswellmc{variant: "Desktop"})
|
||||
RegisterPCI(0x8086, 0x0c04, haswellmc{variant: "Mobile"})
|
||||
RegisterPCI(0x8086, 0x0a04, haswellmc{variant: "ULT"})
|
||||
RegisterPCI(0x8086, 0x0c08, haswellmc{variant: "Server"})
|
||||
RegisterPCI(0x8086, 0x0d00, haswellmc{variant: "Crystal Well Desktop"})
|
||||
RegisterPCI(0x8086, 0x0d04, haswellmc{variant: "Crystal Well Mobile"})
|
||||
RegisterPCI(0x8086, 0x0d08, haswellmc{variant: "Crystal Well Server"})
|
||||
for _, id := range []uint16{
|
||||
0x0402, 0x0412, 0x041e, 0x0422, 0x0d22, /* Desktop */
|
||||
0x0406, 0x0416, 0x0426, /* Mobile */
|
||||
0x040a, 0x041a, 0x042a, /* Server */
|
||||
0x0a06, 0x0a16, 0x0a26, /* ULT */
|
||||
0x0a0e, 0x0a1e, /* ULX */
|
||||
0x0d16, 0x0d26, 0x0d36, /* Mobile 4+3, GT3e */
|
||||
} {
|
||||
RegisterPCI(0x8086, id, GenericVGA{GenericPCI{Comment: "VGA controller"}})
|
||||
}
|
||||
/* CPU HD Audio */
|
||||
RegisterPCI(0x8086, 0x0a0c, GenericPCI{})
|
||||
RegisterPCI(0x8086, 0x0c0c, GenericPCI{})
|
||||
}
|
@ -180,7 +180,10 @@ func (l *LogDevReader) GetInteltool() (ret InteltoolData) {
|
||||
paragraph := ""
|
||||
ret.GPIO = map[uint16]uint32{}
|
||||
ret.RCBA = map[uint16]uint32{}
|
||||
ret.IOBP = map[uint32]uint32{}
|
||||
ret.IGD = map[uint32]uint32{}
|
||||
ret.MCHBAR = map[uint16]uint32{}
|
||||
ret.PMBASE = map[uint16]uint32{}
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
switch {
|
||||
@ -188,10 +191,18 @@ func (l *LogDevReader) GetInteltool() (ret InteltoolData) {
|
||||
addr, value := 0, 0
|
||||
fmt.Sscanf(line, "0x%x: 0x%x", &addr, &value)
|
||||
ret.RCBA[uint16(addr)] = uint32(value)
|
||||
case len(line) > 11 && line[0] == '0' && line[1] == 'x' && line[10] == ':' && paragraph == "IOBP":
|
||||
addr, value := 0, 0
|
||||
fmt.Sscanf(line, "0x%x: 0x%x", &addr, &value)
|
||||
ret.IOBP[uint32(addr)] = uint32(value)
|
||||
case len(line) > 9 && line[0] == '0' && line[1] == 'x' && line[8] == ':' && paragraph == "IGD":
|
||||
addr, value := 0, 0
|
||||
fmt.Sscanf(line, "0x%x: 0x%x", &addr, &value)
|
||||
ret.IGD[uint32(addr)] = uint32(value)
|
||||
case len(line) > 7 && line[0] == '0' && line[1] == 'x' && line[6] == ':' && paragraph == "MCHBAR":
|
||||
addr, value := 0, 0
|
||||
fmt.Sscanf(line, "0x%x: 0x%x", &addr, &value)
|
||||
ret.MCHBAR[uint16(addr)] = uint32(value)
|
||||
case strings.Contains(line, "DEFAULT"):
|
||||
continue
|
||||
case strings.Contains(line, "DIFF"):
|
||||
@ -200,6 +211,10 @@ func (l *LogDevReader) GetInteltool() (ret InteltoolData) {
|
||||
addr, value := 0, 0
|
||||
fmt.Sscanf(line, "gpiobase+0x%x: 0x%x", &addr, &value)
|
||||
ret.GPIO[uint16(addr)] = uint32(value)
|
||||
case strings.HasPrefix(line, "pmbase"):
|
||||
addr, value := 0, 0
|
||||
fmt.Sscanf(line, "pmbase+0x%x: 0x%x", &addr, &value)
|
||||
ret.PMBASE[uint16(addr)] = uint32(value)
|
||||
case strings.HasPrefix(line, "============="):
|
||||
paragraph = strings.Trim(line, "= ")
|
||||
}
|
||||
|
490
util/autoport/lynxpoint.go
Normal file
490
util/autoport/lynxpoint.go
Normal file
@ -0,0 +1,490 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type LPVariant int
|
||||
|
||||
const (
|
||||
LYNX_POINT_MOBILE LPVariant = iota
|
||||
LYNX_POINT_DESKTOP
|
||||
LYNX_POINT_SERVER
|
||||
LYNX_POINT_ULT
|
||||
)
|
||||
|
||||
type lynxpoint struct {
|
||||
variant LPVariant
|
||||
node *DevTreeNode
|
||||
}
|
||||
|
||||
func lpPchGetFlashSize(ctx Context) {
|
||||
inteltool := ctx.InfoSource.GetInteltool()
|
||||
/* In LP PCH, Boot BIOS Straps field in GCS has only one bit. */
|
||||
switch (inteltool.RCBA[0x3410] >> 10) & 1 {
|
||||
case 0:
|
||||
ROMProtocol = "SPI"
|
||||
highflkb := uint32(0)
|
||||
for reg := uint16(0); reg < 5; reg++ {
|
||||
fl := (inteltool.RCBA[0x3854+4*reg] >> 16) & 0x1fff
|
||||
flkb := (fl + 1) << 2
|
||||
if flkb > highflkb {
|
||||
highflkb = flkb
|
||||
}
|
||||
}
|
||||
ROMSizeKB = int(highflkb)
|
||||
FlashROMSupport = "y"
|
||||
}
|
||||
}
|
||||
|
||||
func (b lynxpoint) GetGPIOHeader() string {
|
||||
return "southbridge/intel/lynxpoint/pch.h"
|
||||
}
|
||||
|
||||
func (b lynxpoint) EnableGPE(in int) {
|
||||
if b.variant != LYNX_POINT_ULT {
|
||||
b.node.Registers[fmt.Sprintf("gpi%d_routing", in)] = "2"
|
||||
}
|
||||
}
|
||||
|
||||
func (b lynxpoint) EncodeGPE(in int) int {
|
||||
return in + 0x10
|
||||
}
|
||||
|
||||
func (b lynxpoint) DecodeGPE(in int) int {
|
||||
return in - 0x10
|
||||
}
|
||||
|
||||
func (b lynxpoint) NeedRouteGPIOManually() {
|
||||
b.node.Comment += ", FIXME: set gpiX_routing for EC support"
|
||||
}
|
||||
|
||||
func GetLptDesktopEHCISetting(loc_param uint32, txamp uint32) (string, int) {
|
||||
var port_pos string
|
||||
var port_length int
|
||||
|
||||
if loc_param == 4 {
|
||||
port_pos = "USB_PORT_BACK_PANEL"
|
||||
if txamp <= 2 {
|
||||
port_length = 0x40
|
||||
} else if txamp >= 4 {
|
||||
port_length = 0x140
|
||||
} else {
|
||||
port_length = 0x110
|
||||
}
|
||||
} else {
|
||||
port_pos = "USB_PORT_FLEX"
|
||||
port_length = 0x40
|
||||
}
|
||||
return port_pos, port_length
|
||||
}
|
||||
|
||||
func GetLptMobileEHCISetting(loc_param uint32, txamp uint32) (string, int) {
|
||||
var port_pos string
|
||||
var port_length int
|
||||
|
||||
if loc_param == 4 {
|
||||
port_pos = "USB_PORT_DOCK"
|
||||
if txamp <= 1 {
|
||||
port_length = 0x40
|
||||
} else {
|
||||
port_length = 0x80
|
||||
}
|
||||
} else if loc_param == 6 {
|
||||
/* not internal, not dock, port_length >= 0x70 */
|
||||
port_pos = "USB_PORT_BACK_PANEL"
|
||||
if txamp <= 2 {
|
||||
port_length = 0x80
|
||||
} else {
|
||||
port_length = 0x110
|
||||
}
|
||||
} else {
|
||||
port_pos = "USB_PORT_BACK_PANEL"
|
||||
port_length = 0x40
|
||||
}
|
||||
return port_pos, port_length
|
||||
}
|
||||
|
||||
func GetLptLPEHCISetting(loc_param uint32, txamp uint32) (string, int) {
|
||||
var port_pos string
|
||||
var port_length int
|
||||
|
||||
if loc_param == 6 {
|
||||
/* back panel or mini pcie, length >= 0x70 */
|
||||
port_pos = "USB_PORT_MINI_PCIE"
|
||||
if txamp <= 2 {
|
||||
port_length = 0x80
|
||||
} else {
|
||||
port_length = 0x110
|
||||
}
|
||||
} else if loc_param == 4 {
|
||||
port_pos = "USB_PORT_DOCK"
|
||||
if txamp <= 1 {
|
||||
port_length = 0x40
|
||||
} else {
|
||||
port_length = 0x80
|
||||
}
|
||||
} else {
|
||||
port_pos = "USB_PORT_BACK_PANEL"
|
||||
port_length = 0x40
|
||||
}
|
||||
return port_pos, port_length
|
||||
}
|
||||
|
||||
func (b lynxpoint) Scan(ctx Context, addr PCIDevData) {
|
||||
|
||||
SouthBridge = &b
|
||||
|
||||
inteltool := ctx.InfoSource.GetInteltool()
|
||||
|
||||
isULT := (b.variant == LYNX_POINT_ULT)
|
||||
|
||||
if isULT {
|
||||
Lynxpoint_LP_GPIO(ctx, inteltool)
|
||||
} else {
|
||||
GPIO(ctx, inteltool)
|
||||
}
|
||||
|
||||
KconfigBool["SOUTHBRIDGE_INTEL_LYNXPOINT"] = true
|
||||
if isULT {
|
||||
KconfigBool["INTEL_LYNXPOINT_LP"] = true
|
||||
}
|
||||
KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true
|
||||
if isULT {
|
||||
KconfigInt["USBDEBUG_HCD_INDEX"] = 1
|
||||
} else {
|
||||
KconfigInt["USBDEBUG_HCD_INDEX"] = 2
|
||||
KconfigComment["USBDEBUG_HCD_INDEX"] = "FIXME: check this"
|
||||
}
|
||||
|
||||
if isULT {
|
||||
lpPchGetFlashSize(ctx)
|
||||
} else {
|
||||
ich9GetFlashSize(ctx)
|
||||
}
|
||||
|
||||
FADT := ctx.InfoSource.GetACPI()["FACP"]
|
||||
|
||||
sp0dtle_data := (inteltool.IOBP[0xea002750] >> 24) & 0xf
|
||||
sp0dtle_edge := (inteltool.IOBP[0xea002754] >> 16) & 0xf
|
||||
sp1dtle_data := (inteltool.IOBP[0xea002550] >> 24) & 0xf
|
||||
sp1dtle_edge := (inteltool.IOBP[0xea002554] >> 16) & 0xf
|
||||
|
||||
if sp0dtle_data != sp0dtle_edge {
|
||||
fmt.Printf("Different SATA Gen3 port0 DTLE data and edge values are used.\n")
|
||||
}
|
||||
|
||||
if sp1dtle_data != sp1dtle_edge {
|
||||
fmt.Printf("Different SATA Gen3 port1 DTLE data and edge values are used.\n")
|
||||
}
|
||||
|
||||
cur := DevTreeNode{
|
||||
Chip: "southbridge/intel/lynxpoint",
|
||||
Comment: "Intel Series 8 Lynx Point PCH",
|
||||
|
||||
/* alt_gp_smi_en is not generated because coreboot doesn't use SMI like OEM firmware */
|
||||
Registers: map[string]string{
|
||||
"gen1_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x84:0x88]),
|
||||
"gen2_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x88:0x8c]),
|
||||
"gen3_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x8c:0x90]),
|
||||
"gen4_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x90:0x94]),
|
||||
"sata_port_map": fmt.Sprintf("0x%x", PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 2}].ConfigDump[0x92]&0x3f),
|
||||
"docking_supported": (FormatBool((FADT[113] & (1 << 1)) != 0)),
|
||||
"sata_port0_gen3_dtle": fmt.Sprintf("0x%x", sp0dtle_data),
|
||||
"sata_port1_gen3_dtle": fmt.Sprintf("0x%x", sp1dtle_data),
|
||||
},
|
||||
PCISlots: []PCISlot{
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x13, Func: 0}, writeEmpty: isULT, additionalComment: "Smart Sound Audio DSP"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x14, Func: 0}, writeEmpty: true, additionalComment: "xHCI Controller"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x15, Func: 0}, writeEmpty: isULT, additionalComment: "Serial I/O DMA"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x15, Func: 1}, writeEmpty: isULT, additionalComment: "I2C0"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x15, Func: 2}, writeEmpty: isULT, additionalComment: "I2C1"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x15, Func: 3}, writeEmpty: isULT, additionalComment: "GSPI0"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x15, Func: 4}, writeEmpty: isULT, additionalComment: "GSPI1"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x15, Func: 5}, writeEmpty: isULT, additionalComment: "UART0"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x15, Func: 6}, writeEmpty: isULT, additionalComment: "UART1"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 0}, writeEmpty: true, additionalComment: "Management Engine Interface 1"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 1}, writeEmpty: true, additionalComment: "Management Engine Interface 2"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 2}, writeEmpty: true, additionalComment: "Management Engine IDE-R"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 3}, writeEmpty: true, additionalComment: "Management Engine KT"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x17, Func: 0}, writeEmpty: isULT, additionalComment: "SDIO"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x19, Func: 0}, writeEmpty: true, additionalComment: "Intel Gigabit Ethernet"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1a, Func: 0}, writeEmpty: !isULT, additionalComment: "USB2 EHCI #2"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1b, Func: 0}, writeEmpty: true, additionalComment: "High Definition Audio"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 0}, writeEmpty: true, additionalComment: "PCIe Port #1"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 1}, writeEmpty: true, additionalComment: "PCIe Port #2"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 2}, writeEmpty: true, additionalComment: "PCIe Port #3"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 3}, writeEmpty: true, additionalComment: "PCIe Port #4"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 4}, writeEmpty: true, additionalComment: "PCIe Port #5"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 5}, writeEmpty: true, additionalComment: "PCIe Port #6"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 6}, writeEmpty: !isULT, additionalComment: "PCIe Port #7"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 7}, writeEmpty: !isULT, additionalComment: "PCIe Port #8"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1d, Func: 0}, writeEmpty: true, additionalComment: "USB2 EHCI #1"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 0}, writeEmpty: true, additionalComment: "LPC bridge"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 2}, writeEmpty: true, additionalComment: "SATA Controller (AHCI)"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 3}, writeEmpty: true, additionalComment: "SMBus"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 5}, writeEmpty: !isULT, additionalComment: "SATA Controller (Legacy)"},
|
||||
PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 6}, writeEmpty: true, additionalComment: "Thermal"},
|
||||
},
|
||||
}
|
||||
|
||||
if isULT {
|
||||
cur.Registers["gpe0_en_1"] = fmt.Sprintf("0x%x", inteltool.PMBASE[0x90])
|
||||
cur.Registers["gpe0_en_2"] = fmt.Sprintf("0x%x", inteltool.PMBASE[0x94])
|
||||
cur.Registers["gpe0_en_3"] = fmt.Sprintf("0x%x", inteltool.PMBASE[0x98])
|
||||
cur.Registers["gpe0_en_4"] = fmt.Sprintf("0x%x", inteltool.PMBASE[0x9c])
|
||||
} else {
|
||||
cur.Registers["gpe0_en_1"] = fmt.Sprintf("0x%x", inteltool.PMBASE[0x28])
|
||||
cur.Registers["gpe0_en_2"] = fmt.Sprintf("0x%x", inteltool.PMBASE[0x2c])
|
||||
}
|
||||
|
||||
b.node = &cur
|
||||
|
||||
PutPCIChip(addr, cur)
|
||||
PutPCIDevParent(addr, "", "lpc")
|
||||
|
||||
DSDTIncludes = append(DSDTIncludes, DSDTInclude{
|
||||
File: "southbridge/intel/common/acpi/platform.asl",
|
||||
})
|
||||
DSDTIncludes = append(DSDTIncludes, DSDTInclude{
|
||||
File: "southbridge/intel/lynxpoint/acpi/globalnvs.asl",
|
||||
Comment: "global NVS and variables",
|
||||
})
|
||||
DSDTIncludes = append(DSDTIncludes, DSDTInclude{
|
||||
File: "southbridge/intel/common/acpi/sleepstates.asl",
|
||||
})
|
||||
DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{
|
||||
File: "southbridge/intel/lynxpoint/acpi/pch.asl",
|
||||
})
|
||||
|
||||
AddBootBlockFile("bootblock.c", "")
|
||||
bb := Create(ctx, "bootblock.c")
|
||||
defer bb.Close()
|
||||
Add_gpl(bb)
|
||||
bb.WriteString(`#include <southbridge/intel/lynxpoint/pch.h>
|
||||
|
||||
/* FIXME: remove this if not needed */
|
||||
void mainboard_config_superio(void)
|
||||
{
|
||||
}
|
||||
`)
|
||||
|
||||
sb := Create(ctx, "romstage.c")
|
||||
defer sb.Close()
|
||||
Add_gpl(sb)
|
||||
sb.WriteString(`#include <stdint.h>
|
||||
#include <northbridge/intel/haswell/haswell.h>
|
||||
#include <northbridge/intel/haswell/raminit.h>
|
||||
#include <southbridge/intel/lynxpoint/pch.h>
|
||||
|
||||
void mainboard_config_rcba(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* FIXME: called after romstage_common, remove it if not used */
|
||||
void mb_late_romstage_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void mb_get_spd_map(struct spd_info *spdi)
|
||||
{
|
||||
/* FIXME: check this */
|
||||
spdi->addresses[0] = 0x50;
|
||||
spdi->addresses[1] = 0x51;
|
||||
spdi->addresses[2] = 0x52;
|
||||
spdi->addresses[3] = 0x53;
|
||||
}
|
||||
|
||||
const struct usb2_port_config mainboard_usb2_ports[MAX_USB2_PORTS] = {
|
||||
/* FIXME: Length and Location are computed from IOBP values, may be inaccurate */
|
||||
/* Length, Enable, OCn#, Location */
|
||||
`)
|
||||
|
||||
pdo1 := PCIMap[PCIAddr{Bus: 0, Dev: 0x1d, Func: 0}].ConfigDump[0x64]
|
||||
ocmap1 := PCIMap[PCIAddr{Bus: 0, Dev: 0x1d, Func: 0}].ConfigDump[0x74:0x78]
|
||||
|
||||
var pdo2 uint8
|
||||
var ocmap2 []uint8
|
||||
var nPorts uint
|
||||
if isULT {
|
||||
nPorts = 8
|
||||
} else {
|
||||
pdo2 = PCIMap[PCIAddr{Bus: 0, Dev: 0x1a, Func: 0}].ConfigDump[0x64]
|
||||
ocmap2 = PCIMap[PCIAddr{Bus: 0, Dev: 0x1a, Func: 0}].ConfigDump[0x74:0x78]
|
||||
nPorts = 14
|
||||
}
|
||||
|
||||
xusb2pr := GetLE16(PCIMap[PCIAddr{Bus: 0, Dev: 0x14, Func: 0}].ConfigDump[0xd0:0xd4])
|
||||
|
||||
for port := uint(0); port < nPorts; port++ {
|
||||
var port_oc int = -1
|
||||
var port_pos string
|
||||
var port_disable uint8
|
||||
|
||||
if port < 8 {
|
||||
port_disable = ((pdo1 >> port) & (uint8(xusb2pr>>port) ^ 1)) & 1
|
||||
for oc := 0; oc < 4; oc++ {
|
||||
if (ocmap1[oc] & (1 << port)) != 0 {
|
||||
port_oc = oc
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
port_disable = ((pdo2 >> (port - 8)) & (uint8(xusb2pr>>port) ^ 1)) & 1
|
||||
for oc := 0; oc < 4; oc++ {
|
||||
if (ocmap2[oc] & (1 << (port - 8))) != 0 {
|
||||
port_oc = oc + 4
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get USB2 port length and location from IOBP */
|
||||
port_iobp := inteltool.IOBP[0xe5004100+uint32(port)*0x100]
|
||||
loc_param := (port_iobp >> 8) & 7
|
||||
txamp := (port_iobp >> 11) & 7
|
||||
var port_length int
|
||||
|
||||
if isULT {
|
||||
port_pos, port_length = GetLptLPEHCISetting(loc_param, txamp)
|
||||
} else if b.variant == LYNX_POINT_MOBILE {
|
||||
port_pos, port_length = GetLptMobileEHCISetting(loc_param, txamp)
|
||||
} else { /* desktop or server */
|
||||
port_pos, port_length = GetLptDesktopEHCISetting(loc_param, txamp)
|
||||
}
|
||||
|
||||
if port_disable == 1 {
|
||||
port_pos = "USB_PORT_SKIP"
|
||||
}
|
||||
|
||||
if port_oc == -1 {
|
||||
fmt.Fprintf(sb, "\t{ 0x%04x, %d, USB_OC_PIN_SKIP, %s },\n",
|
||||
port_length, (port_disable ^ 1), port_pos)
|
||||
} else {
|
||||
fmt.Fprintf(sb, "\t{ 0x%04x, %d, %d, %s },\n",
|
||||
port_length, (port_disable ^ 1), port_oc, port_pos)
|
||||
}
|
||||
}
|
||||
|
||||
sb.WriteString(`};
|
||||
|
||||
const struct usb3_port_config mainboard_usb3_ports[MAX_USB3_PORTS] = {
|
||||
`)
|
||||
|
||||
xpdo := PCIMap[PCIAddr{Bus: 0, Dev: 0x14, Func: 0}].ConfigDump[0xe8]
|
||||
u3ocm := PCIMap[PCIAddr{Bus: 0, Dev: 0x14, Func: 0}].ConfigDump[0xc8:0xd0]
|
||||
|
||||
if !isULT {
|
||||
nPorts = 6
|
||||
} else {
|
||||
nPorts = 4
|
||||
}
|
||||
|
||||
for port := uint(0); port < nPorts; port++ {
|
||||
var port_oc int = -1
|
||||
port_disable := (xpdo >> port) & 1
|
||||
for oc := 0; oc < 8; oc++ {
|
||||
if (u3ocm[oc] & (1 << port)) != 0 {
|
||||
port_oc = oc
|
||||
break
|
||||
}
|
||||
}
|
||||
if port_oc == -1 {
|
||||
fmt.Fprintf(sb, "\t{ %d, USB_OC_PIN_SKIP },\n",
|
||||
(port_disable ^ 1))
|
||||
} else {
|
||||
fmt.Fprintf(sb, "\t{ %d, %d },\n",
|
||||
(port_disable ^ 1), port_oc)
|
||||
}
|
||||
}
|
||||
|
||||
sb.WriteString(`};
|
||||
`)
|
||||
|
||||
}
|
||||
|
||||
func init() {
|
||||
for _, id := range []uint16{
|
||||
0x8c41, 0x8c49, 0x8c4b, 0x8c4f,
|
||||
} {
|
||||
RegisterPCI(0x8086, uint16(id), lynxpoint{variant: LYNX_POINT_MOBILE})
|
||||
}
|
||||
|
||||
for _, id := range []uint16{
|
||||
0x8c42, 0x8c44, 0x8c46, 0x8c4a,
|
||||
0x8c4c, 0x8c4e, 0x8c50, 0x8c5c,
|
||||
} {
|
||||
RegisterPCI(0x8086, uint16(id), lynxpoint{variant: LYNX_POINT_DESKTOP})
|
||||
}
|
||||
|
||||
for _, id := range []uint16{
|
||||
0x8c52, 0x8c54, 0x8c56,
|
||||
} {
|
||||
RegisterPCI(0x8086, uint16(id), lynxpoint{variant: LYNX_POINT_SERVER})
|
||||
}
|
||||
|
||||
for _, id := range []uint16{
|
||||
0x9c41, 0x9c43, 0x9c45,
|
||||
} {
|
||||
RegisterPCI(0x8086, uint16(id), lynxpoint{variant: LYNX_POINT_ULT})
|
||||
}
|
||||
|
||||
/* PCIe bridge */
|
||||
for _, id := range []uint16{
|
||||
0x8c10, 0x8c12, 0x8c14, 0x8c16, 0x8c18, 0x8c1a, 0x8c1c, 0x8c1e,
|
||||
0x9c10, 0x9c12, 0x9c14, 0x9c16, 0x9c18, 0x9c1a,
|
||||
} {
|
||||
RegisterPCI(0x8086, id, GenericPCI{})
|
||||
}
|
||||
|
||||
/* SMBus controller */
|
||||
RegisterPCI(0x8086, 0x8c22, GenericPCI{MissingParent: "smbus"})
|
||||
RegisterPCI(0x8086, 0x9c22, GenericPCI{MissingParent: "smbus"})
|
||||
|
||||
/* SATA */
|
||||
for _, id := range []uint16{
|
||||
0x8c00, 0x8c02, 0x8c04, 0x8c06, 0x8c08, 0x8c0e,
|
||||
0x8c01, 0x8c03, 0x8c05, 0x8c07, 0x8c09, 0x8c0f,
|
||||
0x9c03, 0x9c05, 0x9c07, 0x9c0f,
|
||||
} {
|
||||
RegisterPCI(0x8086, id, GenericPCI{})
|
||||
}
|
||||
|
||||
/* EHCI */
|
||||
for _, id := range []uint16{
|
||||
0x9c26, 0x8c26, 0x8c2d,
|
||||
} {
|
||||
RegisterPCI(0x8086, id, GenericPCI{})
|
||||
}
|
||||
|
||||
/* XHCI */
|
||||
RegisterPCI(0x8086, 0x8c31, GenericPCI{})
|
||||
RegisterPCI(0x8086, 0x9c31, GenericPCI{})
|
||||
|
||||
/* ME and children */
|
||||
for _, id := range []uint16{
|
||||
0x8c3a, 0x8c3b, 0x8c3c, 0x8c3d,
|
||||
0x9c3a, 0x9c3b, 0x9c3c, 0x9c3d,
|
||||
} {
|
||||
RegisterPCI(0x8086, id, GenericPCI{})
|
||||
}
|
||||
|
||||
/* Ethernet */
|
||||
RegisterPCI(0x8086, 0x8c33, GenericPCI{})
|
||||
|
||||
/* Thermal */
|
||||
RegisterPCI(0x8086, 0x8c24, GenericPCI{})
|
||||
RegisterPCI(0x8086, 0x9c24, GenericPCI{})
|
||||
|
||||
/* LAN Controller on LP PCH (if EEPROM has 0x0000/0xffff in DID) */
|
||||
RegisterPCI(0x8086, 0x155a, GenericPCI{})
|
||||
|
||||
/* SDIO */
|
||||
RegisterPCI(0x8086, 0x9c35, GenericPCI{})
|
||||
|
||||
/* Smart Sound Technology Controller */
|
||||
RegisterPCI(0x8086, 0x9c36, GenericPCI{})
|
||||
|
||||
/* Serial I/O */
|
||||
for id := uint16(0x9c60); id <= 0x9c66; id++ {
|
||||
RegisterPCI(0x8086, id, GenericPCI{})
|
||||
}
|
||||
}
|
240
util/autoport/lynxpoint_lp_gpio.go
Normal file
240
util/autoport/lynxpoint_lp_gpio.go
Normal file
@ -0,0 +1,240 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
PIRQI = 0
|
||||
PIRQJ = 1
|
||||
PIRQK = 2
|
||||
PIRQL = 3
|
||||
PIRQM = 4
|
||||
PIRQN = 5
|
||||
PIRQO = 6
|
||||
PIRQP = 7
|
||||
PIRQQ = 8
|
||||
PIRQR = 9
|
||||
PIRQS = 10
|
||||
PIRQT = 11
|
||||
PIRQU = 12
|
||||
PIRQV = 13
|
||||
PIRQW = 14
|
||||
PIRQX = 15
|
||||
)
|
||||
|
||||
/* from sb/intel/lynxpoint/lp_gpio.c */
|
||||
func lp_gpio_to_pirq(gpioNum uint16) int {
|
||||
var pirqmap = map[uint16] int {
|
||||
8: PIRQI,
|
||||
9: PIRQJ,
|
||||
10: PIRQK,
|
||||
13: PIRQL,
|
||||
14: PIRQM,
|
||||
45: PIRQN,
|
||||
46: PIRQO,
|
||||
47: PIRQP,
|
||||
48: PIRQQ,
|
||||
49: PIRQR,
|
||||
50: PIRQS,
|
||||
51: PIRQT,
|
||||
52: PIRQU,
|
||||
53: PIRQV,
|
||||
54: PIRQW,
|
||||
55: PIRQX,
|
||||
}
|
||||
pirq, valid := pirqmap[gpioNum]
|
||||
if (valid) {
|
||||
return pirq
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
func conf0str(conf0 uint32) string {
|
||||
if (conf0 & 1) == 0 {
|
||||
return "GPIO_MODE_NATIVE"
|
||||
} else {
|
||||
s := []string{"GPIO_MODE_GPIO"}
|
||||
var gpio_output bool
|
||||
if ((conf0 >> 2) & 1) == 1 {
|
||||
s = append(s, "GPIO_DIR_INPUT")
|
||||
gpio_output = false
|
||||
} else {
|
||||
s = append(s, "GPIO_DIR_OUTPUT")
|
||||
gpio_output = true
|
||||
}
|
||||
if ((conf0 >> 3) & 1) == 1 {
|
||||
s = append(s, "GPIO_INVERT")
|
||||
}
|
||||
if ((conf0 >> 4) & 1) == 1 {
|
||||
s = append(s, "GPIO_IRQ_LEVEL")
|
||||
}
|
||||
if gpio_output {
|
||||
if ((conf0 >> 31) & 1) == 1 {
|
||||
s = append(s, "GPO_LEVEL_HIGH")
|
||||
} else {
|
||||
s = append(s, "GPO_LEVEL_LOW")
|
||||
}
|
||||
}
|
||||
return strings.Join(s, " | ")
|
||||
}
|
||||
}
|
||||
|
||||
func lpgpio_preset(conf0 uint32, owner uint32, route uint32, irqen uint32, pirq uint32) string {
|
||||
if conf0 == 0xd { /* 0b1101: MODE_GPIO | INPUT | INVERT */
|
||||
if owner == 0 { /* OWNER_ACPI */
|
||||
if irqen == 0 && pirq == 0 {
|
||||
if route == 0 { /* SCI */
|
||||
return "GPIO_ACPI_SCI"
|
||||
} else {
|
||||
return "GPIO_ACPI_SMI"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
} else { /* OWNER_GPIO */
|
||||
if route == 0 && irqen == 0 && pirq != 0 {
|
||||
return "GPIO_INPUT_INVERT"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
if conf0 == 0x5 && owner == 1 { /* 0b101: MODE_GPIO | INPUT, OWNER_GPIO */
|
||||
if route == 0 && irqen == 0 {
|
||||
if pirq == 1 {
|
||||
return "GPIO_PIRQ"
|
||||
} else {
|
||||
return "GPIO_INPUT"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
if owner == 1 && irqen == 1 {
|
||||
if route == 0 && pirq == 0 {
|
||||
if conf0 == 0x5 { /* 0b00101 */
|
||||
return "GPIO_IRQ_EDGE"
|
||||
}
|
||||
if conf0 == 0x15 { /* 0b10101 */
|
||||
return "GPIO_IRQ_LEVEL"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func gpio_str(conf0 uint32, conf1 uint32, owner uint32, route uint32, irqen uint32, reset uint32, blink uint32, pirq uint32) string {
|
||||
s := []string{}
|
||||
s = append(s, fmt.Sprintf(".conf0 = %s", conf0str(conf0)))
|
||||
if conf1 != 0 {
|
||||
s = append(s, fmt.Sprintf(".conf1 = 0x%x", conf1))
|
||||
}
|
||||
if owner != 0 {
|
||||
s = append(s, ".owner = GPIO_OWNER_GPIO")
|
||||
}
|
||||
if route != 0 {
|
||||
s = append(s, ".route = GPIO_ROUTE_SMI")
|
||||
}
|
||||
if irqen != 0 {
|
||||
s = append(s, ".irqen = GPIO_IRQ_ENABLE")
|
||||
}
|
||||
if reset != 0 {
|
||||
s = append(s, ".reset = GPIO_RESET_RSMRST")
|
||||
}
|
||||
if blink != 0 {
|
||||
s = append(s, ".blink = GPO_BLINK")
|
||||
}
|
||||
if pirq != 0 {
|
||||
s = append(s, ".pirq = GPIO_PIRQ_APIC_ROUTE")
|
||||
}
|
||||
return strings.Join(s, ", ")
|
||||
}
|
||||
|
||||
/* start addresses of GPIO registers */
|
||||
const (
|
||||
GPIO_OWN = 0x0
|
||||
GPIPIRQ2IOXAPIC = 0x10
|
||||
GPO_BLINK = 0x18
|
||||
GPI_ROUT = 0x30
|
||||
GP_RST_SEL = 0x60
|
||||
GPI_IE = 0x90
|
||||
GPnCONFIGA = 0x100
|
||||
GPnCONFIGB = 0x104
|
||||
)
|
||||
|
||||
func PrintLPGPIO(gpio *os.File, inteltool InteltoolData) {
|
||||
for gpioNum := uint16(0); gpioNum <= 94; gpioNum++ {
|
||||
if gpioNum < 10 {
|
||||
fmt.Fprintf(gpio, "\t[%d] = ", gpioNum)
|
||||
} else {
|
||||
fmt.Fprintf(gpio, "\t[%d] = ", gpioNum)
|
||||
}
|
||||
conf0 := inteltool.GPIO[GPnCONFIGA+gpioNum*8]
|
||||
conf1 := inteltool.GPIO[GPnCONFIGB+gpioNum*8]
|
||||
set := gpioNum / 32
|
||||
bit := gpioNum % 32
|
||||
/* owner only effective in GPIO mode */
|
||||
owner := (inteltool.GPIO[GPIO_OWN+set*4] >> bit) & 1
|
||||
route := (inteltool.GPIO[GPI_ROUT+set*4] >> bit) & 1
|
||||
irqen := (inteltool.GPIO[GPI_IE+set*4] >> bit) & 1
|
||||
reset := (inteltool.GPIO[GP_RST_SEL+set*4] >> bit) & 1
|
||||
var blink, pirq uint32
|
||||
/* blink only effective in GPIO output mode */
|
||||
if set == 0 {
|
||||
blink = (inteltool.GPIO[GPO_BLINK] >> bit) & 1
|
||||
} else {
|
||||
blink = 0
|
||||
}
|
||||
irqset := lp_gpio_to_pirq(gpioNum)
|
||||
if irqset >= 0 {
|
||||
pirq = (inteltool.GPIO[GPIPIRQ2IOXAPIC] >> uint(irqset)) & 1
|
||||
} else {
|
||||
pirq = 0
|
||||
}
|
||||
|
||||
if (conf0 & 1) == 0 {
|
||||
fmt.Fprintf(gpio, "LP_GPIO_NATIVE,\n")
|
||||
} else if (conf0 & 4) == 0 {
|
||||
/* configured as output */
|
||||
if ((conf0 >> 31) & 1) == 0 {
|
||||
fmt.Fprintf(gpio, "LP_GPIO_OUT_LOW,\n")
|
||||
} else {
|
||||
fmt.Fprintf(gpio, "LP_GPIO_OUT_HIGH,\n")
|
||||
}
|
||||
} else if (conf1 & 4) != 0 {
|
||||
/* configured as input and sensing disabled */
|
||||
fmt.Fprintf(gpio, "LP_GPIO_UNUSED,\n")
|
||||
} else {
|
||||
is_preset := false
|
||||
if conf1 == 0 && reset == 0 && blink == 0 {
|
||||
preset := lpgpio_preset(conf0, owner, route, irqen, pirq)
|
||||
if preset != "" {
|
||||
fmt.Fprintf(gpio, "LP_%s,\n", preset)
|
||||
is_preset = true
|
||||
}
|
||||
}
|
||||
if !is_preset {
|
||||
fmt.Fprintf(gpio, "{ %s },\n", gpio_str(conf0, conf1, owner, route, irqen, reset, blink, pirq))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Lynxpoint_LP_GPIO(ctx Context, inteltool InteltoolData) {
|
||||
gpio := Create(ctx, "gpio.c")
|
||||
defer gpio.Close()
|
||||
|
||||
AddROMStageFile("gpio.c", "")
|
||||
|
||||
Add_gpl(gpio)
|
||||
gpio.WriteString(`#include <southbridge/intel/lynxpoint/lp_gpio.h>
|
||||
|
||||
const struct pch_lp_gpio_map mainboard_lp_gpio_map[] = {
|
||||
`)
|
||||
PrintLPGPIO(gpio, inteltool)
|
||||
gpio.WriteString("\tLP_GPIO_END\n};\n")
|
||||
}
|
@ -31,9 +31,12 @@ type PCIDevice interface {
|
||||
}
|
||||
|
||||
type InteltoolData struct {
|
||||
GPIO map[uint16]uint32
|
||||
RCBA map[uint16]uint32
|
||||
IGD map[uint32]uint32
|
||||
GPIO map[uint16]uint32
|
||||
RCBA map[uint16]uint32
|
||||
IOBP map[uint32]uint32
|
||||
IGD map[uint32]uint32
|
||||
MCHBAR map[uint16]uint32
|
||||
PMBASE map[uint16]uint32
|
||||
}
|
||||
|
||||
type DMIData struct {
|
||||
@ -253,6 +256,7 @@ type DevTreeNode struct {
|
||||
SubVendor uint16
|
||||
SubSystem uint16
|
||||
Chip string
|
||||
Ops string
|
||||
Comment string
|
||||
}
|
||||
|
||||
@ -380,6 +384,10 @@ func WriteDev(dt *os.File, offset int, alias string, dev DevTreeNode) {
|
||||
fmt.Fprintf(dt, " # %s", dev.Comment)
|
||||
}
|
||||
fmt.Fprintf(dt, "\n")
|
||||
if dev.Ops != "" {
|
||||
Offset(dt, offset+1)
|
||||
fmt.Fprintf(dt, "ops %s\n", dev.Ops)
|
||||
}
|
||||
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)
|
||||
|
Reference in New Issue
Block a user