forked from rcore-os/zCore
Some code for pmt, can compile but cannot run
This commit is contained in:
parent
f4b8ae829f
commit
099969b41f
|
@ -5,22 +5,23 @@ use {
|
|||
sync::Arc,
|
||||
vec::Vec,
|
||||
},
|
||||
spin::Mutex,
|
||||
dev::Iommu,
|
||||
kernel_hal::PAGE_SIZE,
|
||||
crate::vm::*,
|
||||
};
|
||||
|
||||
// Iommu refers to DummyIommu in fuchsia
|
||||
// BusTransactionInitiator
|
||||
#[allow(dead_code)]
|
||||
pub struct Bti {
|
||||
base: KObjectBase,
|
||||
iommu: Arc<Iommu>,
|
||||
bti_id: u64,
|
||||
pinned_memory: Vec<Pinned>,
|
||||
quarantine: Vec<Quarantined>
|
||||
inner: Mutex<BtiInner>,
|
||||
}
|
||||
|
||||
struct Pinned {
|
||||
|
||||
struct BtiInner {
|
||||
pmts: Vec<Arc<Pmt>>,
|
||||
quarantine: Vec<Quarantined>
|
||||
}
|
||||
|
||||
struct Quarantined {
|
||||
|
@ -35,19 +36,43 @@ impl Bti {
|
|||
base: KObjectBase::new(),
|
||||
iommu,
|
||||
bti_id,
|
||||
pinned_memory: Vec::new(),
|
||||
quarantine: Vec::new(),
|
||||
inner: Mutex::new(BtiInner{
|
||||
pmts: Vec::new(),
|
||||
quarantine: Vec::new(),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_info(&self) -> ZxInfoBti {
|
||||
let inner = self.inner.lock();
|
||||
ZxInfoBti {
|
||||
minimum_contiguity: PAGE_SIZE as u64,
|
||||
aspace_size: 0xffffffffffffffff,
|
||||
pmo_count: self.pinned_memory.len() as u64, // need lock
|
||||
quarantine_count: self.quarantine.len() as u64, // need lock
|
||||
minimum_contiguity: self.minimum_contiguity() as u64,
|
||||
aspace_size: self.aspace_size() as u64,
|
||||
pmo_count: inner.pmts.len() as u64,
|
||||
quarantine_count: inner.quarantine.len() as u64,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pin(&self,
|
||||
vmo: Arc<VmObject>,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
perms: IommuPerms) -> ZxResult<Arc<Pmt>> {
|
||||
if size == 0 {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
let pmt = Pmt::create(self, vmo, perms, offset, size)?;
|
||||
self.inner.lock().pmts.push(pmt.clone()); // I'm not sure...
|
||||
Ok(pmt)
|
||||
}
|
||||
|
||||
pub fn minimum_contiguity(&self) -> usize {
|
||||
self.iommu.minimum_contiguity()
|
||||
}
|
||||
|
||||
pub fn aspace_size(&self) -> usize {
|
||||
self.iommu.aspace_size()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use {
|
||||
crate::object::*,
|
||||
crate::vm::PAGE_SIZE,
|
||||
alloc::{sync::Arc, vec::Vec},
|
||||
bitflags::bitflags,
|
||||
};
|
||||
|
||||
// Iommu refers to DummyIommu in fuchsia
|
||||
|
@ -26,4 +28,20 @@ impl Iommu {
|
|||
pub fn is_valid_bus_txn_id(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn minimum_contiguity(&self) -> usize {
|
||||
PAGE_SIZE as usize
|
||||
}
|
||||
|
||||
pub fn aspace_size(&self) -> usize {
|
||||
-1 as isize as usize
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct IommuPerms: u32 {
|
||||
const PERM_READ = 1 << 0;
|
||||
const PERM_WRITE = 1 << 1;
|
||||
const PERM_EXECUTE = 1 << 2;
|
||||
}
|
||||
}
|
|
@ -2,5 +2,6 @@ use super::*;
|
|||
|
||||
mod bti;
|
||||
mod iommu;
|
||||
mod pmt;
|
||||
|
||||
pub use self::{bti::*, iommu::*};
|
||||
pub use self::{bti::*, iommu::*, pmt::*};
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#![allow(warnings)]
|
||||
use {
|
||||
super::*,
|
||||
crate::object::*,
|
||||
crate::vm::{DevVAddr, roundup},
|
||||
crate::vm::*,
|
||||
alloc::{
|
||||
sync::{Arc, Weak},
|
||||
vec::Vec,
|
||||
}
|
||||
};
|
||||
|
||||
// PinnedMemoryToken
|
||||
#[allow(dead_code)]
|
||||
pub struct Pmt {
|
||||
base: KObjectBase,
|
||||
vmo: Arc<VmObject>,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
mapped_addrs: Vec<DevVAddr>,
|
||||
}
|
||||
|
||||
impl_kobject!(Pmt);
|
||||
|
||||
impl Drop for Pmt {
|
||||
fn drop(&mut self) {
|
||||
// TODO: unpin pages
|
||||
}
|
||||
}
|
||||
|
||||
impl Pmt {
|
||||
pub fn create(
|
||||
bti: &Bti,
|
||||
vmo: Arc<VmObject>,
|
||||
perms: IommuPerms,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
) -> ZxResult<Arc<Self>> {
|
||||
if vmo.is_paged() {
|
||||
vmo.commit(offset, size)?;
|
||||
vmo.pin(offset, size)?;
|
||||
}
|
||||
|
||||
let num_addrs: usize = if vmo.is_contiguous() {
|
||||
1
|
||||
} else {
|
||||
roundup(size, bti.minimum_contiguity())
|
||||
};
|
||||
|
||||
let mapped_addrs = Pmt::mapped_into_iommu(num_addrs)?;
|
||||
Ok(Arc::new(Pmt {
|
||||
base: KObjectBase::new(),
|
||||
vmo,
|
||||
offset,
|
||||
size,
|
||||
mapped_addrs,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn mapped_into_iommu(_num_addrs: usize) -> ZxResult<Vec<DevVAddr>> {
|
||||
Err(ZxError::NOT_SUPPORTED)
|
||||
}
|
||||
|
||||
pub fn encode_addrs(
|
||||
&self,
|
||||
_compress_results: bool,
|
||||
_contiguous: bool,
|
||||
_addrs_count: usize,
|
||||
) -> ZxResult<Vec<DevVAddr>> {
|
||||
Err(ZxError::NOT_SUPPORTED)
|
||||
}
|
||||
}
|
|
@ -12,6 +12,9 @@ pub type PhysAddr = usize;
|
|||
/// Virtual Address
|
||||
pub type VirtAddr = usize;
|
||||
|
||||
// Device Address
|
||||
pub type DevVAddr = usize;
|
||||
|
||||
/// Size of a page
|
||||
pub const PAGE_SIZE: usize = 0x1000;
|
||||
|
||||
|
@ -29,6 +32,10 @@ pub fn pages(size: usize) -> usize {
|
|||
size.wrapping_add(PAGE_SIZE - 1) / PAGE_SIZE
|
||||
}
|
||||
|
||||
pub fn roundup(x: usize, align: usize) -> usize {
|
||||
x.wrapping_add(align - 1) / align
|
||||
}
|
||||
|
||||
pub fn roundup_pages(size: usize) -> usize {
|
||||
if page_aligned(size) {
|
||||
size
|
||||
|
|
|
@ -92,7 +92,13 @@ pub trait VMObjectTrait: Sync + Send {
|
|||
Err(ZxError::NOT_SUPPORTED)
|
||||
}
|
||||
|
||||
fn is_contiguous(&self) -> bool;
|
||||
fn is_contiguous(&self) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
fn is_paged(&self) -> bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VmObject {
|
||||
|
|
|
@ -458,7 +458,7 @@ impl VMObjectTrait for VMObjectPaged {
|
|||
return res;
|
||||
}
|
||||
let start_page = offset / PAGE_SIZE;
|
||||
let end_page = (start_page + len - 1) / PAGE_SIZE + 1;
|
||||
let end_page = pages(offset + len);
|
||||
for i in start_page .. end_page {
|
||||
let frame = inner.frames.get(&i).unwrap();
|
||||
if frame.pin_count == VM_PAGE_OBJECT_MAX_PIN_COUNT {
|
||||
|
@ -490,7 +490,7 @@ impl VMObjectTrait for VMObjectPaged {
|
|||
}
|
||||
|
||||
let start_page = offset / PAGE_SIZE;
|
||||
let end_page = (start_page + len - 1) / PAGE_SIZE + 1;
|
||||
let end_page = pages(offset + len);
|
||||
for i in start_page..end_page {
|
||||
let frame = inner.frames.get(&i).unwrap();
|
||||
if frame.pin_count == 0 {
|
||||
|
@ -503,11 +503,9 @@ impl VMObjectTrait for VMObjectPaged {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: for vmo_create_contiguous
|
||||
fn is_contiguous(&self) -> bool {
|
||||
false
|
||||
fn is_paged(&self) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum CommitResult {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use {
|
||||
super::*,
|
||||
zircon_object::{
|
||||
dev::{Bti, Iommu},
|
||||
dev::*,
|
||||
resource::*,
|
||||
},
|
||||
bitflags::bitflags,
|
||||
|
@ -72,7 +72,7 @@ impl Syscall<'_> {
|
|||
vmo: HandleValue,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
addrs: UserOutPtr<PhysAddr>,
|
||||
mut addrs: UserOutPtr<DevVAddr>,
|
||||
addrs_count: usize,
|
||||
mut out: UserOutPtr<HandleValue>,
|
||||
) -> ZxResult {
|
||||
|
@ -90,23 +90,21 @@ impl Syscall<'_> {
|
|||
return Err(ZxError::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
let mut iommu_perms = IommuOptions::empty();
|
||||
let mut compress_results = false;
|
||||
let mut contiguous = false;
|
||||
let mut iommu_perms = IommuPerms::empty();
|
||||
let options = BtiOptions::from_bits_truncate(options);
|
||||
|
||||
|
||||
if options.contains(BtiOptions::PERM_READ) {
|
||||
if !rights.contains(Rights::READ) {
|
||||
return Err(ZxError::ACCESS_DENIED);
|
||||
}
|
||||
iommu_perms.insert(IommuOptions::PERM_READ)
|
||||
iommu_perms.insert(IommuPerms::PERM_READ)
|
||||
}
|
||||
|
||||
if options.contains(BtiOptions::PERM_WRITE) {
|
||||
if !rights.contains(Rights::WRITE) {
|
||||
return Err(ZxError::ACCESS_DENIED);
|
||||
}
|
||||
iommu_perms.insert(IommuOptions::PERM_WRITE);
|
||||
iommu_perms.insert(IommuPerms::PERM_WRITE);
|
||||
}
|
||||
|
||||
if options.contains(BtiOptions::PERM_EXECUTE) {
|
||||
|
@ -116,25 +114,24 @@ impl Syscall<'_> {
|
|||
if !rights.contains(Rights::READ) {
|
||||
return Err(ZxError::ACCESS_DENIED);
|
||||
}
|
||||
iommu_perms.insert(IommuOptions::PERM_EXECUTE);
|
||||
iommu_perms.insert(IommuPerms::PERM_EXECUTE);
|
||||
}
|
||||
|
||||
|
||||
if options.contains(BtiOptions::CONTIGUOUS) && options.contains(BtiOptions::COMPRESS) {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
|
||||
if options.contains(BtiOptions::COMPRESS) {
|
||||
compress_results = true;
|
||||
}
|
||||
|
||||
if options.contains(BtiOptions::CONTIGUOUS) {
|
||||
if !vmo.is_contiguous() {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
contiguous = true;
|
||||
if options.contains(BtiOptions::CONTIGUOUS) && !vmo.is_contiguous() {
|
||||
return Err(ZxError::INVALID_ARGS)
|
||||
}
|
||||
let compress_results = options.contains(BtiOptions::COMPRESS);
|
||||
let contiguous = options.contains(BtiOptions::CONTIGUOUS);
|
||||
|
||||
Err(ZxError::NOT_SUPPORTED)
|
||||
let pmt = bti.pin(vmo, offset, size, iommu_perms)?;
|
||||
addrs.write_array(&pmt.as_ref().encode_addrs(compress_results, contiguous, addrs_count)?)?;
|
||||
|
||||
let handle = proc.add_handle(Handle::new(pmt, Rights::INSPECT));
|
||||
out.write(handle)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,10 +148,3 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
struct IommuOptions: u32 {
|
||||
const PERM_READ = 1 << 0;
|
||||
const PERM_WRITE = 1 << 1;
|
||||
const PERM_EXECUTE = 1 << 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use {
|
|||
alloc::vec::Vec,
|
||||
core::convert::TryFrom,
|
||||
numeric_enum_macro::numeric_enum,
|
||||
zircon_object::{signal::Port, task::*, vm::*},
|
||||
zircon_object::{signal::Port, task::*, vm::*, dev::*},
|
||||
};
|
||||
|
||||
impl Syscall<'_> {
|
||||
|
@ -289,6 +289,10 @@ impl Syscall<'_> {
|
|||
actual.write(count)?;
|
||||
avail.write(avail_count)?;
|
||||
}
|
||||
Topic::Bti => {
|
||||
let bti = proc.get_object_with_rights::<Bti>(handle, Rights::INSPECT)?;
|
||||
UserOutPtr::<ZxInfoBti>::from(buffer).write(bti.get_info())?;
|
||||
}
|
||||
_ => {
|
||||
error!("not supported info topic: {:?}", topic);
|
||||
return Err(ZxError::NOT_SUPPORTED);
|
||||
|
|
Loading…
Reference in New Issue