diff --git a/LoongArch/Makefile b/LoongArch/Makefile index f406eeb..a08b590 100644 --- a/LoongArch/Makefile +++ b/LoongArch/Makefile @@ -1,6 +1,6 @@ - -COMPILE_FILE_C = main.c gpio.c rtc.c acpi.c conf.c pci.c util.c spi.c mps.c i2c.c spd.c ht.c argparse.c process.c smbios.c -COMPILE_FILE_O = main.o gpio.o rtc.o acpi.o conf.o pci.o util.o spi.o mps.o i2c.o spd.o ht.o argparse.o process.o smbios.o +# SPDX-License-Identifier: GPL-2.0 +COMPILE_FILE_C = main.c gpio.c rtc.c acpi.c conf.c pci.c util.c spi.c mps.c i2c.c spd.c ht.c argparse.c process.c smbios.c temp.c avs.c +COMPILE_FILE_O = main.o gpio.o rtc.o acpi.o conf.o pci.o util.o spi.o mps.o i2c.o spd.o ht.o argparse.o process.o smbios.o temp.o avs.o #COMPILE_PATH = /opt/LoongArch_Toolchains/loongarch64-linux-gnu-2021-06-19-vector/bin/loongarch64-linux-gnu-gcc #COMPILE_PATH = /opt/LoongArch_Toolchains/loongarch64-linux-gnu-2021-06-19-vector/bin/loongarch64-linux-gnu-gcc diff --git a/LoongArch/acpi.c b/LoongArch/acpi.c index 94423ef..c5b6698 100644 --- a/LoongArch/acpi.c +++ b/LoongArch/acpi.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 + #include #include #include diff --git a/LoongArch/avs.c b/LoongArch/avs.c new file mode 100644 index 0000000..5361c90 --- /dev/null +++ b/LoongArch/avs.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "def.h" +#include "i2c.h" + +extern int is3d; +extern int is3c; + +//#define SPI_CONFUSE_SPACE (0x0efdfe000000 + 0x8000/*Need 4K align*/ ) //b000 is Spi,so add 0x3000 + +//3D5000 +#define CPU_3C5000_NODE0_I2C0 0x1fe00160 +#define CPU_3C5000_NODE1_I2C0 0x10001fe00160ULL +#define CPU_3C5000_NODE2_I2C0 0x20001fe00160ULL +#define CPU_3C5000_NODE3_I2C0 0x30001fe00160ULL + +#define Write64(addr, data) (*(volatile UINT64*)(addr) = (data)) +#define Write32(addr, data) (*(volatile UINT32*)(addr) = (data)) +#define Write16(addr, data) (*(volatile UINT16*)(addr) = (data)) +#define Writel(addr, data) (*(volatile UINT32*)(addr) = (data)) +#define Writew(addr, data) (*(volatile UINT16*)(addr) = (data)) +#define Writeb(addr, data) (*(volatile UINT8*)(addr) = (data)) +#define Read64(addr) (*(volatile UINT64*)(addr)) +#define Read32(addr) (*(volatile UINT32*)(addr)) +#define Read16(addr) (*(volatile UINT16*)(addr)) +#define Readl(addr) (*(volatile UINT32*)(addr)) +#define Readw(addr) (*(volatile UINT16*)(addr)) +#define Readb(addr) (*(volatile UINT8*)(addr)) + + +UINTN AvsRegBaseAddr; + +static const char *const avs_usages[] = { + PROGRAM_NAME" avs ", + NULL, +}; + +unsigned long long devaddr_3c5000_avs[4] = { + CPU_3C5000_NODE0_I2C0, + CPU_3C5000_NODE1_I2C0, + CPU_3C5000_NODE2_I2C0, + CPU_3C5000_NODE3_I2C0 +}; + +#define AVS_BASE AvsRegBaseAddr +#define AVS_CSR AVS_BASE +#define AVS_MREG AVS_BASE + 0x4 +#define AVS_SREG AVS_BASE + 0x8 + +/* p: 1 n: 0*/ +VOID +AvsSetVol(int rail_sel, int vol, int rx_delay, int clk_div) +{ + if ((vol < 600) || (vol > 1300)) { + printf("\r\nAVS: Set vol range error!!!\r\n"); + return; + } + + Writel(AVS_CSR, 0x10000 | (clk_div << 17) | (0x7 << 25) | (rx_delay << 20)); + Writel(AVS_MREG, 0x80000000 | (vol << 4) | (rail_sel << 20)); + + while(Readl(AVS_SREG) & 0x80000000); + + if((Readl(AVS_SREG) & 0x60000000)) { + printf("set avs_vol erro!\n"); + } +} + +/* p: 1 n: 0*/ +UINTN +AvsGetVol(int rail_sel, int rx_delay, int clk_div) +{ + Writel(AVS_CSR, 0x10000 | (clk_div << 17) | (0x7 << 25) | (rx_delay << 20)); + Writel(AVS_MREG, 0xe0000000 | (rail_sel << 20)); + + while(Readl(AVS_SREG) & 0x80000000); + + if((Readl(AVS_SREG) & 0x60000000)) + return 0; + else + return (Readl(AVS_SREG) & 0xffff); +} + +/* p: 1 n: 0*/ +VOID +AvsVolPrint() +{ + UINT32 Val; + Val = AvsGetVol(0, 0, 4); + if (!Val) { + printf("AVS: Get Vddn error!\n"); + } else { + printf("AVS: Get Vddn value is: %d \n",Val); + } + Val = AvsGetVol(1, 0, 4); + if (!Val) { + printf("AVS: Get Vddp error!\n"); + } else { + printf("AVS: Get Vddp value is: %d \n",Val); + } +} + +int avs_read (int id) +{ + void * p = NULL; + int status ; + char RecordName[30] = {0}; + int c = 0; + char str[30] = {0}; + int fd; + + fd = open ("/dev/mem", O_RDWR | O_SYNC); + if (fd < 0) { + printf("can't open file,please use root .\n"); + return 1; + } + + p = vtpa(devaddr_3c5000_avs[id], fd); + + UINT64 NodeId; + UINT16 Val16; + + AvsRegBaseAddr = (UINT64) p; + + AvsVolPrint(); + + close(fd); + + return status; +} + +int avs_write_vdd (int id, int vol, int channel) +{ + void * p = NULL; + int status ; + char RecordName[30] = {0}; + int c = 0; + char str[30] = {0}; + int fd; + + fd = open ("/dev/mem", O_RDWR | O_SYNC); + if (fd < 0) { + printf("can't open file,please use root .\n"); + return 1; + } + + p = vtpa(devaddr_3c5000_avs[id], fd); + + UINT64 NodeId; + UINT32 Val16; + + AvsRegBaseAddr = (UINT64) p; + + AvsSetVol(channel, vol, 0, 4); + + close (fd); + return 0; +} + +int cmd_avs (int argc, const char **argv) +{ + int read = 0; + int write = 0; + int id = 0; + int vol = 0; + int channel = 0; + uid_t uid; + struct argparse argparse; + + struct argparse_option options[] = { + OPT_HELP(), + OPT_BOOLEAN ('r', "read", &read, "read avs", NULL, 0, 0), + OPT_BOOLEAN ('w', "write", &write, "write avs", NULL, 0, 0), + OPT_INTEGER ('i', "id", &id, "avs id(0-3)", NULL, 0, 0), + OPT_INTEGER ('d', "vol", &vol, "vol(800-1200)", NULL, 0, 0), + OPT_INTEGER ('c', "channel", &channel, "channel(0-1)", NULL, 0, 0), + OPT_END(), + }; + + argparse_init(&argparse, options, avs_usages, 0); + argc = argparse_parse(&argparse, argc, argv); + + if (!(read || write)) { + argparse_usage(&argparse); + return 1; + } + + uid = geteuid (); + if (uid != 0) { + printf("Please run with root!\n"); + return -1; + } + + if (read) { + if (id > 3) { + printf("id is 0~3\n"); + return -1; + } + avs_read (id); + } else if (write) { + if (id > 3) { + printf("id is 0~3\n"); + return -1; + } + if ((vol < 800) || (vol > 1200)) { + printf("vol is 800~1200\n"); + return -1; + } + avs_write_vdd (id,vol,channel); + } + return 0; +} diff --git a/LoongArch/conf.c b/LoongArch/conf.c index 24365ce..284496f 100644 --- a/LoongArch/conf.c +++ b/LoongArch/conf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/LoongArch/def.h b/LoongArch/def.h index 51b81d8..a482121 100644 --- a/LoongArch/def.h +++ b/LoongArch/def.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef __DEF_H_ #define __DEF_H_ #include "argparse.h" @@ -9,7 +10,7 @@ #endif #define PROGRAM_NAME "OsTools" -#define PROGRAM_VERSION "1.2" +#define PROGRAM_VERSION "1.3" #define LS7A_CONF_BASE_ADDR 0x10010000 #define LS7A_MISC_BASE_ADDR 0x10080000 @@ -45,5 +46,7 @@ int cmd_pci (int argc, const char **argv); int cmd_rtc (int argc, const char **argv); int cmd_spd (int argc, const char **argv); int cmd_spi (int argc, const char **argv); +int cmd_temp (int argc, const char **argv); +int cmd_avs (int argc, const char **argv); #endif diff --git a/LoongArch/file.h b/LoongArch/file.h index c3a597a..10f3e22 100644 --- a/LoongArch/file.h +++ b/LoongArch/file.h @@ -1,4 +1,4 @@ - +// SPDX-License-Identifier: GPL-2.0 #ifndef _FILE_H_ #define _FILE_H_ diff --git a/LoongArch/gpio.c b/LoongArch/gpio.c index 4b8e471..36d498a 100644 --- a/LoongArch/gpio.c +++ b/LoongArch/gpio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/LoongArch/ht.c b/LoongArch/ht.c index 4d73a91..b7bf76a 100644 --- a/LoongArch/ht.c +++ b/LoongArch/ht.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/LoongArch/main.c b/LoongArch/main.c index 48122f0..800a75b 100644 --- a/LoongArch/main.c +++ b/LoongArch/main.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -32,6 +33,8 @@ static struct cmd_struct commands[] = { {"ht", cmd_ht}, {"mps", cmd_mps}, {"spd", cmd_spd}, + {"temp", cmd_temp}, + {"avs", cmd_avs}, }; int main (int argc, const char *argv[]) diff --git a/LoongArch/mps.c b/LoongArch/mps.c index 8c812bc..b3582ce 100644 --- a/LoongArch/mps.c +++ b/LoongArch/mps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/LoongArch/pci.c b/LoongArch/pci.c index 0cec09e..82b87b4 100644 --- a/LoongArch/pci.c +++ b/LoongArch/pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/LoongArch/process.c b/LoongArch/process.c index d5fd049..d7e09cc 100644 --- a/LoongArch/process.c +++ b/LoongArch/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/LoongArch/process.h b/LoongArch/process.h index bef8d62..e3ba7c8 100644 --- a/LoongArch/process.h +++ b/LoongArch/process.h @@ -1,4 +1,4 @@ - +// SPDX-License-Identifier: GPL-2.0 #ifndef _PROCESS_H_ #define _PROCESS_H_ diff --git a/LoongArch/rtc.c b/LoongArch/rtc.c index 47bbef4..6f8f842 100644 --- a/LoongArch/rtc.c +++ b/LoongArch/rtc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/LoongArch/smbios.c b/LoongArch/smbios.c index bc61e01..3038b9e 100644 --- a/LoongArch/smbios.c +++ b/LoongArch/smbios.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -63,7 +64,7 @@ VOID SpiFlashSafeWrite ( UINTN Num ); -int spi_update_smbios() +int spi_update_smbios(const char *addr) { void * p = NULL; unsigned long long devaddr; @@ -85,7 +86,14 @@ int spi_update_smbios() Index = 0; smbiosheader = NULL; - devaddr = 0x1fe001f0; + if(addr != NULL){ + sscanf (addr,"%lx", &devaddr); + devaddr &= 0xfffffffffffffff0ULL; + offset = 0x41000; //7A flash smbiosheader offset + nameoffset = 0x52000; //7A flash nameheader offset + } else { + devaddr = 0x1fe001f0; + } int fd = open ("/dev/mem", O_RDWR|O_SYNC); if(fd < 0) { diff --git a/LoongArch/spd.c b/LoongArch/spd.c index 4de3f6e..1dfde59 100644 --- a/LoongArch/spd.c +++ b/LoongArch/spd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/LoongArch/spi.c b/LoongArch/spi.c index 018fd99..d9aa504 100644 --- a/LoongArch/spi.c +++ b/LoongArch/spi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -7,12 +8,14 @@ #include "def.h" #include "file.h" #include "process.h" +#include #define readw(addr) (*(volatile unsigned int *)(addr)) //#define SPI_ADDR 0x1fe001f0 #define SPI_ADDR 0 //Get at runtime -#define FLASH_SIZE 0x800000 +unsigned int Size = 0; +#define FLASH_SIZE (Size ? Size : 0x800000/*default 8M*/) #define GPIO_0 (0x1<<0) #define GPIO_1 (0x1<<1) @@ -164,6 +167,7 @@ Fopen_File ( Str[i] = Ch; i++; } + fclose(fp); // printf("Cpu_Tame:%s", Str); // printf("Cpu_Type0:%s", Cpu_Type[0]); } @@ -851,6 +855,7 @@ static int spi_update_flash (const char *path) void *p = NULL; int status ; unsigned long long devaddr; + struct stat statbuf; devaddr = 0x1fe001f0; @@ -860,6 +865,19 @@ static int spi_update_flash (const char *path) return 1; } + // get file size + if (stat (path, &statbuf) == 0) { + printf ("The file size %s is %#lx bytes.\n", path, statbuf.st_size); + if (Size != 0) { + printf ("specify Flush Size %#lx .\n",Size); + } else { + Size = (statbuf.st_size + 4*1024 - 1) & ~(4*1024 - 1); + printf ("Assign file Size: %lx for one section(4K): .\n",Size); + } + } else { + printf ("Failed to get file status.\n"); + } + /*Transfer Virtul to Phy Addr*/ p = vtpa(devaddr, fd); SPI_REG_BASE = (UINTN)p; @@ -871,6 +889,7 @@ static int spi_update_flash (const char *path) printf("Read File Error , PATH error!!!\n"); return 1; } + fread(buf, FLASH_SIZE, 1, pfile); printf("------------Read Buf Get Success!-----------\n"); @@ -881,13 +900,17 @@ static int spi_update_flash (const char *path) return status; } -static int spi_dump_flash (const char *path) +static int spi_dump_flash (const char *path, const char *addr) { void *p = NULL; int status ; unsigned long long devaddr; - devaddr = 0x1fe001f0; + if (addr != NULL) { + sscanf (addr,"%lx", &devaddr); + } else { + devaddr = 0x1fe001f0; + } int fd = open ("/dev/mem", O_RDWR |O_SYNC); if(fd < 0) { @@ -908,7 +931,7 @@ static int spi_dump_flash (const char *path) return 1; } - fwrite (buf, 1, 4128768, pfile); + fwrite (buf, 1, FLASH_SIZE, pfile); fflush (pfile); fclose (pfile); free (buf); @@ -950,7 +973,7 @@ static int spi_read_flash (const char* addr, int count) return status; } -int spi_update_smbios(); +int spi_update_smbios(const char *addr); static const char *const spi_usages[] = { PROGRAM_NAME" spi ", @@ -988,6 +1011,7 @@ int cmd_spi (int argc, const char **argv) OPT_INTEGER ('i', "id", &id, "Mac id", NULL, 0, 0), OPT_STRING ('m', "mac", &mac, "Mac address(e.g. 00:11:22:33:44:55)", NULL, 0, 0), OPT_INTEGER ('c', "count", &count, "read count", NULL, 0, 0), + OPT_INTEGER ('S', "Size", &Size, "Flush Size", NULL, 0, 0), OPT_END (), }; @@ -1014,8 +1038,8 @@ int cmd_spi (int argc, const char **argv) char *Path="./"FILE_NAME_1; char Cpu_Name[100]; Fopen_File(Path, Cpu_Name); - is3c = !strncmp("Loongson-3C5000", Cpu_Name, 15); - is3d = !strncmp("Loongson-3D5000", Cpu_Name, 15); + is3c = !!strstr(Cpu_Name, "3C5000"); + is3d = !!strstr(Cpu_Name, "3D5000"); spi_update_flash (file); } else if (flag_dump) { @@ -1023,7 +1047,7 @@ int cmd_spi (int argc, const char **argv) printf ("Please setup the file.\n"); return 1; } - spi_dump_flash (file); + spi_dump_flash (file, addr); } else if (flag_read) { if (addr == NULL) { printf ("Please setup the address.\n"); @@ -1047,7 +1071,7 @@ int cmd_spi (int argc, const char **argv) } spi_update_gmac(addr, id, mac); } else if (flag_smbios) { - spi_update_smbios(); + spi_update_smbios(addr); } return 0; diff --git a/LoongArch/temp.c b/LoongArch/temp.c new file mode 100644 index 0000000..3446f05 --- /dev/null +++ b/LoongArch/temp.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "def.h" + +#define CHIPSET0_TEMP 0xe0010000414ULL + +static const char *const temp_usages[] = { + PROGRAM_NAME" temp ", + NULL, +}; + +int chipset_temp_read (void) +{ + void * p = NULL; + int status ; + unsigned long long devaddr; + + int fd = open ("/dev/mem", O_RDWR | O_SYNC); + if (fd < 0) { + printf("can't open file,please use root .\n"); + return 1; + } + + devaddr = CHIPSET0_TEMP; + + /*Transfer Virtul to Phy Addr*/ + p = vtpa (devaddr, fd); + + /*Debug Rtc*/ + printf("Chipset Temp Read Start ...\n"); + unsigned int tmp_tmp = 0; + + tmp_tmp = *(volatile unsigned int *)p; + printf ("Chipset0 Current Temp Val:%d \n", (tmp_tmp & 0xffff0000) >> 24); + + status = releaseMem(p); + close(fd); + return status; +} + +int cmd_temp (int argc, const char **argv) +{ + int read = 0; + int write = 0; + uid_t uid; + struct argparse argparse; + + struct argparse_option options[] = { + OPT_HELP(), + OPT_BOOLEAN ('r', "read", &read, "read Temp", NULL, 0, 0), + OPT_BOOLEAN ('w', "write", &write, "write No", NULL, 0, 0), + OPT_END(), + }; + + argparse_init(&argparse, options, temp_usages, 0); + argc = argparse_parse(&argparse, argc, argv); + + if (!(read || write)) { + argparse_usage(&argparse); + return 1; + } + + uid = geteuid (); + if (uid != 0) { + printf("Please run with root!\n"); + return -1; + } + + if (read) { + chipset_temp_read (); + } else if (write) { + //rtc_write (); + } + return 0; +} diff --git a/LoongArch/util.c b/LoongArch/util.c index 30fd86c..b79c1c1 100644 --- a/LoongArch/util.c +++ b/LoongArch/util.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/build.sh b/build.sh index feca3be..16dab03 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 #!/bin/bash make -C LoongArch clean