1package main 2 3import "fmt" 4 5type bd82x6x struct { 6 variant string 7 node *DevTreeNode 8} 9 10func (b bd82x6x) IsPCIeHotplug(ctx Context, port int) bool { 11 portDev, ok := PCIMap[PCIAddr{Bus: 0, Dev: 0x1c, Func: port}] 12 if !ok { 13 return false 14 } 15 return (portDev.ConfigDump[0xdb] & (1 << 6)) != 0 16} 17 18func ich9GetFlashSize(ctx Context) { 19 inteltool := ctx.InfoSource.GetInteltool() 20 switch (inteltool.RCBA[0x3410] >> 10) & 3 { 21 /* SPI. All boards I've seen with sandy/ivy use SPI. */ 22 case 3: 23 ROMProtocol = "SPI" 24 highflkb := uint32(0) 25 for reg := uint16(0); reg < 5; reg++ { 26 fl := (inteltool.RCBA[0x3854+4*reg] >> 16) & 0x1fff 27 flkb := (fl + 1) << 2 28 if flkb > highflkb { 29 highflkb = flkb 30 } 31 } 32 ROMSizeKB = int(highflkb) 33 /* Shared with ME. Flashrom is unable to handle it. */ 34 FlashROMSupport = "n" 35 } 36} 37 38func (b bd82x6x) GetGPIOHeader() string { 39 return "southbridge/intel/bd82x6x/pch.h" 40} 41 42func (b bd82x6x) EnableGPE(in int) { 43 b.node.Registers[fmt.Sprintf("gpi%d_routing", in)] = "2" 44} 45 46func (b bd82x6x) EncodeGPE(in int) int { 47 return in + 0x10 48} 49 50func (b bd82x6x) DecodeGPE(in int) int { 51 return in - 0x10 52} 53 54func (b bd82x6x) NeedRouteGPIOManually() { 55 b.node.Comment += ", FIXME: set gpiX_routing for EC support" 56} 57 58func (b bd82x6x) Scan(ctx Context, addr PCIDevData) { 59 60 SouthBridge = &b 61 62 inteltool := ctx.InfoSource.GetInteltool() 63 GPIO(ctx, inteltool) 64 65 KconfigBool["SOUTHBRIDGE_INTEL_"+b.variant] = true 66 KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true 67 KconfigInt["USBDEBUG_HCD_INDEX"] = 2 68 KconfigComment["USBDEBUG_HCD_INDEX"] = "FIXME: check this" 69 dmi := ctx.InfoSource.GetDMI() 70 if dmi.Vendor == "LENOVO" { 71 KconfigInt["DRAM_RESET_GATE_GPIO"] = 10 72 } else { 73 KconfigInt["DRAM_RESET_GATE_GPIO"] = 60 74 } 75 KconfigComment["DRAM_RESET_GATE_GPIO"] = "FIXME: check this" 76 77 ich9GetFlashSize(ctx) 78 79 DSDTDefines = append(DSDTDefines, 80 DSDTDefine{ 81 Key: "BRIGHTNESS_UP", 82 Value: "\\_SB.PCI0.GFX0.INCB", 83 }, 84 DSDTDefine{ 85 Key: "BRIGHTNESS_DOWN", 86 Value: "\\_SB.PCI0.GFX0.DECB", 87 }) 88 89 FADT := ctx.InfoSource.GetACPI()["FACP"] 90 91 pcieHotplugMap := "{ " 92 93 for port := 0; port < 7; port++ { 94 if b.IsPCIeHotplug(ctx, port) { 95 pcieHotplugMap += "1, " 96 } else { 97 pcieHotplugMap += "0, " 98 } 99 } 100 101 if b.IsPCIeHotplug(ctx, 7) { 102 pcieHotplugMap += "1 }" 103 } else { 104 pcieHotplugMap += "0 }" 105 } 106 107 cur := DevTreeNode{ 108 Chip: "southbridge/intel/bd82x6x", 109 Comment: "Intel Series 6 Cougar Point PCH", 110 111 Registers: map[string]string{ 112 "sata_interface_speed_support": "0x3", 113 "gen1_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x84:0x88]), 114 "gen2_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x88:0x8c]), 115 "gen3_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x8c:0x90]), 116 "gen4_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x90:0x94]), 117 "pcie_port_coalesce": "1", 118 "pcie_hotplug_map": pcieHotplugMap, 119 120 "sata_port_map": fmt.Sprintf("0x%x", PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 2}].ConfigDump[0x92]&0x3f), 121 122 "docking_supported": (FormatBool((FADT[113] & (1 << 1)) != 0)), 123 "spi_uvscc": fmt.Sprintf("0x%x", inteltool.RCBA[0x38c8]), 124 "spi_lvscc": fmt.Sprintf("0x%x", inteltool.RCBA[0x38c4]&^(1<<23)), 125 }, 126 PCISlots: []PCISlot{ 127 PCISlot{PCIAddr: PCIAddr{Dev: 0x14, Func: 0}, writeEmpty: false, alias: "xhci", additionalComment: "USB 3.0 Controller"}, 128 PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 0}, writeEmpty: true, alias: "mei1", additionalComment: "Management Engine Interface 1"}, 129 PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 1}, writeEmpty: true, alias: "mei2", additionalComment: "Management Engine Interface 2"}, 130 PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 2}, writeEmpty: true, alias: "me_ide_r", additionalComment: "Management Engine IDE-R"}, 131 PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 3}, writeEmpty: true, alias: "me_kt", additionalComment: "Management Engine KT"}, 132 PCISlot{PCIAddr: PCIAddr{Dev: 0x19, Func: 0}, writeEmpty: true, alias: "gbe", additionalComment: "Intel Gigabit Ethernet"}, 133 PCISlot{PCIAddr: PCIAddr{Dev: 0x1a, Func: 0}, writeEmpty: true, alias: "ehci2", additionalComment: "USB2 EHCI #2"}, 134 PCISlot{PCIAddr: PCIAddr{Dev: 0x1b, Func: 0}, writeEmpty: true, alias: "hda", additionalComment: "High Definition Audio"}, 135 PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 0}, writeEmpty: true, alias: "pcie_rp1", additionalComment: "PCIe Port #1"}, 136 PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 1}, writeEmpty: true, alias: "pcie_rp2", additionalComment: "PCIe Port #2"}, 137 PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 2}, writeEmpty: true, alias: "pcie_rp3", additionalComment: "PCIe Port #3"}, 138 PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 3}, writeEmpty: true, alias: "pcie_rp4", additionalComment: "PCIe Port #4"}, 139 PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 4}, writeEmpty: true, alias: "pcie_rp5", additionalComment: "PCIe Port #5"}, 140 PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 5}, writeEmpty: true, alias: "pcie_rp6", additionalComment: "PCIe Port #6"}, 141 PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 6}, writeEmpty: true, alias: "pcie_rp7", additionalComment: "PCIe Port #7"}, 142 PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 7}, writeEmpty: true, alias: "pcie_rp8", additionalComment: "PCIe Port #8"}, 143 PCISlot{PCIAddr: PCIAddr{Dev: 0x1d, Func: 0}, writeEmpty: true, alias: "ehci1", additionalComment: "USB2 EHCI #1"}, 144 PCISlot{PCIAddr: PCIAddr{Dev: 0x1e, Func: 0}, writeEmpty: true, alias: "pci_bridge", additionalComment: "PCI bridge"}, 145 PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 0}, writeEmpty: true, alias: "lpc", additionalComment: "LPC bridge"}, 146 PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 2}, writeEmpty: true, alias: "sata1", additionalComment: "SATA Controller 1"}, 147 PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 3}, writeEmpty: true, alias: "smbus", additionalComment: "SMBus"}, 148 PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 5}, writeEmpty: true, alias: "sata2", additionalComment: "SATA Controller 2"}, 149 PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 6}, writeEmpty: true, alias: "thermal", additionalComment: "Thermal"}, 150 }, 151 } 152 153 b.node = &cur 154 155 xhciDev, ok := PCIMap[PCIAddr{Bus: 0, Dev: 0x14, Func: 0}] 156 157 if ok { 158 cur.Registers["xhci_switchable_ports"] = FormatHexLE32(xhciDev.ConfigDump[0xd4:0xd8]) 159 cur.Registers["superspeed_capable_ports"] = FormatHexLE32(xhciDev.ConfigDump[0xdc:0xe0]) 160 cur.Registers["xhci_overcurrent_mapping"] = FormatHexLE32(xhciDev.ConfigDump[0xc0:0xc4]) 161 } 162 163 PutPCIChip(addr, cur) 164 PutPCIDevParent(addr, "", "lpc") 165 166 DSDTIncludes = append(DSDTIncludes, DSDTInclude{ 167 File: "southbridge/intel/common/acpi/platform.asl", 168 }) 169 DSDTIncludes = append(DSDTIncludes, DSDTInclude{ 170 File: "southbridge/intel/bd82x6x/acpi/globalnvs.asl", 171 }) 172 DSDTIncludes = append(DSDTIncludes, DSDTInclude{ 173 File: "southbridge/intel/common/acpi/sleepstates.asl", 174 }) 175 DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{ 176 File: "southbridge/intel/bd82x6x/acpi/pch.asl", 177 }) 178 179 AddBootBlockFile("early_init.c", "") 180 AddROMStageFile("early_init.c", "") 181 182 sb := Create(ctx, "early_init.c") 183 defer sb.Close() 184 Add_gpl(sb) 185 186 sb.WriteString(`#include <bootblock_common.h> 187#include <device/pci_ops.h> 188#include <southbridge/intel/bd82x6x/pch.h> 189`) 190 usbPortConfig := "{\n" 191 192 currentMap := map[uint32]int{ 193 0x20000153: 0, 194 0x20000f57: 1, 195 0x2000055b: 2, 196 0x20000f51: 3, 197 0x2000094a: 4, 198 0x2000035f: 5, 199 0x20000f53: 6, 200 0x20000f5b: 7, 201 0x20000553: 9, 202 } 203 204 for port := uint(0); port < 14; port++ { 205 var pinmask uint32 206 OCPin := -1 207 if port < 8 { 208 pinmask = inteltool.RCBA[0x35a0] 209 } else { 210 pinmask = inteltool.RCBA[0x35a4] 211 } 212 for pin := uint(0); pin < 4; pin++ { 213 if ((pinmask >> ((port % 8) + 8*pin)) & 1) != 0 { 214 OCPin = int(pin) 215 if port >= 8 { 216 OCPin += 4 217 } 218 } 219 } 220 current, ok := currentMap[inteltool.RCBA[uint16(0x3500+4*port)]] 221 if !ok { 222 usbPortConfig += fmt.Sprintf("\t\t\t\t{%d, 0x%x, %d},\n", 223 ((inteltool.RCBA[0x359c]>>port)&1)^1, 224 inteltool.RCBA[uint16(0x3500+4*port)] & 0xfff, 225 OCPin) 226 } else { 227 usbPortConfig += fmt.Sprintf("\t\t\t\t{%d, %d, %d},\n", 228 ((inteltool.RCBA[0x359c]>>port)&1)^1, 229 current, 230 OCPin) 231 } 232 } 233 usbPortConfig += "\t\t\t}" 234 cur.Registers["usb_port_config"] = usbPortConfig 235 236 sb.WriteString(` 237void bootblock_mainboard_early_init(void) 238{ 239`) 240 RestorePCI16Simple(sb, addr, 0x82) 241 242 RestorePCI16Simple(sb, addr, 0x80) 243 244 sb.WriteString("}\n") 245 246 gnvs := Create(ctx, "acpi_tables.c") 247 defer gnvs.Close() 248 249 Add_gpl(gnvs) 250 gnvs.WriteString(`#include <acpi/acpi_gnvs.h> 251#include <soc/nvs.h> 252 253/* FIXME: check this function. */ 254void mainboard_fill_gnvs(struct global_nvs *gnvs) 255{ 256 /* The lid is open by default. */ 257 gnvs->lids = 1; 258 259 /* Temperature at which OS will shutdown */ 260 gnvs->tcrt = 100; 261 /* Temperature at which OS will throttle CPU */ 262 gnvs->tpsv = 90; 263} 264`) 265} 266 267func init() { 268 /* BD82X6X LPC */ 269 for id := 0x1c40; id <= 0x1c5f; id++ { 270 RegisterPCI(0x8086, uint16(id), bd82x6x{variant: "BD82X6X"}) 271 } 272 273 /* C216 LPC */ 274 for id := 0x1e41; id <= 0x1e5f; id++ { 275 RegisterPCI(0x8086, uint16(id), bd82x6x{variant: "C216"}) 276 } 277 278 /* PCIe bridge */ 279 for _, id := range []uint16{ 280 0x1c10, 0x1c12, 0x1c14, 0x1c16, 281 0x1c18, 0x1c1a, 0x1c1c, 0x1c1e, 282 0x1e10, 0x1e12, 0x1e14, 0x1e16, 283 0x1e18, 0x1e1a, 0x1e1c, 0x1e1e, 284 0x1e25, 0x244e, 0x2448, 285 } { 286 RegisterPCI(0x8086, id, GenericPCI{}) 287 } 288 289 /* SMBus controller */ 290 RegisterPCI(0x8086, 0x1c22, GenericPCI{MissingParent: "smbus"}) 291 RegisterPCI(0x8086, 0x1e22, GenericPCI{MissingParent: "smbus"}) 292 293 /* SATA */ 294 for _, id := range []uint16{ 295 0x1c00, 0x1c01, 0x1c02, 0x1c03, 296 0x1e00, 0x1e01, 0x1e02, 0x1e03, 297 } { 298 RegisterPCI(0x8086, id, GenericPCI{}) 299 } 300 301 /* EHCI */ 302 for _, id := range []uint16{ 303 0x1c26, 0x1c2d, 0x1e26, 0x1e2d, 304 } { 305 RegisterPCI(0x8086, id, GenericPCI{}) 306 } 307 308 /* XHCI */ 309 RegisterPCI(0x8086, 0x1e31, GenericPCI{}) 310 311 /* ME and children */ 312 for _, id := range []uint16{ 313 0x1c3a, 0x1c3b, 0x1c3c, 0x1c3d, 314 0x1e3a, 0x1e3b, 0x1e3c, 0x1e3d, 315 } { 316 RegisterPCI(0x8086, id, GenericPCI{}) 317 } 318 319 /* Ethernet */ 320 RegisterPCI(0x8086, 0x1502, GenericPCI{}) 321 RegisterPCI(0x8086, 0x1503, GenericPCI{}) 322 323} 324