Skip to content

Commit feb3778

Browse files
WhatAmISupposedToPutHerejannau
authored andcommitted
fixup! soc: apple: Add support for the AOP co-processor
1 parent db89507 commit feb3778

2 files changed

Lines changed: 65 additions & 10 deletions

File tree

drivers/soc/apple/aop.rs

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//!
66
//! Copyright (C) The Asahi Linux Contributors
77
8-
use core::{arch::asm, mem, ptr, slice};
8+
use core::{arch::asm, cmp, mem, ptr, slice};
99

1010
use kernel::{
1111
bindings, c_str, device,
@@ -23,6 +23,7 @@ use kernel::{
2323
workqueue::{self, impl_has_work, new_work, Work, WorkItem},
2424
};
2525

26+
const AOP_MAX_CALLS: usize = 8;
2627
const AOP_MMIO_SIZE: usize = 0x1e0000;
2728
const ASC_MMIO_SIZE: usize = 0x4000;
2829
const BOOTARGS_OFFSET: usize = 0x22c;
@@ -54,6 +55,7 @@ const EPIC_SUBTYPE_STD_SERVICE: u16 = 0xc0;
5455
const EPIC_SUBTYPE_FAKEHID_REPORT: u16 = 0xc4;
5556
const EPIC_SUBTYPE_RETCODE: u16 = 0x84;
5657
const EPIC_SUBTYPE_RETCODE_PAYLOAD: u16 = 0xa0;
58+
const EPIC_SUBTYPE_STRING: u16 = 0x8a;
5759
const QE_MAGIC1: u32 = from_fourcc(b" POI");
5860
const QE_MAGIC2: u32 = from_fourcc(b" POA");
5961

@@ -115,7 +117,7 @@ struct FutureValue<T> {
115117
completion: CondVar,
116118
}
117119

118-
impl<T: Clone> FutureValue<T> {
120+
impl<T> FutureValue<T> {
119121
fn pin_init() -> impl PinInit<FutureValue<T>> {
120122
pin_init!(
121123
FutureValue {
@@ -133,7 +135,7 @@ impl<T: Clone> FutureValue<T> {
133135
while ret_guard.is_none() {
134136
self.completion.wait(&mut ret_guard);
135137
}
136-
ret_guard.as_ref().unwrap().clone()
138+
ret_guard.take().unwrap()
137139
}
138140
fn reset(&self) {
139141
*self.val.lock() = None;
@@ -146,13 +148,19 @@ struct AFKRingBuffer {
146148
buf_size: usize,
147149
}
148150

151+
struct CallResult {
152+
retcode: u32,
153+
extra_data: Option<KVec<u8>>,
154+
}
155+
149156
struct AFKEndpoint {
150157
index: u8,
151158
iomem: Option<CoherentAllocation<u8>>,
152159
txbuf: Option<AFKRingBuffer>,
153160
rxbuf: Option<AFKRingBuffer>,
154161
seq: u16,
155-
calls: [Option<Arc<FutureValue<u32>>>; 8],
162+
calls: [Option<Arc<FutureValue<CallResult>>>; AOP_MAX_CALLS],
163+
call_returns: [Option<KVec<u8>>; AOP_MAX_CALLS],
156164
}
157165

158166
unsafe impl Send for AFKEndpoint {}
@@ -165,7 +173,8 @@ impl AFKEndpoint {
165173
txbuf: None,
166174
rxbuf: None,
167175
seq: 0,
168-
calls: [const { None }; 8],
176+
calls: [const { None }; AOP_MAX_CALLS],
177+
call_returns: [const { None }; AOP_MAX_CALLS],
169178
}
170179
}
171180

@@ -409,7 +418,10 @@ impl AFKEndpoint {
409418
return Err(EIO);
410419
}
411420
} else if ehdr.category == EPIC_CATEGORY_REPLY {
412-
if subtype == EPIC_SUBTYPE_RETCODE_PAYLOAD || subtype == EPIC_SUBTYPE_RETCODE {
421+
if subtype == EPIC_SUBTYPE_RETCODE_PAYLOAD
422+
|| subtype == EPIC_SUBTYPE_RETCODE
423+
|| subtype == EPIC_SUBTYPE_STRING
424+
{
413425
if data.len() < mem::size_of::<u32>() {
414426
dev_err!(
415427
client.dev,
@@ -429,7 +441,20 @@ impl AFKEndpoint {
429441
);
430442
return Err(EIO);
431443
}
432-
self.calls[tag - 1].take().unwrap().complete(retcode);
444+
let future = self.calls[tag - 1].take().unwrap();
445+
let extra_data = if let Some(mut ret) = self.call_returns[tag - 1].take() {
446+
let len = cmp::min(data.len() - 4, ret.len());
447+
ret[..len].copy_from_slice(&data[4..(len + 4)]);
448+
ret.truncate(len);
449+
Some(ret)
450+
} else {
451+
None
452+
};
453+
future.complete(CallResult {
454+
retcode,
455+
extra_data,
456+
});
457+
433458
return Ok(());
434459
} else {
435460
dev_err!(
@@ -510,7 +535,8 @@ impl AFKEndpoint {
510535
channel: u32,
511536
subtype: u16,
512537
data: &[u8],
513-
) -> Result<Arc<FutureValue<u32>>> {
538+
ret: Option<KVec<u8>>,
539+
) -> Result<Arc<FutureValue<CallResult>>> {
514540
let mut tag = 0;
515541
for i in 0..self.calls.len() {
516542
if self.calls[i].is_none() {
@@ -537,6 +563,7 @@ impl AFKEndpoint {
537563
tag: tag as u16,
538564
..EPICHeader::default()
539565
};
566+
self.call_returns[tag - 1] = ret;
540567
self.send_rb(
541568
client,
542569
rtkit,
@@ -785,9 +812,28 @@ impl AOP for AopData {
785812
let mut rtk_guard = self.rtkit.lock();
786813
let rtk = rtk_guard.as_mut().unwrap();
787814
let mut ep_guard = self.endpoints[ep_idx as usize].lock();
788-
ep_guard.epic_notify(self, rtk, svc.channel, subtype, msg_bytes)?
815+
ep_guard.epic_notify(self, rtk, svc.channel, subtype, msg_bytes, None)?
816+
};
817+
Ok(call.wait().retcode)
818+
}
819+
fn epic_call_ret(
820+
&self,
821+
svc: &EPICService,
822+
subtype: u16,
823+
msg_bytes: &[u8],
824+
ret_len: usize,
825+
) -> Result<(u32, KVec<u8>)> {
826+
let ep_idx = svc.endpoint - AFK_ENDPOINT_START;
827+
let call = {
828+
let mut rtk_guard = self.rtkit.lock();
829+
let rtk = rtk_guard.as_mut().unwrap();
830+
let mut ep_guard = self.endpoints[ep_idx as usize].lock();
831+
let mut ret_buf = KVec::new();
832+
ret_buf.resize(ret_len, 0, GFP_KERNEL)?;
833+
ep_guard.epic_notify(self, rtk, svc.channel, subtype, msg_bytes, Some(ret_buf))?
789834
};
790-
Ok(call.wait())
835+
let res = call.wait();
836+
Ok((res.retcode, res.extra_data.unwrap()))
791837
}
792838
fn add_fakehid_listener(
793839
&self,

rust/kernel/soc/apple/aop.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ pub trait FakehidListener {
2424
pub trait AOP: Send + Sync {
2525
/// Calls a method on a specified service
2626
fn epic_call(&self, svc: &EPICService, subtype: u16, msg_bytes: &[u8]) -> Result<u32>;
27+
/// Just like epic_call, but also returns a value
28+
fn epic_call_ret(
29+
&self,
30+
svc: &EPICService,
31+
subtype: u16,
32+
msg_bytes: &[u8],
33+
ret_len: usize,
34+
) -> Result<(u32, KVec<u8>)>;
35+
2736
/// Adds the listener for the specified service
2837
fn add_fakehid_listener(
2938
&self,

0 commit comments

Comments
 (0)