diff options
| author | 2025-09-08 03:10:14 -0400 | |
|---|---|---|
| committer | 2025-09-08 03:10:14 -0400 | |
| commit | f3483f60d9bfd690164207342133dee021ee2686 (patch) | |
| tree | 6ff412961fbceb838eb321d9b72ffbdc2f502673 /inxi | |
| parent | d5742ac66a4860e4bc506bb51fcb12506a8678fe (diff) | |
| parent | 7422e185a5db8bdcb6f8a98302f9f954eae2915f (diff) | |
Update upstream source from tag 'upstream/3.3.39-1'
Update to upstream version '3.3.39-1'
with Debian dir c02b1091a1d03acb7a501fb19dbca1a728e8869a
Diffstat (limited to 'inxi')
| -rwxr-xr-x | inxi | 1005 |
1 files changed, 675 insertions, 330 deletions
@@ -49,8 +49,8 @@ use POSIX qw(ceil uname strftime ttyname); ## INXI INFO ## my $self_name='inxi'; -my $self_version='3.3.38'; -my $self_date='2025-04-06'; +my $self_version='3.3.39'; +my $self_date='2025-08-29'; my $self_patch='00'; ## END INXI INFO ## @@ -515,6 +515,9 @@ sub set_os { if ($cpu_arch =~ /arm|aarch/){ $risc{'arm'} = 1; $risc{'id'} = 'arm';} + elsif ($cpu_arch =~ /loong|godson/){ + $risc{'loongson'} = 1; + $risc{'id'} = 'loongson';} elsif ($cpu_arch =~ /mips/){ $risc{'mips'} = 1; $risc{'id'} = 'mips';} @@ -527,7 +530,7 @@ sub set_os { elsif ($cpu_arch =~ /(sparc|sun4[uv])/){ $risc{'sparc'} = 1; $risc{'id'} = 'sparc';} - # aarch32 mips32, i386. centaur/via/intel/amd handled in cpu + # aarch32 mips32, i386. amd/centaur/intel/via/zhaoxin handled in cpu if ($cpu_arch =~ /(armv[1-7]|32|[23456]86)/){ $bits_sys = 32; } @@ -1922,6 +1925,12 @@ sub disk_data { ['vmstat', '-H'], ); run_commands(\@cmds,'disk-bsd'); + # for issue 56, which will probably never be done, but bootloader data + @cmds = ( + ['efibootmgr', ''], # root, of course + ); + run_commands(\@cmds,'bootleader'); + } sub display_data { @@ -1961,6 +1970,7 @@ sub display_data { 'kde-full-session' => $ENV{'KDE_FULL_SESSION'}, 'kde-session-version' => $ENV{'KDE_SESSION_VERSION'}, 'vdpau-driver' => $ENV{'VDPAU_DRIVER'}, + 'windowmanager' => $ENV{'WINDOWMANAGER'}, 'xdg-current-desktop' => $ENV{'XDG_CURRENT_DESKTOP'}, 'xdg-session-desktop' => $ENV{'XDG_SESSION_DESKTOP'}, 'xdg-vtnr' => $ENV{'XDG_VTNR'}, @@ -2787,7 +2797,10 @@ sub download_file { sub get_file_http_tiny { my ($type,$url,$file,$ua) = @_; $ua = ($ua && $dl{'ua'}) ? $dl{'ua'} . $ua: ''; - my %headers = ($ua) ? ('agent' => $ua) : (); + my %headers; + $headers{'agent'} = $ua if $ua; + # default behavior of no check may change to check, not sure why, be explicit + $headers{'verify_SSL'} = 0 if $force{'no-ssl'}; my $tiny = HTTP::Tiny->new(%headers); # note: default is no verify, so default here actually is to verify unless overridden $tiny->verify_SSL => 1 if !$force{'no-ssl'}; @@ -4045,7 +4058,7 @@ sub is_hex { } ## NOTE: for perl pre 5.012 length(undef) returns warning -# receives string, returns boolean 1 if integer +# receives string, returns boolean 1 if integer. tr/// 4x faster than regex sub is_int { if (defined $_[0] && length($_[0]) && length($_[0]) == ($_[0] =~ tr/0123456789//)){ @@ -5106,6 +5119,10 @@ sub get { }}, 'irc' => sub { $b_irc = 1;}, + 'loongson' => sub { + undef %risc; + $risc{'id'} = 'loongson'; + $risc{'loongson'} = 1;}, 'man' => sub { $force{'man'} = 1;}, 'max-wrap|wrap-max|indent-min:i' => sub { @@ -5153,13 +5170,8 @@ sub get { }}, 'output-file|export-file:s' => sub { my ($opt,$arg) = @_; - if ($arg){ - if ($arg eq 'print' || main::check_output_path($arg)){ - $output_file = $arg; - } - else { - main::error_handler('output-file-bad', $opt, $arg); - } + if ($arg =~ /^(json|screen|xml)$/){ + $output_type = $arg; } else { main::error_handler('bad-arg', $opt, $arg); @@ -5172,6 +5184,16 @@ sub get { $risc{'ppc'} = 1;}, 'recommends' => sub { $show{'recommends'} = 1;}, + 'risc' => sub { + my ($opt,$arg) = @_; + if ($arg =~ /^(arm|loongson|mips|ppc|riscv|sparc)$/){ + undef %risc; + $risc{'id'} = $arg; + $risc{$arg} = 1; + } + else { + main::error_handler('bad-arg', $opt, $arg); + }}, 'riscv' => sub { undef %risc; $risc{'id'} = 'riscv'; @@ -5480,8 +5502,9 @@ sub show_options { ['1', '-b', '--basic', "Basic report: System (-S); basic CPU; Machine (-M); Battery (-B) (if found); Graphics (-G); Network devices (-N); basic Disk; Info (-I). Same as $self_name^-v2. See -e for expanded report."], - ['1', '-B', '--battery', "System battery info, including charge, condition - voltage (if critical), plus extra info (if battery present/detected)."], + ['1', '-B', '--battery', "System battery info, including charge, condition, + health (if avalable and not good), voltage (if critical), plus extra info + (if battery present/detected)."], ['1', '-C', '--cpu', "CPU report (if each item available): basic topology, model, type (see man for types), cache, average CPU speed, min/max speeds, per core clock speeds."], @@ -5664,8 +5687,9 @@ sub show_options { ['2', '-A', '', "Specific vendor/product information (if relevant); PCI/USB ID of device; Version/port(s)/driver version (if available); inactive sound servers/APIs."], - ['2', '-B', '', "Current/minimum voltage, vendor/model, status (if available); - attached devices (e.g. wireless mouse, keyboard, if present)."], + ['2', '-B', '', "Health, if available; urrent/minimum voltage, vendor/model, + status (if available); temperature (if available); attached devices (e.g. + wireless mouse, keyboard, if present)."], ['2', '-C', '', "L1/L3 cache (if most Linux, or if root and dmidecode installed); smt if disabled, CPU $flags (short list, use -f to see full list); Highest core speed (if > 1 core); CPU boost (turbo) enabled/disabled, if @@ -5722,7 +5746,8 @@ sub show_options { ['2', '-A', '', "Chip vendor:product ID for each audio device; PCIe speed, lanes (if found); USB rev, speed, lanes (if found); sound server/api helper daemons/plugins."], - ['2', '-B', '', "Power used, in watts; serial number."], + ['2', '-B', '', "Power used, in watts; serial number/ adds 'charging:' + section for charge info; charge cycles."], ['2', '-D', '', "Disk transfer speed; NVMe lanes; USB rev, speed, lanes (if found); Disk serial number; LVM volume group free space (if available); disk duid (some BSDs)."], @@ -5773,7 +5798,8 @@ sub show_options { ['1', '-xxx', '--extra 3', "Show extra, extra, extra data (only works with verbose or line reports, not short form):"], ['2', '-A', '', "Serial number, class ID."], - ['2', '-B', '', "Chemistry, cycles, location (if available)."], + ['2', '-B', '', "Manufacure date (uncommen); chemistry; location (uncommon); + temp min, max (uncommon); charge type (uncommon)."], ['2', '-C', '', "CPU voltage, external clock speed (if root and dmidecode installed); smt status, if available."], ['2', '-D', '', "Firmware rev. if available; partition scheme, in some cases; @@ -5817,6 +5843,8 @@ sub show_options { ['2', '-A', '', "If available: list of alternate kernel modules/drivers for device(s); PCIe lanes-max: gen, speed, lanes (if relevant); USB mode (if found); list of installed tools for servers."], + ['2', '-B', '', "Charge control min/max (if available); available charging + types (uncommon)."], ['2', '-C', '', "If available: microarchitecture level (64 bit AMD/Intel only).CPU generation, process node, built years; CPU socket type, base/boost speeds (dmidecode+root/sudo/doas required); Full topology line, with dies, @@ -6476,7 +6504,7 @@ sub clean_disk { my ($item) = @_; return $item if !$item; # <?unknown>?| - $item =~ s/vendor.*|product.*|O\.?E\.?M\.?//gi; + $item =~ s/vendor.*|product.*|(name\s)?n\/a|O\.?E\.?M\.?//gi; $item =~ s/^\s+|\s+$//g; $item =~ s/\s\s+/ /g; return $item; @@ -6484,8 +6512,8 @@ sub clean_disk { sub clean_dmi { my ($string) = @_; - $string = clean_unset($string,'AssetTagNum|^Base Board .*|^Chassis .*|' . - 'Manufacturer.*| Or Motherboard|\bOther\b.*|PartNum.*|SerNum|' . + $string = clean_unset($string,'Asset\s?Tag\s?Num.*|^Base\s?Board.*|^Chassis.*|' . + 'Manufacturer.*| Or Motherboard|\bOther\b.*|Part\s?Num.*|Ser(ial)?\s?Num.*|' . '^System .*|^0x[0]+$'); $string =~ s/\bbios\b|\bacpi\b//gi; $string =~ s/http:\/\/www.abit.com.tw\//Abit/i; @@ -6698,11 +6726,11 @@ sub message { $id ||= ''; $id2 ||= ''; my %message = ( - 'arm-cpu-f' => 'Use -f option to see features', 'audio-server-on-pipewire-pulse' => 'off (using pipewire-pulse)', 'audio-server-process-on' => 'active (process)', 'audio-server-root-na' => 'n/a (root, process)', 'audio-server-root-on' => 'active (root, process)', + 'battery-bad' => 'bad battery?', 'battery-data' => 'No system battery data found. Is one present?', 'battery-data-bsd' => 'No battery data found. Try with --dmidecode', 'battery-data-sys' => 'No /sys data found.', @@ -6794,6 +6822,7 @@ sub message { 'recommends' => 'see --recommends', 'repo-data', "No repo data detected. Does $self_name support your package manager?", 'repo-data-bsd', "No repo data detected. Does $self_name support $id?", + 'risc-cpu-f' => 'Use -f option to see features', 'risc-pci' => 'No ' . uc($id) . ' data found for this feature.', 'root-feature' => 'Feature requires superuser permissions.', 'root-item-incomplete' => "Full $id report requires superuser permissions.", @@ -7986,11 +8015,11 @@ sub sound_tools { { package BatteryItem; my (@upower_items,$b_upower,$upower); +my $battery = {}; sub get { eval $start if $b_log; my ($key1,$val1); - my $battery = {}; my $rows = []; my $num = 0; if ($force{'dmidecode'}){ @@ -8001,7 +8030,7 @@ sub get { @$rows = ({main::key($num++,0,1,$key1) => $val1}); } else { - battery_data_dmi($battery); + battery_data_dmi(); if (!%$battery){ if ($show{'battery-forced'}){ $key1 = 'Message'; @@ -8010,12 +8039,12 @@ sub get { } } else { - battery_output($rows,$battery); + battery_output($rows); } } } elsif ($bsd_type && ($sysctl{'battery'} || $show{'battery-forced'})){ - battery_data_sysctl($battery) if $sysctl{'battery'}; + battery_data_sysctl() if $sysctl{'battery'}; if (!%$battery){ if ($show{'battery-forced'}){ $key1 = 'Message'; @@ -8024,11 +8053,11 @@ sub get { } } else { - battery_output($rows,$battery); + battery_output($rows); } } elsif (-d '/sys/class/power_supply/'){ - battery_data_sys($battery); + battery_data_sys(); if (!%$battery){ if ($show{'battery-forced'}){ $key1 = 'Message'; @@ -8037,7 +8066,7 @@ sub get { } } else { - battery_output($rows,$battery); + battery_output($rows); } } else { @@ -8052,146 +8081,231 @@ sub get { return $rows; } -# alarm capacity capacity_level charge_full charge_full_design charge_now -# cycle_count energy_full energy_full_design energy_now location manufacturer model_name -# power_now present serial_number status technology type voltage_min_design voltage_now -# 0: name - battery id, not used -# 1: status -# 2: present -# 3: technology -# 4: cycle_count -# 5: voltage_min_design -# 6: voltage_now -# 7: power_now -# 8: energy_full_design -# 9: energy_full -# 10: energy_now -# 11: capacity -# 12: capacity_level -# 13: of_orig -# 14: model_name -# 15: manufacturer -# 16: serial_number -# 17: location +# sys files, these form the names used for sysctl and dmi sources too. +# see: pinxi/docs/inxi-battery.txt for more info on these items. +# +# %$battery keys: +# alarm +# capacity +# capacity_level +# charge_behaviour +# charge_control_end_threshold +# charge_control_start_threshold +# cycle_count +# energy_capacity +# energy_capacity_check +# energy_full +# energy_full_design +# energy_full_raw - use if low battery wh, < 1 +# energy_now +# energy_now_raw - use if low battery wh, < 1 +# health +# location - dmidecode has sometimes, but not usual +# manufacter_date +# manufacturer +# model_name +# name - battery id, not used +# of_orig +# of_orig_raw - use if low battery wh, < 1 +# power_now +# present +# purpose +# serial_number +# status +# technology +# temp +# temp_max +# temp_min +# voltage_min_design +# voltage_now sub battery_output { eval $start if $b_log; - my ($rows,$battery) = @_; - my ($key); + my $rows = $_[0]; my $num = 0; my $j = 0; # print Data::Dumper::Dumper $battery; - foreach $key (sort keys %$battery){ + foreach my $id (sort keys %$battery){ $num = 0; my ($charge,$condition,$model,$serial,$status) = ('','','','',''); my ($chemistry,$cycles,$location) = ('','',''); - next if !$battery->{$key}{'purpose'} || $battery->{$key}{'purpose'} ne 'primary'; - # $battery->{$key}{''}; + next if !$battery->{$id}{'purpose'} || $battery->{$id}{'purpose'} ne 'primary'; + # $battery->{$id}{''}; # we need to handle cases where charge or energy full is 0 - if (defined $battery->{$key}{'energy_now'} && $battery->{$key}{'energy_now'} ne ''){ - $charge = "$battery->{$key}{'energy_now'} Wh"; - if ($battery->{$key}{'energy_full'} && - main::is_numeric($battery->{$key}{'energy_full'})){ - my $percent = sprintf("%.1f", $battery->{$key}{'energy_now'}/$battery->{$key}{'energy_full'}*100); - $charge .= ' (' . $percent . '%)'; + if (defined $battery->{$id}{'energy_now'}){ + if (defined $battery->{$id}{'energy_now_raw'}){ + $battery->{$id}{'energy_now'} = $battery->{$id}{'energy_now_raw'}; + } + $charge = "$battery->{$id}{'energy_now'} Wh"; + # if energy_full is non zero or zero, and less than 1, capacity is not set + if ($battery->{$id}{'energy_capacity'}){ + $charge .= ' (' . $battery->{$id}{'energy_capacity'} . '%'; + # Got 'critical' for an almost fully charged battery, hold off on this. + # if ($extra > 0 && $battery->{$id}{'capacity_level'}){ + # $charge .= ' ' . $battery->{$id}{'capacity_level'}; + # } + $charge .= ')'; } } # better than nothing, shows the charged percent - elsif (defined $battery->{$key}{'capacity'} && $battery->{$key}{'capacity'} ne ''){ - $charge = $battery->{$key}{'capacity'} . '%' + elsif (defined $battery->{$id}{'energy_capacity'} && + main::is_numeric($battery->{$id}{'energy_capacity'})){ + $charge = $battery->{$id}{'energy_capacity'} . '%' + } + elsif (defined $battery->{$id}{'capacity'} && + main::is_numeric($battery->{$id}{'capacity'})){ + $charge = $battery->{$id}{'capacity'} . '%' } else { $charge = 'N/A'; } - if ($battery->{$key}{'energy_full'} || $battery->{$key}{'energy_full_design'}){ - $battery->{$key}{'energy_full_design'} ||= 'N/A'; - $battery->{$key}{'energy_full'} = (defined $battery->{$key}{'energy_full'} && - $battery->{$key}{'energy_full'} ne '') ? $battery->{$key}{'energy_full'} : 'N/A'; - $condition = "$battery->{$key}{'energy_full'}/$battery->{$key}{'energy_full_design'} Wh"; - if ($battery->{$key}{'of_orig'}){ - $condition .= " ($battery->{$key}{'of_orig'}%)"; + if ($battery->{$id}{'energy_full'} || $battery->{$id}{'energy_full_design'}){ + $battery->{$id}{'energy_full_design'} ||= 'N/A'; + # can be zero or close to it. + if (!defined $battery->{$id}{'energy_full'}){ + $battery->{$id}{'energy_full'} = 'N/A'; + } + elsif (defined $battery->{$id}{'energy_full_raw'}){ + $battery->{$id}{'energy_full'} = $battery->{$id}{'energy_full_raw'}; + } + $condition = "$battery->{$id}{'energy_full'}/$battery->{$id}{'energy_full_design'} Wh"; + if ($battery->{$id}{'of_orig'}){ + $condition .= " ($battery->{$id}{'of_orig'}%)"; + } + # if energy_full is non zero or zero, but less than 1, of_origin is 0 + # and of_origin_raw is the actual decimal value + elsif (defined $battery->{$id}{'of_orig'} && + $battery->{$id}{'of_orig'} == 0){ + if ($battery->{$id}{'of_orig_raw'}){ + $battery->{$id}{'of_orig'} = $battery->{$id}{'of_orig_raw'}; + } + $condition .= ' (' . $battery->{$id}{'of_orig'} . '%)'; } } $condition ||= 'N/A'; $j = scalar @$rows; push(@$rows, { - main::key($num++,1,1,'ID') => $key, - main::key($num++,0,2,'charge') => $charge, - main::key($num++,0,2,'condition') => $condition, + main::key($num++,1,1,'ID') => $id, }); - if ($extra > 2){ - if ($battery->{$key}{'power_now'}){ - $rows->[$j]{main::key($num++,0,2,'power')} = sprintf('%0.1f W',($battery->{$key}{'power_now'}/10**6)); + $rows->[$j]{main::key($num++,1,2,'charge')} = $charge; + if ($battery->{$id}{'energy_capacity_check'}){ + $rows->[$j]{main::key($num++,0,3,'note')} = $battery->{$id}{'energy_capacity_check'}; + } + $rows->[$j]{main::key($num++,1,2,'condition')} = $condition; + if ($battery->{$id}{'battery_bad'}){ + $rows->[$j]{main::key($num++,0,3,'alert')} = $battery->{$id}{'battery_bad'}; + } + if ($battery->{$id}{'health'} && + ($extra > 0 || $battery->{$id}{'health'} ne 'good')){ + $rows->[$j]{main::key($num++,0,3,'health')} = $battery->{$id}{'health'}; + } + if ($extra > 0 && $battery->{$id}{'temp'}){ + $rows->[$j]{main::key($num++,1,3,'temp')} = $battery->{$id}{'temp'} . ' C'; + if ($extra > 2 && $battery->{$id}{'temp_max'}){ + if ($battery->{$id}{'temp_min'}){ + $rows->[$j]{main::key($num++,0,4,'min')} = $battery->{$id}{'temp_min'} . ' C'; + } + $rows->[$j]{main::key($num++,0,4,'max')} = $battery->{$id}{'temp_max'} . ' C'; } } - if ($extra > 0 || ($battery->{$key}{'voltage_now'} && - $battery->{$key}{'voltage_min_design'} && - ($battery->{$key}{'voltage_now'} - $battery->{$key}{'voltage_min_design'}) < 0.5)){ - $battery->{$key}{'voltage_now'} ||= 'N/A'; - $rows->[$j]{main::key($num++,1,2,'volts')} = $battery->{$key}{'voltage_now'}; - if ($battery->{$key}{'voltage_now'} ne 'N/A' || $battery->{$key}{'voltage_min_design'}){ - $battery->{$key}{'voltage_min_design'} ||= 'N/A'; - $rows->[$j]{main::key($num++,0,3,'min')} = $battery->{$key}{'voltage_min_design'}; + if ($extra > 2 && $battery->{$id}{'power_now'}){ + $rows->[$j]{main::key($num++,0,2,'power')} = $battery->{$id}{'power_now'} . ' W'; + } + if ($extra > 0 || ($battery->{$id}{'voltage_now'} && + $battery->{$id}{'voltage_min_design'} && + ($battery->{$id}{'voltage_now'} - $battery->{$id}{'voltage_min_design'}) < 0.5)){ + $battery->{$id}{'voltage_now'} ||= 'N/A'; + $rows->[$j]{main::key($num++,1,2,'volts')} = $battery->{$id}{'voltage_now'}; + if ($battery->{$id}{'voltage_now'} ne 'N/A' || $battery->{$id}{'voltage_min_design'}){ + $battery->{$id}{'voltage_min_design'} ||= 'N/A'; + $rows->[$j]{main::key($num++,0,3,'min')} = $battery->{$id}{'voltage_min_design'}; } } if ($extra > 0){ - if ($battery->{$key}{'manufacturer'} || $battery->{$key}{'model_name'}){ - if ($battery->{$key}{'manufacturer'} && $battery->{$key}{'model_name'}){ - $model = "$battery->{$key}{'manufacturer'} $battery->{$key}{'model_name'}"; + if ($battery->{$id}{'manufacturer'} || $battery->{$id}{'model_name'}){ + if ($battery->{$id}{'manufacturer'} && $battery->{$id}{'model_name'}){ + $model = "$battery->{$id}{'manufacturer'} $battery->{$id}{'model_name'}"; } - elsif ($battery->{$key}{'manufacturer'}){ - $model = $battery->{$key}{'manufacturer'}; + elsif ($battery->{$id}{'manufacturer'}){ + $model = $battery->{$id}{'manufacturer'}; } - elsif ($battery->{$key}{'model_name'}){ - $model = $battery->{$key}{'model_name'}; + elsif ($battery->{$id}{'model_name'}){ + $model = $battery->{$id}{'model_name'}; } } else { $model = 'N/A'; } - $rows->[$j]{main::key($num++,0,2,'model')} = $model; + $rows->[$j]{main::key($num++,1,2,'model')} = $model; if ($extra > 2){ - $chemistry = ($battery->{$key}{'technology'}) ? $battery->{$key}{'technology'}: 'N/A'; + if ($battery->{$id}{'manufacture_date'}){ + $rows->[$j]{main::key($num++,0,3,'made')} = $battery->{$id}{'manufacture_date'}; + } + $chemistry = ($battery->{$id}{'technology'}) ? $battery->{$id}{'technology'}: 'N/A'; $rows->[$j]{main::key($num++,0,2,'type')} = $chemistry; } if ($extra > 1){ - $serial = main::filter($battery->{$key}{'serial_number'}); + $serial = main::filter($battery->{$id}{'serial_number'}); $rows->[$j]{main::key($num++,0,2,'serial')} = $serial; } - $status = ($battery->{$key}{'status'}) ? $battery->{$key}{'status'}: 'N/A'; - $rows->[$j]{main::key($num++,0,2,'status')} = $status; - if ($extra > 2){ - if ($battery->{$key}{'cycle_count'}){ - $rows->[$j]{main::key($num++,0,2,'cycles')} = $battery->{$key}{'cycle_count'}; + if ($extra > 2 && $battery->{$id}{'location'}){ + $rows->[$j]{main::key($num++,0,2,'location')} = $battery->{$id}{'location'}; + } + $status = ($battery->{$id}{'status'}) ? $battery->{$id}{'status'}: 'N/A'; + if ($extra > 1){ + $rows->[$j]{main::key($num++,1,2,'charging')} = ''; + $rows->[$j]{main::key($num++,0,3,'status')} = $status; + if ($b_admin && defined $battery->{$id}{'charge_control_end_threshold'} || + defined $battery->{$id}{'charge_control_start_threshold'} || + $battery->{$id}{'charge_behavior'}){ + $rows->[$j]{main::key($num++,1,3,'control')} = ''; + my $start = (defined $battery->{$id}{'charge_control_start_threshold'}) ? + $battery->{$id}{'charge_control_start_threshold'} . '%': 'N/A'; + my $end = (defined $battery->{$id}{'charge_control_end_threshold'}) ? + $battery->{$id}{'charge_control_end_threshold'} . '%': 'N/A'; + $rows->[$j]{main::key($num++,0,4,'start')} = $start; + $rows->[$j]{main::key($num++,0,4,'end')} = $end; + if ($battery->{$id}{'charge_behavior'}){ + $rows->[$j]{main::key($num++,0,4,'behavior')} = $battery->{$id}{'charge_behavior'}; + } } - if ($battery->{$key}{'location'}){ - $rows->[$j]{main::key($num++,0,2,'location')} = $battery->{$key}{'location'}; + if ($extra > 2 && $battery->{$id}{'charge_type'}){ + $rows->[$j]{main::key($num++,1,3,'type')} = $battery->{$id}{'charge_type'}; + if ($b_admin && $battery->{$id}{'charge_types'}){ + $rows->[$j]{main::key($num++,0,4,'avail')} = $battery->{$id}{'charge_types'}; + } } + # this is surprisingly uncommon, and sometimes is 0, which is false + my $cycles = ($battery->{$id}{'cycle_count'}) ? $battery->{$id}{'cycle_count'}: 'N/A'; + $rows->[$j]{main::key($num++,0,3,'cycles')} = $cycles; + } + else { + $rows->[$j]{main::key($num++,0,2,'status')} = $status; } } - $battery->{$key} = undef; + # dump the primary battery now + $battery->{$id} = undef; } - # print Data::Dumper::Dumper \%$battery; # now if there are any devices left, print them out, excluding Mains if ($extra > 0){ + # print Data::Dumper::Dumper \%$battery; $upower = main::check_program('upower'); - foreach $key (sort keys %$battery){ + foreach my $id (sort keys %$battery){ $num = 0; - next if !defined $battery->{$key} || $battery->{$key}{'purpose'} eq 'mains'; + next if !defined $battery->{$id} || $battery->{$id}{'purpose'} eq 'mains'; my ($charge,$model,$serial,$percent,$status,$vendor) = ('','','','','',''); $j = scalar @$rows; - my $upower_data = ($upower) ? upower_data($key) : {}; + my $upower_data = ($upower) ? upower_data($id) : {}; if ($upower_data->{'percent'}){ $charge = $upower_data->{'percent'}; } - elsif ($battery->{$key}{'capacity_level'} && - lc($battery->{$key}{'capacity_level'}) ne 'unknown'){ - $charge = $battery->{$key}{'capacity_level'}; + elsif ($battery->{$id}{'capacity_level'}){ + $charge = $battery->{$id}{'capacity_level'}; } else { $charge = 'N/A'; } - $model = $battery->{$key}{'model_name'} if $battery->{$key}{'model_name'}; - $vendor = $battery->{$key}{'manufacturer'} if $battery->{$key}{'manufacturer'}; + $model = $battery->{$id}{'model_name'} if $battery->{$id}{'model_name'}; + $vendor = $battery->{$id}{'manufacturer'} if $battery->{$id}{'manufacturer'}; if ($vendor || $model){ if ($vendor && $model){ $model = "$vendor $model"; @@ -8204,84 +8318,198 @@ sub battery_output { $model = 'N/A'; } push(@$rows, { - main::key($num++,1,1,'Device') => $key, + main::key($num++,1,1,'Device') => $id, main::key($num++,0,2,'model') => $model, },); if ($extra > 1){ - $serial = main::filter($battery->{$key}{'serial_number'}); + $serial = main::filter($battery->{$id}{'serial_number'}); $rows->[$j]{main::key($num++,0,2,'serial')} = $serial; } $rows->[$j]{main::key($num++,0,2,'charge')} = $charge; if ($extra > 2 && $upower_data->{'rechargeable'}){ $rows->[$j]{main::key($num++,0,2,'rechargeable')} = $upower_data->{'rechargeable'}; } - $status = ($battery->{$key}{'status'}) ? $battery->{$key}{'status'}: 'N/A' ; + $status = ($battery->{$id}{'status'}) ? $battery->{$id}{'status'}: 'N/A' ; $rows->[$j]{main::key($num++,0,2,'status')} = $status; } } eval $end if $b_log; } +## BATTERY DATA ## + +# BATTERY DATA PROCESSOR # +sub process_battery_data { + eval $start if $b_log; + for my $id (keys %$battery){ + # note:voltage_now fluctuates, which will make capacity numbers change a bit + # if any of these values failed, the math will be wrong, but no way to fix that + # tests show more systems give right capacity/charge with voltage_min_design + # than with voltage_now. Because of this, only use these as fallbacks to energy_*. + if ($battery->{$id}{'voltage_min_design'}){ + # CHARGE is Ah, which are converted to Wh by: Ah x voltage. + if (!$battery->{$id}{'energy_now'} && $battery->{$id}{'charge_now'}){ + $battery->{$id}{'energy_now'} = $battery->{$id}{'charge_now'} * $battery->{$id}{'voltage_min_design'}; + } + if (!$battery->{$id}{'energy_full'} && $battery->{$id}{'charge_full'}){ + $battery->{$id}{'energy_full'} = $battery->{$id}{'charge_full'}*$battery->{$id}{'voltage_min_design'}; + } + if (!$battery->{$id}{'energy_full_design'} && $battery->{$id}{'charge_full_design'}){ + $battery->{$id}{'energy_full_design'} = $battery->{$id}{'charge_full_design'} * $battery->{$id}{'voltage_min_design'}; + } + } + # Emulation data: + # $battery->{$id}{'energy_full'} = 0.01; + # $battery->{$id}{'energy_now'} = 0.01; + # Format Percentages + # Even with failing battery now and full should retain right proportions + if ($battery->{$id}{'energy_now'} && $battery->{$id}{'energy_full'}){ + $battery->{$id}{'energy_capacity'} = 100 * ($battery->{$id}{'energy_now'}/$battery->{$id}{'energy_full'}); + $battery->{$id}{'energy_capacity'} = sprintf('%.1f',$battery->{$id}{'energy_capacity'}) + 0; + if ($battery->{$id}{'energy_capacity'} > 100){ + $battery->{$id}{'energy_capacity_check'} = main::message('note-check'); + } + } + if ($battery->{$id}{'energy_full_design'} && $battery->{$id}{'energy_full'}){ + $battery->{$id}{'of_orig'} = 100 * ($battery->{$id}{'energy_full'}/$battery->{$id}{'energy_full_design'}); + if ($battery->{$id}{'of_orig'} < 1){ + # note: g prints only significant digits + $battery->{$id}{'of_orig_raw'} = sprintf('%.1g',$battery->{$id}{'of_orig'}); + } + elsif ($battery->{$id}{'of_orig'} < 5){ + $battery->{$id}{'battery_bad'} = main::message('battery-bad'); + } + $battery->{$id}{'of_orig'} = sprintf('%.1f',$battery->{$id}{'of_orig'}) + 0; + } + # format energy + if ($battery->{$id}{'energy_full'}){ + if ($battery->{$id}{'energy_full'} < 1){ + # note: g prints only significant digits + $battery->{$id}{'energy_full_raw'} = sprintf('%.1g',$battery->{$id}{'energy_full'}); + if (!$battery->{$id}{'battery_bad'}){ + $battery->{$id}{'battery_bad'} = main::message('battery-bad'); + } + } + $battery->{$id}{'energy_full'} = sprintf('%.1f',$battery->{$id}{'energy_full'}) + 0; + } + if ($battery->{$id}{'energy_full_design'}){ + $battery->{$id}{'energy_full_design'} = sprintf('%.1f',$battery->{$id}{'energy_full_design'}) + 0; + } + if ($battery->{$id}{'energy_now'}){ + if ($battery->{$id}{'energy_now'} < 1){ + # note: g prints only significant digits + $battery->{$id}{'energy_now_raw'} = sprintf('%.1g',$battery->{$id}{'energy_now'}); + } + $battery->{$id}{'energy_now'} = sprintf('%.1f',$battery->{$id}{'energy_now'}) + 0; + } + if ($battery->{$id}{'power_now'}){ + $battery->{$id}{'power_now'} = sprintf('%.1f',$battery->{$id}{'power_now'}) + 0; + } + # format voltages + if ($battery->{$id}{'voltage_min_design'}){ + $battery->{$id}{'voltage_min_design'} = sprintf("%.2f", $battery->{$id}{'voltage_min_design'}) + 0; + } + # could be zero + if (defined $battery->{$id}{'voltage_now'}){ + $battery->{$id}{'voltage_now'} = sprintf("%.2f", $battery->{$id}{'voltage_now'}) + 0; + } + # Format special values + if ($battery->{$id}{'manufacture_year'}){ + $battery->{$id}{'manufacture_date'} = $battery->{$id}{'manufacture_year'}; + if ($battery->{$id}{'manufacture_month'}){ + $battery->{$id}{'manufacture_date'} .= sprintf('-%02d',$battery->{$id}{'manufacture_month'}); + if ($battery->{$id}{'manufacture_day'}){ + $battery->{$id}{'manufacture_date'} .= sprintf('-%02d',$battery->{$id}{'manufacture_day'}); + } + } + } + } + print Data::Dumper::Dumper $battery if $dbg[33]; + main::log_data('dump','process: %$battery',$battery) if $b_log; + eval $end if $b_log; +} + +# BATTERY DATA SOURCES # + # charge: mAh energy: Wh sub battery_data_sys { eval $start if $b_log; - my $battery = $_[0]; - my ($b_ma,$file,$id,$item,$path,$value); + my ($file,$id,$item,$path,$value); my $num = 0; my @batteries = main::globber("/sys/class/power_supply/*"); # note: there is no 'location' file, but dmidecode has it # 'type' is generic, like: Battery, Mains # capacity_level is a string, like: Normal - my @items = qw(alarm capacity capacity_level charge_full charge_full_design - charge_now constant_charge_current constant_charge_current_max cycle_count - energy_full energy_full_design energy_now location manufacturer model_name - power_now present scope serial_number status technology type voltage_min_design - voltage_now); + my @items = qw(alarm capacity capacity_level charge_behaviour + charge_control_end_threshold charge_control_start_threshold + charge_full charge_full_design charge_now charge_type charge_types + constant_charge_current constant_charge_current_max cycle_count + energy_full energy_full_design energy_now health location manufacture_day + manufacture_month manufacture_year manufacturer model_name + power_now present scope serial_number status technology temp temp_alert_max + temp_alert_min temp_max temp_min type voltage_min_design voltage_now); foreach $item (@batteries){ - $b_ma = 0; $id = $item; $id =~ s%/sys/class/power_supply/%%g; foreach $file (@items){ $path = "$item/$file"; + undef $value; # android shows some files only root readable - $value = (-r $path) ? main::reader($path,'',0): ''; + $value = main::reader($path,'',0) if -r $path; # mains, plus in psu if ($file eq 'type' && $value && lc($value) ne 'battery'){ $battery->{$id}{'purpose'} = 'mains'; } if ($value){ $value = main::trimmer($value); - if ($file eq 'voltage_min_design'){ - $value = sprintf("%.1f", $value/1000000); - } - elsif ($file eq 'voltage_now'){ - $value = sprintf("%.1f", $value/1000000); - } - elsif ($file eq 'energy_full_design'){ - $value = $value/1000000; - } - elsif ($file eq 'energy_full'){ - $value = $value/1000000; + if ($file eq 'capacity_level'){ + $value = lc($value); + $value =~ s/unknown//; } - elsif ($file eq 'energy_now'){ - $value = sprintf("%.1f", $value/1000000); + # overides threshhold behavior + elsif ($file eq 'charge_behaviour'){ + $value = lc($value); } # note: the following 3 were off, 100000 instead of 1000000 # why this is, I do not know. I did not document any reason for that # so going on assumption it is a mistake. # CHARGE is mAh, which are converted to Wh by: mAh x voltage. # Note: voltage fluctuates so will make results vary slightly. - elsif ($file eq 'charge_full_design'){ + if ($file eq 'charge_full_design'){ $value = $value/1000000; - $b_ma = 1; } elsif ($file eq 'charge_full'){ $value = $value/1000000; - $b_ma = 1; } elsif ($file eq 'charge_now'){ $value = $value/1000000; - $b_ma = 1; + } + elsif ($file eq 'charge_type'){ + $value = lc($value); + $value =~ s/unknown|n\/a//; # both are valid values + } + # active in [] + elsif ($file eq 'charge_types'){ + $value = lc($value); + $value =~ s/\bunknown|n\/a\b//g; # both are valid values + if (!$battery->{$id}{'charge_type'} && $value =~ /\[([^]]+)\]/){ + $battery->{$id}{'charge_type'} = $1; + } + $value =~ s/\[|\]//g; + $value = join(',',sort(split(/\s+/,$value))); + } + elsif ($file eq 'energy_full_design'){ + $value = $value/1000000; + } + elsif ($file eq 'energy_full'){ + $value = $value/1000000; + } + elsif ($file eq 'energy_now'){ + $value = $value/1000000; + } + elsif ($file eq 'health'){ + $value = lc($value); + $value =~ s/unknown//; } elsif ($file eq 'manufacturer'){ $value = main::clean_dmi($value); @@ -8289,15 +8517,38 @@ sub battery_data_sys { elsif ($file eq 'model_name'){ $value = main::clean_dmi($value); } + elsif ($file eq 'power_now'){ + $value = $value/1000000; + } # Valid values: Unknown,Charging,Discharging,Not charging,Full # don't use clean_unset because Not charging is a valid value. elsif ($file eq 'status'){ $value = lc($value); $value =~ s/unknown//; - + } + elsif ($file eq 'temp'){ + $value = $value/10; + } + elsif ($file eq 'temp_alert_max'){ + $value = $value/10; + } + elsif ($file eq 'temp_alert_min'){ + $value = $value/10; + } + elsif ($file eq 'temp_max'){ + $value = $value/10; + } + elsif ($file eq 'temp_min'){ + $value = $value/10; + } + elsif ($file eq 'voltage_min_design'){ + $value = $value/1000000; + } + elsif ($file eq 'voltage_now'){ + $value = $value/1000000; } } - elsif ($b_root && -e $path && ! -r $path){ + elsif (!$b_root && -e $path && ! -r $path){ $value = main::message('root-required'); } $battery->{$id}{$file} = $value; @@ -8319,48 +8570,16 @@ sub battery_data_sys { $battery->{$id}{'purpose'} = 'device'; } } - # note:voltage_now fluctuates, which will make capacity numbers change a bit - # if any of these values failed, the math will be wrong, but no way to fix that - # tests show more systems give right capacity/charge with voltage_min_design - # than with voltage_now - if ($b_ma && $battery->{$id}{'voltage_min_design'}){ - if ($battery->{$id}{'charge_now'}){ - $battery->{$id}{'energy_now'} = $battery->{$id}{'charge_now'} * $battery->{$id}{'voltage_min_design'}; - } - if ($battery->{$id}{'charge_full'}){ - $battery->{$id}{'energy_full'} = $battery->{$id}{'charge_full'}*$battery->{$id}{'voltage_min_design'}; - } - if ($battery->{$id}{'charge_full_design'}){ - $battery->{$id}{'energy_full_design'} = $battery->{$id}{'charge_full_design'} * $battery->{$id}{'voltage_min_design'}; - } - } - if ($battery->{$id}{'energy_now'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'capacity'} = 100 * $battery->{$id}{'energy_now'}/$battery->{$id}{'energy_full'}; - $battery->{$id}{'capacity'} = sprintf("%.1f", $battery->{$id}{'capacity'}); - } - if ($battery->{$id}{'energy_full_design'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'of_orig'} = 100 * $battery->{$id}{'energy_full'}/$battery->{$id}{'energy_full_design'}; - $battery->{$id}{'of_orig'} = sprintf("%.1f", $battery->{$id}{'of_orig'}); - } - if ($battery->{$id}{'energy_now'}){ - $battery->{$id}{'energy_now'} = sprintf("%.1f", $battery->{$id}{'energy_now'}); - } - if ($battery->{$id}{'energy_full_design'}){ - $battery->{$id}{'energy_full_design'} = sprintf("%.1f",$battery->{$id}{'energy_full_design'}); - } - if ($battery->{$id}{'energy_full'}){ - $battery->{$id}{'energy_full'} = sprintf("%.1f", $battery->{$id}{'energy_full'}); - } } print Data::Dumper::Dumper $battery if $dbg[33]; main::log_data('dump','sys: %$battery',$battery) if $b_log; + process_battery_data(); eval $end if $b_log; } sub battery_data_sysctl { eval $start if $b_log; - my $battery = $_[0]; - my ($id); + my $id; for (@{$sysctl{'battery'}}){ if (/^(hw\.sensors\.)acpi([^\.]+)(\.|:)/){ $id = uc($2); @@ -8407,48 +8626,19 @@ sub battery_data_sysctl { } } } - # then do the condition/charge percent math + # then set to primary for my $id (keys %$battery){ $battery->{$id}{'purpose'} = 'primary'; - # CHARGE is Ah, which are converted to Wh by: Ah x voltage. - if ($battery->{$id}{'voltage_min_design'}){ - if ($battery->{$id}{'charge_now'}){ - $battery->{$id}{'energy_now'} = $battery->{$id}{'charge_now'} * $battery->{$id}{'voltage_min_design'}; - } - if ($battery->{$id}{'charge_full'}){ - $battery->{$id}{'energy_full'} = $battery->{$id}{'charge_full'}*$battery->{$id}{'voltage_min_design'}; - } - if ($battery->{$id}{'charge_full_design'}){ - $battery->{$id}{'energy_full_design'} = $battery->{$id}{'charge_full_design'} * $battery->{$id}{'voltage_min_design'}; - } - } - if ($battery->{$id}{'energy_full_design'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'of_orig'} = 100 * $battery->{$id}{'energy_full'}/$battery->{$id}{'energy_full_design'}; - $battery->{$id}{'of_orig'} = sprintf("%.1f", $battery->{$id}{'of_orig'}); - } - if ($battery->{$id}{'energy_now'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'capacity'} = 100 * $battery->{$id}{'energy_now'}/$battery->{$id}{'energy_full'}; - $battery->{$id}{'capacity'} = sprintf("%.1f", $battery->{$id}{'capacity'}); - } - if ($battery->{$id}{'energy_now'}){ - $battery->{$id}{'energy_now'} = sprintf("%.1f", $battery->{$id}{'energy_now'}); - } - if ($battery->{$id}{'energy_full'}){ - $battery->{$id}{'energy_full'} = sprintf("%.1f", $battery->{$id}{'energy_full'}); - } - if ($battery->{$id}{'energy_full_design'}){ - $battery->{$id}{'energy_full_design'} = sprintf("%.1f", $battery->{$id}{'energy_full_design'}); - } } print Data::Dumper::Dumper $battery if $dbg[33]; main::log_data('dump','dmi: %$battery',$battery) if $b_log; + process_battery_data(); eval $end if $b_log; } # note, dmidecode does not have charge_now or charge_full sub battery_data_dmi { eval $start if $b_log; - my $battery = $_[0]; my ($id); my $i = 0; foreach my $row (@dmi){ @@ -8473,21 +8663,13 @@ sub battery_data_dmi { $battery->{$id}{'model_name'} = main::clean_dmi($value[1])} elsif ($value[0] eq 'Design Capacity'){ $value[1] =~ s/\s*mwh$//i; - $battery->{$id}{'energy_full_design'} = sprintf("%.1f", $value[1]/1000); + $battery->{$id}{'energy_full_design'} = $value[1]/1000; } elsif ($value[0] eq 'Design Voltage'){ $value[1] =~ s/\s*mv$//i; - $battery->{$id}{'voltage_min_design'} = sprintf("%.1f", $value[1]/1000); + $battery->{$id}{'voltage_min_design'} = $value[1]/1000; } } - if ($battery->{$id}{'energy_now'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'capacity'} = 100 * $battery->{$id}{'energy_now'} / $battery->{$id}{'energy_full'}; - $battery->{$id}{'capacity'} = sprintf("%.1f%", $battery->{$id}{'capacity'}); - } - if ($battery->{$id}{'energy_full_design'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'of_orig'} = 100 * $battery->{$id}{'energy_full'} / $battery->{$id}{'energy_full_design'}; - $battery->{$id}{'of_orig'} = sprintf("%.0f%", $battery->{$id}{'of_orig'}); - } } elsif ($row->[0] > 22){ last; @@ -8495,11 +8677,12 @@ sub battery_data_dmi { } print Data::Dumper::Dumper $battery if $dbg[33]; main::log_data('dump','dmi: %$battery',$battery) if $b_log; + process_battery_data(); eval $end if $b_log; } sub upower_data { - my ($id) = @_; + my $id = $_[0]; eval $start if $b_log; my $data = {}; if (!$b_upower && $upower){ @@ -9367,25 +9550,29 @@ sub full_output { if (($extra > 0 && !$show{'cpu-flag'}) || $show{'cpu-flag'}){ my @flags = ($cpu->{'flags'}) ? split(/\s+/, $cpu->{'flags'}) : (); my $flag_key = (%risc || $bsd_type) ? 'Features': 'Flags'; - my $flag = 'N/A'; + my $flag_list = 'N/A'; if (!$show{'cpu-flag'}){ - if (@flags){ - # failure to read dmesg.boot: dmesg.boot permissions; then short -Cx list flags - @flags = grep {/^(dmesg.boot|permissions|avx[2-9]?|ht|lm|nx|pae|pni|(sss|ss)e([2-9])?([a-z])?(_[0-9])?|svm|vmx)$/} @flags; + $flag_key .= '-basic' if !%risc; + # failure to read dmesg.boot: dmesg.boot permissions + if ($bsd_type && (@flags = grep {/^(dmesg.boot|permissions)$/} @flags)){ + # do nothing, we're done, it's bad data + } + # ARM/Loongson have Features, never seen them for MIPS/PPC/SPARC/RISCV, but check + elsif (%risc && @flags){ + $flag_list = main::message('risc-cpu-f'); + @flags = (); # dump it, we're not printing it + } + # not risc or bad bsd data, create the short list + elsif (@flags) { + @flags = grep {/^(avx[2-9]?|ht|lm|nx|pae|pni|(sss|ss)e([2-9])?([a-z])?(_[0-9])?|svm|vmx)$/} @flags; @flags = map {s/pni/sse3/; $_} @flags if @flags; - @flags = sort @flags; - } - # only ARM has Features, never seen them for MIPS/PPC/SPARC/RISCV, but check - if ($risc{'arm'} && $flag eq 'N/A'){ - $flag = main::message('arm-cpu-f'); } } if (@flags){ - @flags = sort @flags; - $flag = join(' ', @flags); + $flag_list = join(' ', sort @flags); } push(@$rows, { - main::key($num++,0,1,$flag_key) => $flag, + main::key($num++,0,1,$flag_key) => $flag_list, },); } if ($b_admin){ @@ -9603,38 +9790,56 @@ sub set_fake_cpu_data { # $ci = "$fake_data_dir/cpu/loongson/3A5000M-4-core-4.19.0.txt"; ## CPU CPUINFO/SYS PAIRS DATA FILES ## + ## Android # $ci = "$fake_data_dir/cpu/sys-ci-pairs/android-pocom3-fake-cpuinfo.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/android-pocom3-fake-sys.txt"; + ## ARM # $ci = "$fake_data_dir/cpu/sys-ci-pairs/arm-pine64-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/arm-pine64-sys-1.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/arm-riscyslack2-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/arm-riscyslack2-sys-1.txt"; + ## Elbrus + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/elbrus-e16c-1-cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/elbrus-e16c-1-sys.txt"; + ## PPC # $ci = "$fake_data_dir/cpu/sys-ci-pairs/ppc-stuntkidz~cpuinfo.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/ppc-stuntkidz~sys.txt"; + ## RISCV # $ci = "$fake_data_dir/cpu/sys-ci-pairs/riscv-unmatched-2021~cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/riscv-unmatched-2021~sys-1.txt"; - # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~cpuinfo-1.txt"; - # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~sys-1.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/risc-v-spacemit-8-core-cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/risc-v-spacemit-8-core-sys.txt"; + ## Loongson + $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a5000-hv/cpuinfo.txt"; + $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a5000-hv/cpu-sys.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a5000m/cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a5000m/cpu-sys.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3c5000/cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3c5000/cpu-sys.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3d5000/cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3d5000/cpu-sys.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a6000-hw/cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a6000-hw/cpu-sys.txt"; + # AMD # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-amd-phenom-chrisretusn-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-amd-phenom-chrisretusn-sys-1.txt"; - # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-cpuinfo.txt"; - # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/ryzen-threadripper-1x64-3950x-cpuinfo.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/ryzen-threadripper-1x64-3950x-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/amd-threadripper-1x12-5945wx-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/amd-threadripper-1x12-5945wx-sys-1.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/amd-epyc-2x-16-core-4-die-cpuinfo-1.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/amd-epyc-2x-16-core-4-die-sys-1.txt"; + # Intel + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~cpuinfo-1.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~sys-1.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/intel-i7-1165G7-4-core-no-smt-cpuinfo.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/intel-i7-1165G7-4-core-no-smt-sys.txt"; - # $ci = "$fake_data_dir/cpu/sys-ci-pairs/elbrus-e16c-1-cpuinfo.txt"; - # $sys = "$fake_data_dir/cpu/sys-ci-pairs/elbrus-e16c-1-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/intel-raptor-lake-10-core-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/intel-raptor-lake-10-core-sys-1.txt"; - # $ci = "$fake_data_dir/cpu/sys-ci-pairs/risc-v-spacemit-8-core-cpuinfo.txt"; - # $sys = "$fake_data_dir/cpu/sys-ci-pairs/risc-v-spacemit-8-core-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/intel-xeon-2x12-core-mt-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/intel-xeon-2x12-core-mt-sys-1.txt"; - $ci = "$fake_data_dir/cpu/sys-ci-pairs/amd-epyc-2x-16-core-4-die-cpuinfo-1.txt"; - $sys = "$fake_data_dir/cpu/sys-ci-pairs/amd-epyc-2x-16-core-4-die-sys-1.txt"; $fake_data{'cpuinfo'} = $ci; $fake_data{'sys'} = $sys; } @@ -9687,8 +9892,8 @@ sub cpuinfo_data_grabber { main::log_data('dump','%cpuinfo_machine',\%cpuinfo_machine); } if ($dbg[41]){ - print Data::Dumper::Dumper \@cpuinfo; - print Data::Dumper::Dumper \%cpuinfo_machine; + print 'cpuinfo: ', Data::Dumper::Dumper \@cpuinfo; + print 'cpuinfo_machine: ', Data::Dumper::Dumper \%cpuinfo_machine; } eval $end if $b_log; } @@ -9722,7 +9927,7 @@ sub cpuinfo_data { next if !$block; if ($b_block_1){ $b_block_1 = 0; - # this may also kick in for centaur/via types, but no data available, guess + # this may also kick in for centaur/via/zhaoxin types. zhaoxin shows as centaur if (!$cpu->{'type'} && $block->{'vendor_id'}){ $cpu->{'type'} = cpu_vendor($block->{'vendor_id'}); } @@ -9747,12 +9952,15 @@ sub cpuinfo_data { # print "p0:\n"; } } - elsif ($cpu->{'model_name'} =~ /loongson|godson/i){ + elsif ($risc{'loongson'} || $cpu->{'model_name'} =~ /loong|godson/i){ $cpu->{'type'} = 'loongson'; } elsif ($risc{'mips'} || $cpu->{'model_name'} =~ /mips/i){ $cpu->{'type'} = 'mips'; } + elsif (!%risc && $cpu->{'model_name'} =~ /zhaoxin/i){ + $cpu->{'type'} = 'zhaoxin'; + } } $temp = main::get_defined($block->{'architecture'}, $block->{'cpu family'},$block->{'cpu architecture'}); @@ -9761,11 +9969,14 @@ sub cpuinfo_data { # translate integers to hex $cpu->{'family'} = uc(sprintf("%x",$temp)); } + elsif ($risc{'loongson'}){ + $cpu->{'family'} = $temp; + } elsif ($risc{'arm'}){ $cpu->{'arch'} = $temp; } } - # note: stepping and ARM cpu revision are integers + # note: stepping and ARM cpu revision integers, loongson hex $temp = main::get_defined($block->{'stepping'},$block->{'cpu revision'}); # can be 0, but can be 'unknown' if (defined $temp || @@ -9816,7 +10027,7 @@ sub cpuinfo_data { $block->{'l3 cache size'} =~ /(\d+\s*[KMG])i?B?$/){ $cpu->{'l3-cache'} = main::translate_size($1); } - $temp = main::get_defined($block->{'flags'} || $block->{'features'}); + $temp = main::get_defined($block->{'flags'},$block->{'features'}); if ($temp){ $cpu->{'flags'} = $temp; } @@ -11637,6 +11848,8 @@ sub cp_cpu_arch { # print "type:$type fam:$family model:$model step:$stepping\n"; # Note: AMD family is not Ext fam . fam but rather Ext-fam + fam. # But model is Ext model . model... + # This is very confusing because cpuinfo shows say, family: 23 for 17h, aka 8F + # which gives: 8 + F = 23. hex of which is 17h if ($type eq 'amd'){ if ($family eq '3'){ $arch = 'Am386'; @@ -11712,7 +11925,7 @@ sub cp_cpu_arch { $year = '2003-14';} } # note: family F K8 needs granular breakdowns, was a long lived family - elsif ($family eq 'F'){ + elsif ($family eq 'F'){ # F, aka 15 ## verified # check: B|E|F if ($model =~ /^(4|5|7|8|B|C|E|F)$/){ @@ -11740,7 +11953,7 @@ sub cp_cpu_arch { $year = '2004-2008';} } # K9 was planned but skipped - elsif ($family eq '10'){ # 1F + elsif ($family eq '10'){ # 1F, aka 16 ## verified if ($model =~ /^(2)$/){ $arch = 'K10'; # 2:2:budapest;2:1,3:barcelona @@ -11759,7 +11972,7 @@ sub cp_cpu_arch { } # very loose, all stepping 1: covers athlon x2, sempron, turion x2 # years unclear, could be 2005 start, or 2008 - elsif ($family eq '11'){ # 2F + elsif ($family eq '11'){ # 2F, aka 17 if ($model =~ /^(3)$/){ $arch = 'K11 Turion X2'; # mix of K8/K10 $note = $check; @@ -11767,7 +11980,7 @@ sub cp_cpu_arch { $year = ''; } } # might also need cache handling like 14/16 - elsif ($family eq '12'){ # 3F + elsif ($family eq '12'){ # 3F, aka 18 if ($model =~ /^(1)$/){ $arch = 'K12 Fusion'; # K10 based apu, llano $process = 'GF 32nm'; @@ -11778,7 +11991,7 @@ sub cp_cpu_arch { $year = '2011';} # check years } # SOC, apu - elsif ($family eq '14'){ # 5F + elsif ($family eq '14'){ # 5F, aka 20 if ($model =~ /^(1|2)$/){ $arch = 'Bobcat'; $process = 'GF 40nm'; @@ -11788,7 +12001,7 @@ sub cp_cpu_arch { $process = 'GF 40nm'; $year = '2011-13';} } - elsif ($family eq '15'){ # 6F + elsif ($family eq '15'){ # 6F, aka 21 # note: only model 1 confirmd if ($model =~ /^(0|1|3|4|5|6|7|8|9|A|B|C|D|E|F)$/){ $arch = 'Bulldozer'; @@ -11815,7 +12028,7 @@ sub cp_cpu_arch { $year = '2011-12';} } # SOC, apu - elsif ($family eq '16'){ # 7F + elsif ($family eq '16'){ # 7F, aka 22 if ($model =~ /^(0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F)$/){ $arch = 'Jaguar'; $process = 'GF 28nm'; @@ -11829,7 +12042,7 @@ sub cp_cpu_arch { $process = 'GF 28nm'; $year = '2013-14';} } - elsif ($family eq '17'){ # 8F + elsif ($family eq '17'){ # 8F, aka 23 # can't find stepping/model for no ht 2x2 core/die models, only first ones if ($model =~ /^(1|11|20)$/){ $arch = 'Zen'; @@ -11863,13 +12076,13 @@ sub cp_cpu_arch { $year = '';} } # Joint venture between AMD and Chinese companies. Type amd? or hygon? - elsif ($family eq '18'){ # 9F + elsif ($family eq '18'){ # 9F, aka 24 # model 0, zen 1 $arch = 'Zen (Hygon Dhyana)'; $gen = '1'; $process = 'GF 14nm'; $year = '';} - elsif ($family eq '19'){ # AF + elsif ($family eq '19'){ # AF, aka 25 # zen 4 raphael, phoenix 1 use n5 I believe # Epyc Bergamo zen4c 4nm, only few full model IDs, update when appear # zen4c is for cloud hyperscale @@ -11904,7 +12117,7 @@ sub cp_cpu_arch { $year = '2021-22';} } # Zen 5: TSMC n3/n4, epyc turin / granite ridge? / turin dense zen 5c 3nm - elsif ($family eq '20'){ # BF + elsif ($family eq '1A'){ # BF, aka 26 if ($model =~ /^(0)$/){ $arch = 'Zen 5'; $gen = '5'; @@ -11916,17 +12129,38 @@ sub cp_cpu_arch { $process = 'TSMC n3 (3nm)'; # turin could be 4nm, need more data $year = '2024+';} # Strix Point; Granite Ridge; Krackan Point; Strix Halo - elsif ($model =~ /^(2.|4.|6.|7.)$/){ + elsif ($model =~ /^[2-7].$/){ $arch = 'Zen 5'; $gen = '5'; $process = 'TSMC n4 (4nm)'; # desktop, granite ridge, confirm 2024 $year = '2024+';} + # seen: 90,A0,C0 + elsif ($model =~ /^(9|[A-G]).$/){ + $arch = 'Zen 6'; + $note = '6'; + $process = 'TSMC n2/n3 (2,3nm)'; + $year = '2025+';} else { $arch = 'Zen 5'; $note = $check; $process = 'TSMC n3/n4 (3,4nm)'; $year = '2024+';} } + # note: no live data on zen 7 yet + elsif ($family eq '1B'){ # CF, aka 27 + $arch = 'Zen 7'; + $note = $check; + $process = 'TSMC n2/n3 (2,3nm)'; + $year = '2026+'; + } + # this is a guess + elsif ($family eq '1D'){ # DF, aka 28 + $arch = 'Zen 8'; + $note = $check; + $process = 'TSMC a14 (1.4nm)'; + $year = '2027+'; + } + # Roadmap: check to verify, AMD is usually closer to target than Intel # Epyc 4 genoa: zen 4, nm, 2022+ (dec 2022), cxl-1.1,pcie-5, ddr-5 } @@ -11983,18 +12217,16 @@ sub cp_cpu_arch { elsif ($stepping <= 12){ $arch = 'Via Isaah';} elsif ($stepping <= 13){ + $arch = 'Via Isaah';} + # these are both stepping E + elsif ($stepping <= 14){ $arch = 'Via Eden';} elsif ($stepping <= 14){ $arch = 'Zhaoxin ZX';} - $process = '90nm'; # guess - $year = '';} - } - elsif ($family eq '7'){ - if ($model =~ /^(1.|3.)$/){ - $arch = 'Zhaoxin ZX'; - $process = '90nm'; # guess - $year = ''; - } + $process = '40nm'; + $year = '2014';} + elsif ($model =~ /^(47)$/){ + $arch = 'Centaur CNS';} } } # note, to test uncoment $cpu{'type'} = Elbrus in proc/cpuinfo logic @@ -12433,6 +12665,15 @@ sub cp_cpu_arch { $arch = 'Emerald Rapids'; # 5th gen xeon $process = 'Intel 7 (10nm)'; $year = '2023+';} + elsif ($model =~ /^(D5)$/){ + $arch = 'Wildcat Lake'; + $process = 'Intel 18a (1.8nm)'; + $year = '2025+';} + elsif ($model =~ /^(D7)$/){ + $arch = 'Bartlett Lake'; + $note = $check; # confirm process + $process = 'Intel 18a (1.8nm)'; + $year = '2026+';} elsif ($model =~ /^(DD)$/){ $arch = 'Clearwater Forest'; $process = 'Intel 18a (1.8nm)'; @@ -12530,27 +12771,27 @@ sub cp_cpu_arch { # can't safely match model 1, but nobody will run inxi on that # Not certain when SMIC took over from STM, which is a swiss firm. if ($name =~ /\b2[BCE]\b/){ - $arch = 'Godson'; + $arch = 'Godson-1'; $process = 'STM 180nm'; $year = '2003-2006';} elsif ($name =~ /\b1[ABCD]\b/){ - $arch = 'Loongson-1'; + $arch = 'Godson-1/Loongson-1'; $process = 'STM 130nm'; $year = '2010-2014';} elsif ($name =~ /\b1C101/){ - $arch = 'Loongson-1'; + $arch = 'Godson-1/Loongson-1'; $process = 'STM 130nm'; $year = '2018';} elsif ($name =~ /\b2F\b/){ - $arch = 'Loongson-2'; + $arch = 'Godson-2/Loongson-2'; $process = 'STM 90nm'; $year = '2007';} elsif ($name =~ /\b2[GIH]\b/){ - $arch = 'Loongson-2'; + $arch = 'Godson-2/Loongson-2'; $process = 'STM 65nm'; $year = '2012-2013';} elsif ($name =~ /\b2K(1000)?\b/){ - $arch = 'Loongson-2'; + $arch = 'Godson-2/Loongson-2'; $process = 'STM 40nm'; $year = '2017';} elsif ($name =~ /3A1000/){ @@ -12581,10 +12822,71 @@ sub cp_cpu_arch { $arch = 'Loongson-3/LoongArch'; $process = 'SMIC 12-14nm'; $year = '2021+';} - elsif ($name =~ /3[A-C]6000/){ + elsif ($name =~ /3[D]5000/){ + $arch = 'Loongson-3/LoongArch'; + $process = 'SMIC 12-14nm'; + $year = '2023+';} + elsif ($name =~ /3[AB]6000/){ $arch = 'Loongson-3/LoongArch'; $process = 'SMIC 12-14nm'; $year = '2023+';} + elsif ($name =~ /3[CD]6000/){ + $arch = 'Loongson-3/LoongArch'; + $process = 'SMIC 12-14nm'; + $year = '2024+';} + elsif ($name =~ /3[A-D]7000/){ + $arch = 'Loongson-3/LoongArch'; + $process = 'SMIC 7nm'; + $year = '2025+';} + } + # this is an x86_64 cpu so has full CPUID + elsif ($type eq 'zhaoxin'){ + # family 1-6 was via and very early zhaoxin + if ($family eq '6'){ + # no model IDs for first gen via clones + # A?000 KaiXian, A??000 Kaisheng; Successor to via isiah 2 + if ($model =~ /^\d$/){ # guess early + $arch = 'VIA-Isaiah2'; + $process = 'TSMC 40nm'; + $year = '2014+';} + # B3000 KaiXian, B3000 Kaisheng; Successor to via isiah 2 + elsif ($model =~ /^x$/){ + $arch = 'VIA-Isaiah2'; + $process = 'TSMC 40nm'; + $year = '2014-15+';} + # C,C+4000 KaiXian, C+4000 Kaisheng; Successor to via isiah 2 + elsif ($model =~ /^([A-F]|1\d)$/){ # seen F, 19 + $arch = 'ZhangJian'; + $process = 'HLMC 28nm'; # also reported as TSMC + $year = '2015+';} + # D4600 + elsif ($model =~ /^(1[A-F])$/){ # seen 1F + $arch = 'ZhangJian'; + $process = 'HLMC 28nm'; # also reported as TSMC + $year = '2015+';} + } + elsif ($family eq '7'){ + # KX5000 KaiXian, KH20000 Kaisheng, seen: 1B + if ($model =~ /^(.|1.)$/){ # seen B + $arch = 'WuDaoKou'; + $process = 'HLMC 28nm'; # also reported as TSMC + $year = '2017+';} + # KX6000 KaiXian, KH30000 Kaisheng, seen: 3B + elsif ($model =~ /^3.$/){ + $arch = 'LuJiaZui'; + $process = 'TSMC 16nm'; + $year = '2019+';} + # KH40000 Kaisheng + elsif ($model =~ /^(5.)$/){ # seen 5B for 40000 + $arch = 'YongFeng'; # 世纪大道 + $process = '16nm'; # smic? + $year = '2023+';} + # KZ,KX7000 KaiXian + elsif ($model =~ /^[67].$/){ # guess + $arch = 'Shijidadao'; + $process = '7nm'; # smic,huawei 7nm? + $year = '2024+';} + } } eval $end if $b_log; return [$arch,$note,$process,$gen,$year]; @@ -12800,15 +13102,15 @@ sub cpu_vendor { my $string = $_[0]; my $vendor = ''; $string = lc($string); - if ($string =~ /intel/){ + if ($string =~ /intel/i){ $vendor = "intel"; } - elsif ($string =~ /amd/){ + elsif ($string =~ /amd/i){ $vendor = "amd"; } - # via/centaur/zhaoxin branding - elsif ($string =~ /centaur|zhaoxin/){ - $vendor = "centaur"; + # via/centaur/zhaoxin branding, but zhaoxin shows centaurhauls as vendor + elsif ($string =~ /(centaur|zhaoxin)/i){ + $vendor = lc($1); } elsif ($string eq 'elbrus'){ $vendor = "elbrus"; @@ -14219,14 +14521,14 @@ sub set_disk_vendors { ['(\bINTEL\b|^(SSD(PAM|SA2)|HBR|(MEM|SSD)PEB?K|SSD(MCE|S[AC])))','\bINTEL\b','Intel',''], ['^(Intel[\s_-]?)?SRCSAS?','^Intel','Intel RAID',''], # note: S[AV][1-9]\d can trigger false positives - ['(K(ING)?STON|^(A400|ASTC|OM8P|RBU|S100\d\d|S[AV][1234]00|S[HMN]S|SK[CY]|SQ5|SS200|SVP|SS0|SUV|SNV|T52|T[ABY]29|Y29\d|Ultimate CF)|V100|DataTraveler|DT\s?(DUO|Microduo|101)|HyperX|13fe\b)','(KINGSTON|13fe)','Kingston',''], # maybe SHS: SHSS37A SKC SUV + ['(K(ING)?STON|^(A29\d\d\d|A400|ASTC|OM8P|Fury|RBU|S100\d\d|S[AV][1234]00|S[HMN]S|SK[CY]|SQ5|SS200|SVP|SS0|SUV|SNV|T52|T[ABY]29|Y29\d|Ultimate CF)|V100|DataTraveler|DT\s?(DUO|Microduo|101)|HyperX|13fe\b)','(KINGSTON|13fe)','Kingston',''], # maybe SHS: SHSS37A SKC SUV # must come before samsung MU. NOTE: toshiba can have: TOSHIBA_MK6475GSX: mush: MKNSSDCR120GB_ ['(^MKN|Mushkin)','Mushkin','Mushkin',''], # MKNS # MU = Multiple_Flash_Reader too risky: |M[UZ][^L] HD103SI HD start risky # HM320II HM320II HM - ['(SAMSUNG|^(AGN[BD]|AWMB|[BC]DS20|[BCD]WB|BJ[NT]|[BC]GND|CJ[NT]|CKT|CUT|[DG]3 Station|DUO\b|DUT|EB\dMW|E[CS]\d[A-Z]\d|ED2|EE4|FD\d[A-Z]\d|[GS]2 Portable|GE4|GN|HD\d{3}[A-Z]{2}$|(HM|SP)\d{2}|HS\d|KLUD|M[AB]G\d[FG]|MCC|MCBOE|MCG\d+GC|[CD]JN|MZ|^G[CD][1-9][QS]|P[BM]\d|(SSD\s?)?SM\s?841)|^SSD\s?[89]\d{2}\s(DCT|PRO|QVD|\d+[GT]B)|\bEVO\b|SV\d|[BE][A-Z][1-9]QT|YP\b|[CH]N-M|MMC[QR]E)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM + ['(SAMSUNG|^(A[GJ]N[BD]|AWMB|[BC]DS20|[BCD]WB|BJ[NT]|[BC]GND|CJ[NT]|CKT|CUT|[DG]3 Station|DUO\b|DUT|EB\dMW|E[CS]\d[A-Z]\d|ED2|EE4|FD\d[A-Z]\d|[GS]2 Portable|GE4|GN|HD\d{3}[A-Z]{2}$|(HM|SP)\d{2}|HS\d|KLUD|M[AB]G\d[FG]|MCC|MCBOE|MCG\d+GC|[CD]JN|MZ|^G[CD][1-9][QS]|P[BM]\d|(SSD\s?)?SM\s?841)|^SSD\s?[89]\d{2}\s(DCT|PRO|QVD|\d+[GT]B)|\bEVO\b|SV\d|[BE][A-Z][1-9]QT|YP\b|[CH]N-M|MMC[QR]E)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM # Android UMS Composite?U1 - ['(SanDisk|0781|^(A[BCD]LC[DE]|AFGCE|D[AB]4|DX[1-9]|Extreme|EZSD|Firebird|S[CD]\d{2}G|SB\d+G|SC\d{3,4}|SD(CF|S[S]?[ADQ]|SL\d+G|SU\d|U\d|\sUltra)|SDW[1-9]|SE\d{2}|SEM\d{2}|\d[STU]|U(3\b|1\d0))|Clip Sport|Cruzer|iXpand|SN(\d+G|128|256)|SSD (Plus|U1[01]0) [1-9]|SU(02|04|08|16|32|64)G|ULTRA\s(FIT|trek|II)|^X[1-6]\d{2})','(SanDisk|0781)','SanDisk',''], + ['(SanDisk|0781|^(A[BCD]LC[DE]|AFGCE|D[AB]4|DX[1-9]|Extreme|EZSD|Firebird|MDG|S[CD]\d{2}G|SB\d+G|SC\d{3,4}|SD(CF|S[S]?[ADQ]|SL\d+G|SU\d|U\d|\sUltra)|SDW[1-9]|SE\d{2}|SEM\d{2}|\d[STU]|U(3\b|1\d0))|Clip Sport|Cruzer|iXpand|SN(\d+G|128|256)|SSD (Plus|U1[01]0) [1-9]|SU(02|04|08|16|32|64)G|ULTRA\s(FIT|trek|II)|^X[1-6]\d{2})','(SanDisk|0781)','SanDisk',''], # these are HP/Sandisk cobranded. DX110064A5xnNMRI ids as HP and Sandisc ['(^DX[1-9])','^(HP\b|SANDDISK)','Sandisk/HP',''], # ssd drive, must come before seagate ST test # real, SSEAGATE Backup+; XP1600HE30002 | 024 HN (spinpoint) ; possible usb: 24AS @@ -14335,7 +14637,7 @@ sub set_disk_vendors { ['^BIOSTAR','^BIOSTAR','Biostar',''], ['^BIWIN','^BIWIN','BIWIN',''], ['^Blackpcs','^Blackpcs','Blackpcs',''], - ['^(BlitzWolf|BW-?PSSD)','^BlitzWolf','BlitzWolf',''], + ['^(BlitzWolf|BW)','^BlitzWolf','BlitzWolf',''], ['^(BlueCase|BS2N\d)','^BlueCase[\s-]?(Horizon)?','BlueCase Horizon',''], ['^(Blue[\s-]?Feather|BF\d)','^Blue[\s-]?Feather','Blue Feather',''], ['^(BlueRay|SDM\d)','^BlueRay','BlueRay',''], @@ -14364,6 +14666,7 @@ sub set_disk_vendors { ['^CnMemory|Spaceloop','^CnMemory','CnMemory',''], ['^(Creative|(Nomad\s?)?MuVo)','^Creative','Creative',''], ['^CSD','^CSD','CSD',''], + ['^(Cusu|CV\d\d\d)','^Cusu','Cusu',''], ['^CYX\b','^CYX','CYX',''], ['^(Dane-?Elec|Z Mate)','^Dane-?Elec','DaneElec',''], ['^DATABAR','^DATABAR','DataBar',''], @@ -14473,6 +14776,7 @@ sub set_disk_vendors { # Wilk Elektronik SA, poland ['^((Wilk|WE)\s*)?(GOODRAM|GOODDRIVE|IR[\s-]?SSD|IRP|SSDPR|Iridium)','^GOODRAM','GOODRAM',''], ['^(Gost)','^Gost','Gost',''], + ['^(Graviton)','^Graviton','Graviton-Enclosure',''], ['^(GreatWall|GW\d{3})','^GreatWall','GreatWall',''], ['^(GreenHouse|GH\b)','^GreenHouse','GreenHouse',''], ['^Gritronix','^Gritronixx?','Gritronix',''], @@ -14497,6 +14801,7 @@ sub set_disk_vendors { ['^(HMZM)','^HMZM','HMZM',''], ['^Hoodisk','^Hoodisk','Hoodisk',''], ['^(HRUIYL)','^HRUIYL','HRUIYL',''], + ['^(HUADISK|HY)','^HUADISK','HUADISK',''], ['^(HUAWEI|HWE)','^HUAWEI','Huawei',''], ['^Hypertec','^Hypertec','Hypertec',''], ['^HyperX','^HyperX','HyperX',''], @@ -14515,7 +14820,7 @@ sub set_disk_vendors { ['^(Infokit)','^Infokit','Infokit',''], # note: Initio default controller, means master/slave jumper is off/wrong, not a vendor ['^Inland','^Inland','Inland',''], - ['^(InnoDisk|DEM\d|Innolite|SATA\s?Slim|DRPS)','^InnoDisk( Corp.)?','InnoDisk',''], + ['^(InnoDisk|DEM\d|EverGreen|Innolite|SATA\s?Slim|DRPS)','^InnoDisk( Corp.)?','InnoDisk',''], ['(Innostor|1f75)','(Innostor|1f75)','Innostor',''], ['(^Innovation|Innovation\s?IT)','Innovation(\s*IT)?','Innovation IT',''], ['^Innovera','^Innovera','Innovera',''], @@ -14547,7 +14852,7 @@ sub set_disk_vendors { ['(Kaizen|KZ\d\d)','Kaizen','Kaizen',''], ['^Kazuk','^Kazuk','Kazuk',''], ['(\bKDI\b|^OM3P)','\bKDI\b','KDI',''], - ['^KEEPDATA','^KEEPDATA','KeepData',''], + ['^(KEEPDATA|KD)','^KEEPDATA','KeepData',''], ['^KLLISRE','^KLLISRE','KLLISRE',''], ['^KimMIDI','^KimMIDI','KimMIDI',''], ['^Kimtigo','^Kimtigo','Kimtigo',''], @@ -14558,6 +14863,7 @@ sub set_disk_vendors { ['(KingDian|^NGF|S(280|400))','KingDian','KingDian',''], ['^(Kingfast|TYFS|2710)','^Kingfast','Kingfast',''], ['^KingMAX','^KingMAX','KingMAX',''], + ['^(KingPrice|KP)','^KingPrice','KingPrice',''], ['^Kingrich','^Kingrich','Kingrich',''], ['^Kingsand','^Kingsand','Kingsand',''], ['KING\s?SHA\s?RE','KING\s?SHA\s?RE','KingShare',''], @@ -14573,10 +14879,12 @@ sub set_disk_vendors { ['^(KNUP|KP\b)','^KNUP','KNUP',''], ['^(Kodak|Memory\s?Saver)','^Kodak','Kodak',''], ['^(KOOTION|X12)','^KOOTION','KOOTION',''], + ['^(Kowin|KW)','^Kowin','Kowin',''], ['^(KUAIKAI|MSAM)','^KUAIKAI','KuaKai',''], ['(KUIJIA|DAHUA)','^KUIJIA','KUIJIA',''], ['^KUNUP','^KUNUP','KUNUP',''], ['^KUU','^KUU\b','KUU',''], # KUU-128GB + ['^(Kioxia|KYO)','^Kioxia','Kioxia',''], ['^(Lacie|P92|itsaKey|iamaKey)','^Lacie','LaCie',''], ['^LANBO','^LANBO','LANBO',''], ['^LankXin','^LankXin','LankXin',''], @@ -14616,6 +14924,7 @@ sub set_disk_vendors { ['^MARVELL','^MARVELL','Marvell',''], ['^Maxsun','^Maxsun','Maxsun',''], ['^(McQuest)','^McQuest([\s-]?Digital)?','McQuest Digital',''], + ['^(MCTECH)','^MCTECH','MCTECH',''], ['^MDT\b','^MDT','MDT (rebuilt WD/Seagate)',''], # mdt rebuilds wd/seagate hdd # MD1TBLSSHD, careful with this MD starter!! ['^MD[1-9]','^Max\s*Digital','MaxDigital',''], @@ -14624,6 +14933,7 @@ sub set_disk_vendors { ['^(MEDIAMAX|WL\d{2})','^MEDIAMAX','MediaMax',''], ['^(Memorex|TravelDrive|TD\s?Classic)','^Memorex','Memorex',''], ['^Mengmi','^Mengmi','Mengmi',''], + ['^MLD','^MLD','MLD',''], ['^MGTEC','^MGTEC','MGTEC',''], ['^MicroFrom','^MicroFrom','MicroFrom',''], ['^(MILLENNIUM[\s-]?TECHNOLOGY|MIL\d\d)','^MILLENNIUM[\s-]?TECHNOLOGY','Millenium Technology',''], @@ -14672,6 +14982,7 @@ sub set_disk_vendors { ['(Origin|Inception|^TLC\d)','^Origin','Origin',''], ['^Ortial','^Ortial','Ortial',''], ['^OSC','^OSC\b','OSC',''], + ['^OV','^OV','OV',''], ['^(Ovation)','^Ovation','Ovation',''], ['^oyunkey','^oyunkey','Oyunkey',''], ['^PALIT','PALIT','Palit',''], # ssd @@ -14682,7 +14993,7 @@ sub set_disk_vendors { ['^PERC\b','','Dell PowerEdge RAID Card',''], # ssd ['(\bPhilips)','\bPhilips','Philips',''], ['(PHISON[\s-]?|ESR\d|PS[5E]|311CD|\bSSG\d\d)','PHISON[\s-]?','Phison',''],# E12-256G-PHISON-SSD-B3-BB1 - ['^(Pichau[\s-]?Gaming|PG\d{2})','^Pichau[\s-]?Gaming','Pichau Gaming',''], + ['^(Pichau|PG\d{2}|PCH[-s_-])','^Pichau[\s-]?(Gaming)?','Pichau',''], ['^Pioneer','Pioneer','Pioneer',''], ['^Platinet','Platinet','Platinet',''], ['^(PLEXTOR|PX-)','^PLEXTOR','Plextor',''], @@ -14751,8 +15062,9 @@ sub set_disk_vendors { ['^(SMART( Storage Systems)?|TX)','^(SMART( Storage Systems)?)','Smart Storage Systems',''], ['^Sobetter','^Sobetter','Sobetter',''], ['^Solidata','^Solidata','Solidata',''], - ['^(SOLIDIGM|SSDPFK)','^SOLIDIGM\b','solidgm',''], + ['^(SOLIDIGM|SSDPFK|P41PL)','^SOLIDIGM\b','Solidgm',''], ['^(Sony|IM9|Microvalut|S[FR]-)','^Sony','Sony',''], + ['^Speed[\s_-]?Star','^Speed[\s_-]?Star','Speed Star',''], # Note: SSC can be prefix for several companies ['^SSK\b','^SSK','SSK',''], ['^(SSSTC|CL1-)','^SSSTC','SSSTC',''], @@ -14781,6 +15093,7 @@ sub set_disk_vendors { ['^(TDK|TF[1-9]\d|LoR)','^TDK','TDK',''], ['(^TEAC|\bUF00)','^TEAC','TEAC',''], ['^(TEAM|T[\s-]?Create|CX[12]\b|L\d\s?Lite|T\d{3,}[A-Z]|TM\d|(Dark\s?)?L3\b|T[\s-]?Force)','^TEAM(\s*Group)?','TeamGroup',''], + ['^(Techbyte|TEC[\s_-])','^Techbyte','Techbyte',''], ['^(Teclast|CoolFlash)','^Teclast','Teclast',''], ['^(tecmiyo)','^tecmiyo','TECMIYO',''], ['^Teelkoou','^Teelkoou','Teelkoou',''], @@ -14797,11 +15110,12 @@ sub set_disk_vendors { ['^TopSunligt','^TopSunligt','TopSunligt',''], # is this a typo? hard to know ['^TopSunlight','^TopSunlight','TopSunlight',''], ['^TOROSUS','^TOROSUS','Torosus',''], - ['(Transcend|^((SSD\s|F)?TS|ESD\d|EZEX|USDU)|1307|JetDrive|JetFlash)','\b(Transcend|1307)\b','Transcend',''], + ['(Transcend|^((ATA\s|SSD\s|F)?TS|ESD\d|EZEX|USDU)|1307|JetDrive|JetFlash)','\b(Transcend|1307)\b','Transcend',''], ['^(TrekStor|DS (maxi|pocket)|DataStation)','^TrekStor','TrekStor',''], ['^Turbox','^Turbox','Turbox',''], ['^TurXun','^TurXun','TurXun',''], ['^(TwinMOS|TW\d)','^TwinMOS','TwinMOS',''], + ['^(TWSC|TSC\d)','^TWSC','TWSC',''], # note: udisk means usb disk, it's not a vendor ID ['^UDinfo','^UDinfo','UDinfo',''], ['^UMAX','^UMAX','UMAX',''], @@ -14829,6 +15143,7 @@ sub set_disk_vendors { ['^(Visipro|SDVP)','^Visipro','Visipro',''], ['^VISIONTEK','^VISIONTEK','VisionTek',''], ['^VMware','^VMware','VMware',''], + ['^(VSP)','^VSP[\s_-]?Tech(nology)?','VSP Technology',''], ['^(Vseky|Vaseky|V8\d{2})','^Vaseky','Vaseky',''], # ata-Vseky_V880_350G_ ['^(Walgreen|Infinitive)','^Walgreen','Walgreen',''], ['^Walram','^Walram','WALRAM',''], @@ -14840,7 +15155,7 @@ sub set_disk_vendors { ['^(wicgtyp|[MN][V]?900)','^wicgtyp','wicgtyp',''], ['^Wilk','^Wilk','Wilk',''], ['^(WinMemory|SW[GR]\d)','^WinMemory','WinMemory',''], - ['^(Winton|WT\d{2})','^Winton','Winton',''], + ['^(Winten|WT(\d{2}|M2))','^Winten','Winten',''], ['^(WISE)','^WISE','WISE',''], ['^WPC','^WPC','WPC',''], # WPC-240GB ['^(Wortmann(\sAG)?|Terra\s?US)','^Wortmann(\sAG)?','Wortmann AG',''], @@ -18448,7 +18763,7 @@ sub set_amd_data { 'years' => '2022+', }, {'arch' => 'RDNA-3', - 'ids' => '73f0|7480|7481|7483|7487|7489|748b|7499', + 'ids' => '73f0|7480|7481|7483|7487|7489|748b|7499|749f', 'code' => 'Navi-3x', 'process' => 'TSMC n6 (6nm)', 'years' => '2023+', @@ -18459,6 +18774,12 @@ sub set_amd_data { 'process' => 'TSMC n4 (4nm)', 'years' => '2023+', }, + {'arch' => 'RDNA-4', + 'ids' => '7550|7551|7590', + 'code' => 'Navi-4x', + 'process' => 'TSMC n4 (4nm)', + 'years' => '2025+', + }, {'arch' => 'CDNA-1', 'ids' => '7388|738c|738e', 'code' => 'Instinct-MI1xx', @@ -18472,7 +18793,7 @@ sub set_amd_data { 'years' => '2021-22+', }, {'arch' => 'CDNA-3', - 'ids' => '74a0|74a1|74a2|74a5|74a9|74b5|74bd', + 'ids' => '74a0|74a1|74a2|74a5|74a9|74b5|74b9|74bd', 'code' => 'Instinct-MI3xx', 'process' => 'TSMC n5 (5nm)', 'years' => '2023+', @@ -18576,8 +18897,9 @@ sub set_intel_data { 'years' => '2012-13', }, {'arch' => 'Gen-8', - 'ids' => '1602|1606|160a|160b|160d|160e|1612|1616|161a|161b|161d|161e|1622|' . - '1626|162a|162b|162d|162e|1632|1636|163a|163b|163d|163e|22b0|22b1|22b2|22b3', + 'ids' => '0d22|1602|1606|160a|160b|160d|160e|1612|1616|161a|161b|161d|161e|' . + '1622|1626|162a|162b|162d|162e|1632|1636|163a|163b|163d|163e|22b0|22b1|22b2|' . + '22b3', 'code' => '', 'process' => 'Intel 14nm', 'years' => '2014-15', @@ -18602,9 +18924,9 @@ sub set_intel_data { }, # gen10 was cancelled. {'arch' => 'Gen-11', - 'ids' => '0d16|0d26|0d36|4541|4551|4555|4557|4571|4e51|4e55|4e57|4e61|4e71|' . - '8a50|8a51|8a52|8a53|8a54|8a56|8a57|8a58|8a59|8a5a|8a5b|8a5c|8a5d|8a70|8a71|' . - '9840|9841', + 'ids' => '0d12|0d16|0d26|0d36|4541|4551|4555|4557|4571|4e51|4e55|4e57|4e61|' . + '4e71|8a50|8a51|8a52|8a53|8a54|8a56|8a57|8a58|8a59|8a5a|8a5b|8a5c|8a5d|8a70|' . + '8a71|9840|9841', 'code' => '', 'process' => 'Intel 10nm', 'years' => '2019-21', @@ -18652,21 +18974,28 @@ sub set_intel_data { 'years' => '2023+', }, {'arch' => 'Xe2', - 'ids' => 'e202|e20b|e20c|e20d|e210|e212|e215|e216', + 'ids' => 'e202|e20b|e20c|e20d|e210|e211|e212|e215|e216', 'code' => '', 'process' => 'TSMC n4 (4nm)', 'years' => '2024+', }, {'arch' => 'Xe2', - 'ids' => '6420|64a0|64b0|b080|b081|b082|b083|b08f|b090|b0a0|b0b0', + 'ids' => '6420|64a0|64b0', 'code' => '', 'process' => 'TSMC n3 (3nm)', 'years' => '2024+', }, - {'arch' => 'Xe-LPG', + {'arch' => 'Xe2-LPG', 'ids' => '7d41|7d51|7d67|7dd1|b640', 'code' => '', - 'process' => 'TSMC 3nm?', + 'process' => 'TSMC n3 (3nm)', + 'years' => '2025+', + }, + {'arch' => 'Xe3', + 'ids' => 'b080|b081|b082|b083|b084|b085|b086|b087|b08f|b090|b0a0|b0b0|fd80|' . + 'fd81', + 'code' => '', + 'process' => 'TSMC 18A', 'years' => '2025+', }, ]; @@ -18900,7 +19229,7 @@ sub set_nv_data { 'legacy' => 0, 'process' => 'TSMC 28nm', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2014-2019', @@ -18917,7 +19246,7 @@ sub set_nv_data { 'legacy' => 0, 'process' => 'TSMC 16nm', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2016-2021', @@ -18929,25 +19258,25 @@ sub set_nv_data { 'legacy' => 0, 'process' => 'TSMC 12nm', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2017-2020', }, {'arch' => 'Turing', 'ids' => '1e02|1e04|1e07|1e09|1e30|1e36|1e78|1e81|1e82|1e84|1e87|1e89|1e90|' . - '1e91|1e93|1eb0|1eb1|1eb5|1eb6|1ec2|1ec7|1ed0|1ed1|1ed3|1ef5|1f02|1f03|1f06|' . - '1f07|1f08|1f0a|1f0b|1f10|1f11|1f12|1f14|1f15|1f36|1f42|1f47|1f50|1f51|1f54|' . - '1f55|1f76|1f82|1f83|1f91|1f95|1f96|1f97|1f98|1f99|1f9c|1f9d|1f9f|1fa0|1fb0|' . - '1fb1|1fb2|1fb6|1fb7|1fb8|1fb9|1fba|1fbb|1fbc|1fdd|1ff0|1ff2|1ff9|2182|2184|' . - '2187|2188|2189|2191|2192|21c4|21d1|25a6|25a7|25a9|25aa|25ad|25ed|28b0|28b8|' . - '28f8', + '1e91|1e93|1eb0|1eb1|1eb5|1eb6|1eb8|1ec2|1ec7|1ed0|1ed1|1ed3|1ef5|1f02|1f03|' . + '1f06|1f07|1f08|1f0a|1f0b|1f10|1f11|1f12|1f14|1f15|1f36|1f42|1f47|1f50|1f51|' . + '1f54|1f55|1f76|1f82|1f83|1f91|1f95|1f96|1f97|1f98|1f99|1f9c|1f9d|1f9f|1fa0|' . + '1fb0|1fb1|1fb2|1fb6|1fb7|1fb8|1fb9|1fba|1fbb|1fbc|1fdd|1ff0|1ff2|1ff9|2182|' . + '2184|2187|2188|2189|2191|2192|21c4|21d1|25a6|25a7|25a9|25aa|25ad|25ed|28b0|' . + '28b8|28f8', 'code' => 'TUxxx', 'kernel' => '', 'legacy' => 0, 'process' => 'TSMC 12nm FF', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2018-2022', @@ -18959,13 +19288,13 @@ sub set_nv_data { '24b1|24b6|24b7|24b8|24b9|24ba|24bb|24c7|24c9|24dc|24dd|24e0|24fa|2503|2504|' . '2507|2508|2520|2521|2523|2531|2544|2560|2563|2571|2582|2584|25a0|25a2|25a5|' . '25ab|25ac|25b0|25b2|25b6|25b8|25b9|25ba|25bb|25bc|25bd|25e0|25e2|25e5|25ec|' . - '25f9|25fa|25fb|2822|2838|28a3', + '25f9|25fa|25fb|2822|2838|28a3|28e3', 'code' => 'GAxxx', 'kernel' => '', 'legacy' => 0, 'process' => 'TSMC n7 (7nm)', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2020-2023', @@ -18977,7 +19306,7 @@ sub set_nv_data { 'legacy' => 0, 'process' => 'TSMC n4 (5nm)', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => $status_current, 'xorg' => '', 'years' => '2022+', @@ -18986,25 +19315,27 @@ sub set_nv_data { 'ids' => '2684|2685|2689|26b1|26b2|26b3|26b5|26b9|26ba|2702|2704|2705|2709|' . '2717|2730|2757|2770|2782|2783|2786|2788|27a0|27b0|27b1|27b2|27b6|27b8|27ba|' . '27bb|27e0|27fb|2803|2805|2808|2820|2860|2882|28a0|28a1|28b0|28b9|28ba|28bb|' . - '28e0|28e1|2b85|2b87|2c02', + '28e0|28e1|2b85|2b87|2b8c|2c02|2c05|2c18|2c19|2c58|2c59|2d04|2d05|2d18|2d19|' . + '2d58|2d59|2d83|2d98|2dd8|2f04|2f18|2f58', 'code' => 'AD1xx', 'kernel' => '', 'legacy' => 0, 'process' => 'TSMC n4 (5nm)', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => $status_current, 'xorg' => '', 'years' => '2022+', }, {'arch' => 'Blackwell', - 'ids' => '2901', + 'ids' => '2901|2941|2bb1|2bb3|2bb4|2bb5|2c31|2c33|2c34|2c38|2c39|2d30|2d39|' . + '2db8|2db9|2f38', 'code' => 'GB2xx', 'kernel' => '', 'legacy' => 0, 'process' => 'TSMC 4np (5nm)', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => $status_current, 'xorg' => '', 'years' => '2024+', @@ -20150,7 +20481,7 @@ sub machine_output { } $bios_date ||= 'N/A'; if ($extra > 1 && $data->{'bios_romsize'}){ - $bios_romsize = $data->{'bios_romsize'}; + $bios_romsize = main::get_size($data->{'bios_romsize'},'string'); } $rows->[$j]{main::key($num++,1,1,'Mobo')} = $mobo_vendor; $rows->[$j]{main::key($num++,1,2,'model')} = $mobo_model; @@ -20535,7 +20866,12 @@ sub machine_data_dmi { elsif ($value[0] eq 'Version'){ $data->{'bios_version'} = main::clean_dmi($value[1]) } elsif ($value[0] eq 'ROM Size'){ - $data->{'bios_romsize'} = main::clean_dmi($value[1]) } + $data->{'bios_romsize'} = main::clean_dmi($value[1]); + # Translate to KiB + if ($data->{'bios_romsize'} =~ /(\d+\s*[kKMG])i?B?$/){ + $data->{'bios_romsize'} = main::translate_size($1); + } + } elsif ($value[0] eq 'BIOS Revision'){ $data->{'bios_rev'} = main::clean_dmi($value[1]) } } @@ -25590,6 +25926,7 @@ sub set_ram_vendors { ['^(AX[\d]{4}|Axiom)','Axiom','Axiom',''], ['^(BD\d|Black[s-]?Diamond)','Black[s-]?Diamond','Black Diamond',''], ['^(-BN$|Brute[s-]?Networks)','Brute[s-]?Networks','Brute Networks',''], + ['^(CXMT|ChangXin)','ChangXin([s-]?Memory[s-]?Technologies)?','CXMT',''], ['^(CM|Corsair)','Corsair','Corsair',''], ['^(CT\d|BL|Crucial)','Crucial','Crucial',''], ['^(CY|Cypress)','Cypress','Cypress',''], @@ -30073,7 +30410,7 @@ sub set_dboot_data { { package DesktopData; my ($b_dbg_de,$desktop_session,$gdmsession,$kde_full_session, -$kde_session_version,$tk_test,$xdg_desktop,@data,%xprop); +$kde_session_version,$tk_test,$windowmanager,$xdg_desktop,@data,%xprop); my $desktop = []; sub get { @@ -30287,11 +30624,13 @@ sub de_kde_tde_data { $kded = $program; $kded_name = 'kded'; } - # note: if TDM is used to start kde, can pass ps tde test + # note: if TDM is used to start kde, can pass ps tde test. To avoid this, + # in some cases WINDOWMANAGER is set with starttde|startkde|startplasma if ($desktop_session eq 'trinity' || $xdg_desktop eq 'trinity' || - (!$desktop_session && !$xdg_desktop && @{$ps_data{'de-ps-detect'}} && - (grep {/^tde/} @{$ps_data{'de-ps-detect'}}))){ - # 14.2 moved kdesktop to location not in PATH in some distros, so either of these will fail + $windowmanager =~ /starttde/ || + (!$desktop_session && !$xdg_desktop && $windowmanager !~ /start(kde|plasma)/ && + @{$ps_data{'de-ps-detect'}} && (grep {/^tde/} @{$ps_data{'de-ps-detect'}}))){ + # 14.2 moved kdesktop to location not in PATH in some distros, so eithe# start of these will fail if (($program = main::check_program('kdesktop')) || ($program = main::check_program('twin'))){ ($desktop->[0],$desktop->[1],$v_data) = ProgramData::full('kdesktop-trinity',$program,0,'raw'); @@ -30308,8 +30647,10 @@ sub de_kde_tde_data { # KDE_SESSION_VERSION is the integer version of the desktop # NOTE: as of plasma 5, the tool: about-distro MAY be available, that will show # actual desktop data, so once that's in debian/ubuntu, if it gets in, add that test + # corner case root start, all env variables empty except WINDOWMANAGER elsif ($desktop_session eq 'kde-plasma' || $desktop_session eq 'plasma' || - $xdg_desktop eq 'kde' || $kde_session_version){ + $xdg_desktop eq 'kde' || $kde_session_version || + ($windowmanager && $windowmanager =~ /start(kde|plasma)/)){ # KDE <= 4 if ($kde_session_version && $kde_session_version <= 4){ if ($program = main::check_program($kded_name)){ @@ -30839,6 +31180,7 @@ sub set_env_data { $kde_session_version = ($ENV{'KDE_SESSION_VERSION'}) ? $ENV{'KDE_SESSION_VERSION'} : ''; # for fallback to fallback protections re false gnome id $gdmsession = ($ENV{'GDMSESSION'}) ? clean_env($ENV{'GDMSESSION'}) : ''; + $windowmanager = ($ENV{'WINDOWMANAGER'}) ? clean_env($ENV{'WINDOWMANAGER'}) : ''; main::feature_debugger('desktop-scalars', ['$desktop_session: ' . $desktop_session, '$xdg_desktop: ' . $xdg_desktop, @@ -33008,6 +33350,7 @@ sub debian_id { '12' => 'bookworm', '13' => 'trixie', '14' => 'forky', + '15' => 'duke', ); } else { @@ -33020,7 +33363,7 @@ sub debian_id { '5' => 'daedalus', # bookworm '6' => 'excalibur',# trixie '7' => 'freia', # forky - # '' => 'ceres/daedalus', # sid/unstable + # '' => 'ceres', # sid/unstable ); } # debian often numeric, devuan usually not @@ -33063,10 +33406,12 @@ sub ubuntu_id { my ($id) = (''); # xx.04, xx.10 my %codenames = ( - # '??' => '26.04', - # '??' => '25.10', - # '??' => '25.04', - # '??' => '24.10', + # '??' => '27.04', + # '??' => '26.10', + # '??' => '26.04 LTS', + 'questing' => '25.10', + 'plucky' => '25.04', + 'oracular' => '24.10', 'noble' => '24.04 LTS', 'mantic' => '23.10', 'lunar' => '23.04', |
