IT8613E,温度,电压,风扇,逻辑设备号,寄存器数据更改看门狗代码备份。
命令行输入分以下几种情况:
①mySIO.efi输出当前的温度,电压,风扇转速
②mySIO.efi Xd "X"表示逻辑设备号,输出LDN=X时的寄存器列表
③mySIO.efi W X,这里执行看门狗功能,X表示秒数,代码设定1-9秒
④mySIO.efi Xd offset value,执行LDN=x时,地址offset寄存器的值设置为value
⑤mySIO.efi G X,风扇调速,X表示档位,有0,1,2三个档位,0表示停止,有个bug,执行完毕会输出一个风扇转速值,这个值是更改前的值。
⑥mySIO.efi GP10 I/O N/Y H/L,其中GP10表示GPIO10,可更改,第二个表示输入模式还是输出模式,N/Y选择不反转/反转,H/L表示高/低电平.
mySIO.c
。
#include <Uefi.h>
#include <stdio.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/IoLib.h>
#include <Library/ShellLib.h>
#include <Library/ShellCEntryLib.h>
#include <Library/BaseLib/BaseLibInternals.h>
CHAR16 ListHeader[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
UINT8 hex_List[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
UINT8 Multiple_function[] = {0x25,0x26,0x27,0x28,0x29};
UINT8 I_O_Registers[6] = {0xC8,0xC9,0xCA,0xCB,0xCC,0xCD};
UINT8 Polarity_Registers[6] = {0xB0,0xB1,0xB2,0xB3,0xB4,0x00};
UINT8 Pull_UP_Registers[6] = {0xB8,0x00,0xBA,0xBB,0xBC,0xBD};
UINT8 Simple_Enable_Register[6] = {0xC0,0xC1,0xC2,0xC3,0xC4,0x00};
UINT8 setone[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//enter PNP mode
void EnterPnpMode(void)
{
IoWrite8(0x2E,0x87);
IoWrite8(0x2E,0x01);
IoWrite8(0x2E,0x55);
IoWrite8(0x2E,0x55);
}
void SelectLDN(UINT8 LDNnumber)
{
IoWrite8(0x2E,0x07);
IoWrite8(0x2F,LDNnumber);
}
void ExitPnpMode(void)
{
IoWrite8(0x2E,0x02);
IoWrite8(0x2F,0x02);
}
void ReadLdnRegister(void)
{
unsigned int row,col;
UINT8 addr = 0;
unsigned int value[16][16];
Print(L"-------------------------------------------------------\n");
for(row = 0;row < 16;row++)
{
Print(L"%x0 ",row);
// ShellPrintEx(0,row,L"%V%x0",row);
for(col = 0;col < 16;col++)
{
IoWrite8(0x2E,addr);
value[row][col] = IoRead8(0x2F);
if(value[row][col] < 16)
{
Print(L" 0%x",value[row][col]);
}
else
{
Print(L" %x",value[row][col]);
}
addr++;
}
Print(L"\n");
}
}
void WriteLdnRegister(UINT8 Offset,UINT8 Value)
{
IoWrite8(0x2E,Offset);
IoWrite8(0x2F,Value);
}
void PrintListHeader(void)
{
UINT8 Index = 0;
for(UINT8 Cow = 4;Cow < 48+4;Cow += 3)
{
ShellPrintEx(Cow,4,L"%V0");
ShellPrintEx(Cow+1,4,L"%V%c",ListHeader[Index]);
Index += 1;
}
Print(L"\n");
}
VOID SetGPIO(IN UINT8 GPIONumbr,IN UINT8 I_O_Mode,IN UINT8 InvertOrNot, IN UINT8 *H_L_Level)
{
UINT16 BaseAddress;
UINT16 addrMSB,addrLSB;
//UINT8 ReadLevel;
//multiple function
IoWrite8(0x2E,Multiple_function[GPIONumbr/10-1]);
IoWrite8(0x2F,IoRead8(0x2F) | setone[GPIONumbr%10]);//对应位置1
// IN OR OUT 输出时是否有反转
if (I_O_Mode == 0)//out
{
IoWrite8(0x2E,Polarity_Registers[GPIONumbr/10-1]);
if (InvertOrNot == 1)//fan zhuan
{
IoWrite8(0x2F,IoRead8(0x2F) | setone[GPIONumbr%10]);//对应位置1
}
else
{
IoWrite8(0x2F,IoRead8(0x2F) | hex_List[0]);//对应位置0
}
}
//排除G2X,G53上拉
if(GPIONumbr/10 != 2 || (GPIONumbr/10 != 5 && GPIONumbr%10 != 3))
{
IoWrite8(0x2E,Pull_UP_Registers[GPIONumbr/10-1]);
IoWrite8(0x2F,IoRead8(0x2F) | setone[GPIONumbr%10]);//对应位置1
}
//GP6X
if(GPIONumbr/10 != 6)
{
IoWrite8(0x2E,Simple_Enable_Register[GPIONumbr/10 -1]);
IoWrite8(0x2F,IoRead8(0x2F) | setone[GPIONumbr%10]);
}
IoWrite8(0X2E,0x62);
addrMSB = IoRead8(0x2F);
IoWrite8(0x2E,0x63);
addrLSB = IoRead8(0x2F);
BaseAddress = (addrMSB << 8) | addrLSB;
if (I_O_Mode == 0)
{
IoWrite8(0x2E,I_O_Registers[GPIONumbr/10-1]);
IoWrite8(0x2F,IoRead8(0x2F)|setone[GPIONumbr%10]);
if (*H_L_Level == 1)
{
//IoWrite16(0x2E,BaseAddress + (GPIONumbr/10 - 1));
IoWrite8(BaseAddress + (GPIONumbr/10 - 1),IoRead8(BaseAddress + (GPIONumbr/10 - 1)) | setone[GPIONumbr%10]);
}
else if(*H_L_Level == 0)
{
//IoWrite16(0x2E,BaseAddress + (GPIONumbr/10 - 1));
IoWrite8(BaseAddress + (GPIONumbr/10 - 1),IoRead8(BaseAddress + (GPIONumbr/10 - 1))&(0xff - setone[GPIONumbr%10]));
}
}
else if(I_O_Mode == 1)
{
//IoWrite8(0x2E,I_O_Registers[GPIONumbr/10-1]);
IoWrite8(0x2F,IoRead8(I_O_Registers[GPIONumbr/10-1]) & (0xff - setone[GPIONumbr%10]));
}
}
unsigned int GetEcBasedAddress()//temp
{
unsigned int addrMSB,addrLSB;
unsigned int baseaddr;
SelectLDN(hex_List[4]);
IoWrite8(0x2E,0x30);
IoWrite8(0x2F,0x01);
IoWrite8(0x2E,0x60);
addrMSB = IoRead8(0x2F);
IoWrite8(0x2E,0x61);
addrLSB = IoRead8(0x2F);
baseaddr = (addrMSB << 8 & 0xff00) | addrLSB;
return baseaddr;
}
unsigned int ReadEcSpace(UINT8 index)
{
unsigned int data,addr;
unsigned int Index_Port,Data_Port;
addr = GetEcBasedAddress();
//Print(L"GetEcBasedAddress Temp:%x\n",addr);
Index_Port = addr + 5;
Data_Port = addr + 6;
//bank0
IoWrite8(0x2E,0x06);
IoWrite8(0x2F,0x80);
IoWrite8(Index_Port,index);
data = IoRead8(Data_Port);
return data;
}
void ReadTemp()
{
unsigned int temp0,temp1;
temp0 = ReadEcSpace(0x29);
temp1 = ReadEcSpace(0x2A);
Print(L"temp0 CPU: %d\n",temp0);
Print(L"temp1: %d\n",temp1);
}
void ReadFan()
{
unsigned int fan;
unsigned int fanMSB,fanLSB;
fanMSB = ReadEcSpace(0x19);
fanLSB = ReadEcSpace(0x0E);
fan = (fanMSB << 8 & 0xff00)|fanLSB;
Print(L"fanMSB: %x or %d \n",fanMSB,fanMSB);
Print(L"fanLSB: %x or %d\n",fanLSB,fanLSB);
Print(L"fan:%x\n",fan);
Print(L"fan: %d\n",(135*10000)/(fan*2));
}
void FanGear( UINT8 gear)
{
unsigned int addr;
//Print(L"enter fan gear\n");
addr = GetEcBasedAddress();
//enable
IoWrite8(addr+0x05,0x13);
IoWrite8(addr+0x06,0x01 << 5);
//Print(L"enter fan gear enable\n");
//select software Operation
IoWrite8(addr+0x05,0x16);
IoWrite8(addr+0x06,0x00);
//Print(L"enter fan gear software\n");
//polarity
IoWrite8(addr+0x05,0x14);
IoWrite8(addr+0x06,0x01 << 7);
//Print(L"enter fan gear polarity\n");
//Print(L"%x\n",gear);
//gear PWM 0-255
if (gear == hex_List[0])
{
IoWrite8(addr+0x05,0x6B);
IoWrite8(addr+0x06,0x00);
Print(L"enter fan gear PWM 0\n");
}
else if(gear == hex_List[1])
{
IoWrite8(addr+0x05,0x6B);
IoWrite8(addr+0x06,0x80);
Print(L"enter fan gear PWM 128\n");
}
else if(gear == hex_List[2])
{
IoWrite8(addr+0x05,0x6B);
IoWrite8(addr+0x06,0xFF);
Print(L"enter fan gear PWM 255\n");
}
}
void ReadVoltage()
{
unsigned int voltage0,voltage1,voltage2;
unsigned int voltage01,voltage02;
unsigned int voltage11,voltage12;
unsigned int voltage21,voltage22;
voltage0 = ReadEcSpace(0x20);
voltage1 = ReadEcSpace(0x21);
voltage2 =ReadEcSpace(0x22);
voltage01 = voltage0*109/10000;
voltage02 = voltage0*109%10000;
voltage11 = voltage1*109/10000;
voltage12 = voltage1*109%10000;
voltage21 = voltage2*109/10000;
voltage22 = voltage2*109%10000;
Print(L"voltage0:%d.%d V\n",voltage01,voltage02);
Print(L"voltage1:%d.%d V\n",voltage11,voltage12);
Print(L"voltage2:%d.%d V\n",voltage21,voltage22);
}
void WatchDog(UINT8 sec)
{
EnterPnpMode();
Print(L"0x07");
SelectLDN(0x07);
//enable wdt IRQ
//IoWrite8(0x2E,0xF1);
//IoWrite8(0x2F,IoRead8(0x2F)|(0x01<<2));
//select clock
//IoWrite8(0x2E,0x23);
// IoWrite8(0x2F,IoRead8(0x2F)|(0x01<<4));
// Print(L"clock\n");
IoWrite8(0x2E,0x72);
//IoWrite8(0x2F,0x90);PWRGD
IoWrite8(0x2F,0xD0);//KST
//Print(L"configuration\n");
//Timer control
IoWrite8(0x2E,0x71);
IoWrite8(0x2F,0x08);//5s
//Print(L"Timer control\n");
//73 LSB
IoWrite8(0x2E,0x73);
IoWrite8(0x2F,hex_List[sec]);
//Print(L"LSB\n");
ExitPnpMode();
}
INTN ShellAppMain(IN UINTN Argc,IN CHAR16 **Argv)
{
UINT8 LDNnumber;
UINT8 Offset;
UINT8 Value;
UINT8 GPIONumbr;
UINT8 I_O_Mode;//1为in,0为out
UINT8 InvertOrNot;
UINT8 H_L_Level;
UINT8 gear;//fan
UINT8 sec;
switch(Argc)
{
case 1 :
//gST->ConOut->ClearScreen(gST->ConOut);
EnterPnpMode();
ReadTemp();
ReadVoltage();
ReadFan();
ExitPnpMode();
break;
case 2 :
if(*(Argv[1]+1) == 'D' || *(Argv[1]+1) == 'd')
{
LDNnumber = hex_List[InternalHexCharToUintn(*Argv[1])];
EnterPnpMode();
SelectLDN(LDNnumber);
gST->ConOut->ClearScreen(gST->ConOut);
PrintListHeader();
ReadLdnRegister();
ExitPnpMode();
}
else
{
Print(L"Please enter the correct parameter format!\n");
}
break;
case 3:
if (*(Argv[1]) == 'g' || *(Argv[1]) == 'G')
{
EnterPnpMode();
ReadTemp();//select LDN ,EC
gear = (UINT8)InternalHexCharToUintn(*Argv[2]);
//Print(L"main %x\n",gear);
FanGear(gear);
ReadVoltage();
ReadFan();
ExitPnpMode();
}
else if(*(Argv[1]) == 'W' || *(Argv[1]) == 'w')
{
Print(L"wdt\n");
sec = (UINT8)InternalHexCharToUintn(*Argv[2]);
WatchDog(sec);
}
break;
case 4 :
if(*(Argv[1]+1) == 'D' || *(Argv[1]+1) == 'd')
{
LDNnumber = hex_List[InternalHexCharToUintn(*Argv[1])];
Offset = hex_List[InternalHexCharToUintn(*Argv[2])]*16 + hex_List[InternalHexCharToUintn(*((Argv[2])+1))];
//The value to be written in
Value = hex_List[InternalHexCharToUintn(*Argv[3])]*16 + hex_List[InternalHexCharToUintn(*((Argv[3])+1))];
EnterPnpMode();
SelectLDN(LDNnumber);
WriteLdnRegister(Offset,Value);
gST->ConOut->ClearScreen(gST->ConOut);
PrintListHeader();
ReadLdnRegister();
ExitPnpMode();
}
else
{
Print(L"Please enter the correct parameter format!\n");
}
break;
case 5 :
if(*Argv[1] == 'G' || *Argv[1] == 'g')
{
GPIONumbr = hex_List[InternalHexCharToUintn(*(Argv[1]+2))*10 + InternalHexCharToUintn(*(Argv[1]+3))];
if (*Argv[2] == 'I' || *Argv[2] == 'i')
{
I_O_Mode = 1;
}
else if(*Argv[2] == 'O' || *Argv[2] == 'o')
{
I_O_Mode = 0;
}
if (*Argv[3] == 'Y' || *Argv[3] == 'y')
{
InvertOrNot = 1;
}
else if(*Argv[3] == 'N' || *Argv[3] == 'n')
{
InvertOrNot = 0;
}
if (*Argv[4] == 'H' || *Argv[4] == 'h')
{
H_L_Level = 1;
}
else if(*Argv[4] == 'L' || *Argv[4] == 'l')
{
H_L_Level = 0;
}
EnterPnpMode();
SelectLDN(0x07);
SetGPIO(GPIONumbr,I_O_Mode,InvertOrNot,&H_L_Level);
gST->ConOut->ClearScreen(gST->ConOut);
PrintListHeader();
ReadLdnRegister();
ExitPnpMode();
}
else
{
Print(L"Please enter the correct parameter format!\n");
}
break;
}
return 0;
}
mySIO.inf
。
// An highlighted block
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = mySIO
FILE_GUID = ED123456-1345-7890-AAAA-123321ABCABC
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = ShellCEntryLib
[Sources]
mySIO.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
StdLib/StdLib.dec
[LibraryClasses]
ShellCEntryLib
UefiBootServicesTableLib
UefiLib
IoLib
ShellLib