1 /** @file 2 Platform Hook Library instances 3 4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> 5 SPDX-License-Identifier: BSD-2-Clause-Patent 6 7 **/ 8 9 #include <Base.h> 10 #include <Uefi/UefiBaseType.h> 11 #include <Library/PlatformHookLib.h> 12 #include <Library/BaseLib.h> 13 #include <Library/IoLib.h> 14 #include <Library/PciLib.h> 15 #include <Library/PcdLib.h> 16 #include <SystemAgent/Include/SaAccess.h> 17 #include <SioRegs.h> 18 #include <Library/MmPciLib.h> 19 #include <Library/PchCycleDecodingLib.h> 20 #include <Register/PchRegsLpc.h> 21 #include <PchAccess.h> 22 23 #define COM1_BASE 0x3f8 24 #define COM2_BASE 0x2f8 25 26 #define SIO_DOCKING_LPC_SWITCH_REGISTER_ADDRESS 0x0690 27 28 #define LPC_SIO_INDEX_DEFAULT_PORT_2 0x2E 29 #define LPC_SIO_DATA_DEFAULT_PORT_2 0x2F 30 #define LPC_SIO_GPIO_REGISTER_ADDRESS_2 0x0A20 31 32 #define LEGACY_DAUGHTER_CARD_SIO_INDEX_PORT 0x2E 33 #define LEGACY_DAUGHTER_CARD_SIO_DATA_PORT 0x2F 34 #define LEGACY_DAUGHTER_CARD_2_SIO_INDEX_PORT 0x4E 35 #define LEGACY_DAUGHTER_CARD_2_SIO_DATA_PORT 0x4F 36 37 typedef struct { 38 UINT8 Register; 39 UINT8 Value; 40 } EFI_SIO_TABLE; 41 42 GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioTable[] = { 43 {0x002, 0x88}, // Power On UARTs 44 {0x024, COM1_BASE >> 2}, 45 {0x025, COM2_BASE >> 2}, 46 {0x028, 0x043}, // IRQ of UARTs, UART2 IRQ=3,UART1 IRQ=4, 47 {0x029, 0x080}, // SIRQ_CLKRUN_EN 48 {0x02A, 0x000}, 49 {0x02B, 0x0DE}, 50 {0x00A, 0x040}, 51 {0x00C, 0x00E}, 52 {0x02c, 0x002}, 53 {0x030, FixedPcdGet16 (PcdSioBaseAddress) >> 4}, 54 {0x03b, SIO_DOCKING_LPC_SWITCH_REGISTER_ADDRESS >> 8}, 55 {0x03c, SIO_DOCKING_LPC_SWITCH_REGISTER_ADDRESS & 0xff}, 56 {0x03a, 0x00A}, // LPC Docking Enabling 57 {0x031, 0x01f}, 58 {0x032, 0x000}, 59 {0x033, 0x004}, 60 {0x038, 0x0FB}, 61 {0x035, 0x0FE}, 62 {0x036, 0x000}, 63 {0x037, 0x0FF}, 64 {0x039, 0x000}, 65 {0x034, 0x001}, 66 {0x012, FixedPcdGet16 (PcdLpcSioConfigDefaultPort) & 0xFF}, // Relocate configuration ports base address 67 {0x013, (FixedPcdGet16 (PcdLpcSioConfigDefaultPort) >> 8) & 0xFF} // to ensure SIO config address can be accessed in OS 68 }; 69 70 GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioTableSmsc1000[] = { 71 {0x002, 0x88}, // Power On UARTs 72 {0x007, 0x00}, 73 {0x024, COM1_BASE >> 2}, 74 {0x025, COM2_BASE >> 2}, 75 {0x028, 0x043}, // IRQ of UARTs, UART2 IRQ=3,UART1 IRQ=4, 76 {0x029, 0x080}, // SIRQ_CLKRUN_EN 77 {0x02A, 0x000}, 78 {0x02B, 0x0DE}, 79 {0x00A, 0x040}, 80 {0x00C, 0x00E}, 81 {0x030, FixedPcdGet16 (PcdSioBaseAddress) >> 4}, 82 {0x03b, SIO_DOCKING_LPC_SWITCH_REGISTER_ADDRESS >> 8}, 83 {0x03c, SIO_DOCKING_LPC_SWITCH_REGISTER_ADDRESS & 0xff}, 84 {0x03a, 0x00A}, // LPC Docking Enabling 85 {0x031, 0x01f}, 86 {0x032, 0x000}, 87 {0x033, 0x004}, 88 {0x038, 0x0FB}, 89 {0x035, 0x0FE}, 90 {0x036, 0x000}, 91 {0x037, 0x0FE}, 92 {0x039, 0x000}, 93 {0x034, 0x001} 94 }; 95 96 GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioTableWpcn381u[] = { 97 {0x29, 0x0A0}, // Enable super I/O clock and set to 48MHz 98 {0x22, 0x003}, // 99 {0x07, 0x003}, // Select UART0 device 100 {0x60, (COM1_BASE >> 8)}, // Set Base Address MSB 101 {0x61, (COM1_BASE & 0x00FF)}, // Set Base Address LSB 102 {0x70, 0x004}, // Set to IRQ4 103 {0x30, 0x001}, // Enable it with Activation bit 104 {0x07, 0x002}, // Select UART1 device 105 {0x60, (COM2_BASE >> 8)}, // Set Base Address MSB 106 {0x61, (COM2_BASE & 0x00FF)}, // Set Base Address LSB 107 {0x70, 0x003}, // Set to IRQ3 108 {0x30, 0x001}, // Enable it with Activation bit 109 {0x07, 0x007}, // Select GPIO device 110 {0x60, (LPC_SIO_GPIO_REGISTER_ADDRESS_2 >> 8)}, // Set Base Address MSB 111 {0x61, (LPC_SIO_GPIO_REGISTER_ADDRESS_2 & 0x00FF)}, // Set Base Address LSB 112 {0x30, 0x001}, // Enable it with Activation bit 113 {0x21, 0x001}, // Global Device Enable 114 {0x26, 0x000} // Fast Enable UART 0 & 1 as their enable & activation bit 115 }; 116 117 // 118 // National PC8374L 119 // 120 GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mDesktopSioTable[] = { 121 {0x007, 0x03}, // Select Com1 122 {0x061, 0xF8}, // 0x3F8 123 {0x060, 0x03}, // 0x3F8 124 {0x070, 0x04}, // IRQ4 125 {0x030, 0x01} // Active 126 }; 127 128 // 129 // IT8628 130 // 131 GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioIt8628TableSerialPort[] = { 132 {0x023, 0x09}, // Clock Selection register 133 {0x007, 0x01}, // Com1 Logical Device Number select 134 {0x061, 0xF8}, // Serial Port 1 Base Address MSB Register 135 {0x060, 0x03}, // Serial Port 1 Base Address LSB Register 136 {0x070, 0x04}, // Serial Port 1 Interrupt Level Select 137 {0x030, 0x01}, // Serial Port 1 Activate 138 {0x007, 0x02}, // Com1 Logical Device Number select 139 {0x061, 0xF8}, // Serial Port 2 Base Address MSB Register 140 {0x060, 0x02}, // Serial Port 2 Base Address MSB Register 141 {0x070, 0x03}, // Serial Port 2 Interrupt Level Select 142 {0x030, 0x01} // Serial Port 2 Activate 143 }; 144 145 GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioIt8628TableParallelPort[] = { 146 {0x007, 0x03}, // Parallel Port Logical Device Number select 147 {0x030, 0x00}, // Parallel port Activate 148 {0x061, 0x78}, // Parallel Port Base Address 1 MSB Register 149 {0x060, 0x03}, // Parallel Port Base Address 1 LSB Register 150 {0x063, 0x78}, // Parallel Port Base Address 2 MSB Register 151 {0x062, 0x07}, // Parallel Port Base Address 1 LSB Register 152 {0x0F0, 0x03} // Special Configuration register 153 }; 154 155 156 GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioTableWinbondX374[] = { 157 {0x07, 0x03}, // Select UART0 device 158 {0x60, (COM1_BASE >> 8)}, // Set Base Address MSB 159 {0x61, (COM1_BASE & 0x00FF)}, // Set Base Address LSB 160 {0x70, 0x04}, // Set to IRQ4 161 {0x30, 0x01} // Enable it with Activation bit 162 }; 163 164 GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioTablePilot3[] = { 165 {0x07, 0x02}, // Set logical device SP Serial port Com0 166 {0x61, 0xF8}, // Write Base Address LSB register 0x3F8 167 {0x60, 0x03}, // Write Base Address MSB register 0x3F8 168 {0x70, 0x04}, // Write IRQ1 value (IRQ 1) keyboard 169 {0x30, 0x01} // Enable serial port with Activation bit 170 }; 171 172 /** 173 Detect if a National 393 SIO is docked. If yes, enable the docked SIO 174 and its serial port, and disable the onboard serial port. 175 176 @retval EFI_SUCCESS Operations performed successfully. 177 **/ 178 STATIC 179 VOID 180 CheckNationalSio ( 181 VOID 182 ) 183 { 184 UINT8 Data8; 185 186 // 187 // Pc87393 access is through either (0x2e, 0x2f) or (0x4e, 0x4f). 188 // We use (0x2e, 0x2f) which is determined by BADD default strapping 189 // 190 191 // 192 // Read the Pc87393 signature 193 // 194 IoWrite8 (0x2e, 0x20); 195 Data8 = IoRead8 (0x2f); 196 197 if (Data8 == 0xea) { 198 // 199 // Signature matches - National PC87393 SIO is docked 200 // 201 202 // 203 // Enlarge the LPC decode scope to accommodate the Docking LPC Switch 204 // Register (SIO_DOCKING_LPC_SWITCH_REGISTER_ADDRESS is allocated at 205 // SIO_BASE_ADDRESS + 0x10) 206 // 207 PchLpcGenIoRangeSet ((FixedPcdGet16 (PcdSioBaseAddress) & (UINT16)~0x7F), 0x20); 208 209 // 210 // Enable port switch 211 // 212 IoWrite8 (SIO_DOCKING_LPC_SWITCH_REGISTER_ADDRESS, 0x06); 213 214 // 215 // Turn on docking power 216 // 217 IoWrite8 (FixedPcdGet16 (PcdSioBaseAddress) + 0x0E, 0x8c); 218 219 IoWrite8 (FixedPcdGet16 (PcdSioBaseAddress) + 0x0E, 0x9c); 220 221 IoWrite8 (FixedPcdGet16 (PcdSioBaseAddress) + 0x0E, 0xBc); 222 223 // 224 // Enable port switch 225 // 226 IoWrite8 (SIO_DOCKING_LPC_SWITCH_REGISTER_ADDRESS, 0x7); 227 228 // 229 // GPIO setting 230 // 231 IoWrite8 (0x2e, 0x24); 232 IoWrite8 (0x2f, 0x29); 233 234 // 235 // Enable chip clock 236 // 237 IoWrite8 (0x2e, 0x29); 238 IoWrite8 (0x2f, 0x1e); 239 240 241 // 242 // Enable serial port 243 // 244 245 // 246 // Select com1 247 // 248 IoWrite8 (0x2e, 0x7); 249 IoWrite8 (0x2f, 0x3); 250 251 // 252 // Base address: 0x3f8 253 // 254 IoWrite8 (0x2e, 0x60); 255 IoWrite8 (0x2f, 0x03); 256 IoWrite8 (0x2e, 0x61); 257 IoWrite8 (0x2f, 0xf8); 258 259 // 260 // Interrupt: 4 261 // 262 IoWrite8 (0x2e, 0x70); 263 IoWrite8 (0x2f, 0x04); 264 265 // 266 // Enable bank selection 267 // 268 IoWrite8 (0x2e, 0xf0); 269 IoWrite8 (0x2f, 0x82); 270 271 // 272 // Activate 273 // 274 IoWrite8 (0x2e, 0x30); 275 IoWrite8 (0x2f, 0x01); 276 277 // 278 // Disable onboard serial port 279 // 280 IoWrite8 (FixedPcdGet16 (PcdLpcSioConfigDefaultPort), 0x55); 281 282 // 283 // Power Down UARTs 284 // 285 IoWrite8 (PcdGet16 (PcdLpcSioIndexPort), 0x2); 286 IoWrite8 (PcdGet16 (PcdLpcSioDataPort), 0x00); 287 288 // 289 // Dissable COM1 decode 290 // 291 IoWrite8 (PcdGet16 (PcdLpcSioIndexPort), 0x24); 292 IoWrite8 (PcdGet16 (PcdLpcSioDataPort), 0); 293 294 // 295 // Disable COM2 decode 296 // 297 IoWrite8 (PcdGet16 (PcdLpcSioIndexPort), 0x25); 298 IoWrite8 (PcdGet16 (PcdLpcSioDataPort), 0); 299 300 // 301 // Disable interrupt 302 // 303 IoWrite8 (PcdGet16 (PcdLpcSioIndexPort), 0x28); 304 IoWrite8 (PcdGet16 (PcdLpcSioDataPort), 0x0); 305 306 IoWrite8 (FixedPcdGet16 (PcdLpcSioConfigDefaultPort), 0xAA); 307 308 // 309 // Enable floppy 310 // 311 312 // 313 // Select floppy 314 // 315 IoWrite8 (0x2e, 0x7); 316 IoWrite8 (0x2f, 0x0); 317 318 // 319 // Base address: 0x3f0 320 // 321 IoWrite8 (0x2e, 0x60); 322 IoWrite8 (0x2f, 0x03); 323 IoWrite8 (0x2e, 0x61); 324 IoWrite8 (0x2f, 0xf0); 325 326 // 327 // Interrupt: 6 328 // 329 IoWrite8 (0x2e, 0x70); 330 IoWrite8 (0x2f, 0x06); 331 332 // 333 // DMA 2 334 // 335 IoWrite8 (0x2e, 0x74); 336 IoWrite8 (0x2f, 0x02); 337 338 // 339 // Activate 340 // 341 IoWrite8 (0x2e, 0x30); 342 IoWrite8 (0x2f, 0x01); 343 344 } else { 345 346 // 347 // No National pc87393 SIO is docked, turn off dock power and 348 // disable port switch 349 // 350 // IoWrite8 (SIO_BASE_ADDRESS + 0x0E, 0xbf); 351 // IoWrite8 (0x690, 0); 352 353 // 354 // If no National pc87393, just return 355 // 356 return; 357 } 358 } 359 360 361 /** 362 Check whether the IT8628 SIO present on LPC. If yes, enable its serial 363 ports, parallel port, and port 80. 364 365 @retval EFI_SUCCESS Operations performed successfully. 366 **/ 367 STATIC 368 VOID 369 It8628SioSerialPortInit ( 370 VOID 371 ) 372 { 373 UINT8 ChipId0 = 0; 374 UINT8 ChipId1 = 0; 375 UINT16 LpcIoDecondeRangeSet = 0; 376 UINT16 LpcIoDecoodeSet = 0; 377 UINT8 Index; 378 UINTN LpcBaseAddr; 379 380 381 // 382 // Enable I/O decoding for COM1 (3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh. 383 // 384 LpcBaseAddr = MmPciBase ( 385 DEFAULT_PCI_BUS_NUMBER_PCH, 386 PCI_DEVICE_NUMBER_PCH_LPC, 387 PCI_FUNCTION_NUMBER_PCH_LPC 388 ); 389 390 LpcIoDecondeRangeSet = (UINT16) MmioRead16 (LpcBaseAddr + R_PCH_LPC_IOD); 391 LpcIoDecoodeSet = (UINT16) MmioRead16 (LpcBaseAddr + R_PCH_LPC_IOE); 392 MmioWrite16 ((LpcBaseAddr + R_PCH_LPC_IOD), (LpcIoDecondeRangeSet | ((V_PCH_LPC_IOD_COMB_2F8 << 4) | V_PCH_LPC_IOD_COMA_3F8))); 393 MmioWrite16 ((LpcBaseAddr + R_PCH_LPC_IOE), (LpcIoDecoodeSet | (B_PCH_LPC_IOE_SE | B_PCH_LPC_IOE_CBE | B_PCH_LPC_IOE_CAE))); 394 395 // 396 // Enter MB PnP Mode 397 // 398 IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x87); 399 IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x01); 400 IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x55); 401 IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x55); 402 403 // 404 // Read Chip Id of SIO IT8628 (registers 0x20 and 0x21) 405 // 406 IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x20); 407 ChipId0 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2); 408 409 IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x21); 410 ChipId1 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2); 411 412 // 413 // Enable Serial Port 1, Port 2 414 // 415 if ((ChipId0 == 0x86) && (ChipId1 == 0x28)) { 416 for (Index = 0; Index < sizeof (mSioIt8628TableSerialPort) / sizeof (EFI_SIO_TABLE); Index++) { 417 IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, mSioIt8628TableSerialPort[Index].Register); 418 IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, mSioIt8628TableSerialPort[Index].Value); 419 } 420 } 421 422 // 423 // Exit MB PnP Mode 424 // 425 IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x02); 426 IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, 0x02); 427 428 return; 429 } 430 431 432 /** 433 Performs platform specific initialization required for the CPU to access 434 the hardware associated with a SerialPortLib instance. This function does 435 not initialize the serial port hardware itself. Instead, it initializes 436 hardware devices that are required for the CPU to access the serial port 437 hardware. This function may be called more than once. 438 439 @retval RETURN_SUCCESS The platform specific initialization succeeded. 440 @retval RETURN_DEVICE_ERROR The platform specific initialization could not be completed. 441 442 **/ 443 RETURN_STATUS 444 EFIAPI 445 PlatformHookSerialPortInitialize ( 446 VOID 447 ) 448 { 449 UINT16 ConfigPort; 450 UINT16 IndexPort; 451 UINT16 DataPort; 452 UINT16 DeviceId; 453 UINT8 Index; 454 UINT16 AcpiBase; 455 456 // 457 // Set the ICH ACPI Base Address (Reg#40h) and ACPI Enable bit 458 // in ACPI Controll (Reg#44h bit7) for PrePpiStall function use. 459 // 460 IndexPort = 0; 461 DataPort = 0; 462 Index = 0; 463 AcpiBase = 0; 464 PchAcpiBaseGet (&AcpiBase); 465 if (AcpiBase == 0) { 466 PchAcpiBaseSet (PcdGet16 (PcdAcpiBaseAddress)); 467 } 468 469 // 470 // Enable I/O decoding for COM1(3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh, 4Eh/4Fh, 60h/64Fh and 62h/66h. 471 // 472 PchLpcIoDecodeRangesSet (PcdGet16 (PcdLpcIoDecodeRange)); 473 PchLpcIoEnableDecodingSet (PcdGet16 (PchLpcIoEnableDecoding)); 474 475 // Configure Sio IT8628 476 It8628SioSerialPortInit (); 477 478 DeviceId = MmioRead16 (MmPciBase (SA_MC_BUS, 0, 0) + R_SA_MC_DEVICE_ID); 479 if (IS_SA_DEVICE_ID_MOBILE (DeviceId)) { 480 // 481 // if no EC, it is SV Bidwell Bar board 482 // 483 if ((IoRead8 (0x66) != 0xFF) && (IoRead8 (0x62) != 0xFF)) { 484 // 485 // Super I/O initialization for SMSC SI1007 486 // 487 ConfigPort = FixedPcdGet16 (PcdLpcSioConfigDefaultPort); 488 DataPort = PcdGet16 (PcdLpcSioDataDefaultPort); 489 IndexPort = PcdGet16 (PcdLpcSioIndexDefaultPort); 490 491 // 492 // 128 Byte Boundary and SIO Runtime Register Range is 0x0 to 0xF; 493 // 494 PchLpcGenIoRangeSet (FixedPcdGet16 (PcdSioBaseAddress) & (~0x7F), 0x10); 495 496 // 497 // Program and Enable Default Super IO Configuration Port Addresses and range 498 // 499 PchLpcGenIoRangeSet (FixedPcdGet16 (PcdLpcSioConfigDefaultPort) & (~0xF), 0x10); 500 501 // 502 // Enter Config Mode 503 // 504 IoWrite8 (ConfigPort, 0x55); 505 506 // 507 // Check for SMSC SIO1007 508 // 509 IoWrite8 (IndexPort, 0x0D); // SMSC SIO1007 Device ID register is 0x0D 510 if (IoRead8 (DataPort) == 0x20) { // SMSC SIO1007 Device ID is 0x20 511 // 512 // Configure SIO 513 // 514 for (Index = 0; Index < sizeof (mSioTable) / sizeof (EFI_SIO_TABLE); Index++) { 515 IoWrite8 (IndexPort, mSioTable[Index].Register); 516 IoWrite8 (DataPort, mSioTable[Index].Value); 517 } 518 519 // 520 // Exit Config Mode 521 // 522 IoWrite8 (FixedPcdGet16 (PcdLpcSioConfigDefaultPort), 0xAA); 523 524 // 525 // GPIO 15-17:IN 10-14:OUT Enable RS232 ref: Page42 of CRB_SCH 526 // 527 IoWrite8 (FixedPcdGet16 (PcdSioBaseAddress) + 0x0c, 0x1f); 528 } 529 530 // 531 // Check if a National Pc87393 SIO is docked 532 // 533 CheckNationalSio (); 534 535 // 536 // Super I/O initialization for SMSC SIO1000 537 // 538 ConfigPort = PcdGet16 (PcdLpcSioIndexPort); 539 IndexPort = PcdGet16 (PcdLpcSioIndexPort); 540 DataPort = PcdGet16 (PcdLpcSioDataPort); 541 542 // 543 // Enter Config Mode 544 // 545 IoWrite8 (ConfigPort, 0x55); 546 547 // 548 // Check for SMSC SIO1000 549 // 550 if (IoRead8 (ConfigPort) != 0xFF) { 551 // 552 // Configure SIO 553 // 554 for (Index = 0; Index < sizeof (mSioTableSmsc1000) / sizeof (EFI_SIO_TABLE); Index++) { 555 IoWrite8 (IndexPort, mSioTableSmsc1000[Index].Register); 556 IoWrite8 (DataPort, mSioTableSmsc1000[Index].Value); 557 } 558 559 // 560 // Exit Config Mode 561 // 562 IoWrite8 (FixedPcdGet16 (PcdLpcSioConfigDefaultPort), 0xAA); 563 } 564 565 // 566 // Super I/O initialization for Winbond WPCN381U 567 // 568 IndexPort = LPC_SIO_INDEX_DEFAULT_PORT_2; 569 DataPort = LPC_SIO_DATA_DEFAULT_PORT_2; 570 571 // 572 // Check for Winbond WPCN381U 573 // 574 IoWrite8 (IndexPort, 0x20); // Winbond WPCN381U Device ID register is 0x20 575 if (IoRead8 (DataPort) == 0xF4) { // Winbond WPCN381U Device ID is 0xF4 576 // 577 // Configure SIO 578 // 579 for (Index = 0; Index < sizeof (mSioTableWpcn381u) / sizeof (EFI_SIO_TABLE); Index++) { 580 IoWrite8 (IndexPort, mSioTableWpcn381u[Index].Register); 581 IoWrite8 (DataPort, mSioTableWpcn381u[Index].Value); 582 } 583 } 584 } //EC is not exist, skip mobile board detection for SV board 585 586 // 587 //add for SV Bidwell Bar board 588 // 589 if (IoRead8 (COM1_BASE) == 0xFF) { 590 // 591 // Super I/O initialization for Winbond WPCD374 (LDC2) and 8374 (LDC) 592 // Looking for LDC2 card first 593 // 594 IoWrite8 (LEGACY_DAUGHTER_CARD_2_SIO_INDEX_PORT, 0x55); 595 if (IoRead8 (LEGACY_DAUGHTER_CARD_2_SIO_INDEX_PORT) == 0x55) { 596 IndexPort = LEGACY_DAUGHTER_CARD_2_SIO_INDEX_PORT; 597 DataPort = LEGACY_DAUGHTER_CARD_2_SIO_DATA_PORT; 598 } else { 599 IndexPort = LEGACY_DAUGHTER_CARD_SIO_INDEX_PORT; 600 DataPort = LEGACY_DAUGHTER_CARD_SIO_DATA_PORT; 601 } 602 603 IoWrite8 (IndexPort, 0x20); // Winbond x374 Device ID register is 0x20 604 if (IoRead8 (DataPort) == 0xF1) { // Winbond x374 Device ID is 0xF1 605 for (Index = 0; Index < sizeof (mSioTableWinbondX374) / sizeof (EFI_SIO_TABLE); Index++) { 606 IoWrite8 (IndexPort, mSioTableWinbondX374[Index].Register); 607 IoWrite8 (DataPort, mSioTableWinbondX374[Index].Value); 608 } 609 } 610 }// end of Bidwell Bar SIO initialization 611 } else if (IS_SA_DEVICE_ID_DESKTOP (DeviceId) || IS_SA_DEVICE_ID_SERVER (DeviceId)) { 612 // 613 // If we are in debug mode, we will allow serial status codes 614 // 615 616 // 617 // National PC8374 SIO & Winbond WPCD374 (LDC2) 618 // 619 IndexPort = LEGACY_DAUGHTER_CARD_2_SIO_INDEX_PORT; 620 621 IoWrite8 (IndexPort, 0x55); 622 if (IoRead8 (IndexPort) == 0x55) { 623 IndexPort = LEGACY_DAUGHTER_CARD_2_SIO_INDEX_PORT; 624 DataPort = LEGACY_DAUGHTER_CARD_2_SIO_DATA_PORT; 625 } else { 626 IndexPort = LEGACY_DAUGHTER_CARD_SIO_INDEX_PORT; 627 DataPort = LEGACY_DAUGHTER_CARD_SIO_DATA_PORT; 628 } 629 630 // 631 // Configure SIO 632 // 633 IoWrite8 (IndexPort, 0x20); // Winbond x374 Device ID register is 0x20 634 if (IoRead8 (DataPort) == 0xF1) { // Winbond x374 Device ID is 0xF1 635 for (Index = 0; Index < sizeof (mDesktopSioTable) / sizeof (EFI_SIO_TABLE); Index++) { 636 IoWrite8 (IndexPort, mDesktopSioTable[Index].Register); 637 //PrePpiStall (200); 638 IoWrite8 (DataPort, mDesktopSioTable[Index].Value); 639 //PrePpiStall (200); 640 } 641 return RETURN_SUCCESS; 642 } 643 // 644 // Configure Pilot3 SIO 645 // 646 IoWrite8 (PILOTIII_SIO_INDEX_PORT, PILOTIII_UNLOCK); //Enter config mode. 647 IoWrite8 (PILOTIII_SIO_INDEX_PORT, PILOTIII_CHIP_ID_REG); // Pilot3 SIO Device ID register is 0x20. 648 if (IoRead8 (PILOTIII_SIO_DATA_PORT) == PILOTIII_CHIP_ID) { // Pilot3 SIO Device ID register is 0x03. 649 // 650 // Configure SIO 651 // 652 for (Index = 0; Index < sizeof (mSioTablePilot3) / sizeof (EFI_SIO_TABLE); Index++) { 653 IoWrite8 (PILOTIII_SIO_INDEX_PORT, mSioTablePilot3[Index].Register); 654 IoWrite8 (PILOTIII_SIO_DATA_PORT, mSioTablePilot3[Index].Value); 655 } 656 } 657 IoWrite8 (PILOTIII_SIO_INDEX_PORT , PILOTIII_LOCK); //Exit config mode. 658 } 659 660 661 return RETURN_SUCCESS; 662 } 663