0

Below is the code to initializing the IO device, and I wanna to call a function to do CMOS read/write, but I don't know the DevicePath and Protocol? Does anyone know this? thanks a lot;

    /*
    
    Routine Description:
    
        Check to see if DevicePath exists for a given Protocol. Return Error if it
        exists. Return GlobalIoFuncs set match the DevicePath
    
      Arguments:
    
        DevicePath      - to operate on
        Protocol        - to check the DevicePath against
        ErrorStr        - ASCII string to display on error
        GlobalIoFncs    - Returned with DeviceIoProtocol for the DevicePath
    
    Returns:
    
        Pass or Fail based on  wether GlobalIoFncs where found
    
    */
EFI_STATUS 
InitializeGlobalIoDevice (
            IN  EFI_DEVICE_PATH             *DevicePath,
            IN  EFI_GUID                    *Protocol,
            IN  CHAR8                       *ErrorStr EFI_UNUSED,
            OUT EFI_DEVICE_IO_INTERFACE     **GlobalIoFncs
            )
    {
        EFI_STATUS      Status;
        EFI_HANDLE      Handle;
    
        //
        // Check to see if this device path already has Protocol on it.
        //  if so we are loading recursivly and should exit with an error
        //
        Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &DevicePath, &Handle);
        if (!EFI_ERROR(Status)) {
            DEBUG ((D_INIT, "Device Already Loaded for %a device\n", ErrorStr));
            return EFI_LOAD_ERROR;
        }
    
        Status = uefi_call_wrapper(BS->LocateDevicePath, 3, &DeviceIoProtocol, &DevicePath, &Handle);
        if (!EFI_ERROR(Status)) {
            Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DeviceIoProtocol, (VOID*)GlobalIoFncs);
        }
    
        ASSERT (!EFI_ERROR(Status));
        return Status;
    }

Need your help....

Tody Kwok
  • 185
  • 2
  • 12

1 Answers1

1

In UEFI spec, there is no Protocol or Device Path defined for CMOS.

If you'd like to read/write the CMOS RTC, there are GetTime() and SetTime() APIs defined in Runtime Services. They can be directly called from RT in gnu-efi.

If you want to read/write other CMOS registers, simply access I/O port 0x70/0x71 with inb/outb instruction with inline assembly in C. That's also how EDK2 accesses CMOS.

https://github.com/tianocore/edk2/blob/master/OvmfPkg/Library/PlatformInitLib/Cmos.c https://github.com/tianocore/edk2/blob/master/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c

KagurazakaKotori
  • 562
  • 4
  • 14