Skip to main content

ferrix_lib/
resources.rs

1/* resources.rs
2 *
3 * Copyright 2026 Michail Krasnov <mskrasnov07@ya.ru>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21//! Resources and addresses
22
23use anyhow::{Result, anyhow};
24use serde::{Deserialize, Serialize};
25use std::fs::read_to_string;
26
27use crate::traits::ToJson;
28
29/// Resources and addresses
30///
31/// > **NOTE!** Needs `root` permissions to get addresses!
32#[derive(Debug, Clone, Deserialize, Serialize)]
33pub struct Resources {
34    pub io_ports: Vec<Resource>,
35    pub io_mem: Vec<Resource>,
36    pub dma: Vec<Resource>,
37}
38
39impl ToJson for Resources {}
40
41#[derive(Debug, Clone, Deserialize, Serialize)]
42pub struct Resource {
43    pub address: String,
44    pub title: String,
45}
46
47impl Resources {
48    pub fn new() -> Result<Self> {
49        let ports = read_to_string("/proc/ioports")?;
50        let ports = ports.lines();
51
52        let mem = read_to_string("/proc/iomem")?;
53        let mem = mem.lines();
54
55        let dma = read_to_string("/proc/dma")?;
56        let dma = dma.lines();
57
58        let mut io_ports = Vec::new();
59        let mut io_mem = Vec::new();
60        let mut io_dma = Vec::new();
61
62        for line in ports {
63            io_ports.push(Resource::try_from(line)?);
64        }
65        io_ports.shrink_to_fit();
66        for line in mem {
67            io_mem.push(Resource::try_from(line)?);
68        }
69        io_mem.shrink_to_fit();
70        for line in dma {
71            io_dma.push(Resource::try_from(line)?);
72        }
73        io_dma.shrink_to_fit();
74
75        Ok(Self {
76            io_ports,
77            io_mem,
78            dma: io_dma,
79        })
80    }
81}
82
83impl TryFrom<&str> for Resource {
84    type Error = anyhow::Error;
85
86    fn try_from(value: &str) -> std::result::Result<Self, Self::Error> {
87        let mut v = value.split(':');
88        match (v.next(), v.next()) {
89            (Some(addr), Some(value)) => Ok(Self {
90                address: addr.trim_end().to_string(),
91                title: value.trim().to_string(),
92            }),
93            _ => Err(anyhow!("Unknown string format: \"{value}\"")),
94        }
95    }
96}