2 Implementation of SmBusLib class library for PEI phase.
4 Copyright (c) 2006, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 Module Name: SmbusLib.c
18 #include "InternalSmbusLib.h"
21 Executes an SMBUS quick read command.
23 Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.
24 Only the SMBUS slave address field of SmBusAddress is required.
25 If Status is not NULL, then the status of the executed command is returned in Status.
26 If PEC is set in SmBusAddress, then ASSERT().
27 If Command in SmBusAddress is not zero, then ASSERT().
28 If Length in SmBusAddress is not zero, then ASSERT().
29 If any reserved bits of SmBusAddress are set, then ASSERT().
31 @param SmBusAddress Address that encodes the SMBUS Slave Address,
32 SMBUS Command, SMBUS Data Length, and PEC.
33 @param Status Return status for the executed command.
34 This is an optional parameter and may be NULL.
40 IN UINTN SmBusAddress
,
41 OUT RETURN_STATUS
*Status OPTIONAL
44 ASSERT (!SMBUS_LIB_PEC (SmBusAddress
));
45 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress
) == 0);
46 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
47 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
49 InternalSmBusExec (EfiSmbusQuickRead
, SmBusAddress
, 0, NULL
, Status
);
53 Executes an SMBUS quick write command.
55 Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.
56 Only the SMBUS slave address field of SmBusAddress is required.
57 If Status is not NULL, then the status of the executed command is returned in Status.
58 If PEC is set in SmBusAddress, then ASSERT().
59 If Command in SmBusAddress is not zero, then ASSERT().
60 If Length in SmBusAddress is not zero, then ASSERT().
61 If any reserved bits of SmBusAddress are set, then ASSERT().
63 @param SmBusAddress Address that encodes the SMBUS Slave Address,
64 SMBUS Command, SMBUS Data Length, and PEC.
65 @param Status Return status for the executed command.
66 This is an optional parameter and may be NULL.
72 IN UINTN SmBusAddress
,
73 OUT RETURN_STATUS
*Status OPTIONAL
76 ASSERT (!SMBUS_LIB_PEC (SmBusAddress
));
77 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress
) == 0);
78 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
79 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
81 InternalSmBusExec (EfiSmbusQuickWrite
, SmBusAddress
, 0, NULL
, Status
);
83 // Bugbug: Undefined return value in spec
89 Executes an SMBUS receive byte command.
91 Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.
92 Only the SMBUS slave address field of SmBusAddress is required.
93 The byte received from the SMBUS is returned.
94 If Status is not NULL, then the status of the executed command is returned in Status.
95 If Command in SmBusAddress is not zero, then ASSERT().
96 If Length in SmBusAddress is not zero, then ASSERT().
97 If any reserved bits of SmBusAddress are set, then ASSERT().
99 @param SmBusAddress Address that encodes the SMBUS Slave Address,
100 SMBUS Command, SMBUS Data Length, and PEC.
101 @param Status Return status for the executed command.
102 This is an optional parameter and may be NULL.
104 @return The byte received from the SMBUS.
110 IN UINTN SmBusAddress
,
111 OUT RETURN_STATUS
*Status OPTIONAL
116 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress
) == 0);
117 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
118 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
120 InternalSmBusExec (EfiSmbusReceiveByte
, SmBusAddress
, 1, &Byte
, Status
);
126 Executes an SMBUS send byte command.
128 Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.
129 The byte specified by Value is sent.
130 Only the SMBUS slave address field of SmBusAddress is required. Value is returned.
131 If Status is not NULL, then the status of the executed command is returned in Status.
132 If Command in SmBusAddress is not zero, then ASSERT().
133 If Length in SmBusAddress is not zero, then ASSERT().
134 If any reserved bits of SmBusAddress are set, then ASSERT().
136 @param SmBusAddress Address that encodes the SMBUS Slave Address,
137 SMBUS Command, SMBUS Data Length, and PEC.
138 @param Value The 8-bit value to send.
139 @param Status Return status for the executed command.
140 This is an optional parameter and may be NULL.
142 @return The parameter of Value.
148 IN UINTN SmBusAddress
,
150 OUT RETURN_STATUS
*Status OPTIONAL
155 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress
) == 0);
156 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
157 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
160 InternalSmBusExec (EfiSmbusSendByte
, SmBusAddress
, 1, &Byte
, Status
);
166 Executes an SMBUS read data byte command.
168 Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.
169 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
170 The 8-bit value read from the SMBUS is returned.
171 If Status is not NULL, then the status of the executed command is returned in Status.
172 If Length in SmBusAddress is not zero, then ASSERT().
173 If any reserved bits of SmBusAddress are set, then ASSERT().
175 @param SmBusAddress Address that encodes the SMBUS Slave Address,
176 SMBUS Command, SMBUS Data Length, and PEC.
177 @param Status Return status for the executed command.
178 This is an optional parameter and may be NULL.
180 @return The byte read from the SMBUS.
186 IN UINTN SmBusAddress
,
187 OUT RETURN_STATUS
*Status OPTIONAL
192 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
193 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
195 InternalSmBusExec (EfiSmbusReadByte
, SmBusAddress
, 1, &Byte
, Status
);
201 Executes an SMBUS write data byte command.
203 Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.
204 The 8-bit value specified by Value is written.
205 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
207 If Status is not NULL, then the status of the executed command is returned in Status.
208 If Length in SmBusAddress is not zero, then ASSERT().
209 If any reserved bits of SmBusAddress are set, then ASSERT().
211 @param SmBusAddress Address that encodes the SMBUS Slave Address,
212 SMBUS Command, SMBUS Data Length, and PEC.
213 @param Value The 8-bit value to write.
214 @param Status Return status for the executed command.
215 This is an optional parameter and may be NULL.
217 @return The parameter of Value.
223 IN UINTN SmBusAddress
,
225 OUT RETURN_STATUS
*Status OPTIONAL
230 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
231 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
234 InternalSmBusExec (EfiSmbusWriteByte
, SmBusAddress
, 1, &Byte
, Status
);
240 Executes an SMBUS read data word command.
242 Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.
243 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
244 The 16-bit value read from the SMBUS is returned.
245 If Status is not NULL, then the status of the executed command is returned in Status.
246 If Length in SmBusAddress is not zero, then ASSERT().
247 If any reserved bits of SmBusAddress are set, then ASSERT().
249 @param SmBusAddress Address that encodes the SMBUS Slave Address,
250 SMBUS Command, SMBUS Data Length, and PEC.
251 @param Status Return status for the executed command.
252 This is an optional parameter and may be NULL.
254 @return The byte read from the SMBUS.
260 IN UINTN SmBusAddress
,
261 OUT RETURN_STATUS
*Status OPTIONAL
266 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
267 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
269 InternalSmBusExec (EfiSmbusReadWord
, SmBusAddress
, 2, &Word
, Status
);
275 Executes an SMBUS write data word command.
277 Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
278 The 16-bit value specified by Value is written.
279 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
281 If Status is not NULL, then the status of the executed command is returned in Status.
282 If Length in SmBusAddress is not zero, then ASSERT().
283 If any reserved bits of SmBusAddress are set, then ASSERT().
285 @param SmBusAddress Address that encodes the SMBUS Slave Address,
286 SMBUS Command, SMBUS Data Length, and PEC.
287 @param Value The 16-bit value to write.
288 @param Status Return status for the executed command.
289 This is an optional parameter and may be NULL.
291 @return The parameter of Value.
297 IN UINTN SmBusAddress
,
299 OUT RETURN_STATUS
*Status OPTIONAL
304 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
305 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
308 InternalSmBusExec (EfiSmbusWriteWord
, SmBusAddress
, 2, &Word
, Status
);
314 Executes an SMBUS process call command.
316 Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
317 The 16-bit value specified by Value is written.
318 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
319 The 16-bit value returned by the process call command is returned.
320 If Status is not NULL, then the status of the executed command is returned in Status.
321 If Length in SmBusAddress is not zero, then ASSERT().
322 If any reserved bits of SmBusAddress are set, then ASSERT().
324 @param SmBusAddress Address that encodes the SMBUS Slave Address,
325 SMBUS Command, SMBUS Data Length, and PEC.
326 @param Value The 16-bit value to write.
327 @param Status Return status for the executed command.
328 This is an optional parameter and may be NULL.
330 @return The 16-bit value returned by the process call command.
336 IN UINTN SmBusAddress
,
338 OUT RETURN_STATUS
*Status OPTIONAL
341 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
342 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
344 InternalSmBusExec (EfiSmbusProcessCall
, SmBusAddress
, 2, &Value
, Status
);
350 Executes an SMBUS read block command.
352 Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
353 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
354 Bytes are read from the SMBUS and stored in Buffer.
355 The number of bytes read is returned, and will never return a value larger than 32-bytes.
356 If Status is not NULL, then the status of the executed command is returned in Status.
357 It is the caller¡¯s responsibility to make sure Buffer is large enough for the total number of bytes read.
358 SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
359 If Length in SmBusAddress is not zero, then ASSERT().
360 If Buffer is NULL, then ASSERT().
361 If any reserved bits of SmBusAddress are set, then ASSERT().
363 @param SmBusAddress Address that encodes the SMBUS Slave Address,
364 SMBUS Command, SMBUS Data Length, and PEC.
365 @param Buffer Pointer to the buffer to store the bytes read from the SMBUS.
366 @param Status Return status for the executed command.
367 This is an optional parameter and may be NULL.
369 @return The number of bytes read.
375 IN UINTN SmBusAddress
,
377 OUT RETURN_STATUS
*Status OPTIONAL
380 ASSERT (Buffer
!= NULL
);
381 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
382 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
384 return InternalSmBusExec (EfiSmbusReadBlock
, SmBusAddress
, 0x1f, Buffer
, Status
);
388 Executes an SMBUS write block command.
390 Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
391 The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
392 Bytes are written to the SMBUS from Buffer.
393 The number of bytes written is returned, and will never return a value larger than 32-bytes.
394 If Status is not NULL, then the status of the executed command is returned in Status.
395 If Length in SmBusAddress is zero or greater than 32, then ASSERT().
396 If Buffer is NULL, then ASSERT().
397 If any reserved bits of SmBusAddress are set, then ASSERT().
399 @param SmBusAddress Address that encodes the SMBUS Slave Address,
400 SMBUS Command, SMBUS Data Length, and PEC.
401 @param Buffer Pointer to the buffer to store the bytes read from the SMBUS.
402 @param Status Return status for the executed command.
403 This is an optional parameter and may be NULL.
405 @return The number of bytes written.
411 IN UINTN SmBusAddress
,
413 OUT RETURN_STATUS
*Status OPTIONAL
416 ASSERT (Buffer
!= NULL
);
417 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
419 return InternalSmBusExec (EfiSmbusWriteBlock
, SmBusAddress
, SMBUS_LIB_LENGTH (SmBusAddress
), Buffer
, Status
);
423 Executes an SMBUS block process call command.
425 Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
426 The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
427 Bytes are written to the SMBUS from OutBuffer. Bytes are then read from the SMBUS into InBuffer.
428 If Status is not NULL, then the status of the executed command is returned in Status.
429 It is the caller¡¯s responsibility to make sure InBuffer is large enough for the total number of bytes read.
430 SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
431 If OutBuffer is NULL, then ASSERT().
432 If InBuffer is NULL, then ASSERT().
433 If any reserved bits of SmBusAddress are set, then ASSERT().
436 @param SmBusAddress Address that encodes the SMBUS Slave Address,
437 SMBUS Command, SMBUS Data Length, and PEC.
438 @param OutBuffer Pointer to the buffer of bytes to write to the SMBUS.
439 @param InBuffer Pointer to the buffer of bytes to read from the SMBUS.
440 @param Status Return status for the executed command.
441 This is an optional parameter and may be NULL.
443 @return The number of bytes written.
448 SmBusBlockProcessCall (
449 IN UINTN SmBusAddress
,
452 OUT RETURN_STATUS
*Status OPTIONAL
455 ASSERT (InBuffer
!= NULL
);
456 ASSERT (OutBuffer
!= NULL
);
457 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
460 // BugBug: Not sure whether it's all right.
462 InternalSmBusExec (EfiSmbusWriteBlock
, SmBusAddress
, SMBUS_LIB_LENGTH (SmBusAddress
), OutBuffer
, Status
);
464 return InternalSmBusExec (EfiSmbusReadBlock
, SmBusAddress
, 1, InBuffer
, Status
);
468 Enumerates the SMBUS and assigns slave addresses.
470 Executes the SMBUS enumeration algorithm and assigns a valid address to all SMBUS slave devices.
471 The total number of SMBUS slave devices detected is returned.
472 The status of the executed command is returned.
473 If Slave Address in SmBusAddress is not zero, then ASSERT().
474 If Command in SmBusAddress is not zero, then ASSERT().
475 If Length in SmBusAddress is not zero, then ASSERT().
476 If PEC in SmBusAddress is set, then ASSERT().
477 If any reserved bits of SmBusAddress are set, then ASSERT().
479 @param SmBusAddress Address that encodes the SMBUS Slave Address,
480 SMBUS Command, SMBUS Data Length, and PEC.
482 @retval RETURN_SUCCESS The SMBUS command was executed.
483 @retval RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
484 @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected
485 in the Host Status Register bit.
486 Device errors are a result of a transaction collision, illegal command field,
487 unclaimed cycle (host initiated), or bus errors (collisions).
493 IN UINTN SmBusAddress
496 ASSERT (!SMBUS_LIB_PEC (SmBusAddress
));
497 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress
) == 0);
498 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
499 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
500 ASSERT (SMBUS_LIB_SLAVE_ADDRESS (SmBusAddress
) == 0);
502 return InternalSmBusArpDevice (SmBusAddress
, NULL
);
506 Assigns an SMBUS slave addresses.
508 Assigns the SMBUS device specified by Uuid the slave address specified by SmBusAddress.
509 The status of the executed command is returned.
510 If Command in SmBusAddress is not zero, then ASSERT().
511 If Length in SmBusAddress is not zero, then ASSERT().
512 If PEC in SmBusAddress is set, then ASSERT().
513 If any reserved bits of SmBusAddress are set, then ASSERT().
515 @param SmBusAddress Address that encodes the SMBUS Slave Address,
516 SMBUS Command, SMBUS Data Length, and PEC.
517 @param Uuid Pointer to the UUID of the device to assign a slave address.
519 @retval RETURN_SUCCESS The SMBUS command was executed.
520 @retval RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
521 @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected
522 in the Host Status Register bit.
523 Device errors are a result of a transaction collision, illegal command field,
524 unclaimed cycle (host initiated), or bus errors (collisions).
530 IN UINTN SmBusAddress
,
534 ASSERT (!SMBUS_LIB_PEC (SmBusAddress
));
535 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress
) == 0);
536 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
537 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
539 return InternalSmBusArpDevice (SmBusAddress
, Uuid
);
543 Retrieves the UUID associated with an SMBUS slave device.
545 Retrieves the UUID associated with the slave address specified
546 by SmBusAddress and returns the UUID in Uuid.
547 The status of the executed command is returned.
548 If Command in SmBusAddress is not zero, then ASSERT().
549 If Length in SmBusAddress is not zero, then ASSERT().
550 If PEC in SmBusAddress is set, then ASSERT().
551 If Uuid is NULL, then ASSERT().
552 If any reserved bits of SmBusAddress are set, then ASSERT().
554 @param SmBusAddress Address that encodes the SMBUS Slave Address,
555 SMBUS Command, SMBUS Data Length, and PEC.
556 @param Uuid Pointer to the UUID retrieved from the SMBUS slave device.
558 @retval RETURN_SUCCESS The SMBUS command was executed.
559 @retval RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
560 @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected
561 in the Host Status Register bit.
562 Device errors are a result of a transaction collision, illegal command field,
563 unclaimed cycle (host initiated), or bus errors (collisions).
569 IN UINTN SmBusAddress
,
574 EFI_SMBUS_DEVICE_MAP
*SmBusDeviceMap
;
575 RETURN_STATUS ReturnStatus
;
576 UINTN SmbusDeviceAddress
;
579 ASSERT (Uuid
!= NULL
);
580 ASSERT (!SMBUS_LIB_PEC (SmBusAddress
));
581 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress
) == 0);
582 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress
) == 0);
583 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress
) == 0);
585 ReturnStatus
= InternalGetArpMap (&Length
, &SmBusDeviceMap
);
586 if (!RETURN_ERROR (ReturnStatus
)) {
587 SmbusDeviceAddress
= SMBUS_LIB_SLAVE_ADDRESS (SmBusAddress
);
588 for (Index
= 0; Index
< Length
; Index
++) {
589 if (SmBusDeviceMap
[Index
].SmbusDeviceAddress
.SmbusDeviceAddress
== SmbusDeviceAddress
) {
590 CopyMem (Uuid
, &SmBusDeviceMap
[Index
].SmbusDeviceUdid
, sizeof (EFI_SMBUS_UDID
));