66#include <unistd.h>
77#include <string.h>
88#include <ctype.h>
9+ #include <stdbool.h>
910
1011#include "crc.h"
1112#include "gpio_defines.h"
1213#include "config_definition.h"
1314#define C_TO_K (temp_c ) ((temp_c) + 273)
1415
16+ static bool verbose = false;
17+
1518enum power_state {
1619 /* Steady states */
1720 POWER_G3 = 0 , /*
@@ -213,71 +216,194 @@ static struct default_ssd_cfg ssd_cfg = {
213216 .gpu_3v_5v_en = {.gpio = GPU_3V_5V_EN , .function = GPIO_FUNC_HIGH , .flags = GPIO_OUTPUT_LOW , .power_domain = POWER_S5 },
214217};
215218
216- void dump_descriptor (struct gpu_cfg_descriptor * desc )
219+ void print_descriptor (struct gpu_cfg_descriptor * desc )
217220{
218221
219- // Just for debugging
220- // printf("Descriptor\n");
221- // printf(" Magic %02X%02X%02X%02X\n", (uint8_t)desc->magic[0], (uint8_t)desc->magic[1], (uint8_t)desc->magic[2], (uint8_t)desc->magic[3]);
222- // printf(" Length: %d\n", desc->length);
223- // printf(" Desc Length: %d\n", desc->descriptor_length);
224- // printf(" Desc CRC32: %08X\n", desc->descriptor_crc32);
225- // printf(" CRC32: %08X\n", desc->crc32);
226- // printf(" Desc Version: %d.%d\n", desc->descriptor_version_major, desc->descriptor_version_minor);
227- // printf(" HW Version: %04X\n", desc->hardware_version);
228- // printf(" HW Rev: %d\n", desc->hardware_revision);
229- // printf(" Serialnum: %s\n", desc->serial);
230-
231- printf ("Serialnum: %s\n" , desc -> serial );
222+ if (verbose ) {
223+ printf ("Descriptor\n" );
224+ printf (" Magic %02X%02X%02X%02X\n" , (uint8_t )desc -> magic [0 ], (uint8_t )desc -> magic [1 ], (uint8_t )desc -> magic [2 ], (uint8_t )desc -> magic [3 ]);
225+ printf (" Length: %d\n" , desc -> length );
226+ printf (" Desc Version: %d.%d\n" , desc -> descriptor_version_major , desc -> descriptor_version_minor );
227+ printf (" HW Version: %04X\n" , desc -> hardware_version );
228+ printf (" HW Rev: %d\n" , desc -> hardware_revision );
229+ printf (" Serialnum: %s\n" , desc -> serial );
230+ printf (" Desc Length: %d\n" , desc -> descriptor_length );
231+ printf (" Desc CRC32: %08X\n" , desc -> descriptor_crc32 );
232+ printf (" CRC32: %08X\n" , desc -> crc32 );
233+ } else {
234+ printf ("Serialnum: %s\n" , desc -> serial );
235+ }
232236}
233237
234- void dump_gpu (struct default_gpu_cfg * gpu_cfg )
238+ void print_subsys (struct gpu_subsys_serial * subsys )
235239{
236- printf ("Type: GPU\n " );
237- switch (gpu_cfg -> pcba_serial . gpu_subsys ) {
240+ printf (" Type: " );
241+ switch (subsys -> gpu_subsys ) {
238242 case GPU_PCB :
239- printf ("PCBA Serial: %s \n" , gpu_cfg -> pcba_serial . serial );
243+ printf ("PCB \n" );
240244 break ;
241245 case GPU_LEFT_FAN :
242- printf ("Left Fan SN: %s \n" , gpu_cfg -> pcba_serial . serial );
246+ printf ("Left Fan\n" );
243247 break ;
244248 case GPU_RIGHT_FAN :
245- printf ("Right Fan SN: %s \n" , gpu_cfg -> pcba_serial . serial );
249+ printf ("Right Fan\n" );
246250 break ;
247251 case GPU_HOUSING :
248- printf ("Housing SN: %s \n" , gpu_cfg -> pcba_serial . serial );
252+ printf ("Housing\n" );
249253 break ;
250254 default :
251- printf ("??? Serial: %s \n" , gpu_cfg -> pcba_serial . serial );
255+ printf ("???\n" );
252256 break ;
253257 }
258+ printf (" Serial: %s\n" , subsys -> serial );
254259}
255260
256- void dump_ssd (struct default_ssd_cfg * ssd_cfg )
257- {
258- printf ("Type: SSD\n" );
261+ void print_vendor (enum gpu_vendor vendor ) {
262+ switch (vendor ) {
263+ case GPU_VENDOR_INITIALIZING :
264+ printf ("Vendor Initializing\n" );
265+ break ;
266+ case GPU_FAN_ONLY :
267+ printf ("Fan Only\n" );
268+ break ;
269+ case GPU_AMD_R23M :
270+ printf ("AMD R23M GPU\n" );
271+ break ;
272+ case GPU_SSD :
273+ printf ("SSD\n" );
274+ break ;
275+ case GPU_PCIE_ACCESSORY :
276+ printf ("PCI-E Accessory\n" );
277+ break ;
278+ default :
279+ printf ("Invalid (%d)\n" , vendor );
280+ break ;
281+ }
259282}
260283
284+
261285void read_eeprom (const char * infilename )
262286{
263287 FILE * fptr ;
264288 fptr = fopen (infilename ,"rb" );
265- // TODO: gpu_cfg is bigger than ssd_cfg, that's why I read it into there.
266- // Should make it safer so that if we change the structures, the same still holds.
267- fread ((void * )& gpu_cfg , sizeof (gpu_cfg ), 1 , fptr );
289+
290+ struct gpu_cfg_descriptor descriptor ;
291+ fread ((void * )& descriptor , sizeof (descriptor ), 1 , fptr );
292+
293+ print_descriptor (& descriptor );
294+
295+ void * blocks = malloc (descriptor .descriptor_length );
296+ if (!blocks ) {
297+ fclose (fptr );
298+ return ;
299+ }
300+ fread (blocks , descriptor .descriptor_length , 1 , fptr );
268301 fclose (fptr );
269302
270- uint32_t len = gpu_cfg .descriptor .descriptor_length + sizeof (struct gpu_cfg_descriptor );
271- // TODO: Length comparison won't work if newer versions of the descriptors have different sizes
272- if (len == sizeof (struct default_gpu_cfg )) {
273- dump_descriptor ((struct gpu_cfg_descriptor * )& gpu_cfg );
274- dump_gpu ((struct default_gpu_cfg * ) & gpu_cfg );
275- } else if (len == sizeof (struct default_ssd_cfg )) {
276- dump_descriptor ((struct gpu_cfg_descriptor * )& gpu_cfg );
277- dump_ssd ((struct default_ssd_cfg * ) & gpu_cfg );
278- } else {
279- printf ("Invalid descriptor. No body found (Len %d)\n" , len );
303+ int offset = 0 ;
304+ int n = 0 ;
305+ struct gpu_block_header * block_header ;
306+ while (offset < descriptor .descriptor_length ) {
307+ block_header = (struct gpu_block_header * )(blocks + offset );
308+ void * block_body = blocks + offset + sizeof (struct gpu_block_header );
309+
310+ if (verbose ) {
311+ uint8_t * pcie ;
312+ struct gpu_cfg_fan * fan ;
313+ printf ("Block %d\n" , n );
314+ printf (" Length: %d\n" , block_header -> block_length );
315+ printf (" Type: " );
316+ switch (block_header -> block_type ) {
317+ case GPUCFG_TYPE_UNINITIALIZED :
318+ printf ("Uninitialized\n" );
319+ break ;
320+ case GPUCFG_TYPE_GPIO :
321+ printf ("GPIO\n" );
322+ break ;
323+ case GPUCFG_TYPE_THERMAL_SENSOR :
324+ printf ("Thermal Sensor\n" );
325+ break ;
326+ case GPUCFG_TYPE_FAN :
327+ fan = block_body ;
328+ printf ("Fan\n" );
329+ printf (" ID: %d\n" , fan -> idx );
330+ printf (" Flags: %d\n" , fan -> flags );
331+ printf (" Min RPM: %d\n" , fan -> min_rpm );
332+ printf (" Min Temp: %d\n" , fan -> min_temp );
333+ printf (" Start RPM: %d\n" , fan -> start_rpm );
334+ printf (" Max RPM: %d\n" , fan -> max_rpm );
335+ printf (" Max Temp: %d\n" , fan -> max_temp );
336+ break ;
337+ case GPUCFG_TYPE_POWER :
338+ printf ("Power\n" );
339+ break ;
340+ case GPUCFG_TYPE_BATTERY :
341+ printf ("Battery\n" );
342+ break ;
343+ case GPUCFG_TYPE_PCIE :
344+ printf ("PCI-E\n" );
345+ pcie = block_body ;
346+ switch (* pcie ) {
347+ case PCIE_8X1 :
348+ printf (" Lanes: 8X1\n" );
349+ break ;
350+ case PCIE_4X1 :
351+ printf (" Lanes: 4X1\n" );
352+ break ;
353+ case PCIE_4X2 :
354+ printf (" Lanes: 4X2\n" );
355+ break ;
356+ default :
357+ printf (" Invalid (%d)\n" , * pcie );
358+ break ;
359+ }
360+ break ;
361+ case GPUCFG_TYPE_DPMUX :
362+ printf ("DP-MUX\n" );
363+ break ;
364+ case GPUCFG_TYPE_POWEREN :
365+ printf ("POWER-EN\n" );
366+ break ;
367+ case GPUCFG_TYPE_SUBSYS :
368+ printf ("Subsystem\n" );
369+ print_subsys ((struct gpu_subsys_serial * )block_body );
370+ break ;
371+ case GPUCFG_TYPE_VENDOR :
372+ printf ("Vendor\n" );
373+ printf (" Value: " );
374+ print_vendor (* (enum gpu_vendor * ) block_body );
375+ break ;
376+ case GPUCFG_TYPE_PD :
377+ printf ("PD\n" );
378+ break ;
379+ case GPUCFG_TYPE_GPUPWR :
380+ printf ("GPU Power\n" );
381+ break ;
382+ case GPUCFG_TYPE_CUSTOM_TEMP :
383+ printf ("Custom Temp\n" );
384+ break ;
385+ default :
386+ printf ("Unknown\n" );
387+ break ;
388+ }
389+ } else {
390+ if (block_header -> block_type == GPUCFG_TYPE_SUBSYS ) {
391+ struct gpu_subsys_serial * subsys = block_body ;
392+ if (subsys -> gpu_subsys == GPU_PCB ) {
393+ printf ("PCBA Serial: %s\n" , subsys -> serial );
394+ }
395+ }
396+ if (block_header -> block_type == GPUCFG_TYPE_VENDOR ) {
397+ printf ("Type: " );
398+ print_vendor (* (enum gpu_vendor * ) block_body );
399+ }
400+ }
401+
402+ offset += sizeof (struct gpu_block_header ) + block_header -> block_length ;
403+ n ++ ;
280404 }
405+
406+ free (blocks );
281407}
282408
283409void program_eeprom (const char * serial , struct gpu_cfg_descriptor * descriptor , size_t len , const char * outpath )
@@ -305,7 +431,7 @@ void program_eeprom(const char * serial, struct gpu_cfg_descriptor * descriptor,
305431}
306432
307433int main (int argc , char * argv []) {
308- int gpuflag = 0 ;
434+ int gpuflag = 0 ;
309435 int ssdflag = 0 ;
310436 char * serialvalue = NULL ;
311437 char * pcbvalue = NULL ;
@@ -315,7 +441,7 @@ int main(int argc, char *argv[]) {
315441
316442 opterr = 0 ;
317443
318- while ((c = getopt (argc , argv , "gds :p:o:i:" )) != -1 )
444+ while ((c = getopt (argc , argv , "gdvs :p:o:i:" )) != -1 )
319445 switch (c )
320446 {
321447 case 'g' :
@@ -336,6 +462,9 @@ int main(int argc, char *argv[]) {
336462 case 'i' :
337463 infilename = optarg ;
338464 break ;
465+ case 'v' :
466+ verbose = true;
467+ break ;
339468 case '?' :
340469 if (optopt == 'c' )
341470 fprintf (stderr , "Option -%c requires an argument.\n" , optopt );
@@ -359,7 +488,7 @@ int main(int argc, char *argv[]) {
359488 printf ("Descriptor Version: %d %d\n" , 0 , 1 );
360489
361490 printf ("gpu = %d, ssd = %d, module SN = %s pcb SN = %s output file = %s\n" ,
362- gpuflag , ssdflag , serialvalue , pcbvalue , outfilename , infilename );
491+ gpuflag , ssdflag , serialvalue , pcbvalue , outfilename );
363492
364493 if (gpuflag ) {
365494 if (pcbvalue ) {
0 commit comments