|
1 | 1 | //! This module contains errors and exception types.
|
2 | 2 |
|
| 3 | +use bit_field::BitField; |
| 4 | + |
3 | 5 | /// Exception Error Codes
|
4 | 6 | ///
|
5 | 7 | /// This structure is defined by the following manual sections:
|
@@ -78,3 +80,71 @@ pub enum Exception {
|
78 | 80 | /// Security Exception
|
79 | 81 | Security = 0x1E,
|
80 | 82 | }
|
| 83 | + |
| 84 | +/// The index in a selector error |
| 85 | +#[derive(Copy, Clone, Debug, PartialEq, Eq)] |
| 86 | +pub enum SelectorIndex { |
| 87 | + /// An IDT selector |
| 88 | + Idt(u16), |
| 89 | + |
| 90 | + /// A GDT selector |
| 91 | + Gdt(u16), |
| 92 | + |
| 93 | + /// An LDT selector |
| 94 | + Ldt(u16), |
| 95 | +} |
| 96 | + |
| 97 | +/// A selector error |
| 98 | +/// |
| 99 | +/// This structure is defined by the following manual sections: |
| 100 | +/// * AMD Volume 2: 8.4.1 |
| 101 | +/// * Intel Volume 3A: 6.13 |
| 102 | +#[derive(Copy, Clone, Debug)] |
| 103 | +#[repr(transparent)] |
| 104 | +pub struct SelectorError(u32); |
| 105 | + |
| 106 | +impl SelectorError { |
| 107 | + /// Whether or not the fault was external to the CPU. |
| 108 | + #[inline] |
| 109 | + pub fn external(self) -> bool { |
| 110 | + self.0.get_bit(0) |
| 111 | + } |
| 112 | + |
| 113 | + /// Returns the selector index. |
| 114 | + #[inline] |
| 115 | + pub fn index(self) -> SelectorIndex { |
| 116 | + let index = self.0.get_bits(3..16) as u16; |
| 117 | + |
| 118 | + if self.0.get_bit(1) { |
| 119 | + SelectorIndex::Idt(index) |
| 120 | + } else if self.0.get_bit(2) { |
| 121 | + SelectorIndex::Ldt(index) |
| 122 | + } else { |
| 123 | + SelectorIndex::Gdt(index) |
| 124 | + } |
| 125 | + } |
| 126 | +} |
| 127 | + |
| 128 | +#[cfg(test)] |
| 129 | +mod test { |
| 130 | + use super::*; |
| 131 | + |
| 132 | + #[test] |
| 133 | + fn selector() { |
| 134 | + let se = SelectorError(0b0101010101010101_0101010101010101); |
| 135 | + assert_eq!(se.external(), true); |
| 136 | + assert_eq!(se.index(), SelectorIndex::Ldt(0b0101010101010)); |
| 137 | + |
| 138 | + let se = SelectorError(0b0101010101010101_0101010101010111); |
| 139 | + assert_eq!(se.external(), true); |
| 140 | + assert_eq!(se.index(), SelectorIndex::Idt(0b0101010101010)); |
| 141 | + |
| 142 | + let se = SelectorError(0b0101010101010101_0101010101010011); |
| 143 | + assert_eq!(se.external(), true); |
| 144 | + assert_eq!(se.index(), SelectorIndex::Idt(0b0101010101010)); |
| 145 | + |
| 146 | + let se = SelectorError(0b0101010101010101_0101010101010001); |
| 147 | + assert_eq!(se.external(), true); |
| 148 | + assert_eq!(se.index(), SelectorIndex::Gdt(0b0101010101010)); |
| 149 | + } |
| 150 | +} |
0 commit comments