summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2023-08-03 14:41:09 +0200
committerSimon Rettberg2023-08-03 14:41:09 +0200
commit26f501d7a573c82d1357f6859e933cc838c1c63e (patch)
treeaa8ce7871a6e7e70e9bca840571dcd3cd61c2cf6
parent[statistics] Move function (diff)
downloadslx-admin-26f501d7a573c82d1357f6859e933cc838c1c63e.tar.gz
slx-admin-26f501d7a573c82d1357f6859e933cc838c1c63e.tar.xz
slx-admin-26f501d7a573c82d1357f6859e933cc838c1c63e.zip
[statistics] Add even more more weird JEDEC encodings
-rw-r--r--modules-available/statistics/inc/hardwareparser.inc.php61
1 files changed, 39 insertions, 22 deletions
diff --git a/modules-available/statistics/inc/hardwareparser.inc.php b/modules-available/statistics/inc/hardwareparser.inc.php
index 036b0431..d8ef575f 100644
--- a/modules-available/statistics/inc/hardwareparser.inc.php
+++ b/modules-available/statistics/inc/hardwareparser.inc.php
@@ -45,47 +45,64 @@ class HardwareParser
{
// JEDEC ID:7F 7F 9E 00 00 00 00 00
// or the ID as 8 hex digits with no spacing and prefix
- if (preg_match('/JEDEC(?:\s*ID)?\s*:?\s*([0-9a-f\s]+)/i', $string, $out)
+ $id = null;
+ if (preg_match('/JEDEC(?:\s*ID)?\s*:?\s*([0-9a-f\s]{8,23})\s*$/i', $string, $out)
|| preg_match('/^([0-9a-f]{14}00)$/i', $string, $out)) {
preg_match_all('/[0-9a-f]{2}/i', $out[1], $out);
$bank = 0;
- $id = 0;
foreach ($out[0] as $id) {
$bank++;
$id = hexdec($id) & 0x7f; // Let's just ignore the parity bit, and any potential error
if ($id !== 0x7f)
break;
}
- if ($id !== 0) {
+ if ($id !== null) {
$id = self::lookupJedec($bank, $id);
- if ($id !== null)
- return $id;
}
- } elseif (preg_match('/Unknown.{0,16}[\[(](?:0x)?([0-9a-fA-F]{2,4})[\])]/', $string, $out)
- || (preg_match('/^([0-9A-F]{4})([0-9A-F]{4})([0-9A-F]{4})$/', $string, $out) && $out[1] === $out[3])) {
- // 16bit encoding from DDR3+: lower byte is number of 0x7f bytes, upper byte is id within bank
- $id = hexdec($out[1]);
- // Our bank counting starts at one. Also ignore parity bit.
- $bank = ($id & 0x7f);
- // Shift down id, get rid of parity bit
- $id = ($id >> 8) & 0x7f;
- if (count($out) === 4) {
- // Observed second case, on OptiPlex 5050, is 80AD000080AD, but here endianness is reversed
- $tmp = $id;
- $id = $bank;
- $bank = $tmp;
+ } elseif (preg_match('/Unknown.{0,16}[\[(](?:0x)?([0-9a-fA-F]{2,4})[\])]/', $string, $out)) {
+ // First byte (big endian) is id-in-bank, low byte is bank
+ $id = self::decodeBankAndId($out, false);
+ } elseif (preg_match('/JEDEC(?:\s*ID)?\s*:?\s*([0-9a-f]{2}\s?[0-9a-f]{2})/i', $string, $out)
+ || (preg_match('/^([0-9A-F]{4})([0-9A-F]{4})([0-9A-F]{4})$/', $string, $out) && $out[2] === '0000')) {
+ // First byte is bank, second byte is id-in-bank
+ $id = self::decodeBankAndId($out, true);
+ } elseif (preg_match('/^([0-9a-f]{4})$/i', $string, $out)) {
+ // This one was seen with both endianesses
+ $id = self::decodeBankAndId($out, true);
+ if ($id === null) {
+ $id = self::decodeBankAndId($out, false);
}
- $bank++;
- $id = self::lookupJedec($bank, $id);
- if ($id !== null)
- return $id;
}
+
+ if ($id !== null)
+ return $id;
return $string;
}
/**
* @return ?string
*/
+ private static function decodeBankAndId(array $out, bool $bankFirst)
+ {
+ // 16bit encoding from DDR3+: lower byte is number of 0x7f bytes, upper byte is id within bank
+ $id = hexdec(str_replace(' ', '', $out[1]));
+ // Our bank counting starts at one. Also ignore parity bit.
+ $bank = ($id & 0x7f);
+ // Shift down id, get rid of parity bit
+ $id = ($id >> 8) & 0x7f;
+ if ($bankFirst) {
+ // Observed second case, on OptiPlex 5050, is 80AD000080AD, but here endianness is reversed
+ $tmp = $id;
+ $id = $bank;
+ $bank = $tmp;
+ }
+ $bank++;
+ return self::lookupJedec($bank, $id);
+ }
+
+ /**
+ * @return ?string
+ */
private static function lookupJedec(int $bank, int $id)
{
static $data = false;