diff --git a/lshw-cpuinfo.patch b/lshw-cpuinfo.patch new file mode 100644 index 0000000..5624f3f --- /dev/null +++ b/lshw-cpuinfo.patch @@ -0,0 +1,108 @@ +From 9a81309286a05f2b088c9898a0e3a16e807532be Mon Sep 17 00:00:00 2001 +From: Chandni Verma +Date: Thu, 20 Oct 2016 19:24:46 +0530 +Subject: [PATCH] cpuinfo: Rectify cpuinfo for IBM Power Systems + +'/proc/cpuinfo' file on Power Systems represents online CPU threads, +not physical cores. Also we can dynamically change number of threads. + +Previous patch added support to parse device tree and display core +information under CPU nodes. + +This patch pulls useful info from cpuinfo file and updates CPU nodes. + - description : Processor description + - version : Processor version including subversion + +Signed-off-by: Chandni Verma +[Code cleanup, updated description - Vasant] +Signed-off-by: Vasant Hegde +--- + src/core/cpuinfo.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 46 insertions(+), 1 deletion(-) + +Index: lshw-B.02.18/src/core/cpuinfo.cc +=================================================================== +--- lshw-B.02.18.orig/src/core/cpuinfo.cc ++++ lshw-B.02.18/src/core/cpuinfo.cc +@@ -13,6 +13,13 @@ __ID("@(#) $Id$"); + + static int currentcpu = 0; + ++static inline bool is_system_ppc_ibm(hwNode & node) ++{ ++ string desc = node.getDescription(); ++ ++ return (desc == "PowerNV" || desc == "pSeries Guest" || desc == "pSeries LPAR"); ++} ++ + static hwNode *getcpu(hwNode & node, + int n = 0) + { +@@ -33,6 +40,13 @@ int n = 0) + return cpu; + } + ++ /* ++ * device-tree.cc creates all CPU nodes on Power Systems. ++ * Hence do not create new CPU nodes here. ++ */ ++ if (is_system_ppc_ibm(node)) ++ return NULL; ++ + hwNode *core = node.getChild("core"); + + if (core) +@@ -49,6 +63,20 @@ int n = 0) + + + #ifdef __powerpc__ ++static void cpuinfo_ppc_ibm(hwNode & node, ++ const string & description, const string & version) ++{ ++ hwNode *cpu = getcpu(node, currentcpu); ++ ++ while (cpu) ++ { ++ cpu->setDescription(description); ++ cpu->setVersion(version); ++ ++ cpu = getcpu(node, ++currentcpu); ++ } ++} ++ + static void cpuinfo_ppc(hwNode & node, + string id, + string value) +@@ -570,6 +598,7 @@ bool scan_cpuinfo(hwNode & n) + char buffer[1024]; + size_t count; + string cpuinfo_str = ""; ++ string description = "", version = ""; + + while ((count = read(cpuinfo, buffer, sizeof(buffer))) > 0) + { +@@ -599,7 +628,23 @@ bool scan_cpuinfo(hwNode & n) + cpuinfo_x86(n, id, value); + #endif + #ifdef __powerpc__ +- cpuinfo_ppc(n, id, value); ++ ++ // All cores have same product name and version on power systems ++ if (is_system_ppc_ibm(n)) ++ { ++ if (id == "cpu") ++ description = value; ++ if (id == "revision") ++ version = value; ++ ++ if (description != "" && version != "") ++ { ++ cpuinfo_ppc_ibm(n, description, version); ++ break; ++ } ++ } ++ else ++ cpuinfo_ppc(n, id, value); + #endif + #ifdef __s390x__ + cpuinfo_s390x(n, id, value); diff --git a/lshw-devtree_cpunodes.patch b/lshw-devtree_cpunodes.patch new file mode 100644 index 0000000..5bbfd20 --- /dev/null +++ b/lshw-devtree_cpunodes.patch @@ -0,0 +1,52 @@ +From 6a75f4e52f0a356d54e1cd06f99f91d21bd03663 Mon Sep 17 00:00:00 2001 +From: Chandni Verma +Date: Thu, 14 Jul 2016 23:46:42 +0530 +Subject: [PATCH] devtree: Display CPU nodes before memory + +Present lshw displays memory node before cpu node for Power System. But +on x86, it displays cpu before memory. Lets use same output format on +x86 and Power Systems. + +Note that I've made sure it doesn't hurt other platforms (like Apple) +which has device tree. + +Signed-off-by: Chandni Verma +[Made sure this patch doesn't impact non-IBM Power systems, + updated description - Vasant] +Signed-off-by: Vasant Hegde +--- + src/core/device-tree.cc | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc +index 700dff0..b8feb12 100644 +--- a/src/core/device-tree.cc ++++ b/src/core/device-tree.cc +@@ -931,8 +931,8 @@ bool scan_device_tree(hwNode & n) + { + core->addHint("icon", string("board")); + scan_devtree_root(*core); +- scan_devtree_memory_powernv(*core); + scan_devtree_cpu_power(*core); ++ scan_devtree_memory_powernv(*core); + n.addCapability("powernv", "Non-virtualized"); + n.addCapability("opal", "OPAL firmware"); + } +@@ -982,11 +982,14 @@ bool scan_device_tree(hwNode & n) + core->addHint("icon", string("board")); + scan_devtree_root(*core); + scan_devtree_bootrom(*core); +- scan_devtree_memory(*core); +- if (exists(DEVICETREE "/ibm,lpar-capable")) ++ if (exists(DEVICETREE "/ibm,lpar-capable")) { + scan_devtree_cpu_power(*core); +- else ++ scan_devtree_memory(*core); ++ } ++ else { ++ scan_devtree_memory(*core); + scan_devtree_cpu(*core); ++ } + } + } + diff --git a/lshw-devtree_machine_describtion.patch b/lshw-devtree_machine_describtion.patch new file mode 100644 index 0000000..ea9f481 --- /dev/null +++ b/lshw-devtree_machine_describtion.patch @@ -0,0 +1,38 @@ +From 1fee4c448ea6932fb3a01e866ce4b1741f26c6bb Mon Sep 17 00:00:00 2001 +From: Chandni Verma +Date: Thu, 20 Oct 2016 12:12:13 +0530 +Subject: [PATCH] devtree: Add machine description + +Add machine description for PowerNV and pseries LPAR platform. + +PowerNV = Power Non Virtualized +pSeries LPAR = Linux running on PowerVM LPAR + +Signed-off-by: Chandni Verma +[Split original patch and created separate patch for machine + description - Vasant] +Signed-off-by: Vasant Hegde +--- + src/core/device-tree.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc +index b8feb12..951535c 100644 +--- a/src/core/device-tree.cc ++++ b/src/core/device-tree.cc +@@ -927,6 +927,7 @@ bool scan_device_tree(hwNode & n) + { + n.setVendor(get_string(DEVICETREE "/vendor", "IBM")); + n.setProduct(get_string(DEVICETREE "/model-name")); ++ n.setDescription("PowerNV"); + if (core) + { + core->addHint("icon", string("board")); +@@ -983,6 +984,7 @@ bool scan_device_tree(hwNode & n) + scan_devtree_root(*core); + scan_devtree_bootrom(*core); + if (exists(DEVICETREE "/ibm,lpar-capable")) { ++ n.setDescription("pSeries LPAR"); + scan_devtree_cpu_power(*core); + scan_devtree_memory(*core); + } diff --git a/lshw-dimminfo.patch b/lshw-dimminfo.patch new file mode 100644 index 0000000..36d8bc2 --- /dev/null +++ b/lshw-dimminfo.patch @@ -0,0 +1,356 @@ +From a5fb8431d9888cbd4b40e6435d4379bf0c86cdec Mon Sep 17 00:00:00 2001 +From: Lyonel Vincent +Date: Thu, 20 Oct 2016 00:27:58 +0200 +Subject: [PATCH] merge github pull request 23: parse CPU information + +FIXME: `dimminfo` magic needs cleansing, ugly code getting uglier +--- + src/core/device-tree.cc | 267 ++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 237 insertions(+), 30 deletions(-) + +diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc +index c2b7d15..700dff0 100644 +--- a/src/core/device-tree.cc ++++ b/src/core/device-tree.cc +@@ -26,6 +26,8 @@ + #include + #include + #include ++#include ++#include + + __ID("@(#) $Id$"); + +@@ -227,6 +229,42 @@ static string cpubusinfo(int cpu) + } + + ++static void set_cpu(hwNode & cpu, int currentcpu, const string & basepath) ++{ ++ cpu.setProduct(get_string(basepath + "/name")); ++ cpu.claim(); ++ cpu.setBusInfo(cpubusinfo(currentcpu)); ++ ++ cpu.setSize(get_u32(basepath + "/clock-frequency")); ++ cpu.setClock(get_u32(basepath + "/bus-frequency")); ++ ++ if (exists(basepath + "/altivec")) ++ cpu.addCapability("altivec"); ++ ++ if (exists(basepath + "/performance-monitor")) ++ cpu.addCapability("performance-monitor"); ++} ++ ++ ++static void fill_cache_info(string cache_type, string cachebase, ++ hwNode & cache, hwNode & icache) ++{ ++ cache.claim(); ++ cache.setDescription(cache_type); ++ cache.setSize(get_u32(cachebase + "/d-cache-size")); ++ ++ if (exists(cachebase + "/cache-unified")) ++ cache.setDescription(cache.getDescription() + " (unified)"); ++ else ++ { ++ icache = cache; ++ cache.setDescription(cache.getDescription() + " (data)"); ++ icache.setDescription(icache.getDescription() + " (instruction)"); ++ icache.setSize(get_u32(cachebase + "/i-cache-size")); ++ } ++} ++ ++ + static void scan_devtree_cpu(hwNode & core) + { + struct dirent **namelist; +@@ -254,14 +292,8 @@ static void scan_devtree_cpu(hwNode & core) + hw::strip(get_string(basepath + "/device_type")) != "cpu") + break; // oops, not a CPU! + +- cpu.setProduct(get_string(basepath + "/name")); + cpu.setDescription("CPU"); +- cpu.claim(); +- cpu.setBusInfo(cpubusinfo(currentcpu++)); +- cpu.setSize(get_u32(basepath + "/clock-frequency")); +- cpu.setClock(get_u32(basepath + "/bus-frequency")); +- if (exists(basepath + "/altivec")) +- cpu.addCapability("altivec"); ++ set_cpu(cpu, currentcpu++, basepath); + + version = get_u32(basepath + "/cpu-version"); + if (version != 0) +@@ -273,14 +305,11 @@ static void scan_devtree_cpu(hwNode & core) + snprintf(buffer, sizeof(buffer), "%lx.%d.%d", + (version & 0xffff0000) >> 16, major, minor); + cpu.setVersion(buffer); +- + } ++ + if (hw::strip(get_string(basepath + "/state")) != "running") + cpu.disable(); + +- if (exists(basepath + "/performance-monitor")) +- cpu.addCapability("performance-monitor"); +- + if (exists(basepath + "/d-cache-size")) + { + hwNode cache("cache", +@@ -302,29 +331,19 @@ static void scan_devtree_cpu(hwNode & core) + { + hwNode cache("cache", + hw::memory); ++ hwNode icache("cache", ++ hw::memory); + string cachebase = basepath + "/" + cachelist[j]->d_name; + + if (hw::strip(get_string(cachebase + "/device_type")) != "cache" && + hw::strip(get_string(cachebase + "/device_type")) != "l2-cache") + break; // oops, not a cache! + +- cache.claim(); +- cache.setDescription("L2 Cache"); +- cache.setSize(get_u32(cachebase + "/d-cache-size")); +- cache.setClock(get_u32(cachebase + "/clock-frequency")); ++ cache.setClock(get_u32(cachebase + "/clock-frequency")); ++ fill_cache_info("L2 Cache", cachebase, cache, icache); + +- if (exists(cachebase + "/cache-unified")) +- cache.setDescription(cache.getDescription() + " (unified)"); +- else +- { +- hwNode icache = cache; +- cache.setDescription(cache.getDescription() + " (data)"); +- icache.setDescription(icache.getDescription() + " (instruction)"); +- icache.setSize(get_u32(cachebase + "/i-cache-size")); +- +- if (icache.getSize() > 0) +- cpu.addChild(icache); +- } ++ if (icache.getSize() > 0) ++ cpu.addChild(icache); + + if (cache.getSize() > 0) + cpu.addChild(cache); +@@ -342,6 +361,191 @@ static void scan_devtree_cpu(hwNode & core) + } + } + ++static void set_cpu_config_threads(hwNode & cpu, const string & basepath) ++{ ++ static int threads_per_cpu = 0; ++ ++ /* In power systems, there are equal no. of threads per cpu-core */ ++ if (threads_per_cpu == 0) ++ { ++ int rc; ++ struct stat sbuf; ++ string p = hw::strip(basepath + string("/ibm,ppc-interrupt-server#s")); ++ ++ /* ++ * This file contains as many 32 bit interrupt server numbers, as the ++ * number of threads per CPU (in hexadecimal format). st_size gives size ++ * in bytes of a file. Hence, grouping by 4 bytes, we get the thread ++ * count. ++ */ ++ rc = stat(p.c_str(), &sbuf); ++ if (!rc) ++ threads_per_cpu = sbuf.st_size / 4; ++ } ++ ++ cpu.setConfig("threads", threads_per_cpu); ++} ++ ++ ++static void scan_devtree_cpu_power(hwNode & core) ++{ ++ int n; ++ int currentcpu = 0; ++ struct dirent **namelist; ++ map > > l2_caches; ++ map > l3_caches; ++ ++ pushd(DEVICETREE "/cpus"); ++ n = scandir(".", &namelist, selectdir, alphasort); ++ popd(); ++ if (n < 0) ++ return; ++ ++ /* ++ * 'cpus' node contains CPU, L2 and L3 cache nodes. L1 cache information is ++ * available under CPU node itself. l2-cache (or next-level-cache) property ++ * contains next level cache node phandle/ibm,phanle number. ++ * First pass creates cache nodes and second pass will link cache nodes to ++ * corresponding CPU nodes. ++ */ ++ for (int i = 0; i < n; i++) ++ { ++ string product; ++ string basepath = string(DEVICETREE "/cpus/") + string(namelist[i]->d_name); ++ hwNode cache("cache", hw::memory); ++ hwNode icache("cache", hw::memory); ++ vector value; ++ ++ if (!exists(basepath + "/device_type")) ++ continue; ++ ++ if (hw::strip(get_string(basepath + "/device_type")) != "cache") ++ continue; ++ ++ product = hw::strip(get_string(basepath + "/name")); ++ ++ if (hw::strip(get_string(basepath + "/status")) != "okay") ++ cache.disable(); ++ ++ if (product == "l2-cache") ++ fill_cache_info("L2 Cache", basepath, cache, icache); ++ else ++ fill_cache_info("L3 Cache", basepath, cache, icache); ++ ++ if (icache.getSize() > 0) ++ value.insert(value.begin(), icache); ++ ++ if (cache.getSize() > 0) ++ value.insert(value.begin(), cache); ++ ++ if (value.size() > 0) ++ { ++ uint32_t phandle = 0; ++ ++ if (exists(basepath + "/phandle")) ++ phandle = get_u32(basepath + "/phandle"); ++ else if (exists(basepath + "/ibm,phandle")) // on pSeries LPARs ++ phandle = get_u32(basepath + "/ibm,phandle"); ++ ++ if (!phandle) ++ continue; ++ ++ if (product == "l2-cache") ++ { ++ uint32_t l3_key = 0; // 0 indicating no next level of cache ++ ++ if (exists(basepath + "/l2-cache")) ++ l3_key = get_u32(basepath + "/l2-cache"); ++ else if (exists(basepath + "/next-level-cache")) //on OpenPOWER systems ++ l3_key = get_u32(basepath + "/next-level-cache"); ++ ++ pair > p (l3_key, value); ++ l2_caches[phandle] = p; ++ } ++ else if (product == "l3-cache") ++ { ++ l3_caches[phandle] = value; ++ } ++ } ++ } // first pass end ++ ++ for (int i = 0; i < n; i++) //second and final pass ++ { ++ uint32_t l2_key = 0; ++ uint32_t version = 0; ++ string basepath = string(DEVICETREE "/cpus/") + string(namelist[i]->d_name); ++ hwNode cpu("cpu", hw::processor); ++ ++ if (!exists(basepath + "/device_type")) ++ { ++ free(namelist[i]); ++ continue; ++ } ++ ++ if (hw::strip(get_string(basepath + "/device_type")) != "cpu") ++ { ++ free(namelist[i]); ++ continue; ++ } ++ ++ cpu.setDescription("CPU"); ++ set_cpu(cpu, currentcpu++, basepath); ++ ++ version = get_u32(basepath + "/cpu-version"); ++ if (version != 0) ++ cpu.setVersion(tostring(version)); ++ ++ if (hw::strip(get_string(basepath + "/status")) != "okay") ++ cpu.disable(); ++ ++ set_cpu_config_threads(cpu, basepath); ++ ++ if (exists(basepath + "/d-cache-size")) ++ { ++ hwNode cache("cache", hw::memory); ++ hwNode icache("cache", hw::memory); ++ ++ fill_cache_info("L1 Cache", basepath, cache, icache); ++ ++ if (icache.getSize() > 0) ++ cpu.addChild(icache); ++ ++ if (cache.getSize() > 0) ++ cpu.addChild(cache); ++ } ++ ++ if (exists(basepath + "/l2-cache")) ++ l2_key = get_u32(basepath + "/l2-cache"); ++ else if (exists(basepath + "/next-level-cache")) ++ l2_key = get_u32(basepath + "/next-level-cache"); ++ ++ if (l2_key != 0) ++ { ++ map > >:: ++ const_iterator got = l2_caches.find(l2_key); ++ ++ if (!(got == l2_caches.end())) ++ for (uint32_t j = 0; j < (got->second).second.size(); j++) ++ cpu.addChild((got->second).second[j]); ++ ++ if ((got->second).first != 0) // we have another level of cache ++ { ++ map >::const_iterator got_l3 = ++ l3_caches.find ((got->second).first); ++ ++ if (!(got_l3 == l3_caches.end())) ++ for (uint32_t j = 0; j < (got_l3->second).size(); j++) ++ cpu.addChild((got_l3->second)[j]); ++ } ++ } ++ ++ core.addChild(cpu); ++ ++ free(namelist[i]); ++ } ++ free(namelist); ++} ++ + void add_memory_bank(string name, string path, hwNode & core) + { + struct dirent **dirlist; +@@ -728,7 +932,7 @@ bool scan_device_tree(hwNode & n) + core->addHint("icon", string("board")); + scan_devtree_root(*core); + scan_devtree_memory_powernv(*core); +- scan_devtree_cpu(*core); ++ scan_devtree_cpu_power(*core); + n.addCapability("powernv", "Non-virtualized"); + n.addCapability("opal", "OPAL firmware"); + } +@@ -764,7 +968,7 @@ bool scan_device_tree(hwNode & n) + { + core->addHint("icon", string("board")); + scan_devtree_root(*core); +- scan_devtree_cpu(*core); ++ scan_devtree_cpu_power(*core); + core->addCapability("qemu", "QEMU virtualization"); + core->addCapability("guest", "Virtualization guest"); + } +@@ -779,7 +983,10 @@ bool scan_device_tree(hwNode & n) + scan_devtree_root(*core); + scan_devtree_bootrom(*core); + scan_devtree_memory(*core); +- scan_devtree_cpu(*core); ++ if (exists(DEVICETREE "/ibm,lpar-capable")) ++ scan_devtree_cpu_power(*core); ++ else ++ scan_devtree_cpu(*core); + } + } + diff --git a/lshw.changes b/lshw.changes index 24e584a..6ccec0a 100644 --- a/lshw.changes +++ b/lshw.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Wed Feb 7 15:58:41 UTC 2018 - mpluskal@suse.com + +- Drop not needed post macros +- Add ppc enablement patches (bsc#1079846): + * lshw-cpuinfo.patch + * lshw-devtree_cpunodes.patch + * lshw-devtree_machine_describtion.patch + * lshw-dimminfo.patch + ------------------------------------------------------------------- Tue May 30 14:34:04 UTC 2017 - mpluskal@suse.com diff --git a/lshw.spec b/lshw.spec index 65a1e2b..8f98e8d 100644 --- a/lshw.spec +++ b/lshw.spec @@ -1,7 +1,7 @@ # # spec file for package lshw # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2013 Pascal Bleser # # All modifications and additions to the file contributed by third parties @@ -23,18 +23,26 @@ Release: 0 Summary: HardWare LiSter License: GPL-2.0 Group: Hardware/Other -Url: https://www.ezix.org/project/wiki/HardwareLiSter +URL: https://www.ezix.org/project/wiki/HardwareLiSter Source: https://www.ezix.org/software/files/lshw-%{version}.tar.gz Source1: lshw.desktop.in Source2: lshw.png +# PATCH-FIX-UPSTREAM -- lshw-dimminfo.patch bsc#1079846 +Patch0: lshw-dimminfo.patch +# PATCH-FIX-UPSTREAM -- lshw-devtree_cpunodes.patch bsc#1079846 +Patch1: lshw-devtree_cpunodes.patch +# PATCH-FIX-UPSTREAM -- lshw-devtree_machine_describtion.patch bsc#1079846 +Patch2: lshw-devtree_machine_describtion.patch +# PATCH-FIX-UPSTREAM -- lshw-cpuinfo.patch bsc#1079846 +Patch3: lshw-cpuinfo.patch BuildRequires: gcc-c++ BuildRequires: hicolor-icon-theme BuildRequires: libpng-devel BuildRequires: pkgconfig BuildRequires: update-desktop-files BuildRequires: pkgconfig(gtk+-2.0) >= 2.4 -Recommends: hwdata Recommends: %{name}-lang +Recommends: hwdata %lang_package %description @@ -76,6 +84,10 @@ http://www.ezix.org/software/lshw.html %prep %setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %build make \ @@ -103,14 +115,6 @@ rm -f %{buildroot}%{_datadir}/%{name}/manuf.txt %find_lang lshw -%post gui -%desktop_database_post -%icon_theme_cache_post - -%postun gui -%desktop_database_postun -%icon_theme_cache_postun - %files %defattr(-,root,root,0755) %doc README.md COPYING docs/TODO docs/Changelog docs/lshw.xsd