2 This file contains the callback routines for undi3.1.
3 the callback routines for Undi3.1 have an extra parameter UniqueId which
4 stores the interface context for the NIC that snp is trying to talk.
6 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 Acquire or release a lock of the exclusive access to a critical section of the
23 This is a callback routine supplied to UNDI3.1 at undi_start time.
24 New callbacks for 3.1: there won't be a virtual2physical callback for UNDI 3.1
25 because undi3.1 uses the MemMap call to map the required address by itself!
27 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
28 store Undi interface context (Undi does not read or write
30 @param Enable Non-zero indicates acquire; Zero indicates release.
35 SnpUndi32CallbackBlock (
42 Snp
= (SNP_DRIVER
*) (UINTN
) UniqueId
;
44 // tcpip was calling snp at tpl_notify and when we acquire a lock that was
45 // created at a lower level (TPL_CALLBACK) it gives an assert!
48 EfiAcquireLock (&Snp
->Lock
);
50 EfiReleaseLock (&Snp
->Lock
);
55 Delay MicroSeconds of micro seconds.
57 This is a callback routine supplied to UNDI at undi_start time.
59 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
60 store Undi interface context (Undi does not read or write
62 @param MicroSeconds Number of micro seconds to pause, ususlly multiple of 10.
67 SnpUndi32CallbackDelay (
69 IN UINT64 MicroSeconds
72 if (MicroSeconds
!= 0) {
73 gBS
->Stall ((UINTN
) MicroSeconds
);
78 IO routine for UNDI3.1.
80 This is a callback routine supplied to UNDI at undi_start time.
82 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this
83 to store Undi interface context (Undi does not read or
85 @param ReadOrWrite Indicates read or write, IO or Memory.
86 @param NumBytes Number of bytes to read or write.
87 @param MemOrPortAddr IO or memory address to read from or write to.
88 @param BufferPtr Memory location to read into or that contains the bytes
94 SnpUndi32CallbackMemio (
98 IN UINT64 MemOrPortAddr
,
99 IN OUT UINT64 BufferPtr
103 EFI_PCI_IO_PROTOCOL_WIDTH Width
;
105 Snp
= (SNP_DRIVER
*) (UINTN
) UniqueId
;
107 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 0;
110 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 1;
114 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 2;
118 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 3;
122 switch (ReadOrWrite
) {
124 Snp
->PciIo
->Io
.Read (
127 Snp
->IoBarIndex
, // BAR 1 (for 32bit regs), IO base address
130 (VOID
*) (UINTN
) BufferPtr
135 Snp
->PciIo
->Io
.Write (
138 Snp
->IoBarIndex
, // BAR 1 (for 32bit regs), IO base address
141 (VOID
*) (UINTN
) BufferPtr
146 Snp
->PciIo
->Mem
.Read (
149 Snp
->MemoryBarIndex
, // BAR 0, Memory base address
152 (VOID
*) (UINTN
) BufferPtr
157 Snp
->PciIo
->Mem
.Write (
160 Snp
->MemoryBarIndex
, // BAR 0, Memory base address
163 (VOID
*) (UINTN
) BufferPtr
172 Map a CPU address to a device address.
174 This is a callback routine supplied to UNDI at undi_start time.
176 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
177 store Undi interface context (Undi does not read or write
179 @param CpuAddr Virtual address to be mapped.
180 @param NumBytes Size of memory to be mapped.
181 @param Direction Direction of data flow for this memory's usage:
182 cpu->device, device->cpu or both ways.
183 @param DeviceAddrPtr Pointer to return the mapped device address.
188 SnpUndi32CallbackMap (
193 IN OUT UINT64 DeviceAddrPtr
196 EFI_PHYSICAL_ADDRESS
*DevAddrPtr
;
197 EFI_PCI_IO_PROTOCOL_OPERATION DirectionFlag
;
203 BuffSize
= (UINTN
) NumBytes
;
204 Snp
= (SNP_DRIVER
*) (UINTN
) UniqueId
;
205 DevAddrPtr
= (EFI_PHYSICAL_ADDRESS
*) (UINTN
) DeviceAddrPtr
;
213 case TO_AND_FROM_DEVICE
:
214 DirectionFlag
= EfiPciIoOperationBusMasterCommonBuffer
;
218 DirectionFlag
= EfiPciIoOperationBusMasterWrite
;
222 DirectionFlag
= EfiPciIoOperationBusMasterRead
;
228 // any non zero indicates error!
233 // find an unused map_list entry
235 for (Index
= 0; Index
< MAX_MAP_LENGTH
; Index
++) {
236 if (Snp
->MapList
[Index
].VirtualAddress
== 0) {
241 if (Index
>= MAX_MAP_LENGTH
) {
242 DEBUG ((EFI_D_INFO
, "SNP maplist is FULL\n"));
247 Snp
->MapList
[Index
].VirtualAddress
= (EFI_PHYSICAL_ADDRESS
) CpuAddr
;
249 Status
= Snp
->PciIo
->Map (
252 (VOID
*) (UINTN
) CpuAddr
,
255 &(Snp
->MapList
[Index
].MapCookie
)
257 if (Status
!= EFI_SUCCESS
) {
259 Snp
->MapList
[Index
].VirtualAddress
= 0;
266 Unmap an address that was previously mapped using map callback.
268 This is a callback routine supplied to UNDI at undi_start time.
270 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
271 store. Undi interface context (Undi does not read or write
273 @param CpuAddr Virtual address that was mapped.
274 @param NumBytes Size of memory mapped.
275 @param Direction Direction of data flow for this memory's usage:
276 cpu->device, device->cpu or both ways.
277 @param DeviceAddr The mapped device address.
282 SnpUndi32CallbackUnmap (
293 Snp
= (SNP_DRIVER
*) (UINTN
) UniqueId
;
295 for (Index
= 0; Index
< MAX_MAP_LENGTH
; Index
++) {
296 if (Snp
->MapList
[Index
].VirtualAddress
== CpuAddr
) {
301 if (Index
>= MAX_MAP_LENGTH
) {
302 DEBUG ((EFI_D_ERROR
, "SNP could not find a mapping, failed to unmap.\n"));
306 Snp
->PciIo
->Unmap (Snp
->PciIo
, Snp
->MapList
[Index
].MapCookie
);
307 Snp
->MapList
[Index
].VirtualAddress
= 0;
308 Snp
->MapList
[Index
].MapCookie
= NULL
;
313 Synchronize the virtual buffer contents with the mapped buffer contents.
315 This is a callback routine supplied to UNDI at undi_start time. The virtual
316 and mapped buffers need not correspond to the same physical memory (especially
317 if the virtual address is > 4GB). Depending on the direction for which the
318 buffer is mapped, undi will need to synchronize their contents whenever it
319 writes to/reads from the buffer using either the cpu address or the device
321 EFI does not provide a sync call since virt=physical, we should just do the
322 synchronization ourselves here.
324 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
325 store Undi interface context (Undi does not read or write
327 @param CpuAddr Virtual address that was mapped.
328 @param NumBytes Size of memory mapped.
329 @param Direction Direction of data flow for this memory's usage:
330 cpu->device, device->cpu or both ways.
331 @param DeviceAddr The mapped device address.
336 SnpUndi32CallbackSync (
344 if ((CpuAddr
== 0) || (DeviceAddr
== 0) || (NumBytes
== 0)) {
351 CopyMem ((UINT8
*) (UINTN
) CpuAddr
, (UINT8
*) (UINTN
) DeviceAddr
, NumBytes
);
355 CopyMem ((UINT8
*) (UINTN
) DeviceAddr
, (UINT8
*) (UINTN
) CpuAddr
, NumBytes
);