riscfetch_core/
hardware.rs1use crate::parsing::parse_vector_from_isa;
4use crate::types::HardwareIds;
5use std::fs;
6use sysinfo::System;
7
8pub fn get_isa_string() -> String {
10 if let Ok(content) = fs::read_to_string("/proc/cpuinfo") {
11 for line in content.lines() {
12 if line.starts_with("isa") {
13 if let Some(isa) = line.split(':').nth(1) {
14 return isa.trim().to_string();
15 }
16 }
17 }
18 }
19 "unknown".to_string()
20}
21
22pub fn get_hardware_ids() -> HardwareIds {
24 let mut ids = HardwareIds::default();
25
26 if let Ok(content) = fs::read_to_string("/proc/cpuinfo") {
27 for line in content.lines() {
28 if line.starts_with("mvendorid") {
29 if let Some(val) = line.split(':').nth(1) {
30 let val = val.trim();
31 if !val.is_empty() && val != "0x0" {
32 ids.mvendorid = val.to_string();
33 }
34 }
35 } else if line.starts_with("marchid") {
36 if let Some(val) = line.split(':').nth(1) {
37 let val = val.trim();
38 if !val.is_empty() && val != "0x0" {
39 ids.marchid = val.to_string();
40 }
41 }
42 } else if line.starts_with("mimpid") {
43 if let Some(val) = line.split(':').nth(1) {
44 let val = val.trim();
45 if !val.is_empty() && val != "0x0" {
46 ids.mimpid = val.to_string();
47 }
48 }
49 }
50 }
51 }
52
53 ids
54}
55
56pub fn get_hart_count() -> String {
58 if let Ok(content) = fs::read_to_string("/proc/cpuinfo") {
59 let count = content
60 .lines()
61 .filter(|line| line.starts_with("processor"))
62 .count();
63 if count > 0 {
64 return format!("{count} hart{}", if count > 1 { "s" } else { "" });
65 }
66 }
67
68 let mut sys = System::new();
69 sys.refresh_cpu_all();
70 let count = sys.cpus().len();
71 format!("{count} hart{}", if count > 1 { "s" } else { "" })
72}
73
74pub fn get_hart_count_num() -> usize {
76 if let Ok(content) = fs::read_to_string("/proc/cpuinfo") {
77 let count = content
78 .lines()
79 .filter(|line| line.starts_with("processor"))
80 .count();
81 if count > 0 {
82 return count;
83 }
84 }
85
86 let mut sys = System::new();
87 sys.refresh_cpu_all();
88 sys.cpus().len()
89}
90
91pub fn get_cache_info() -> String {
93 let mut cache_parts = Vec::new();
94
95 if let Ok(l1d_size) = fs::read_to_string("/sys/devices/system/cpu/cpu0/cache/index0/size") {
96 let size = l1d_size.trim();
97 if !size.is_empty() {
98 cache_parts.push(format!("L1D:{size}"));
99 }
100 }
101
102 if let Ok(l1i_size) = fs::read_to_string("/sys/devices/system/cpu/cpu0/cache/index1/size") {
103 let size = l1i_size.trim();
104 if !size.is_empty() {
105 cache_parts.push(format!("L1I:{size}"));
106 }
107 }
108
109 if let Ok(l2_size) = fs::read_to_string("/sys/devices/system/cpu/cpu0/cache/index2/size") {
110 let size = l2_size.trim();
111 if !size.is_empty() {
112 cache_parts.push(format!("L2:{size}"));
113 }
114 }
115
116 if let Ok(l3_size) = fs::read_to_string("/sys/devices/system/cpu/cpu0/cache/index3/size") {
117 let size = l3_size.trim();
118 if !size.is_empty() {
119 cache_parts.push(format!("L3:{size}"));
120 }
121 }
122
123 cache_parts.join(" ")
124}
125
126pub fn get_board_info() -> String {
128 if let Ok(content) = fs::read_to_string("/proc/device-tree/model") {
129 let model = content.trim_matches('\0').trim();
130 if !model.is_empty() {
131 return model.to_string();
132 }
133 }
134
135 if let Ok(content) = fs::read_to_string("/proc/device-tree/compatible") {
136 let parts: Vec<&str> = content.split('\0').collect();
137 if let Some(first) = parts.first() {
138 if !first.is_empty() {
139 return first.to_string();
140 }
141 }
142 }
143
144 String::new()
145}
146
147pub fn get_vector_detail() -> String {
149 let isa = get_isa_string();
150 let mut result = parse_vector_from_isa(&isa).unwrap_or_default();
151
152 if !result.is_empty() {
154 if let Ok(vlen) = fs::read_to_string("/sys/devices/system/cpu/cpu0/riscv/vlen") {
155 result.push_str(&format!(", VLEN={}", vlen.trim()));
156 }
157 }
158
159 result
160}