Skip to main content

gwr_models/registers/
field.rs

1// Copyright (c) 2023 Graphcore Ltd. All rights reserved.
2
3//! Control and Status Register Fields.
4
5use crate::registers::Permission;
6
7#[derive(Clone)]
8pub struct Field {
9    offset: usize,
10    num_bits: usize,
11    reset_value: u64,
12}
13
14impl Field {
15    #[must_use]
16    pub fn new(num_bits: usize, offset: usize, reset_value: u64) -> Self {
17        Self {
18            offset,
19            num_bits,
20            reset_value,
21        }
22    }
23
24    #[must_use]
25    pub fn last_bit(&self) -> usize {
26        self.offset + self.num_bits - 1
27    }
28
29    /// Update as if written by instructions.
30    #[must_use]
31    pub fn apply_write_permissions(&self, value: u64, permissions: &Permission) -> u64 {
32        match permissions {
33            Permission::ReadOnly
34            | Permission::ReadVolatileOnly
35            | Permission::Reserved
36            | Permission::WriteOneCommits
37            | Permission::WriteIgnore => self.clear(value),
38            _ => value,
39        }
40    }
41
42    /// Update as if modified by the hardware.
43    #[must_use]
44    pub fn apply_set_permissions(&self, value: u64, permissions: &Permission) -> u64 {
45        match permissions {
46            Permission::ReadOnly
47            | Permission::Reserved
48            | Permission::WriteOneCommits
49            | Permission::WriteIgnore => {
50                let mask: u64 = (1 << self.num_bits) - 1;
51                value & !((mask) << self.offset) | (self.reset_value << self.offset)
52            }
53            _ => value,
54        }
55    }
56
57    /// Update full register value as if this field were being read by
58    /// instructions
59    #[must_use]
60    pub fn apply_read_permissions(&self, value: u64, permissions: &Permission) -> u64 {
61        let mut value = value;
62        match permissions {
63            Permission::WriteOnly => {
64                value = self.clear(value);
65            }
66            _ => {
67                // Leave value alone
68            }
69        }
70        value
71    }
72
73    /// Access used by hardware.
74    #[must_use]
75    pub fn apply_reset_value(&self, value: u64) -> u64 {
76        let mask: u64 = (1 << self.num_bits) - 1;
77        value & !((mask) << self.offset) | (self.reset_value << self.offset)
78    }
79
80    #[must_use]
81    pub fn clear(&self, value: u64) -> u64 {
82        let mask: u64 = (1 << self.num_bits) - 1;
83        value & !((mask) << self.offset)
84    }
85
86    #[must_use]
87    pub fn value(&self, value: u64) -> u64 {
88        let mask: u64 = (1 << self.num_bits) - 1;
89        (value >> self.offset) & mask
90    }
91}