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 Copyright (c) Microsoft Corporation.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
15 Acquire or release a lock of the exclusive access to a critical section of the
18 This is a callback routine supplied to UNDI3.1 at undi_start time.
19 New callbacks for 3.1: there won't be a virtual2physical callback for UNDI 3.1
20 because undi3.1 uses the MemMap call to map the required address by itself!
22 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
23 store Undi interface context (Undi does not read or write
25 @param Enable Non-zero indicates acquire; Zero indicates release.
30 SnpUndi32CallbackBlock (
37 Snp
= (SNP_DRIVER
*)(UINTN
)UniqueId
;
39 // tcpip was calling snp at tpl_notify and when we acquire a lock that was
40 // created at a lower level (TPL_CALLBACK) it gives an assert!
43 EfiAcquireLock (&Snp
->Lock
);
45 EfiReleaseLock (&Snp
->Lock
);
50 Delay MicroSeconds of micro seconds.
52 This is a callback routine supplied to UNDI at undi_start time.
54 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
55 store Undi interface context (Undi does not read or write
57 @param MicroSeconds Number of micro seconds to pause, usually multiple of 10.
62 SnpUndi32CallbackDelay (
64 IN UINT64 MicroSeconds
67 if (MicroSeconds
!= 0) {
68 gBS
->Stall ((UINTN
)MicroSeconds
);
73 IO routine for UNDI3.1.
75 This is a callback routine supplied to UNDI at undi_start time.
77 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this
78 to store Undi interface context (Undi does not read or
80 @param ReadOrWrite Indicates read or write, IO or Memory.
81 @param NumBytes Number of bytes to read or write.
82 @param MemOrPortAddr IO or memory address to read from or write to.
83 @param BufferPtr Memory location to read into or that contains the bytes
89 SnpUndi32CallbackMemio (
93 IN UINT64 MemOrPortAddr
,
94 IN OUT UINT64 BufferPtr
98 EFI_PCI_IO_PROTOCOL_WIDTH Width
;
100 Snp
= (SNP_DRIVER
*)(UINTN
)UniqueId
;
102 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
)0;
105 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
)1;
109 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
)2;
113 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
)3;
117 switch (ReadOrWrite
) {
119 ASSERT (Snp
->IoBarIndex
< PCI_MAX_BAR
);
120 if (Snp
->IoBarIndex
< PCI_MAX_BAR
) {
121 Snp
->PciIo
->Io
.Read (
124 Snp
->IoBarIndex
, // BAR 1 (for 32bit regs), IO base address
127 (VOID
*)(UINTN
)BufferPtr
134 ASSERT (Snp
->IoBarIndex
< PCI_MAX_BAR
);
135 if (Snp
->IoBarIndex
< PCI_MAX_BAR
) {
136 Snp
->PciIo
->Io
.Write (
139 Snp
->IoBarIndex
, // BAR 1 (for 32bit regs), IO base address
142 (VOID
*)(UINTN
)BufferPtr
149 ASSERT (Snp
->MemoryBarIndex
< PCI_MAX_BAR
);
150 if (Snp
->MemoryBarIndex
< PCI_MAX_BAR
) {
151 Snp
->PciIo
->Mem
.Read (
154 Snp
->MemoryBarIndex
, // BAR 0, Memory base address
157 (VOID
*)(UINTN
)BufferPtr
164 ASSERT (Snp
->MemoryBarIndex
< PCI_MAX_BAR
);
165 if (Snp
->MemoryBarIndex
< PCI_MAX_BAR
) {
166 Snp
->PciIo
->Mem
.Write (
169 Snp
->MemoryBarIndex
, // BAR 0, Memory base address
172 (VOID
*)(UINTN
)BufferPtr
183 Map a CPU address to a device address.
185 This is a callback routine supplied to UNDI at undi_start time.
187 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
188 store Undi interface context (Undi does not read or write
190 @param CpuAddr Virtual address to be mapped.
191 @param NumBytes Size of memory to be mapped.
192 @param Direction Direction of data flow for this memory's usage:
193 cpu->device, device->cpu or both ways.
194 @param DeviceAddrPtr Pointer to return the mapped device address.
199 SnpUndi32CallbackMap (
204 IN OUT UINT64 DeviceAddrPtr
207 EFI_PHYSICAL_ADDRESS
*DevAddrPtr
;
208 EFI_PCI_IO_PROTOCOL_OPERATION DirectionFlag
;
214 BuffSize
= (UINTN
)NumBytes
;
215 Snp
= (SNP_DRIVER
*)(UINTN
)UniqueId
;
216 DevAddrPtr
= (EFI_PHYSICAL_ADDRESS
*)(UINTN
)DeviceAddrPtr
;
224 case TO_AND_FROM_DEVICE
:
225 DirectionFlag
= EfiPciIoOperationBusMasterCommonBuffer
;
229 DirectionFlag
= EfiPciIoOperationBusMasterWrite
;
233 DirectionFlag
= EfiPciIoOperationBusMasterRead
;
239 // any non zero indicates error!
245 // find an unused map_list entry
247 for (Index
= 0; Index
< MAX_MAP_LENGTH
; Index
++) {
248 if (Snp
->MapList
[Index
].VirtualAddress
== 0) {
253 if (Index
>= MAX_MAP_LENGTH
) {
254 DEBUG ((DEBUG_INFO
, "SNP maplist is FULL\n"));
259 Snp
->MapList
[Index
].VirtualAddress
= (EFI_PHYSICAL_ADDRESS
)CpuAddr
;
261 Status
= Snp
->PciIo
->Map (
264 (VOID
*)(UINTN
)CpuAddr
,
267 &(Snp
->MapList
[Index
].MapCookie
)
269 if (Status
!= EFI_SUCCESS
) {
271 Snp
->MapList
[Index
].VirtualAddress
= 0;
278 Unmap an address that was previously mapped using map callback.
280 This is a callback routine supplied to UNDI at undi_start time.
282 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
283 store. Undi interface context (Undi does not read or write
285 @param CpuAddr Virtual address that was mapped.
286 @param NumBytes Size of memory mapped.
287 @param Direction Direction of data flow for this memory's usage:
288 cpu->device, device->cpu or both ways.
289 @param DeviceAddr The mapped device address.
294 SnpUndi32CallbackUnmap (
305 Snp
= (SNP_DRIVER
*)(UINTN
)UniqueId
;
307 for (Index
= 0; Index
< MAX_MAP_LENGTH
; Index
++) {
308 if (Snp
->MapList
[Index
].VirtualAddress
== CpuAddr
) {
313 if (Index
>= MAX_MAP_LENGTH
) {
314 DEBUG ((DEBUG_ERROR
, "SNP could not find a mapping, failed to unmap.\n"));
318 Snp
->PciIo
->Unmap (Snp
->PciIo
, Snp
->MapList
[Index
].MapCookie
);
319 Snp
->MapList
[Index
].VirtualAddress
= 0;
320 Snp
->MapList
[Index
].MapCookie
= NULL
;
325 Synchronize the virtual buffer contents with the mapped buffer contents.
327 This is a callback routine supplied to UNDI at undi_start time. The virtual
328 and mapped buffers need not correspond to the same physical memory (especially
329 if the virtual address is > 4GB). Depending on the direction for which the
330 buffer is mapped, undi will need to synchronize their contents whenever it
331 writes to/reads from the buffer using either the cpu address or the device
333 EFI does not provide a sync call since virt=physical, we should just do the
334 synchronization ourselves here.
336 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
337 store Undi interface context (Undi does not read or write
339 @param CpuAddr Virtual address that was mapped.
340 @param NumBytes Size of memory mapped.
341 @param Direction Direction of data flow for this memory's usage:
342 cpu->device, device->cpu or both ways.
343 @param DeviceAddr The mapped device address.
348 SnpUndi32CallbackSync (
356 if ((CpuAddr
== 0) || (DeviceAddr
== 0) || (NumBytes
== 0)) {
362 CopyMem ((UINT8
*)(UINTN
)CpuAddr
, (UINT8
*)(UINTN
)DeviceAddr
, NumBytes
);
366 CopyMem ((UINT8
*)(UINTN
)DeviceAddr
, (UINT8
*)(UINTN
)CpuAddr
, NumBytes
);