Skip to content

Commit aad9433

Browse files
committed
chromioum_ec: Autodetect Microchip EC when using portio
Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 98e8788 commit aad9433

File tree

3 files changed

+44
-39
lines changed

3 files changed

+44
-39
lines changed

framework_lib/src/chromium_ec/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ impl CrosEc {
268268
return None;
269269
}
270270
debug!("Chromium EC Driver: {:?}", driver);
271+
271272
Some(CrosEc { driver })
272273
}
273274

framework_lib/src/chromium_ec/portio.rs

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ use log::Level;
1212
#[cfg(feature = "linux_pio")]
1313
use nix::unistd::Uid;
1414
use num::FromPrimitive;
15-
#[cfg(feature = "linux_pio")]
16-
use std::sync::{Arc, Mutex};
15+
use spin::Mutex;
1716

18-
use crate::chromium_ec::{has_mec, portio_mec};
17+
use crate::chromium_ec::{portio_mec, EC_MEMMAP_ID};
1918
use crate::os_specific;
2019
use crate::util;
2120

@@ -172,65 +171,68 @@ fn transfer_read(port: u16, address: u16, size: u16) -> Vec<u8> {
172171
buffer
173172
}
174173

175-
#[cfg(feature = "linux_pio")]
174+
#[derive(PartialEq)]
175+
#[allow(dead_code)]
176176
enum Initialized {
177177
NotYet,
178+
SucceededMec,
178179
Succeeded,
179180
Failed,
180181
}
181182

182-
#[cfg(feature = "linux_pio")]
183183
lazy_static! {
184-
static ref INITIALIZED: Arc<Mutex<Initialized>> = Arc::new(Mutex::new(Initialized::NotYet));
184+
static ref INITIALIZED: Mutex<Initialized> = Mutex::new(Initialized::NotYet);
185185
}
186186

187-
#[cfg(not(feature = "linux_pio"))]
188-
fn init() -> bool {
189-
// Nothing to do for bare-metal (UEFI) port I/O
190-
true
187+
fn has_mec() -> bool {
188+
let init = INITIALIZED.lock();
189+
*init != Initialized::Succeeded
191190
}
192191

193-
// In Linux userspace has to first request access to ioports
194-
// TODO: Close these again after we're done
195-
#[cfg(feature = "linux_pio")]
196192
fn init() -> bool {
197-
let mut init = INITIALIZED.lock().unwrap();
193+
let mut init = INITIALIZED.lock();
198194
match *init {
199195
// Can directly give up, trying again won't help
200196
Initialized::Failed => return false,
201197
// Already initialized, no need to do anything.
202-
Initialized::Succeeded => return true,
198+
Initialized::Succeeded | Initialized::SucceededMec => return true,
203199
Initialized::NotYet => {}
204200
}
205201

202+
// First try on MEC
203+
portio_mec::init();
204+
let ec_id = portio_mec::transfer_read(MEC_MEMMAP_OFFSET + EC_MEMMAP_ID, 2);
205+
if ec_id[0] == b'E' && ec_id[1] == b'C' {
206+
*init = Initialized::SucceededMec;
207+
return true;
208+
}
209+
210+
// In Linux userspace has to first request access to ioports
211+
// TODO: Close these again after we're done
212+
#[cfg(feature = "linux_pio")]
206213
if !Uid::effective().is_root() {
207214
error!("Must be root to use port based I/O for EC communication.");
208215
*init = Initialized::Failed;
209216
return false;
210217
}
211-
218+
#[cfg(feature = "linux_pio")]
212219
unsafe {
213-
if has_mec() {
214-
portio_mec::mec_init();
215-
} else {
216-
// 8 for request/response header, 0xFF for response
217-
let res = ioperm(EC_LPC_ADDR_HOST_ARGS as u64, 8 + 0xFF, 1);
218-
if res != 0 {
219-
error!(
220-
"ioperm failed. portio driver is likely block by Linux kernel lockdown mode"
221-
);
222-
return false;
223-
}
224-
225-
let res = ioperm(EC_LPC_ADDR_HOST_CMD as u64, 1, 1);
226-
assert_eq!(res, 0);
227-
let res = ioperm(EC_LPC_ADDR_HOST_DATA as u64, 1, 1);
228-
assert_eq!(res, 0);
229-
230-
let res = ioperm(NPC_MEMMAP_OFFSET as u64, super::EC_MEMMAP_SIZE as u64, 1);
231-
assert_eq!(res, 0);
220+
// 8 for request/response header, 0xFF for response
221+
let res = ioperm(EC_LPC_ADDR_HOST_ARGS as u64, 8 + 0xFF, 1);
222+
if res != 0 {
223+
error!("ioperm failed. portio driver is likely block by Linux kernel lockdown mode");
224+
return false;
232225
}
226+
227+
let res = ioperm(EC_LPC_ADDR_HOST_CMD as u64, 1, 1);
228+
assert_eq!(res, 0);
229+
let res = ioperm(EC_LPC_ADDR_HOST_DATA as u64, 1, 1);
230+
assert_eq!(res, 0);
231+
232+
let res = ioperm(NPC_MEMMAP_OFFSET as u64, super::EC_MEMMAP_SIZE as u64, 1);
233+
assert_eq!(res, 0);
233234
}
235+
234236
*init = Initialized::Succeeded;
235237
true
236238
}

framework_lib/src/chromium_ec/portio_mec.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ const _MEC_LPC_DATA_REGISTER1: u16 = 0x0805;
2222
const MEC_LPC_DATA_REGISTER2: u16 = 0x0806;
2323
const _MEC_LPC_DATA_REGISTER3: u16 = 0x0807;
2424

25-
#[cfg(feature = "linux_pio")]
26-
pub unsafe fn mec_init() {
27-
ioperm(EC_LPC_ADDR_HOST_DATA as u64, 8, 1);
28-
ioperm(MEC_LPC_ADDRESS_REGISTER0 as u64, 10, 1);
25+
pub fn init() {
26+
#[cfg(feature = "linux_pio")]
27+
unsafe {
28+
ioperm(EC_LPC_ADDR_HOST_DATA as u64, 8, 1);
29+
ioperm(MEC_LPC_ADDRESS_REGISTER0 as u64, 10, 1);
30+
}
2931
}
3032

3133
// TODO: Create a wrapper

0 commit comments

Comments
 (0)