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
133 ASSERT (Snp
->IoBarIndex
< PCI_MAX_BAR
);
134 if (Snp
->IoBarIndex
< PCI_MAX_BAR
) {
135 Snp
->PciIo
->Io
.Write (
138 Snp
->IoBarIndex
, // BAR 1 (for 32bit regs), IO base address
141 (VOID
*) (UINTN
) BufferPtr
147 ASSERT (Snp
->MemoryBarIndex
< PCI_MAX_BAR
);
148 if (Snp
->MemoryBarIndex
< PCI_MAX_BAR
) {
149 Snp
->PciIo
->Mem
.Read (
152 Snp
->MemoryBarIndex
, // BAR 0, Memory base address
155 (VOID
*) (UINTN
) BufferPtr
161 ASSERT (Snp
->MemoryBarIndex
< PCI_MAX_BAR
);
162 if (Snp
->MemoryBarIndex
< PCI_MAX_BAR
) {
163 Snp
->PciIo
->Mem
.Write (
166 Snp
->MemoryBarIndex
, // BAR 0, Memory base address
169 (VOID
*) (UINTN
) BufferPtr
179 Map a CPU address to a device address.
181 This is a callback routine supplied to UNDI at undi_start time.
183 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
184 store Undi interface context (Undi does not read or write
186 @param CpuAddr Virtual address to be mapped.
187 @param NumBytes Size of memory to be mapped.
188 @param Direction Direction of data flow for this memory's usage:
189 cpu->device, device->cpu or both ways.
190 @param DeviceAddrPtr Pointer to return the mapped device address.
195 SnpUndi32CallbackMap (
200 IN OUT UINT64 DeviceAddrPtr
203 EFI_PHYSICAL_ADDRESS
*DevAddrPtr
;
204 EFI_PCI_IO_PROTOCOL_OPERATION DirectionFlag
;
210 BuffSize
= (UINTN
) NumBytes
;
211 Snp
= (SNP_DRIVER
*) (UINTN
) UniqueId
;
212 DevAddrPtr
= (EFI_PHYSICAL_ADDRESS
*) (UINTN
) DeviceAddrPtr
;
220 case TO_AND_FROM_DEVICE
:
221 DirectionFlag
= EfiPciIoOperationBusMasterCommonBuffer
;
225 DirectionFlag
= EfiPciIoOperationBusMasterWrite
;
229 DirectionFlag
= EfiPciIoOperationBusMasterRead
;
235 // any non zero indicates error!
240 // find an unused map_list entry
242 for (Index
= 0; Index
< MAX_MAP_LENGTH
; Index
++) {
243 if (Snp
->MapList
[Index
].VirtualAddress
== 0) {
248 if (Index
>= MAX_MAP_LENGTH
) {
249 DEBUG ((EFI_D_INFO
, "SNP maplist is FULL\n"));
254 Snp
->MapList
[Index
].VirtualAddress
= (EFI_PHYSICAL_ADDRESS
) CpuAddr
;
256 Status
= Snp
->PciIo
->Map (
259 (VOID
*) (UINTN
) CpuAddr
,
262 &(Snp
->MapList
[Index
].MapCookie
)
264 if (Status
!= EFI_SUCCESS
) {
266 Snp
->MapList
[Index
].VirtualAddress
= 0;
273 Unmap an address that was previously mapped using map callback.
275 This is a callback routine supplied to UNDI at undi_start time.
277 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
278 store. Undi interface context (Undi does not read or write
280 @param CpuAddr Virtual address that was mapped.
281 @param NumBytes Size of memory mapped.
282 @param Direction Direction of data flow for this memory's usage:
283 cpu->device, device->cpu or both ways.
284 @param DeviceAddr The mapped device address.
289 SnpUndi32CallbackUnmap (
300 Snp
= (SNP_DRIVER
*) (UINTN
) UniqueId
;
302 for (Index
= 0; Index
< MAX_MAP_LENGTH
; Index
++) {
303 if (Snp
->MapList
[Index
].VirtualAddress
== CpuAddr
) {
308 if (Index
>= MAX_MAP_LENGTH
) {
309 DEBUG ((EFI_D_ERROR
, "SNP could not find a mapping, failed to unmap.\n"));
313 Snp
->PciIo
->Unmap (Snp
->PciIo
, Snp
->MapList
[Index
].MapCookie
);
314 Snp
->MapList
[Index
].VirtualAddress
= 0;
315 Snp
->MapList
[Index
].MapCookie
= NULL
;
320 Synchronize the virtual buffer contents with the mapped buffer contents.
322 This is a callback routine supplied to UNDI at undi_start time. The virtual
323 and mapped buffers need not correspond to the same physical memory (especially
324 if the virtual address is > 4GB). Depending on the direction for which the
325 buffer is mapped, undi will need to synchronize their contents whenever it
326 writes to/reads from the buffer using either the cpu address or the device
328 EFI does not provide a sync call since virt=physical, we should just do the
329 synchronization ourselves here.
331 @param UniqueId This was supplied to UNDI at Undi_Start, SNP uses this to
332 store Undi interface context (Undi does not read or write
334 @param CpuAddr Virtual address that was mapped.
335 @param NumBytes Size of memory mapped.
336 @param Direction Direction of data flow for this memory's usage:
337 cpu->device, device->cpu or both ways.
338 @param DeviceAddr The mapped device address.
343 SnpUndi32CallbackSync (
351 if ((CpuAddr
== 0) || (DeviceAddr
== 0) || (NumBytes
== 0)) {
358 CopyMem ((UINT8
*) (UINTN
) CpuAddr
, (UINT8
*) (UINTN
) DeviceAddr
, NumBytes
);
362 CopyMem ((UINT8
*) (UINTN
) DeviceAddr
, (UINT8
*) (UINTN
) CpuAddr
, NumBytes
);