@@ -224,6 +224,7 @@ pub struct Cli {
224224 pub flash_gpu_descriptor : Option < ( u8 , String ) > ,
225225 pub flash_gpu_descriptor_file : Option < String > ,
226226 pub dump_gpu_descriptor_file : Option < String > ,
227+ pub nvidia : bool ,
227228 // UEFI only
228229 pub allupdate : bool ,
229230 pub paginate : bool ,
@@ -309,6 +310,7 @@ pub fn parse(args: &[String]) -> Cli {
309310 info : cli. info ,
310311 // flash_gpu_descriptor
311312 // flash_gpu_descriptor_file
313+ nvidia : cli. nvidia ,
312314 // allupdate
313315 paginate : cli. paginate ,
314316 // raw_command
@@ -775,6 +777,7 @@ fn print_versions(ec: &CrosEc) {
775777 print_nvidia_details ( ) ;
776778}
777779
780+ /// Brief NVIDIA details for --version output
778781#[ cfg( feature = "nvidia" ) ]
779782fn print_nvidia_details ( ) {
780783 let nvml = match Nvml :: init ( ) {
@@ -784,7 +787,6 @@ fn print_nvidia_details() {
784787 return ;
785788 }
786789 } ;
787- // Get the first `Device` (GPU) in the system
788790 let device = match nvml. device_by_index ( 0 ) {
789791 Ok ( device) => device,
790792 Err ( err) => {
@@ -795,55 +797,191 @@ fn print_nvidia_details() {
795797
796798 println ! ( "NVIDIA GPU" ) ;
797799 println ! (
798- " Name: {}" ,
800+ " Name: {}" ,
799801 device. name( ) . unwrap_or( "Unknown" . to_string( ) )
800802 ) ;
801- println ! ( " Architecture: {:?}" , device. architecture( ) ) ;
802803 println ! (
803- " VBIOS Version: {}" ,
804+ " VBIOS Version: {}" ,
804805 device. vbios_version( ) . unwrap_or( "Unknown" . to_string( ) )
805806 ) ;
807+ }
808+
809+ /// Detailed NVIDIA information for --nvidia command
810+ #[ cfg( feature = "nvidia" ) ]
811+ fn print_nvidia_info ( ) {
812+ let nvml = match Nvml :: init ( ) {
813+ Ok ( nvml) => nvml,
814+ Err ( err) => {
815+ error ! ( "Nvidia, library init fail: {:?}" , err) ;
816+ return ;
817+ }
818+ } ;
819+ let device = match nvml. device_by_index ( 0 ) {
820+ Ok ( device) => device,
821+ Err ( err) => {
822+ error ! ( "Nvidia, device not found: {:?}" , err) ;
823+ return ;
824+ }
825+ } ;
826+
827+ println ! ( "NVIDIA GPU" ) ;
828+
829+ // Basic identification
830+ println ! ( "Identification" ) ;
806831 println ! (
807- " INFO ROM Ver: {}" ,
808- device
809- . info_rom_image_version( )
810- . unwrap_or( "Unknown" . to_string( ) )
811- ) ;
812- println ! ( " PCI Info: {:X?}" , device. pci_info( ) ) ;
813- println ! ( " Performance State: {:?}" , device. performance_state( ) ) ;
814- println ! (
815- " Pwr Mgmt Limit Def: {:?}mW" ,
816- device. power_management_limit_default( )
817- ) ;
818- println ! (
819- " Pwr Mgmt Limit: {:?}mW" ,
820- device. power_management_limit( )
821- ) ;
822- println ! (
823- " Pwr Mgmt Limit Con: {:?}" ,
824- device. power_management_limit_constraints( )
825- ) ;
826- println ! ( " Pwr Usage: {:?}mW" , device. power_usage( ) ) ;
827- println ! (
828- " Total Energy: {:?}mJ" ,
829- device. total_energy_consumption( )
832+ " Name: {}" ,
833+ device. name( ) . unwrap_or( "Unknown" . to_string( ) )
830834 ) ;
831- println ! ( " Serial Number: {:?}" , device. serial( ) ) ;
835+ if let Ok ( arch) = device. architecture ( ) {
836+ println ! ( " Architecture: {:?}" , arch) ;
837+ }
838+ if let Ok ( serial) = device. serial ( ) {
839+ println ! ( " Serial Number: {}" , serial) ;
840+ }
841+ if let Ok ( part_number) = device. board_part_number ( ) {
842+ println ! ( " Part Number: {}" , part_number) ;
843+ }
844+ if let Ok ( board_id) = device. board_id ( ) {
845+ println ! ( " Board ID: {}" , board_id) ;
846+ }
847+
848+ // Firmware versions
849+ println ! ( "Firmware" ) ;
832850 println ! (
833- " Throttle Reason : {:? }" ,
834- device. current_throttle_reasons ( )
851+ " VBIOS Version : { }" ,
852+ device. vbios_version ( ) . unwrap_or ( "Unknown" . to_string ( ) )
835853 ) ;
836854 println ! (
837- " Temperature: {:?}C" ,
838- device. temperature( TemperatureSensor :: Gpu )
855+ " InfoROM Version: {}" ,
856+ device
857+ . info_rom_image_version( )
858+ . unwrap_or( "Unknown" . to_string( ) )
839859 ) ;
840- println ! ( " Util Rate: {:?}" , device. utilization_rates( ) ) ;
841- println ! ( " Memory Info: {:?}" , device. memory_info( ) ) ;
842- println ! ( " Part Number: {:?}" , device. board_part_number( ) ) ;
843- println ! ( " Board ID: {:?}" , device. board_id( ) ) ;
844- println ! ( " Num Fans: {:?}" , device. num_fans( ) ) ;
845- println ! ( " Display Active?: {:?}" , device. is_display_active( ) ) ;
846- println ! ( " Display Conn?: {:?}" , device. is_display_connected( ) ) ;
860+
861+ // PCI information
862+ println ! ( "PCI" ) ;
863+ if let Ok ( pci) = device. pci_info ( ) {
864+ println ! ( " Bus: {:02X}" , pci. bus) ;
865+ println ! ( " Device: {:02X}" , pci. device) ;
866+ println ! ( " Domain: {:04X}" , pci. domain) ;
867+ println ! ( " Device ID: {:04X}" , pci. pci_device_id) ;
868+ if let Some ( sub_id) = pci. pci_sub_system_id {
869+ println ! ( " Subsystem ID: {:08X}" , sub_id) ;
870+ }
871+ }
872+
873+ // Power information
874+ println ! ( "Power" ) ;
875+ if let Ok ( state) = device. performance_state ( ) {
876+ println ! ( " Performance State: {:?}" , state) ;
877+ }
878+ if let Ok ( power) = device. power_usage ( ) {
879+ println ! ( " Current Usage: {:.2} W" , power as f64 / 1000.0 ) ;
880+ }
881+ if let Ok ( limit) = device. power_management_limit ( ) {
882+ println ! ( " Power Limit: {:.2} W" , limit as f64 / 1000.0 ) ;
883+ }
884+ if let Ok ( default) = device. power_management_limit_default ( ) {
885+ println ! ( " Default Limit: {:.2} W" , default as f64 / 1000.0 ) ;
886+ }
887+ if let Ok ( constraints) = device. power_management_limit_constraints ( ) {
888+ println ! (
889+ " Min Limit: {:.2} W" ,
890+ constraints. min_limit as f64 / 1000.0
891+ ) ;
892+ println ! (
893+ " Max Limit: {:.2} W" ,
894+ constraints. max_limit as f64 / 1000.0
895+ ) ;
896+ }
897+ if let Ok ( energy) = device. total_energy_consumption ( ) {
898+ println ! ( " Total Energy: {:.2} J" , energy as f64 / 1000.0 ) ;
899+ }
900+
901+ // Thermal information
902+ println ! ( "Thermal" ) ;
903+ if let Ok ( temp) = device. temperature ( TemperatureSensor :: Gpu ) {
904+ println ! ( " GPU Temperature: {}C" , temp) ;
905+ }
906+ if let Ok ( num_fans) = device. num_fans ( ) {
907+ println ! ( " Number of Fans: {}" , num_fans) ;
908+ }
909+
910+ // Throttling
911+ if let Ok ( throttle) = device. current_throttle_reasons ( ) {
912+ println ! ( "Throttle Reasons" ) ;
913+ if throttle. is_empty ( ) {
914+ println ! ( " None" ) ;
915+ } else {
916+ if throttle. contains ( nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: GPU_IDLE ) {
917+ println ! ( " GPU Idle" ) ;
918+ }
919+ if throttle. contains (
920+ nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: APPLICATIONS_CLOCKS_SETTING ,
921+ ) {
922+ println ! ( " Applications Clocks Setting" ) ;
923+ }
924+ if throttle. contains ( nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: SW_POWER_CAP ) {
925+ println ! ( " Software Power Cap" ) ;
926+ }
927+ if throttle. contains ( nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: HW_SLOWDOWN ) {
928+ println ! ( " Hardware Slowdown" ) ;
929+ }
930+ if throttle. contains ( nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: SYNC_BOOST ) {
931+ println ! ( " Sync Boost" ) ;
932+ }
933+ if throttle
934+ . contains ( nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: SW_THERMAL_SLOWDOWN )
935+ {
936+ println ! ( " Software Thermal Slowdown" ) ;
937+ }
938+ if throttle
939+ . contains ( nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: HW_THERMAL_SLOWDOWN )
940+ {
941+ println ! ( " Hardware Thermal Slowdown" ) ;
942+ }
943+ if throttle
944+ . contains ( nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: HW_POWER_BRAKE_SLOWDOWN )
945+ {
946+ println ! ( " Hardware Power Brake Slowdown" ) ;
947+ }
948+ if throttle
949+ . contains ( nvml_wrapper:: bitmasks:: device:: ThrottleReasons :: DISPLAY_CLOCK_SETTING )
950+ {
951+ println ! ( " Display Clock Setting" ) ;
952+ }
953+ }
954+ }
955+
956+ // Utilization
957+ println ! ( "Utilization" ) ;
958+ if let Ok ( util) = device. utilization_rates ( ) {
959+ println ! ( " GPU: {}%" , util. gpu) ;
960+ println ! ( " Memory: {}%" , util. memory) ;
961+ }
962+
963+ // Memory information
964+ println ! ( "Memory" ) ;
965+ if let Ok ( mem) = device. memory_info ( ) {
966+ let total_gb = mem. total as f64 / ( 1024.0 * 1024.0 * 1024.0 ) ;
967+ let used_gb = mem. used as f64 / ( 1024.0 * 1024.0 * 1024.0 ) ;
968+ let free_gb = mem. free as f64 / ( 1024.0 * 1024.0 * 1024.0 ) ;
969+ println ! ( " Total: {:.2} GB" , total_gb) ;
970+ println ! ( " Used: {:.2} GB" , used_gb) ;
971+ println ! ( " Free: {:.2} GB" , free_gb) ;
972+ }
973+
974+ // Display status
975+ println ! ( "Display" ) ;
976+ if let Ok ( active) = device. is_display_active ( ) {
977+ println ! ( " Active: {}" , if active { "Yes" } else { "No" } ) ;
978+ }
979+ if let Ok ( connected) = device. is_display_connected ( ) {
980+ println ! (
981+ " Connected: {}" ,
982+ if connected { "Yes" } else { "No" }
983+ ) ;
984+ }
847985}
848986
849987fn print_esrt ( ) {
@@ -1197,6 +1335,11 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
11971335 println ! ( " Hdr CRC: {:X}" , { header. crc32 } ) ;
11981336 }
11991337 }
1338+ } else if args. nvidia {
1339+ #[ cfg( feature = "nvidia" ) ]
1340+ print_nvidia_info ( ) ;
1341+ #[ cfg( not( feature = "nvidia" ) ) ]
1342+ error ! ( "Not built with nvidia feature" ) ;
12001343 } else if let Some ( maybe_limit) = args. charge_limit {
12011344 print_err ( handle_charge_limit ( & ec, maybe_limit) ) ;
12021345 } else if let Some ( ( limit, soc) ) = args. charge_current_limit {
@@ -1629,6 +1772,7 @@ Options:
16291772 --inputdeck Show status of the input deck
16301773 --inputdeck-mode Set input deck power mode [possible values: auto, off, on] (Framework 16 only)
16311774 --expansion-bay Show status of the expansion bay (Framework 16 only)
1775+ --nvidia Show NVIDIA GPU information (Framework 16 only)
16321776 --charge-limit [<VAL>] Get or set battery charge limit (Percentage number as arg, e.g. '100')
16331777 --charge-current-limit [<VAL>] Get or set battery current charge limit (Percentage number as arg, e.g. '100')
16341778 --get-gpio <GET_GPIO> Get GPIO value by name or all, if no name provided
0 commit comments