/** @file IsaAcpi driver implementation. Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include "LpcDriver.h" // // PS/2 Keyboard Controller // static EFI_ISA_ACPI_RESOURCE mLpcWpce791Ps2KeyboardDeviceResources[] = { {EfiIsaAcpiResourceIo, 0, 0x60, 0x64}, {EfiIsaAcpiResourceInterrupt, 0, 1, 0}, {EfiIsaAcpiResourceEndOfList, 0, 0, 0} }; // // PS/2 Mouse Controller // static EFI_ISA_ACPI_RESOURCE mLpcWpce791Ps2MouseDeviceResources[] = { {EfiIsaAcpiResourceIo, 0, 0x60, 0x64}, {EfiIsaAcpiResourceInterrupt, 0, 12, 0}, {EfiIsaAcpiResourceEndOfList, 0, 0, 0} }; // // COM // static EFI_ISA_ACPI_RESOURCE mLpcWpce791ComDeviceResources[] = { {EfiIsaAcpiResourceIo, 0, 0x3f8, 0x3ff}, {EfiIsaAcpiResourceInterrupt, 0, 4, 0}, {EfiIsaAcpiResourceEndOfList, 0, 0, 0} }; // // Table of ISA Controllers // EFI_ISA_ACPI_RESOURCE_LIST mLpcWpce791DeviceList[] = { {{EISA_PNP_ID(0x303), 0}, mLpcWpce791Ps2KeyboardDeviceResources }, // PS/2 Keyboard Controller {{EISA_PNP_ID(0xF03), 0}, mLpcWpce791Ps2MouseDeviceResources }, // PS/2 Mouse Controller {{EISA_PNP_ID(0x501), 0}, mLpcWpce791ComDeviceResources }, // COM {{0, 0}, NULL } // End }; static ICH_DMA_INIT mIchDmaInitTable [] = { // // Register OFFSET, Value // 0x0D8, 0x000, // Reset DMA Controller 2 0x0D0, 0x000, // Enable DMA controller 2 0x00C, 0x000, // Reset DMA Controller 1 0x008, 0x000, // Enable DMA controller 1 // // Channel 4 // 0x0D6, 0x0c0, // DMA contr. 2 Cascade mode, addr. increment, disable auto init. 0x0D2, 0x000, // Clear write request register 0x0d4, 0x000, // Enable DREQs for channel // // Channel 0 // 0x00B, 0x040, // DMA contr. 1 single mode, addr. increment, disable auto init. 0x009, 0x000, // Clear write request register 0x00A, 0x000, // Enable DREQs for channel // // Channel 1 // 0x00B, 0x041, // DMA contr. 1 single mode, addr. increment, disable auto init. 0x009, 0x001, // Clear write request register 0x00A, 0x001, // Enable DREQs for channel // // Channel 2 // 0x00B, 0x042, // DMA contr. 1 single mode, addr. increment, disable auto init. 0x009, 0x002, // Clear write request register 0x00A, 0x002, // Enable DREQs for channel // // Channel 3 // 0x00B, 0x043, // DMA contr. 1 single mode, addr. increment, disable auto init. 0x009, 0x003, // Clear write request register 0x00A, 0x003, // Enable DREQs for channel // // Channel 5 // 0x0D6, 0x041, // DMA contr. 2 single mode, addr. increment, disable auto init. 0x0D2, 0x001, // Clear write request register 0x0D4, 0x001, // Enable DREQs for channel // // Channel 6 // 0x0D6, 0x042, // DMA contr. 2 single mode, addr. increment, disable auto init. 0x0D2, 0x002, // Clear write request register 0x0D4, 0x002, // Enable DREQs for channel // // Channel 7 // 0x0D6, 0x043, // DMA contr. 2 single mode, addr. increment, disable auto init. 0x0D2, 0x003, // Clear write request register 0x0D4, 0x003 // Enable DREQs for channel }; // // ISA ACPI Protocol Functions // /** Enumerate the ISA devices on the ISA bus. **/ VOID IsaDeviceLookup ( IN EFI_ISA_ACPI_DEVICE_ID *Device, OUT EFI_ISA_ACPI_RESOURCE_LIST **IsaAcpiDevice, OUT EFI_ISA_ACPI_RESOURCE_LIST **NextIsaAcpiDevice ) { UINTN Index; *IsaAcpiDevice = NULL; if (NextIsaAcpiDevice != NULL) { *NextIsaAcpiDevice = NULL; } if (Device == NULL) { Index = 0; } else { for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) { if (Device->HID == mLpcWpce791DeviceList[Index].Device.HID && Device->UID == mLpcWpce791DeviceList[Index].Device.UID) { break; } } if (mLpcWpce791DeviceList[Index].Device.HID == 0) { return; } *IsaAcpiDevice = &(mLpcWpce791DeviceList[Index]); Index++; } if (NextIsaAcpiDevice != NULL && mLpcWpce791DeviceList[Index].Device.HID != 0) { *NextIsaAcpiDevice = &(mLpcWpce791DeviceList[Index]); } } /** Enumerate the ISA devices on the ISA bus It is hard code now and future it will get from ACPI table **/ EFI_STATUS EFIAPI IsaDeviceEnumerate ( IN EFI_ISA_ACPI_PROTOCOL *This, OUT EFI_ISA_ACPI_DEVICE_ID **Device ) { EFI_ISA_ACPI_RESOURCE_LIST *IsaAcpiDevice; EFI_ISA_ACPI_RESOURCE_LIST *NextIsaAcpiDevice; IsaDeviceLookup (*Device, &IsaAcpiDevice, &NextIsaAcpiDevice); if (NextIsaAcpiDevice == NULL) { return EFI_NOT_FOUND; } *Device = &(NextIsaAcpiDevice->Device); return EFI_SUCCESS; } /** Set ISA device power use sio **/ EFI_STATUS EFIAPI IsaDeviceSetPower ( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, IN BOOLEAN OnOff ) { return EFI_UNSUPPORTED; } /** Get current Resource of the specific ISA device It is hardcode now and future will get from ACPI table **/ EFI_STATUS EFIAPI IsaGetCurrentResource ( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList ) { IsaDeviceLookup (Device, ResourceList, NULL); if (*ResourceList == NULL || (*ResourceList)->ResourceItem == NULL) { return EFI_NOT_FOUND; } return EFI_SUCCESS; } EFI_STATUS EFIAPI IsaGetPossibleResource ( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList ) { // // Not supported yet // return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI IsaSetResource ( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList ) { return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI IsaEnableDevice ( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device, IN BOOLEAN Enable ) { return EFI_UNSUPPORTED; } /** Clear out Resource List if device is set to disable by platform policy **/ VOID EmptyResourceList ( IN UINT32 DeviceHid ) { UINT8 Index; for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) { if (DeviceHid == mLpcWpce791DeviceList[Index].Device.HID) { mLpcWpce791DeviceList[Index].ResourceItem = NULL; } } return; } /** Clear out Resource List if device is set to disable by platform policy **/ VOID EmptyResourceListHidUid ( IN UINT32 DeviceHid, IN UINT32 DeviceUid ) { UINT8 Index; for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) { if ((DeviceHid == mLpcWpce791DeviceList[Index].Device.HID) && (DeviceUid == mLpcWpce791DeviceList[Index].Device.UID)) { mLpcWpce791DeviceList[Index].ResourceItem = NULL; } } return; } EFI_STATUS EFIAPI IsaInitDevice ( IN EFI_ISA_ACPI_PROTOCOL *This, IN EFI_ISA_ACPI_DEVICE_ID *Device ) { EFI_WPCE791_POLICY_PROTOCOL *LpcWpce791Policy; EFI_STATUS Status; // // Disable configuration according to platform protocol // Status = gBS->LocateProtocol ( &gEfiLpcWpce791PolicyProtocolGuid, NULL, (VOID **) &LpcWpce791Policy ); if (!EFI_ERROR (Status)) { if (LpcWpce791Policy->DeviceEnables.Ps2Keyboard == EFI_WPCE791_PS2_KEYBOARD_DISABLE) { EmptyResourceList (EISA_PNP_ID (0x303)); DisableLogicalDevice (SIO_KEYBOARD); EmptyResourceList (EISA_PNP_ID (0xF03)); DisableLogicalDevice (SIO_KEYBOARD); } if (LpcWpce791Policy->DeviceEnables.Ps2Mouse == EFI_WPCE791_PS2_MOUSE_DISABLE) { EmptyResourceList (EISA_PNP_ID (0xF03)); DisableLogicalDevice (SIO_MOUSE); } } return EFI_SUCCESS; } VOID EnableInternalUartDevice ( VOID ) { // // Program and enable PMC Base. // IoWrite32 (PCI_IDX, PCI_LPC_REG(R_PCH_LPC_PMC_BASE)); IoWrite32 (PCI_DAT, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN)); // // Program and enable iLB Base. // IoWrite32 (PCI_IDX, PCI_LPC_REG(R_PCH_LPC_ILB_BASE)); IoWrite32 (PCI_DAT, (ILB_BASE_ADDRESS | B_PCH_LPC_ILB_BASE_EN)); // // Enable internal UART interrupt. // MmioOr32 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT32) (B_PCH_ILB_IRQE_UARTIRQEN_IRQ4)); // // GPIO: N67(HV_DDI2_DDC_SCL) - Setting Mode 3 // UART0_TXD // MmioWrite32 ((UINTN) (IO_BASE_ADDRESS + 0xD438), (UINT32) 0x00930300); // // GPIO: N62(HV_DDI2_DDC_SDA) - Setting Mode 3 // UART0_RXD // MmioWrite32 ((UINTN) (IO_BASE_ADDRESS + 0xD410), (UINT32) 0x00930300); MmioOr32 ((UINTN)(PcdGet64 (PcdPciExpressBaseAddress) + (31 << 15)) + R_PCH_LPC_UART_CTRL, (UINT32) B_PCH_LPC_UART_CTRL_COM1_EN); } EFI_STATUS EFIAPI LpcInterfaceInit ( IN EFI_ISA_ACPI_PROTOCOL *This ) { EFI_PCI_IO_PROTOCOL *PciIo; UINTN Index; PciIo = (LPC_ISA_ACPI_FROM_THIS (This))->PciIo; // // DMA controller initialize // for (Index=0; Index < (sizeof (mIchDmaInitTable) / sizeof (ICH_DMA_INIT)); Index++) { PciIo->Io.Write ( PciIo, EfiPciIoWidthUint8, EFI_PCI_IO_PASS_THROUGH_BAR, mIchDmaInitTable[Index].Register, 1, &mIchDmaInitTable[Index].Value ); } if (!PcdGetBool (PcdWpce791UartSerialIoEnable)) { EmptyResourceList (EISA_PNP_ID (0x501)); } else { // // Initialize Serial Port. // EnableInternalUartDevice (); } return EFI_SUCCESS; }