1558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** @file 2558be4559ac1fba1a81b483c90d00680a18640ffniruiyu The implementation for EFI_ISA_IO_PROTOCOL. 3558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 43d78c020d22023d35d27b48817d73ff31a361ac7rsunCopyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR> 5558be4559ac1fba1a81b483c90d00680a18640ffniruiyuThis program and the accompanying materials 6558be4559ac1fba1a81b483c90d00680a18640ffniruiyuare licensed and made available under the terms and conditions of the BSD License 7558be4559ac1fba1a81b483c90d00680a18640ffniruiyuwhich accompanies this distribution. The full text of the license may be found at 8558be4559ac1fba1a81b483c90d00680a18640ffniruiyuhttp://opensource.org/licenses/bsd-license.php 9558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 10558be4559ac1fba1a81b483c90d00680a18640ffniruiyuTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11558be4559ac1fba1a81b483c90d00680a18640ffniruiyuWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 13558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 14558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 15558be4559ac1fba1a81b483c90d00680a18640ffniruiyu#include "IsaIo.h" 16558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 17558be4559ac1fba1a81b483c90d00680a18640ffniruiyu// 18558be4559ac1fba1a81b483c90d00680a18640ffniruiyu// Module Variables 19558be4559ac1fba1a81b483c90d00680a18640ffniruiyu// 20558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_ISA_IO_PROTOCOL mIsaIoInterface = { 21558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 22558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoMemRead, 23558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoMemWrite 24558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 25558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 26558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoIoRead, 27558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoIoWrite 28558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 29558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoCopyMem, 30558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoMap, 31558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoUnmap, 32558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoAllocateBuffer, 33558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoFreeBuffer, 34558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoFlush, 35558be4559ac1fba1a81b483c90d00680a18640ffniruiyu NULL, 36558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0, 37558be4559ac1fba1a81b483c90d00680a18640ffniruiyu NULL 38558be4559ac1fba1a81b483c90d00680a18640ffniruiyu}; 39558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 40558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_ISA_DMA_REGISTERS mDmaRegisters[8] = { 41558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 42558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x00, 43558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x87, 44558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x01 45558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 46558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 47558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x02, 48558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x83, 49558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x03 50558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 51558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 52558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x04, 53558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x81, 54558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x05 55558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 56558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 57558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x06, 58558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x82, 59558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x07 60558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 61558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 62558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x00, 63558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x00, 64558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x00 65558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, // Channel 4 is invalid 66558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 67558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0xC4, 68558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x8B, 69558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0xC6 70558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 71558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 72558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0xC8, 73558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x89, 74558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0xCA 75558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 76558be4559ac1fba1a81b483c90d00680a18640ffniruiyu { 77558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0xCC, 78558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0x8A, 79558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 0xCE 80558be4559ac1fba1a81b483c90d00680a18640ffniruiyu }, 81558be4559ac1fba1a81b483c90d00680a18640ffniruiyu}; 82558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 83558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 84558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Verifies access to an ISA device 85558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 86558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] IsaIoDevice The ISA device to be verified. 87558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Type The Access type. The input must be either IsaAccessTypeMem or IsaAccessTypeIo. 88558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Width The width of the memory operation. 89558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Count The number of memory operations to perform. 90558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Offset The offset in ISA memory space to start the memory operation. 91558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 92558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS Verify success. 93558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. 94558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The device ont support the access type. 95558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 96558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 97558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoVerifyAccess ( 98558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN ISA_IO_DEVICE *IsaIoDevice, 99558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN ISA_ACCESS_TYPE Type, 100558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_WIDTH Width, 101558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINTN Count, 102558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 Offset 103558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 104558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 105558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ISA_ACPI_RESOURCE *Item; 106558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 107558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1083d78c020d22023d35d27b48817d73ff31a361ac7rsun if ((UINT32)Width >= EfiIsaIoWidthMaximum || 109558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width == EfiIsaIoWidthReserved || 110558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width == EfiIsaIoWidthFifoReserved || 111558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width == EfiIsaIoWidthFillReserved 112558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) { 113558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 114558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 115558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 116558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 117558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // If Width is EfiIsaIoWidthFifoUintX then convert to EfiIsaIoWidthUintX 118558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // If Width is EfiIsaIoWidthFillUintX then convert to EfiIsaIoWidthUintX 119558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 120558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Width >= EfiIsaIoWidthFifoUint8 && Width < EfiIsaIoWidthFifoReserved) { 121558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count = 1; 122558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 123558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 124558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width = (EFI_ISA_IO_PROTOCOL_WIDTH) (Width & 0x03); 125558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 126558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = EFI_UNSUPPORTED; 127558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Item = IsaIoDevice->IsaIo.ResourceList->ResourceItem; 128558be4559ac1fba1a81b483c90d00680a18640ffniruiyu while (Item->Type != EfiIsaAcpiResourceEndOfList) { 129558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((Type == IsaAccessTypeMem && Item->Type == EfiIsaAcpiResourceMemory) || 130558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (Type == IsaAccessTypeIo && Item->Type == EfiIsaAcpiResourceIo)) { 131558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Offset >= Item->StartRange && (Offset + Count * (UINT32)(1 << Width)) - 1 <= Item->EndRange) { 132558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_SUCCESS; 133558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 134558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 135558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Offset >= Item->StartRange && Offset <= Item->EndRange) { 136558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = EFI_INVALID_PARAMETER; 137558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 138558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 139558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 140558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Item++; 141558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 142558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 143558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 144558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 145558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 146558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 147558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Convert the IO Information in ACPI descriptor to IO ISA Attribute. 148558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 149558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Information The IO Information in ACPI descriptor 150558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 151558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @return UINT32 The IO ISA Attribute 152558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 153558be4559ac1fba1a81b483c90d00680a18640ffniruiyuUINT32 154558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoAttribute ( 155558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT8 Information 156558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 157558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 158558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT32 Attribute; 159558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 160558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute = 0; 161558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 162558be4559ac1fba1a81b483c90d00680a18640ffniruiyu switch (Information & EFI_ACPI_IO_DECODE_MASK) { 163558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_IO_DECODE_16_BIT: 164558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_ACPI_IO_DECODE_16_BITS; 165558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 166558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 167558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_IO_DECODE_10_BIT: 168558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_ACPI_IO_DECODE_10_BITS; 169558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 170558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 171558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 172558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Attribute; 173558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 174558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 175558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 176558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Convert the IRQ Information in ACPI descriptor to IRQ ISA Attribute. 177558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 178558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Information The IRQ Information in ACPI descriptor 179558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 180558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @return UINT32 The IRQ ISA Attribute 181558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 182558be4559ac1fba1a81b483c90d00680a18640ffniruiyuUINT32 183558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIrqAttribute ( 184558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT8 Information 185558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 186558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 187558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT32 Attribute; 188558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 189558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute = 0; 190558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 191558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((Information & EFI_ACPI_IRQ_POLARITY_MASK) == EFI_ACPI_IRQ_HIGH_TRUE) { 192558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((Information & EFI_ACPI_IRQ_MODE) == EFI_ACPI_IRQ_LEVEL_TRIGGERED) { 193558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute = EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE; 194558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 195558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute = EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE; 196558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 197558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 198558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((Information & EFI_ACPI_IRQ_MODE) == EFI_ACPI_IRQ_LEVEL_TRIGGERED) { 199558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute = EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE; 200558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 201558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute = EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE; 202558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 203558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 204558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Attribute; 205558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 206558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 207558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 208558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Convert the Memory Information in ACPI descriptor to Memory ISA Attribute. 209558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 210558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Information The Memory Information in ACPI descriptor 211558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 212558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @return UINT32 The Memory ISA Attribute 213558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 214558be4559ac1fba1a81b483c90d00680a18640ffniruiyuUINT32 215558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaMemoryAttribute ( 216558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT8 Information 217558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 218558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 219558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT32 Attribute; 220558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 221558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute = 0; 222558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 223558be4559ac1fba1a81b483c90d00680a18640ffniruiyu switch (Information & EFI_ACPI_MEMORY_WRITE_STATUS_MASK) { 224558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_MEMORY_WRITABLE: 225558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_ACPI_MEMORY_WRITEABLE; 226558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 227558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 228558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 229558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Attribute; 230558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 231558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 232558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 233558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Convert the DMA Information in ACPI descriptor to DMA ISA Attribute. 234558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 235558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Information The DMA Information in ACPI descriptor 236558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 237558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @return UINT32 The DMA ISA Attribute 238558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 239558be4559ac1fba1a81b483c90d00680a18640ffniruiyuUINT32 240558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaDmaAttribute ( 241558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT8 Information 242558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 243558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 244558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT32 Attribute; 245558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 246558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute = EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE; 247558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 248558be4559ac1fba1a81b483c90d00680a18640ffniruiyu switch (Information & EFI_ACPI_DMA_SPEED_TYPE_MASK) { 249558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_DMA_SPEED_TYPE_COMPATIBILITY: 250558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE; 251558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 252558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_DMA_SPEED_TYPE_A: 253558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A; 254558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 255558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_DMA_SPEED_TYPE_B: 256558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B; 257558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 258558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_DMA_SPEED_TYPE_F: 259558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C; 260558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 261558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 262558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 263558be4559ac1fba1a81b483c90d00680a18640ffniruiyu switch (Information & EFI_ACPI_DMA_TRANSFER_TYPE_MASK) { 264558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT: 265558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8; 266558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 267558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case EFI_ACPI_DMA_TRANSFER_TYPE_16_BIT: 268558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16; 269558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 270558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 271558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 272558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Attribute; 273558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 274558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 275558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 276558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Convert the ACPI resource descriptor to ISA resource descriptor. 277558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 278558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] AcpiResource Pointer to the ACPI resource descriptor 279558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[out] IsaResource The optional pointer to the buffer to 280558be4559ac1fba1a81b483c90d00680a18640ffniruiyu store the converted ISA resource descriptor 281558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 282558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @return UINTN Number of ISA resource descriptor needed 283558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 284558be4559ac1fba1a81b483c90d00680a18640ffniruiyuUINTN 285558be4559ac1fba1a81b483c90d00680a18640ffniruiyuAcpiResourceToIsaResource ( 286558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN ACPI_RESOURCE_HEADER_PTR AcpiResource, 287558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT EFI_ISA_ACPI_RESOURCE *IsaResource OPTIONAL 288558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 289558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 290558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT32 Index; 291558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINTN Count; 292558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT32 LastIndex; 293558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ACPI_IO_PORT_DESCRIPTOR *Io; 294558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *FixedIo; 295558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ACPI_IRQ_DESCRIPTOR *Irq; 296558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ACPI_DMA_DESCRIPTOR *Dma; 297558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR *Memory; 298558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR *FixedMemory; 299558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 300558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count = 0; 301558be4559ac1fba1a81b483c90d00680a18640ffniruiyu LastIndex = 0; 302558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 303558be4559ac1fba1a81b483c90d00680a18640ffniruiyu switch (AcpiResource.SmallHeader->Byte) { 304558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case ACPI_DMA_DESCRIPTOR: 305558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Dma = (EFI_ACPI_DMA_DESCRIPTOR *) AcpiResource.SmallHeader; 306558be4559ac1fba1a81b483c90d00680a18640ffniruiyu for (Index = 0; Index < sizeof (Dma->ChannelMask) * 8; Index++) { 307558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Dma->ChannelMask & (1 << Index)) { 308558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((Count > 0) && (LastIndex + 1 == Index)) { 309558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (IsaResource != NULL) { 310558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count - 1].EndRange ++; 311558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 312558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 313558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (IsaResource != NULL) { 314558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].Type = EfiIsaAcpiResourceDma; 315558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].Attribute = IsaDmaAttribute (Dma->Information); 316558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].StartRange = Index; 317558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].EndRange = Index; 318558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 319558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count ++; 320558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 321558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 322558be4559ac1fba1a81b483c90d00680a18640ffniruiyu LastIndex = Index; 323558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 324558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 325558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 326558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 327558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case ACPI_IO_PORT_DESCRIPTOR: 328558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Io = (EFI_ACPI_IO_PORT_DESCRIPTOR *) AcpiResource.SmallHeader; 3293a0e054598963d0dedcda04612fe759513e8f75cniruiyu if (Io->Length != 0) { 3303a0e054598963d0dedcda04612fe759513e8f75cniruiyu if (IsaResource != NULL) { 3313a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].Type = EfiIsaAcpiResourceIo; 3323a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].Attribute = IsaIoAttribute (Io->Information); 3333a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].StartRange = Io->BaseAddressMin; 3343a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].EndRange = Io->BaseAddressMin + Io->Length - 1; 3353a0e054598963d0dedcda04612fe759513e8f75cniruiyu } 3363a0e054598963d0dedcda04612fe759513e8f75cniruiyu Count ++; 337558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 338558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 339558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 340558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR: 341558be4559ac1fba1a81b483c90d00680a18640ffniruiyu FixedIo = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) AcpiResource.SmallHeader; 3423a0e054598963d0dedcda04612fe759513e8f75cniruiyu if (FixedIo->Length != 0) { 3433a0e054598963d0dedcda04612fe759513e8f75cniruiyu if (IsaResource != NULL) { 3443a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].Type = EfiIsaAcpiResourceIo; 3453a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].Attribute = EFI_ISA_ACPI_IO_DECODE_10_BITS; 3463a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].StartRange = FixedIo->BaseAddress; 3473a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].EndRange = FixedIo->BaseAddress + FixedIo->Length - 1; 3483a0e054598963d0dedcda04612fe759513e8f75cniruiyu } 3493a0e054598963d0dedcda04612fe759513e8f75cniruiyu Count ++; 350558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 351558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 352558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 353558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case ACPI_IRQ_DESCRIPTOR: 354558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case ACPI_IRQ_NOFLAG_DESCRIPTOR: 355558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Irq = (EFI_ACPI_IRQ_DESCRIPTOR *) AcpiResource.SmallHeader; 356558be4559ac1fba1a81b483c90d00680a18640ffniruiyu for (Index = 0; Index < sizeof (Irq->Mask) * 8; Index++) { 357558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Irq->Mask & (1 << Index)) { 358558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((Count > 0) && (LastIndex + 1 == Index)) { 359558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (IsaResource != NULL) { 360558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count - 1].EndRange ++; 361558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 362558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 363558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (IsaResource != NULL) { 364558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].Type = EfiIsaAcpiResourceInterrupt; 365558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (AcpiResource.SmallHeader->Byte == ACPI_IRQ_DESCRIPTOR) { 366558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].Attribute = IsaIrqAttribute (Irq->Information); 367558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 368558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].Attribute = EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE; 369558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 370558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].StartRange = Index; 371558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].EndRange = Index; 372558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 373558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count++; 374558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 375558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 376558be4559ac1fba1a81b483c90d00680a18640ffniruiyu LastIndex = Index; 377558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 378558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 379558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 380558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 381558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR: 382558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Memory = (EFI_ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR *) AcpiResource.LargeHeader; 3833a0e054598963d0dedcda04612fe759513e8f75cniruiyu if (Memory->Length != 0) { 3843a0e054598963d0dedcda04612fe759513e8f75cniruiyu if (IsaResource != NULL) { 3853a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].Type = EfiIsaAcpiResourceMemory; 3863a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].Attribute = IsaMemoryAttribute (Memory->Information); 3873a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].StartRange = Memory->BaseAddressMin; 3883a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].EndRange = Memory->BaseAddressMin + Memory->Length - 1; 3893a0e054598963d0dedcda04612fe759513e8f75cniruiyu } 3903a0e054598963d0dedcda04612fe759513e8f75cniruiyu Count ++; 391558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 392558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 393558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 394558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR: 395558be4559ac1fba1a81b483c90d00680a18640ffniruiyu FixedMemory = (EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR *) AcpiResource.LargeHeader; 3963a0e054598963d0dedcda04612fe759513e8f75cniruiyu if (FixedMemory->Length != 0) { 3973a0e054598963d0dedcda04612fe759513e8f75cniruiyu if (IsaResource != NULL) { 3983a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].Type = EfiIsaAcpiResourceMemory; 3993a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].Attribute = IsaMemoryAttribute (FixedMemory->Information); 4003a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].StartRange = FixedMemory->BaseAddress; 4013a0e054598963d0dedcda04612fe759513e8f75cniruiyu IsaResource[Count].EndRange = FixedMemory->BaseAddress + FixedMemory->Length - 1; 4023a0e054598963d0dedcda04612fe759513e8f75cniruiyu } 4033a0e054598963d0dedcda04612fe759513e8f75cniruiyu Count ++; 404558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 405558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 406558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 407558be4559ac1fba1a81b483c90d00680a18640ffniruiyu case ACPI_END_TAG_DESCRIPTOR: 408558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (IsaResource != NULL) { 409558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].Type = EfiIsaAcpiResourceEndOfList; 410558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].Attribute = 0; 411558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].StartRange = 0; 412558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaResource[Count].EndRange = 0; 413558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 414558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count ++; 415558be4559ac1fba1a81b483c90d00680a18640ffniruiyu break; 416558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 417558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 418558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Count; 419558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 420558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 421558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 422558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Initializes an ISA I/O Instance 423558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 424558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] IsaIoDevice The isa device to be initialized. 425558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] DevicePath The device path of the isa device. 426558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Resources The ACPI resource list. 427558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 428558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 429558be4559ac1fba1a81b483c90d00680a18640ffniruiyuVOID 430558be4559ac1fba1a81b483c90d00680a18640ffniruiyuInitializeIsaIoInstance ( 431558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN ISA_IO_DEVICE *IsaIoDevice, 432558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 433558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN ACPI_RESOURCE_HEADER_PTR Resources 434558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 435558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 436558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINTN Index; 437558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ACPI_HID_DEVICE_PATH *AcpiNode; 438558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ACPI_RESOURCE_HEADER_PTR ResourcePtr; 439558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 440558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 441558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Use the ISA IO Protocol structure template to initialize the ISA IO instance 442558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 443558be4559ac1fba1a81b483c90d00680a18640ffniruiyu CopyMem ( 444558be4559ac1fba1a81b483c90d00680a18640ffniruiyu &IsaIoDevice->IsaIo, 445558be4559ac1fba1a81b483c90d00680a18640ffniruiyu &mIsaIoInterface, 446558be4559ac1fba1a81b483c90d00680a18640ffniruiyu sizeof (EFI_ISA_IO_PROTOCOL) 447558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 448558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 449558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 450558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Count the resources including the ACPI End Tag 451558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 452558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ResourcePtr = Resources; 453558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Index = 0; 454558be4559ac1fba1a81b483c90d00680a18640ffniruiyu while (ResourcePtr.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) { 455558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 456558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Index += AcpiResourceToIsaResource (ResourcePtr, NULL); 457558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 458558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (ResourcePtr.SmallHeader->Bits.Type == 0) { 459558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ResourcePtr.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.SmallHeader 460558be4559ac1fba1a81b483c90d00680a18640ffniruiyu + ResourcePtr.SmallHeader->Bits.Length 461558be4559ac1fba1a81b483c90d00680a18640ffniruiyu + sizeof (*ResourcePtr.SmallHeader)); 462558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 463558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ResourcePtr.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.LargeHeader 464558be4559ac1fba1a81b483c90d00680a18640ffniruiyu + ResourcePtr.LargeHeader->Length 465558be4559ac1fba1a81b483c90d00680a18640ffniruiyu + sizeof (*ResourcePtr.LargeHeader)); 466558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 467558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 468558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 469558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 470558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Get the Isa Resource count for ACPI End Tag 471558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 472558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Index += AcpiResourceToIsaResource (ResourcePtr, NULL); 473558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 474558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 475558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Initialize the ResourceList 476558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 477558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->IsaIo.ResourceList = AllocatePool (sizeof (EFI_ISA_ACPI_RESOURCE_LIST) + Index * sizeof (EFI_ISA_ACPI_RESOURCE)); 478558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ASSERT (IsaIoDevice->IsaIo.ResourceList != NULL); 479558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->IsaIo.ResourceList->ResourceItem = (EFI_ISA_ACPI_RESOURCE *) (IsaIoDevice->IsaIo.ResourceList + 1); 480558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 481558be4559ac1fba1a81b483c90d00680a18640ffniruiyu AcpiNode = (ACPI_HID_DEVICE_PATH *) ((UINT8 *) DevicePath + GetDevicePathSize (DevicePath) - END_DEVICE_PATH_LENGTH - sizeof (ACPI_HID_DEVICE_PATH)); 482558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->IsaIo.ResourceList->Device.HID = AcpiNode->HID; 483558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->IsaIo.ResourceList->Device.UID = AcpiNode->UID; 484558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 485558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ResourcePtr = Resources; 486558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Index = 0; 487558be4559ac1fba1a81b483c90d00680a18640ffniruiyu while (ResourcePtr.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) { 488558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 489558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Index += AcpiResourceToIsaResource (ResourcePtr, &IsaIoDevice->IsaIo.ResourceList->ResourceItem[Index]); 490558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 491558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (ResourcePtr.SmallHeader->Bits.Type == 0) { 492558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ResourcePtr.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.SmallHeader 493558be4559ac1fba1a81b483c90d00680a18640ffniruiyu + ResourcePtr.SmallHeader->Bits.Length 494558be4559ac1fba1a81b483c90d00680a18640ffniruiyu + sizeof (*ResourcePtr.SmallHeader)); 495558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 496558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ResourcePtr.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.LargeHeader 497558be4559ac1fba1a81b483c90d00680a18640ffniruiyu + ResourcePtr.LargeHeader->Length 498558be4559ac1fba1a81b483c90d00680a18640ffniruiyu + sizeof (*ResourcePtr.LargeHeader)); 499558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 500558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 501558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 502558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 503558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Convert the ACPI End Tag 504558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 505558be4559ac1fba1a81b483c90d00680a18640ffniruiyu AcpiResourceToIsaResource (ResourcePtr, &IsaIoDevice->IsaIo.ResourceList->ResourceItem[Index]); 506558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 507558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 508558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 509558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Performs an ISA I/O Read Cycle 510558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 511558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 512558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Width Specifies the width of the I/O operation. 513558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Offset The offset in ISA I/O space to start the I/O operation. 514558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Count The number of I/O operations to perform. 515558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[out] Buffer The destination buffer to store the results 516558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 517558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The data was read from the device sucessfully. 518558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The Offset is not valid for this device. 519558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. 520558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 521558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 522558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 523558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 524558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoIoRead ( 525558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 526558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_WIDTH Width, 527558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 Offset, 528558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINTN Count, 529558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT VOID *Buffer 530558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 531558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 532558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 533558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_IO_DEVICE *IsaIoDevice; 534558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 535558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This); 536558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 537558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 538558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Verify Isa IO Access 539558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 540558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoVerifyAccess ( 541558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice, 542558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaAccessTypeIo, 543558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width, 544558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 545558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset 546558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 547558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 548558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 549558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 550558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 551558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoDevice->PciIo->Io.Read ( 552558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->PciIo, 553558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (EFI_PCI_IO_PROTOCOL_WIDTH) Width, 554558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PCI_IO_PASS_THROUGH_BAR, 555558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset, 556558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 557558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Buffer 558558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 559558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 560558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 561558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 562558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 563558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 564558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 565558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 566558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 567558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 568558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 569558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 570558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 571558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Performs an ISA I/O Write Cycle 572558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 573558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 574558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Width Specifies the width of the I/O operation. 575558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Offset The offset in ISA I/O space to start the I/O operation. 576558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Count The number of I/O operations to perform. 577558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Buffer The source buffer to write data from 578558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 579558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The data was writen to the device sucessfully. 580558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The Offset is not valid for this device. 581558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. 582558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 583558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 584558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 585558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 586558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoIoWrite ( 587558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 588558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_WIDTH Width, 589558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 Offset, 590558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINTN Count, 591558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN VOID *Buffer 592558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 593558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 594558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 595558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_IO_DEVICE *IsaIoDevice; 596558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 597558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This); 598558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 599558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 600558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Verify Isa IO Access 601558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 602558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoVerifyAccess ( 603558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice, 604558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaAccessTypeIo, 605558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width, 606558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 607558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset 608558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 609558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 610558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 611558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 612558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 613558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoDevice->PciIo->Io.Write ( 614558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->PciIo, 615558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (EFI_PCI_IO_PROTOCOL_WIDTH) Width, 616558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PCI_IO_PASS_THROUGH_BAR, 617558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset, 618558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 619558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Buffer 620558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 621558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 622558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 623558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 624558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 625558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 626558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 627558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 628558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 629558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 630558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 631558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 632558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 633558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Writes an 8-bit I/O Port 634558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 635558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 636558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Offset The offset in ISA IO space to start the IO operation. 637558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Value The data to write port. 638558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 639558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS Success. 640558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER Parameter is invalid. 641558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The address range specified by Offset is not valid. 642558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 643558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 644558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 645558be4559ac1fba1a81b483c90d00680a18640ffniruiyuWritePort ( 646558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 647558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 Offset, 648558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT8 Value 649558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 650558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 651558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 652558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_IO_DEVICE *IsaIoDevice; 653558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 654558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This); 655558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 656558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoDevice->PciIo->Io.Write ( 657558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->PciIo, 658558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EfiPciIoWidthUint8, 659558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PCI_IO_PASS_THROUGH_BAR, 660558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset, 661558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1, 662558be4559ac1fba1a81b483c90d00680a18640ffniruiyu &Value 663558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 664558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 665558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 666558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 667558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 668558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 669558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 670558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 671558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 672558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 673558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Wait for 50 microseconds to take affect. 674558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 675558be4559ac1fba1a81b483c90d00680a18640ffniruiyu gBS->Stall (50); 676558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 677558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_SUCCESS; 678558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 679558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 680558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 681558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Writes I/O operation base address and count number to a 8 bit I/O Port. 682558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 683558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 684558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] AddrOffset The address' offset. 685558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] PageOffset The page's offest. 686558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] CountOffset The count's offset. 687558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] BaseAddress The base address. 688558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Count The number of I/O operations to perform. 689558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 690558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS Success. 691558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER Parameter is invalid. 692558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The address range specified by these Offsets and Count is not valid. 693558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 694558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 695558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 696558be4559ac1fba1a81b483c90d00680a18640ffniruiyuWriteDmaPort ( 697558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 698558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 AddrOffset, 699558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 PageOffset, 700558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 CountOffset, 701558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 BaseAddress, 702558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT16 Count 703558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 704558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 705558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 706558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 707558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort (This, AddrOffset, (UINT8) (BaseAddress & 0xff)); 708558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 709558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 710558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 711558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 712558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort (This, AddrOffset, (UINT8) ((BaseAddress >> 8) & 0xff)); 713558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 714558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 715558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 716558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 717558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort (This, PageOffset, (UINT8) ((BaseAddress >> 16) & 0xff)); 718558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 719558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 720558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 721558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 722558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort (This, CountOffset, (UINT8) (Count & 0xff)); 723558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 724558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 725558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 726558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 727558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort (This, CountOffset, (UINT8) ((Count >> 8) & 0xff)); 728558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 729558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 730558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 731558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 732558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Unmaps a memory region for DMA 733558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 734558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 735558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Mapping The mapping value returned from EFI_ISA_IO.Map(). 736558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 737558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The range was unmapped. 738558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. 739558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 740558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 741558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 742558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoUnmap ( 743558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 744558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN VOID *Mapping 745558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 746558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 747558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_MAP_INFO *IsaMapInfo; 748558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 749558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 750558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Check if DMA is supported. 751558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 752558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_DMA) == 0) { 753558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 754558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 755558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 756558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 757558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // See if the Map() operation associated with this Unmap() required a mapping 758558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // buffer.If a mapping buffer was not required, then this function simply 759558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // returns EFI_SUCCESS. 760558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 761558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Mapping != NULL) { 762558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 763558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Get the MAP_INFO structure from Mapping 764558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 765558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo = (ISA_MAP_INFO *) Mapping; 766558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 767558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 768558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // If this is a write operation from the Agent's point of view, 769558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // then copy the contents of the mapped buffer into the real buffer 770558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // so the processor can read the contents of the real buffer. 771558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 772558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (IsaMapInfo->Operation == EfiIsaIoOperationBusMasterWrite) { 773558be4559ac1fba1a81b483c90d00680a18640ffniruiyu CopyMem ( 774558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (VOID *) (UINTN) IsaMapInfo->HostAddress, 775558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (VOID *) (UINTN) IsaMapInfo->MappedHostAddress, 776558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfBytes 777558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 778558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 779558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 780558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Free the mapped buffer and the MAP_INFO structure. 781558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 782558be4559ac1fba1a81b483c90d00680a18640ffniruiyu gBS->FreePages (IsaMapInfo->MappedHostAddress, IsaMapInfo->NumberOfPages); 783558be4559ac1fba1a81b483c90d00680a18640ffniruiyu FreePool (IsaMapInfo); 784558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 785558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 786558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_SUCCESS; 787558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 788558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 789558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 790558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Flushes any posted write data to the system memory. 791558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 792558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 793558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 794558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The buffers were flushed. 795558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware error. 796558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 797558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 798558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 799558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoFlush ( 800558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This 801558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 802558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 803558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 804558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_IO_DEVICE *IsaIoDevice; 805558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 806558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This); 807558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 808558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoDevice->PciIo->Flush (IsaIoDevice->PciIo); 809558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 810558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 811558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 812558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 813558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 814558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 815558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 816558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 817558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 818558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 819558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 820558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 821558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Performs an ISA Memory Read Cycle 822558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 823558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 824558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Width Specifies the width of the memory operation. 825558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Offset The offset in ISA memory space to start the memory operation. 826558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Count The number of memory operations to perform. 827558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[out] Buffer The destination buffer to store the results 828558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 829558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The data was read from the device successfully. 830558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The Offset is not valid for this device. 831558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. 832558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 833558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 834558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 835558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 836558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoMemRead ( 837558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 838558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_WIDTH Width, 839558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 Offset, 840558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINTN Count, 841558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT VOID *Buffer 842558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 843558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 844558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 845558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_IO_DEVICE *IsaIoDevice; 846558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 847558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 848558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Check if ISA memory is supported. 849558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 850558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_ISA_MEMORY) == 0) { 851558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 852558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 853558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 854558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This); 855558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 856558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 857558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Verify the Isa Io Access 858558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 859558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoVerifyAccess ( 860558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice, 861558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaAccessTypeMem, 862558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width, 863558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 864558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset 865558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 866558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 867558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 868558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 869558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 870558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoDevice->PciIo->Mem.Read ( 871558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->PciIo, 872558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (EFI_PCI_IO_PROTOCOL_WIDTH) Width, 873558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PCI_IO_PASS_THROUGH_BAR, 874558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset, 875558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 876558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Buffer 877558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 878558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 879558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 880558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 881558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 882558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 883558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 884558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 885558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 886558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 887558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 888558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 889558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 890558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Performs an ISA Memory Write Cycle 891558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 892558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 893558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Width Specifies the width of the memory operation. 894558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Offset The offset in ISA memory space to start the memory operation. 895558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Count The number of memory operations to perform. 896558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Buffer The source buffer to write data from 897558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 898558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The data was written to the device sucessfully. 899558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The Offset is not valid for this device. 900558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. 901558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 902558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 903558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 904558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 905558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoMemWrite ( 906558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 907558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_WIDTH Width, 908558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 Offset, 909558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINTN Count, 910558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN VOID *Buffer 911558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 912558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 913558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 914558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_IO_DEVICE *IsaIoDevice; 915558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 916558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 917558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Check if ISA memory is supported. 918558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 919558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_ISA_MEMORY) == 0) { 920558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 921558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 922558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 923558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This); 924558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 925558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 926558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Verify Isa IO Access 927558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 928558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoVerifyAccess ( 929558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice, 930558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaAccessTypeMem, 931558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width, 932558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 933558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset 934558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 935558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 936558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 937558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 938558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 939558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoDevice->PciIo->Mem.Write ( 940558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->PciIo, 941558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (EFI_PCI_IO_PROTOCOL_WIDTH) Width, 942558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PCI_IO_PASS_THROUGH_BAR, 943558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Offset, 944558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 945558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Buffer 946558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 947558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 948558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 949558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 950558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 951558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 952558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 953558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 954558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 955558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 956558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 957558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 958558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 959558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Copy one region of ISA memory space to another region of ISA memory space on the ISA controller. 960558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 961558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 962558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Width Specifies the width of the memory copy operation. 963558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] DestOffset The offset of the destination 964558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] SrcOffset The offset of the source 965558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Count The number of memory copy operations to perform 966558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 967558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The data was copied sucessfully. 968558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for this device. 969558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid. 970558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 971558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 972558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 973558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 974558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoCopyMem ( 975558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 976558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_WIDTH Width, 977558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 DestOffset, 978558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 SrcOffset, 979558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINTN Count 980558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 981558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 982558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 983558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_IO_DEVICE *IsaIoDevice; 984558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 985558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 986558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Check if ISA memory is supported. 987558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 988558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_ISA_MEMORY) == 0) { 989558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 990558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 991558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 992558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This); 993558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 994558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 995558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Verify Isa IO Access for destination and source 996558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 997558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoVerifyAccess ( 998558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice, 999558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaAccessTypeMem, 1000558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width, 1001558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 1002558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DestOffset 1003558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1004558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1005558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1006558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1007558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1008558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoVerifyAccess ( 1009558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice, 1010558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaAccessTypeMem, 1011558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Width, 1012558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count, 1013558be4559ac1fba1a81b483c90d00680a18640ffniruiyu SrcOffset 1014558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1015558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1016558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1017558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1018558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1019558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = IsaIoDevice->PciIo->CopyMem ( 1020558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaIoDevice->PciIo, 1021558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (EFI_PCI_IO_PROTOCOL_WIDTH) Width, 1022558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PCI_IO_PASS_THROUGH_BAR, 1023558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DestOffset, 1024558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PCI_IO_PASS_THROUGH_BAR, 1025558be4559ac1fba1a81b483c90d00680a18640ffniruiyu SrcOffset, 1026558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count 1027558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1028558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1029558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1030558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 1031558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 1032558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 1033558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1034558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1035558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1036558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1037558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 1038558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1039558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 1040558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Maps a memory region for DMA, note this implementation 1041558be4559ac1fba1a81b483c90d00680a18640ffniruiyu only supports slave read/write operation to save code size. 1042558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1043558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param This A pointer to the EFI_ISA_IO_PROTOCOL instance. 1044558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param Operation Indicates the type of DMA (slave or bus master), and if 1045558be4559ac1fba1a81b483c90d00680a18640ffniruiyu the DMA operation is going to read or write to system memory. 1046558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param ChannelNumber The slave channel number to use for this DMA operation. 1047558be4559ac1fba1a81b483c90d00680a18640ffniruiyu If Operation and ChannelAttributes shows that this device 1048558be4559ac1fba1a81b483c90d00680a18640ffniruiyu performs bus mastering DMA, then this field is ignored. 1049558be4559ac1fba1a81b483c90d00680a18640ffniruiyu The legal range for this field is 0..7. 1050558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param ChannelAttributes The attributes of the DMA channel to use for this DMA operation 1051558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param HostAddress The system memory address to map to the device. 1052558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param NumberOfBytes On input the number of bytes to map. On output the number 1053558be4559ac1fba1a81b483c90d00680a18640ffniruiyu of bytes that were mapped. 1054558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param DeviceAddress The resulting map address for the bus master device to use 1055558be4559ac1fba1a81b483c90d00680a18640ffniruiyu to access the hosts HostAddress. 1056558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param Mapping A resulting value to pass to EFI_ISA_IO.Unmap(). 1057558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1058558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. 1059558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined. 1060558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a common buffer. 1061558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. 1062558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. 1063558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 1064558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 1065558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoMapOnlySupportSlaveReadWrite ( 1066558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 1067558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_OPERATION Operation, 1068558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT8 ChannelNumber OPTIONAL, 1069558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 ChannelAttributes, 1070558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN VOID *HostAddress, 1071558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN OUT UINTN *NumberOfBytes, 1072558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, 1073558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT VOID **Mapping 1074558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 1075558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 1076558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 1077558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PHYSICAL_ADDRESS PhysicalAddress; 1078558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_MAP_INFO *IsaMapInfo; 1079558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT8 DmaMode; 1080558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINTN MaxNumberOfBytes; 1081558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT32 BaseAddress; 1082558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT16 Count; 1083558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT8 DmaMask; 1084558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT8 DmaClear; 1085558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT8 DmaChannelMode; 1086558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1087558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((NULL == This) || 1088558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (NULL == HostAddress) || 1089558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (NULL == NumberOfBytes) || 1090558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (NULL == DeviceAddress) || 1091558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (NULL == Mapping) 1092558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) { 1093558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1094558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1095558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1096558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1097558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Initialize the return values to their defaults 1098558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1099558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *Mapping = NULL; 1100558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1101558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1102558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Make sure the Operation parameter is valid. 1103558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Light IsaIo only supports two operations. 1104558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1105558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (!(Operation == EfiIsaIoOperationSlaveRead || 1106558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Operation == EfiIsaIoOperationSlaveWrite)) { 1107558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1108558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1109558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1110558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (ChannelNumber >= 4) { 1111558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1112558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // The Light IsaIo doesn't support channelNumber larger than 4. 1113558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1114558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1115558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1116558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1117558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1118558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Map the HostAddress to a DeviceAddress. 1119558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1120558be4559ac1fba1a81b483c90d00680a18640ffniruiyu PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress; 1121558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((PhysicalAddress + *NumberOfBytes) > BASE_16MB) { 1122558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1123558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Common Buffer operations can not be remapped. If the common buffer 1124558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // is above 16MB, then it is not possible to generate a mapping, so return 1125558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // an error. 1126558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1127558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Operation == EfiIsaIoOperationBusMasterCommonBuffer) { 1128558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 1129558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1130558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1131558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Allocate an ISA_MAP_INFO structure to remember the mapping when Unmap() 1132558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // is called later. 1133558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1134558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo = AllocatePool (sizeof (ISA_MAP_INFO)); 1135558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (IsaMapInfo == NULL) { 1136558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *NumberOfBytes = 0; 1137558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_OUT_OF_RESOURCES; 1138558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1139558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1140558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Return a pointer to the MAP_INFO structure in Mapping 1141558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1142558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *Mapping = IsaMapInfo; 1143558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1144558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1145558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Initialize the MAP_INFO structure 1146558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1147558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->Operation = Operation; 1148558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfBytes = *NumberOfBytes; 1149558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (*NumberOfBytes); 1150558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->HostAddress = PhysicalAddress; 1151558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->MappedHostAddress = BASE_16MB - 1; 1152558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1153558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1154558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Allocate a buffer below 16MB to map the transfer to. 1155558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1156558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = gBS->AllocatePages ( 1157558be4559ac1fba1a81b483c90d00680a18640ffniruiyu AllocateMaxAddress, 1158558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EfiBootServicesData, 1159558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfPages, 1160558be4559ac1fba1a81b483c90d00680a18640ffniruiyu &IsaMapInfo->MappedHostAddress 1161558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1162558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1163558be4559ac1fba1a81b483c90d00680a18640ffniruiyu FreePool (IsaMapInfo); 1164558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *NumberOfBytes = 0; 1165558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *Mapping = NULL; 1166558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1167558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1168558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1169558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // If this is a read operation from the DMA agents's point of view, 1170558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // then copy the contents of the real buffer into the mapped buffer 1171558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // so the DMA agent can read the contents of the real buffer. 1172558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1173558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Operation == EfiIsaIoOperationSlaveRead) { 1174558be4559ac1fba1a81b483c90d00680a18640ffniruiyu CopyMem ( 1175558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (VOID *) (UINTN) IsaMapInfo->MappedHostAddress, 1176558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (VOID *) (UINTN) IsaMapInfo->HostAddress, 1177558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfBytes 1178558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1179558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1180558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1181558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // The DeviceAddress is the address of the maped buffer below 16 MB 1182558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1183558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *DeviceAddress = IsaMapInfo->MappedHostAddress; 1184558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1185558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1186558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // The transfer is below 16 MB, so the DeviceAddress is simply the 1187558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // HostAddress 1188558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1189558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *DeviceAddress = PhysicalAddress; 1190558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1191558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1192558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1193558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Figure out what to program into the DMA Channel Mode Register 1194558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1195558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode = (UINT8) (B_8237_DMA_CHMODE_INCREMENT | (ChannelNumber & 0x03)); 1196558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Operation == EfiIsaIoOperationSlaveRead) { 1197558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode |= V_8237_DMA_CHMODE_MEM2IO; 1198558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1199558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode |= V_8237_DMA_CHMODE_IO2MEM; 1200558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1201558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1202558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // We only support EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE in simplified IsaIo 1203558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1204558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode |= V_8237_DMA_CHMODE_SINGLE; 1205558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1206558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1207558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // A Slave DMA transfer can not cross a 64K boundary. 1208558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Compute *NumberOfBytes based on this restriction. 1209558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1210558be4559ac1fba1a81b483c90d00680a18640ffniruiyu MaxNumberOfBytes = 0x10000 - ((UINT32) (*DeviceAddress) & 0xffff); 1211558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (*NumberOfBytes > MaxNumberOfBytes) { 1212558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *NumberOfBytes = MaxNumberOfBytes; 1213558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1214558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1215558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Compute the values to program into the BaseAddress and Count registers 1216558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // of the Slave DMA controller 1217558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1218558be4559ac1fba1a81b483c90d00680a18640ffniruiyu BaseAddress = (UINT32) (*DeviceAddress); 1219558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count = (UINT16) (*NumberOfBytes - 1); 1220558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1221558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Program the DMA Write Single Mask Register for ChannelNumber 1222558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Clear the DMA Byte Pointer Register 1223558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1224558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMask = R_8237_DMA_WRSMSK_CH0_3; 1225558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaClear = R_8237_DMA_CBPR_CH0_3; 1226558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaChannelMode = R_8237_DMA_CHMODE_CH0_3; 1227558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1228558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort ( 1229558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1230558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMask, 1231558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (UINT8) (B_8237_DMA_WRSMSK_CMS | (ChannelNumber & 0x03)) 1232558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1233558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1234558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1235558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1236558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1237558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort ( 1238558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1239558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaClear, 1240558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (UINT8) (B_8237_DMA_WRSMSK_CMS | (ChannelNumber & 0x03)) 1241558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1242558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1243558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1244558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1245558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1246558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort (This, DmaChannelMode, DmaMode); 1247558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1248558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1249558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1250558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1251558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WriteDmaPort ( 1252558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1253558be4559ac1fba1a81b483c90d00680a18640ffniruiyu mDmaRegisters[ChannelNumber].Address, 1254558be4559ac1fba1a81b483c90d00680a18640ffniruiyu mDmaRegisters[ChannelNumber].Page, 1255558be4559ac1fba1a81b483c90d00680a18640ffniruiyu mDmaRegisters[ChannelNumber].Count, 1256558be4559ac1fba1a81b483c90d00680a18640ffniruiyu BaseAddress, 1257558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count 1258558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1259558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1260558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1261558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1262558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1263558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort ( 1264558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1265558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMask, 1266558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (UINT8) (ChannelNumber & 0x03) 1267558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1268558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1269558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1270558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1271558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1272558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_SUCCESS; 1273558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 1274558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1275558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 1276558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Maps a memory region for DMA. This implementation implement the 1277558be4559ac1fba1a81b483c90d00680a18640ffniruiyu the full mapping support. 1278558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1279558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param This A pointer to the EFI_ISA_IO_PROTOCOL instance. 1280558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param Operation Indicates the type of DMA (slave or bus master), and if 1281558be4559ac1fba1a81b483c90d00680a18640ffniruiyu the DMA operation is going to read or write to system memory. 1282558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param ChannelNumber The slave channel number to use for this DMA operation. 1283558be4559ac1fba1a81b483c90d00680a18640ffniruiyu If Operation and ChannelAttributes shows that this device 1284558be4559ac1fba1a81b483c90d00680a18640ffniruiyu performs bus mastering DMA, then this field is ignored. 1285558be4559ac1fba1a81b483c90d00680a18640ffniruiyu The legal range for this field is 0..7. 1286558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param ChannelAttributes The attributes of the DMA channel to use for this DMA operation 1287558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param HostAddress The system memory address to map to the device. 1288558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param NumberOfBytes On input the number of bytes to map. On output the number 1289558be4559ac1fba1a81b483c90d00680a18640ffniruiyu of bytes that were mapped. 1290558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param DeviceAddress The resulting map address for the bus master device to use 1291558be4559ac1fba1a81b483c90d00680a18640ffniruiyu to access the hosts HostAddress. 1292558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param Mapping A resulting value to pass to EFI_ISA_IO.Unmap(). 1293558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1294558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS - The range was mapped for the returned NumberOfBytes. 1295558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined. 1296558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED - The HostAddress can not be mapped as a common buffer. 1297558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_DEVICE_ERROR - The system hardware could not map the requested address. 1298558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES - The memory pages could not be allocated. 1299558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 1300558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 1301558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoMapFullSupport ( 1302558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 1303558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_OPERATION Operation, 1304558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT8 ChannelNumber OPTIONAL, 1305558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 ChannelAttributes, 1306558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN VOID *HostAddress, 1307558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN OUT UINTN *NumberOfBytes, 1308558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, 1309558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT VOID **Mapping 1310558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 1311558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 1312558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 1313558be4559ac1fba1a81b483c90d00680a18640ffniruiyu BOOLEAN Master; 1314558be4559ac1fba1a81b483c90d00680a18640ffniruiyu BOOLEAN Read; 1315558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PHYSICAL_ADDRESS PhysicalAddress; 1316558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ISA_MAP_INFO *IsaMapInfo; 1317558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT8 DmaMode; 1318558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINTN MaxNumberOfBytes; 1319558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT32 BaseAddress; 1320558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT16 Count; 1321558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT8 DmaMask; 1322558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT8 DmaClear; 1323558be4559ac1fba1a81b483c90d00680a18640ffniruiyu UINT8 DmaChannelMode; 1324558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1325558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((NULL == This) || 1326558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (NULL == HostAddress) || 1327558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (NULL == NumberOfBytes) || 1328558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (NULL == DeviceAddress) || 1329558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (NULL == Mapping) 1330558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) { 1331558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1332558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1333558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1334558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1335558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Initialize the return values to their defaults 1336558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1337558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *Mapping = NULL; 1338558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1339558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1340558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Make sure the Operation parameter is valid 1341558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 13423d78c020d22023d35d27b48817d73ff31a361ac7rsun if ((UINT32)Operation >= EfiIsaIoOperationMaximum) { 1343558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1344558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1345558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1346558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (ChannelNumber >= 8) { 1347558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1348558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1349558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1350558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1351558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // See if this is a Slave DMA Operation 1352558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1353558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Master = TRUE; 1354558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Read = FALSE; 1355558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Operation == EfiIsaIoOperationSlaveRead) { 1356558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Operation = EfiIsaIoOperationBusMasterRead; 1357558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Master = FALSE; 1358558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Read = TRUE; 1359558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1360558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1361558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Operation == EfiIsaIoOperationSlaveWrite) { 1362558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Operation = EfiIsaIoOperationBusMasterWrite; 1363558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Master = FALSE; 1364558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Read = FALSE; 1365558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1366558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1367558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (!Master) { 1368558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1369558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Make sure that ChannelNumber is a valid channel number 1370558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Channel 4 is used to cascade, so it is illegal. 1371558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1372558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (ChannelNumber == 4 || ChannelNumber > 7) { 1373558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1374558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1375558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1376558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // This implementation only support COMPATIBLE DMA Transfers 1377558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1378558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE) == 0) { 1379558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1380558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1381558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1382558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((ChannelAttributes & 1383558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A | 1384558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B | 1385558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C)) != 0) { 1386558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1387558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1388558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1389558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (ChannelNumber < 4) { 1390558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1391558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // If this is Channel 0..3, then the width must be 8 bit 1392558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1393558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8) == 0) || 1394558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16) != 0) 1395558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) { 1396558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1397558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1398558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1399558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1400558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // If this is Channel 4..7, then the width must be 16 bit 1401558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1402558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8) != 0) || 1403558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16) == 0)) { 1404558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1405558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1406558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1407558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1408558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Either Demand Mode or Single Mode must be selected, but not both 1409558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1410558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE) != 0) { 1411558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE) != 0) { 1412558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1413558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1414558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1415558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE) == 0) { 1416558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1417558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1418558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1419558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1420558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1421558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Map the HostAddress to a DeviceAddress. 1422558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1423558be4559ac1fba1a81b483c90d00680a18640ffniruiyu PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress; 1424558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((PhysicalAddress +*NumberOfBytes) > BASE_16MB) { 1425558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1426558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Common Buffer operations can not be remapped. If the common buffer 1427558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // is above 16MB, then it is not possible to generate a mapping, so return 1428558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // an error. 1429558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1430558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Operation == EfiIsaIoOperationBusMasterCommonBuffer) { 1431558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 1432558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1433558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1434558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Allocate an ISA_MAP_INFO structure to remember the mapping when Unmap() 1435558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // is called later. 1436558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1437558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo = AllocatePool (sizeof (ISA_MAP_INFO)); 1438558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (IsaMapInfo == NULL) { 1439558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *NumberOfBytes = 0; 1440558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_OUT_OF_RESOURCES; 1441558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1442558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1443558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Return a pointer to the MAP_INFO structure in Mapping 1444558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1445558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *Mapping = IsaMapInfo; 1446558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1447558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1448558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Initialize the MAP_INFO structure 1449558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1450558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->Operation = Operation; 1451558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfBytes = *NumberOfBytes; 1452558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (*NumberOfBytes); 1453558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->HostAddress = PhysicalAddress; 1454558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->MappedHostAddress = BASE_16MB - 1; 1455558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1456558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1457558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Allocate a buffer below 16MB to map the transfer to. 1458558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1459558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = gBS->AllocatePages ( 1460558be4559ac1fba1a81b483c90d00680a18640ffniruiyu AllocateMaxAddress, 1461558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EfiBootServicesData, 1462558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfPages, 1463558be4559ac1fba1a81b483c90d00680a18640ffniruiyu &IsaMapInfo->MappedHostAddress 1464558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1465558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1466558be4559ac1fba1a81b483c90d00680a18640ffniruiyu FreePool (IsaMapInfo); 1467558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *NumberOfBytes = 0; 1468558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *Mapping = NULL; 1469558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1470558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1471558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1472558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // If this is a read operation from the DMA agents's point of view, 1473558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // then copy the contents of the real buffer into the mapped buffer 1474558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // so the DMA agent can read the contents of the real buffer. 1475558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1476558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Operation == EfiIsaIoOperationBusMasterRead) { 1477558be4559ac1fba1a81b483c90d00680a18640ffniruiyu CopyMem ( 1478558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (VOID *) (UINTN) IsaMapInfo->MappedHostAddress, 1479558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (VOID *) (UINTN) IsaMapInfo->HostAddress, 1480558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IsaMapInfo->NumberOfBytes 1481558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1482558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1483558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1484558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // The DeviceAddress is the address of the maped buffer below 16 MB 1485558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1486558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *DeviceAddress = IsaMapInfo->MappedHostAddress; 1487558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1488558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1489558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // The transfer is below 16 MB, so the DeviceAddress is simply the 1490558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // HostAddress 1491558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1492558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *DeviceAddress = PhysicalAddress; 1493558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1494558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1495558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // If this is a Bus Master operation then return 1496558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1497558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Master) { 1498558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_SUCCESS; 1499558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1500558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1501558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Figure out what to program into the DMA Channel Mode Register 1502558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1503558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode = (UINT8) (B_8237_DMA_CHMODE_INCREMENT | (ChannelNumber & 0x03)); 1504558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Read) { 1505558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode |= V_8237_DMA_CHMODE_MEM2IO; 1506558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1507558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode |= V_8237_DMA_CHMODE_IO2MEM; 1508558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1509558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1510558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE) != 0) { 1511558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode |= B_8237_DMA_CHMODE_AE; 1512558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1513558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1514558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE) != 0) { 1515558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode |= V_8237_DMA_CHMODE_DEMAND; 1516558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1517558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1518558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE) != 0) { 1519558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMode |= V_8237_DMA_CHMODE_SINGLE; 1520558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1521558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1522558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // A Slave DMA transfer can not cross a 64K boundary. 1523558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Compute *NumberOfBytes based on this restriction. 1524558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1525558be4559ac1fba1a81b483c90d00680a18640ffniruiyu MaxNumberOfBytes = 0x10000 - ((UINT32) (*DeviceAddress) & 0xffff); 1526558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (*NumberOfBytes > MaxNumberOfBytes) { 1527558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *NumberOfBytes = MaxNumberOfBytes; 1528558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1529558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1530558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Compute the values to program into the BaseAddress and Count registers 1531558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // of the Slave DMA controller 1532558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1533558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (ChannelNumber < 4) { 1534558be4559ac1fba1a81b483c90d00680a18640ffniruiyu BaseAddress = (UINT32) (*DeviceAddress); 1535558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count = (UINT16) (*NumberOfBytes - 1); 1536558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1537558be4559ac1fba1a81b483c90d00680a18640ffniruiyu BaseAddress = (UINT32) (((UINT32) (*DeviceAddress) & 0xff0000) | (((UINT32) (*DeviceAddress) & 0xffff) >> 1)); 1538558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count = (UINT16) ((*NumberOfBytes - 1) >> 1); 1539558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1540558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1541558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Program the DMA Write Single Mask Register for ChannelNumber 1542558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Clear the DMA Byte Pointer Register 1543558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1544558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (ChannelNumber < 4) { 1545558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMask = R_8237_DMA_WRSMSK_CH0_3; 1546558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaClear = R_8237_DMA_CBPR_CH0_3; 1547558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaChannelMode = R_8237_DMA_CHMODE_CH0_3; 1548558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1549558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMask = R_8237_DMA_WRSMSK_CH4_7; 1550558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaClear = R_8237_DMA_CBPR_CH4_7; 1551558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaChannelMode = R_8237_DMA_CHMODE_CH4_7; 1552558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1553558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1554558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort ( 1555558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1556558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMask, 1557558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (UINT8) (B_8237_DMA_WRSMSK_CMS | (ChannelNumber & 0x03)) 1558558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1559558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1560558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1561558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1562558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1563558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort ( 1564558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1565558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaClear, 1566558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (UINT8) (B_8237_DMA_WRSMSK_CMS | (ChannelNumber & 0x03)) 1567558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1568558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1569558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1570558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1571558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1572558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort (This, DmaChannelMode, DmaMode); 1573558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1574558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1575558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1576558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1577558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WriteDmaPort ( 1578558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1579558be4559ac1fba1a81b483c90d00680a18640ffniruiyu mDmaRegisters[ChannelNumber].Address, 1580558be4559ac1fba1a81b483c90d00680a18640ffniruiyu mDmaRegisters[ChannelNumber].Page, 1581558be4559ac1fba1a81b483c90d00680a18640ffniruiyu mDmaRegisters[ChannelNumber].Count, 1582558be4559ac1fba1a81b483c90d00680a18640ffniruiyu BaseAddress, 1583558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Count 1584558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1585558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1586558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1587558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1588558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1589558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = WritePort ( 1590558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1591558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DmaMask, 1592558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (UINT8) (ChannelNumber & 0x03) 1593558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1594558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1595558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1596558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1597558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1598558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_SUCCESS; 1599558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 1600558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1601558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 1602558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Maps a memory region for DMA 1603558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1604558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param This A pointer to the EFI_ISA_IO_PROTOCOL instance. 1605558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param Operation Indicates the type of DMA (slave or bus master), and if 1606558be4559ac1fba1a81b483c90d00680a18640ffniruiyu the DMA operation is going to read or write to system memory. 1607558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param ChannelNumber The slave channel number to use for this DMA operation. 1608558be4559ac1fba1a81b483c90d00680a18640ffniruiyu If Operation and ChannelAttributes shows that this device 1609558be4559ac1fba1a81b483c90d00680a18640ffniruiyu performs bus mastering DMA, then this field is ignored. 1610558be4559ac1fba1a81b483c90d00680a18640ffniruiyu The legal range for this field is 0..7. 1611558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param ChannelAttributes The attributes of the DMA channel to use for this DMA operation 1612558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param HostAddress The system memory address to map to the device. 1613558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param NumberOfBytes On input the number of bytes to map. On output the number 1614558be4559ac1fba1a81b483c90d00680a18640ffniruiyu of bytes that were mapped. 1615558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param DeviceAddress The resulting map address for the bus master device to use 1616558be4559ac1fba1a81b483c90d00680a18640ffniruiyu to access the hosts HostAddress. 1617558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param Mapping A resulting value to pass to EFI_ISA_IO.Unmap(). 1618558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1619558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. 1620558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER The Operation or HostAddress is undefined. 1621558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a common buffer. 1622558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. 1623558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. 1624558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 1625558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 1626558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 1627558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoMap ( 1628558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 1629558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL_OPERATION Operation, 1630558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT8 ChannelNumber OPTIONAL, 1631558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT32 ChannelAttributes, 1632558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN VOID *HostAddress, 1633558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN OUT UINTN *NumberOfBytes, 1634558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, 1635558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT VOID **Mapping 1636558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 1637558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 1638558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1639558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Check if DMA is supported. 1640558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1641558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_DMA) == 0) { 1642558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 1643558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1644558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1645558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Set Feature Flag PcdIsaBusSupportBusMaster to FALSE to disable support for 1646558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // ISA Bus Master. 1647558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1648558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // So we just return EFI_UNSUPPORTED for these functions. 1649558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1650558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_ONLY_SUPPORT_SLAVE_DMA) != 0) { 1651558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return IsaIoMapOnlySupportSlaveReadWrite ( 1652558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1653558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Operation, 1654558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ChannelNumber, 1655558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ChannelAttributes, 1656558be4559ac1fba1a81b483c90d00680a18640ffniruiyu HostAddress, 1657558be4559ac1fba1a81b483c90d00680a18640ffniruiyu NumberOfBytes, 1658558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DeviceAddress, 1659558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Mapping 1660558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1661558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1662558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1663558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return IsaIoMapFullSupport ( 1664558be4559ac1fba1a81b483c90d00680a18640ffniruiyu This, 1665558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Operation, 1666558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ChannelNumber, 1667558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ChannelAttributes, 1668558be4559ac1fba1a81b483c90d00680a18640ffniruiyu HostAddress, 1669558be4559ac1fba1a81b483c90d00680a18640ffniruiyu NumberOfBytes, 1670558be4559ac1fba1a81b483c90d00680a18640ffniruiyu DeviceAddress, 1671558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Mapping 1672558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1673558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1674558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 1675558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1676558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 1677558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Allocates pages that are suitable for an EfiIsaIoOperationBusMasterCommonBuffer mapping. 1678558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1679558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 1680558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Type The type allocation to perform. 1681558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] MemoryType The type of memory to allocate. 1682558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Pages The number of pages to allocate. 1683558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[out] HostAddress A pointer to store the base address of the allocated range. 1684558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Attributes The requested bit mask of attributes for the allocated range. 1685558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1686558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The requested memory pages were allocated. 1687558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER Type is invalid or MemoryType is invalid or HostAddress is NULL 1688558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_UNSUPPORTED Attributes is unsupported or the memory range specified 1689558be4559ac1fba1a81b483c90d00680a18640ffniruiyu by HostAddress, Pages, and Type is not available for common buffer use. 1690558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. 1691558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 1692558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 1693558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 1694558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoAllocateBuffer ( 1695558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 1696558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ALLOCATE_TYPE Type, 1697558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_MEMORY_TYPE MemoryType, 1698558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINTN Pages, 1699558be4559ac1fba1a81b483c90d00680a18640ffniruiyu OUT VOID **HostAddress, 1700558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINT64 Attributes 1701558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 1702558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 1703558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 1704558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_PHYSICAL_ADDRESS PhysicalAddress; 1705558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1706558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1707558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Set Feature Flag PcdIsaBusOnlySupportSlaveDma to FALSE to disable support for 1708558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // ISA Bus Master. 1709558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Or unset Feature Flag PcdIsaBusSupportDma to disable support for ISA DMA. 1710558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1711558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_DMA) == 0) || 1712558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_ONLY_SUPPORT_SLAVE_DMA) != 0)) { 1713558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 1714558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1715558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1716558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (HostAddress == NULL) { 1717558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1718558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1719558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 17203d78c020d22023d35d27b48817d73ff31a361ac7rsun if ((UINT32)Type >= MaxAllocateType) { 1721558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1722558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1723558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1724558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData 1725558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1726558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) { 1727558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_INVALID_PARAMETER; 1728558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1729558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1730558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((Attributes & ~(EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED)) != 0) { 1731558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 1732558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1733558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1734558be4559ac1fba1a81b483c90d00680a18640ffniruiyu PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (BASE_16MB - 1); 1735558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Type == AllocateAddress) { 1736558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if ((UINTN) (*HostAddress) >= BASE_16MB) { 1737558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 1738558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } else { 1739558be4559ac1fba1a81b483c90d00680a18640ffniruiyu PhysicalAddress = (UINTN) (*HostAddress); 1740558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1741558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1742558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1743558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (Type == AllocateAnyPages) { 1744558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Type = AllocateMaxAddress; 1745558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1746558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1747558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = gBS->AllocatePages (Type, MemoryType, Pages, &PhysicalAddress); 1748558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1749558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 1750558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 1751558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 1752558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1753558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1754558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1755558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1756558be4559ac1fba1a81b483c90d00680a18640ffniruiyu *HostAddress = (VOID *) (UINTN) PhysicalAddress; 1757558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1758558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 1759558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1760558be4559ac1fba1a81b483c90d00680a18640ffniruiyu/** 1761558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Frees memory that was allocated with EFI_ISA_IO.AllocateBuffer(). 1762558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1763558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance. 1764558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] Pages The number of pages to free. 1765558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @param[in] HostAddress The base address of the allocated range. 1766558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1767558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_SUCCESS The requested memory pages were freed. 1768558be4559ac1fba1a81b483c90d00680a18640ffniruiyu @retval EFI_INVALID_PARAMETER The memory was not allocated with EFI_ISA_IO.AllocateBufer(). 1769558be4559ac1fba1a81b483c90d00680a18640ffniruiyu**/ 1770558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFI_STATUS 1771558be4559ac1fba1a81b483c90d00680a18640ffniruiyuEFIAPI 1772558be4559ac1fba1a81b483c90d00680a18640ffniruiyuIsaIoFreeBuffer ( 1773558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN EFI_ISA_IO_PROTOCOL *This, 1774558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN UINTN Pages, 1775558be4559ac1fba1a81b483c90d00680a18640ffniruiyu IN VOID *HostAddress 1776558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ) 1777558be4559ac1fba1a81b483c90d00680a18640ffniruiyu{ 1778558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_STATUS Status; 1779558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1780558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1781558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Set Feature Flag PcdIsaBusOnlySupportSlaveDma to FALSE to disable support for 1782558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // ISA Bus Master. 1783558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // Or unset Feature Flag PcdIsaBusSupportDma to disable support for ISA DMA. 1784558be4559ac1fba1a81b483c90d00680a18640ffniruiyu // 1785558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_DMA) == 0) || 1786558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_ONLY_SUPPORT_SLAVE_DMA) != 0)) { 1787558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return EFI_UNSUPPORTED; 1788558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1789558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1790558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Status = gBS->FreePages ( 1791558be4559ac1fba1a81b483c90d00680a18640ffniruiyu (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, 1792558be4559ac1fba1a81b483c90d00680a18640ffniruiyu Pages 1793558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1794558be4559ac1fba1a81b483c90d00680a18640ffniruiyu if (EFI_ERROR (Status)) { 1795558be4559ac1fba1a81b483c90d00680a18640ffniruiyu REPORT_STATUS_CODE ( 1796558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_ERROR_CODE | EFI_ERROR_MINOR, 1797558be4559ac1fba1a81b483c90d00680a18640ffniruiyu EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR 1798558be4559ac1fba1a81b483c90d00680a18640ffniruiyu ); 1799558be4559ac1fba1a81b483c90d00680a18640ffniruiyu } 1800558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1801558be4559ac1fba1a81b483c90d00680a18640ffniruiyu return Status; 1802558be4559ac1fba1a81b483c90d00680a18640ffniruiyu} 1803558be4559ac1fba1a81b483c90d00680a18640ffniruiyu 1804