|
3 | 3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. |
4 | 4 |
|
5 | 5 | use crate::pci; |
6 | | -use crate::result::Result; |
| 6 | +use crate::result::{Error, Result}; |
| 7 | +use core::convert::TryFrom; |
| 8 | +use spin::Mutex; |
7 | 9 |
|
8 | | -static SMN_MUTEX: spin::Mutex<()> = spin::Mutex::new(()); |
9 | | -const SMN_ADDR_OFFSET: u8 = 0x60; |
10 | | -const SMN_DATA_OFFSET: u8 = 0x64; |
| 10 | +pub(crate) enum Index { |
| 11 | + Smn0 = 0, |
| 12 | + Smn1 = 1, |
| 13 | + Smn2 = 2, |
| 14 | + Smn3 = 3, |
| 15 | + Smn4 = 4, |
| 16 | + Smn5 = 5, |
| 17 | + Smn6 = 6, |
| 18 | +} |
| 19 | + |
| 20 | +impl TryFrom<u8> for Index { |
| 21 | + type Error = Error; |
| 22 | + fn try_from(f: u8) -> Result<Self> { |
| 23 | + match f { |
| 24 | + 0 => Ok(Index::Smn0), |
| 25 | + 1 => Ok(Index::Smn1), |
| 26 | + 2 => Ok(Index::Smn2), |
| 27 | + 3 => Ok(Index::Smn3), |
| 28 | + 4 => Ok(Index::Smn4), |
| 29 | + 5 => Ok(Index::Smn5), |
| 30 | + 6 => Ok(Index::Smn6), |
| 31 | + _ => Err(Error::NumRange), |
| 32 | + } |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +const NSMN: usize = Index::Smn6 as usize + 1; |
| 37 | + |
| 38 | +static ADDR_DATA_PAIRS: [spin::Mutex<(u8, u8)>; NSMN] = [ |
| 39 | + Mutex::new((0x60, 0x64)), |
| 40 | + Mutex::new((0xA0, 0xA4)), |
| 41 | + Mutex::new((0xB8, 0xBC)), |
| 42 | + Mutex::new((0xC4, 0xC8)), |
| 43 | + Mutex::new((0xD0, 0xD4)), |
| 44 | + Mutex::new((0xE0, 0xE4)), |
| 45 | + Mutex::new((0xF8, 0xFC)), |
| 46 | +]; |
11 | 47 |
|
12 | | -pub(crate) fn read(addr: u32) -> Result<u32> { |
13 | | - let _lock = SMN_MUTEX.lock(); |
| 48 | +pub(crate) fn read(k: Index, addr: u32) -> Result<u32> { |
| 49 | + let pair = ADDR_DATA_PAIRS[k as usize].lock(); |
| 50 | + let (addr_off, data_off) = *pair; |
14 | 51 | let value = unsafe { |
15 | 52 | pci::cfg::write( |
16 | 53 | pci::Bus(0), |
17 | 54 | pci::Device::D0, |
18 | 55 | pci::Function::F0, |
19 | | - SMN_ADDR_OFFSET, |
| 56 | + addr_off, |
20 | 57 | addr, |
21 | 58 | )?; |
22 | 59 | pci::cfg::read( |
23 | 60 | pci::Bus(0), |
24 | 61 | pci::Device::D0, |
25 | 62 | pci::Function::F0, |
26 | | - SMN_DATA_OFFSET, |
| 63 | + data_off, |
27 | 64 | ) |
28 | 65 | }?; |
29 | 66 | Ok(value) |
30 | 67 | } |
31 | 68 |
|
32 | | -pub(crate) unsafe fn write(addr: u32, data: u32) -> Result<()> { |
33 | | - let _lock = SMN_MUTEX.lock(); |
| 69 | +pub(crate) unsafe fn write(k: Index, addr: u32, data: u32) -> Result<()> { |
| 70 | + let pair = ADDR_DATA_PAIRS[k as usize].lock(); |
| 71 | + let (addr_off, data_off) = *pair; |
34 | 72 | unsafe { |
35 | 73 | pci::cfg::write( |
36 | 74 | pci::Bus(0), |
37 | 75 | pci::Device::D0, |
38 | 76 | pci::Function::F0, |
39 | | - SMN_ADDR_OFFSET, |
| 77 | + addr_off, |
40 | 78 | addr, |
41 | 79 | )?; |
42 | 80 | pci::cfg::write( |
43 | 81 | pci::Bus(0), |
44 | 82 | pci::Device::D0, |
45 | 83 | pci::Function::F0, |
46 | | - SMN_DATA_OFFSET, |
| 84 | + data_off, |
47 | 85 | data, |
48 | 86 | )?; |
49 | 87 | } |
|
0 commit comments