diff --git a/kernel/rros/clock.rs b/kernel/rros/clock.rs index 95269496d378..e11d264a8da2 100644 --- a/kernel/rros/clock.rs +++ b/kernel/rros/clock.rs @@ -1,16 +1,21 @@ #![allow(warnings, unused)] #![feature(stmt_expr_attributes)] use crate::{ - factory, - factory::{CloneData, RrosElement, RrosFactory, RustFile, RROS_CLONE_PUBLIC}, + factory::{self, CloneData, RrosElement, RrosFactory, RustFile, RROS_CLONE_PUBLIC}, + file::{rros_release_file, RrosFile, RrosFileBinding}, list::*, lock::*, + monitor::{CLOCK_MONOTONIC, CLOCK_REALTIME}, + poll::RrosPollHead, sched::{rros_cpu_rq, this_rros_rq, RQ_TDEFER, RQ_TIMER, RQ_TPROXY}, thread::T_ROOT, + thread::{rros_current, rros_delay, T_SYSRST}, tick, tick::*, - timeout::RROS_INFINITE, + timeout::{RrosTmode, RROS_INFINITE}, timer::*, + tp::rros_timer_is_running, + wait::RrosWaitQueue, RROS_OOB_CPUS, }; @@ -22,16 +27,20 @@ use core::{ clone::Clone, mem::{align_of, size_of}, ops::{Deref, DerefMut}, - todo, }; use kernel::{ - bindings, c_types, clockchips, cpumask, + bindings, + c_types::{self, c_void}, + chrdev::Cdev, + clockchips, cpumask, device::DeviceType, double_linked_list::*, file::File, - file_operations::{FileOpener, FileOperations}, + file_operations::{FileOpener, FileOperations, IoctlCommand}, + io_buffer::IoBufferReader, io_buffer::IoBufferWriter, + ioctl, ktime::*, percpu, prelude::*, @@ -39,8 +48,11 @@ use kernel::{ str::CStr, sync::Lock, sync::SpinLock, - sysfs, timekeeping, + sysfs, + task::Task, + timekeeping, uidgid::{KgidT, KuidT}, + user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter}, }; static mut CLOCKLIST_LOCK: SpinLock = unsafe { SpinLock::new(1) }; @@ -56,10 +68,10 @@ const RROS_CLOCK_IOCBASE: u32 = 'c' as u32; const RROS_CLOCK_MONOTONIC: i32 = -(CLOCK_MONOTONIC as i32); const RROS_CLOCK_REALTIME: i32 = -(CLOCK_REALTIME as i32); -const RROS_CLKIOC_SLEEP: u32 = ioctl::_IOW::<__rros_timespec>(RROS_CLOCK_IOCBASE, 0); -const RROS_CLKIOC_GET_RES: u32 = ioctl::_IOR::<__rros_timespec>(RROS_CLOCK_IOCBASE, 1); -const RROS_CLKIOC_GET_TIME: u32 = ioctl::_IOR::<__rros_timespec>(RROS_CLOCK_IOCBASE, 2); -const RROS_CLKIOC_SET_TIME: u32 = ioctl::_IOR::<__rros_timespec>(RROS_CLOCK_IOCBASE, 3); +const RROS_CLKIOC_SLEEP: u32 = ioctl::_IOW::(RROS_CLOCK_IOCBASE, 0); +const RROS_CLKIOC_GET_RES: u32 = ioctl::_IOR::(RROS_CLOCK_IOCBASE, 1); +const RROS_CLKIOC_GET_TIME: u32 = ioctl::_IOR::(RROS_CLOCK_IOCBASE, 2); +const RROS_CLKIOC_SET_TIME: u32 = ioctl::_IOR::(RROS_CLOCK_IOCBASE, 3); const RROS_CLKIOC_NEW_TIMER: u32 = ioctl::_IO(RROS_CLOCK_IOCBASE, 5); extern "C" { @@ -504,12 +516,11 @@ pub static mut CLOCK_LIST: List<*mut RrosClock> = List::<*mut RrosClock> { pub static mut RROS_CLOCK_FACTORY: SpinLock = unsafe { SpinLock::new(factory::RrosFactory { name: unsafe { CStr::from_bytes_with_nul_unchecked("clock\0".as_bytes()) }, - // fops: Some(&Clockops), nrdev: CONFIG_RROS_NR_CLOCKS, build: None, dispose: Some(clock_factory_dispose), attrs: None, //sysfs::attribute_group::new(), - flags: factory::RrosFactoryType::SINGLE, + flags: factory::RrosFactoryType::Invalid, inside: Some(factory::RrosFactoryInside { type_: DeviceType::new(), class: None, @@ -548,23 +559,23 @@ impl RrosTimerFd { } } -fn get_timer_value(timer: Arc>, value: &mut itimerspec64) { +fn get_timer_value(timer: Arc>, value: &mut Itimerspec64) { let mut inner_timer_lock = timer.lock(); let inner_timer: &mut RrosTimer = inner_timer_lock.deref_mut(); value.it_interval = ktime_to_timespec64(inner_timer.interval); if rros_timer_is_running(inner_timer as *mut RrosTimer) { - value.it_value.tv_sec = 0; - value.it_value.tv_nsec = 0; + value.it_value.0.tv_sec = 0; + value.it_value.0.tv_nsec = 0; } else { value.it_value = ktime_to_timespec64(rros_get_timer_delta(timer.clone())); } } -fn set_timer_value(timer: Arc>, value: &itimerspec64) -> Result { +fn set_timer_value(timer: Arc>, value: &Itimerspec64) -> Result { let start: KtimeT; let period: KtimeT; - if value.it_value.tv_nsec == 0 && value.it_value.tv_sec == 0 { + if value.it_value.0.tv_nsec == 0 && value.it_value.0.tv_sec == 0 { rros_stop_timer(timer.clone()); return Ok(0); } @@ -585,8 +596,8 @@ fn pin_timer(timer: Arc>) {} fn set_timerfd( timerfd: &RrosTimerFd, - value: &mut itimerspec64, - ovalue: itimerspec64, + value: &mut Itimerspec64, + ovalue: Itimerspec64, ) -> Result { get_timer_value(timerfd.timer.clone(), value); @@ -626,31 +637,28 @@ fn new_timerfd(clock: RrosClock) -> Result { } fn clock_common_ioctl(clock: &mut RrosClock, cmd: u32, arg: usize) -> Result { - let mut uts: __rros_timespec = __rros_timespec::new(); - let u_uts: *mut __rros_timespec; - let mut ts64: timespec64 = timespec64 { - tv_sec: 0, - tv_nsec: 0, - }; + let mut uts: Timespec64 = Timespec64::default(); + let u_uts: *mut Timespec64; + let mut ts64: Timespec64 = Timespec64::new(0, 0); let mut ret: Result = Ok(0); match cmd { RROS_CLKIOC_GET_RES => { ts64 = ktime_to_timespec64(clock.resolution); - uts.tv_nsec = ts64.tv_nsec; - uts.tv_sec = ts64.tv_sec; - u_uts = arg as *mut __rros_timespec; + uts.0.tv_nsec = ts64.0.tv_nsec; + uts.0.tv_sec = ts64.0.tv_sec; + u_uts = arg as *mut Timespec64; let mut usptr = unsafe { UserSlicePtr::new( u_uts as *mut c_types::c_void, - core::mem::size_of::<__rros_timespec>(), + core::mem::size_of::(), ) .writer() }; if let Ok(_) = unsafe { usptr.write_raw( - &uts as *const __rros_timespec as *const u8, - core::mem::size_of::<__rros_timespec>(), + &uts as *const Timespec64 as *const u8, + core::mem::size_of::(), ) } { ret = Ok(0) @@ -660,20 +668,20 @@ fn clock_common_ioctl(clock: &mut RrosClock, cmd: u32, arg: usize) -> Result { ts64 = ktime_to_timespec64(clock.read()); - uts.tv_nsec = ts64.tv_nsec; - uts.tv_sec = ts64.tv_sec; - u_uts = arg as *mut __rros_timespec; + uts.0.tv_nsec = ts64.0.tv_nsec; + uts.0.tv_sec = ts64.0.tv_sec; + u_uts = arg as *mut Timespec64; let mut usptr = unsafe { UserSlicePtr::new( u_uts as *mut c_types::c_void, - core::mem::size_of::<__rros_timespec>(), + core::mem::size_of::(), ) .writer() }; if let Ok(_) = unsafe { usptr.write_raw( - &uts as *const __rros_timespec as *const u8, - core::mem::size_of::<__rros_timespec>(), + &uts as *const Timespec64 as *const u8, + core::mem::size_of::(), ) } { ret = Ok(0) @@ -682,27 +690,27 @@ fn clock_common_ioctl(clock: &mut RrosClock, cmd: u32, arg: usize) -> Result { - u_uts = arg as *mut __rros_timespec; + u_uts = arg as *mut Timespec64; let mut usptr = unsafe { UserSlicePtr::new( u_uts as *mut c_types::c_void, - core::mem::size_of::<__rros_timespec>(), + core::mem::size_of::(), ) .reader() }; if let Err(_) = unsafe { usptr.read_raw( - &mut uts as *mut __rros_timespec as *mut u8, - core::mem::size_of::<__rros_timespec>(), + &mut uts as *mut Timespec64 as *mut u8, + core::mem::size_of::(), ) } { return Err(Error::EFAULT); } - if uts.tv_nsec as usize >= 1000_000_000 as usize { + if uts.0.tv_nsec as usize >= 1000_000_000 as usize { return Err(Error::EINVAL); } - ts64.tv_nsec = uts.tv_nsec; - ts64.tv_sec = uts.tv_sec; + ts64.0.tv_nsec = uts.0.tv_nsec; + ts64.0.tv_sec = uts.0.tv_sec; clock.set(timespec64_to_ktime(ts64)); } _ => { @@ -734,7 +742,7 @@ extern "C" fn restart_clock_sleep(param: *mut bindings::restart_block) -> i64 { -(bindings::EINVAL as i64) } -fn clock_sleep(clock: &RrosClock, ts64: timespec64) -> Result { +fn clock_sleep(clock: &RrosClock, ts64: Timespec64) -> Result { let mut restart: bindings::restart_block; let timeout: KtimeT; let rem: KtimeT; @@ -754,7 +762,7 @@ fn clock_sleep(clock: &RrosClock, ts64: timespec64) -> Result { timeout = timespec64_to_ktime(ts64); } } - if let Ok(_) = evl_delay(timeout, rros_tmode::RROS_ABS, clock) { + if let Ok(_) = rros_delay(timeout, RrosTmode::RrosAbs, clock) { return Ok(0); } else { if Task::current().signal_pending() { @@ -774,38 +782,35 @@ fn clock_sleep(clock: &RrosClock, ts64: timespec64) -> Result { fn clock_oob_ioctl(fbind: &RrosFileBinding, cmd: u32, arg: usize) -> Result { //TODO: let clock = unsafe { &mut *((*fbind.element).pointer as *mut RrosClock) }; - let u_uts: *mut __rros_timespec; - let mut uts: __rros_timespec = __rros_timespec::new(); + let u_uts: *mut Timespec64; + let mut uts: Timespec64 = Timespec64::default(); let mut ret: Result = Ok(0); match cmd { RROS_CLKIOC_SLEEP => { - u_uts = arg as *mut __rros_timespec; + u_uts = arg as *mut Timespec64; let mut usrptr = unsafe { UserSlicePtr::new( u_uts as *mut c_types::c_void, - core::mem::size_of::<__rros_timespec>(), + core::mem::size_of::(), ) .reader() }; if let Err(_) = unsafe { usrptr.read_raw( - &mut uts as *mut __rros_timespec as *mut u8, - core::mem::size_of::<__rros_timespec>(), + &mut uts as *mut Timespec64 as *mut u8, + core::mem::size_of::(), ) } { return Err(Error::EFAULT); } - if uts.tv_sec < 0 { + if uts.0.tv_sec < 0 { return Err(Error::EINVAL); } - if uts.tv_nsec as usize >= 1000_000_000 as usize { + if uts.0.tv_nsec as usize >= 1000_000_000 as usize { return Err(Error::EINVAL); } - let ts: timespec64 = timespec64 { - tv_sec: uts.tv_sec, - tv_nsec: uts.tv_nsec, - }; + let ts: Timespec64 = Timespec64::new(uts.0.tv_sec, uts.0.tv_nsec); //TODO: clock_sleep is not implement ret = clock_sleep(clock, ts); } @@ -816,9 +821,9 @@ fn clock_oob_ioctl(fbind: &RrosFileBinding, cmd: u32, arg: usize) -> Result ret } -pub struct Clockops; +pub struct ClockOps; -impl FileOpener for Clockops { +impl FileOpener for ClockOps { fn open(inode: &u8, file: &kernel::file::File) -> kernel::Result { let mut flag: u64 = 0; let mut mark = false; @@ -860,7 +865,7 @@ impl FileOpener for Clockops { } } -impl FileOperations for Clockops { +impl FileOperations for ClockOps { kernel::declare_file_operations!(ioctl, oob_ioctl); type Wrapper = Box; @@ -1173,15 +1178,3 @@ fn rros_ktime_monotonic() -> KtimeT { // return clock->ops.read(clock); // } - -pub fn u_timespec_to_ktime(u_ts: __rros_timespec) -> KtimeT { - extern "C" { - fn rust_helper_timespec64_to_ktime(ts: bindings::timespec64) -> KtimeT; - } - let ts64 = bindings::timespec64 { - tv_sec: u_ts.tv_sec as i64, - tv_nsec: u_ts.tv_nsec as i64, - }; - - unsafe { rust_helper_timespec64_to_ktime(ts64) } -} diff --git a/kernel/rros/factory.rs b/kernel/rros/factory.rs index c35c64a28180..d18651dcdb72 100644 --- a/kernel/rros/factory.rs +++ b/kernel/rros/factory.rs @@ -309,7 +309,7 @@ impl device::Devnode for FactoryTypeDevnode { } kernelh::_kasprintf_2( bindings::GFP_KERNEL, - c_str!("evl/%s/%s").as_char_ptr(), + c_str!("rros/%s/%s").as_char_ptr(), dev.dev_type().unwrap().get_name(), dev.dev_name(), ) @@ -350,23 +350,21 @@ fn create_element_device( }; let _res = do_element_visibility(e.clone(), fac, &mut rdev); - let e_clone = e.clone(); - let mut e_mut = e_clone.borrow_mut(); - let filp = e_mut.fpriv.filp.as_mut().unwrap().get_ptr(); - pr_debug!("the address of filp location 7 is {:p}, {:p}", filp, &filp); - - // if (!rros_element_is_public(e) && !rros_element_has_coredev(e)) { - // if rros_element_is_public(e.clone()) == false && rros_element_has_coredev(e.clone()) == false { - // unsafe { bindings::fd_install(e_mut.fpriv.efd.reserved_fd(), filp) }; - // e.fpriv.efd.commit(File{ptr: filp}); - // } - fd_install(e_mut.fpriv.efd.reserved_fd(), filp); - pr_debug!("the address of filp location 8 is {:p}, {:p}", filp, &filp); - // e->refs++; - // fd_install(e->fpriv.efd, e->fpriv.filp); - // } - // let e_clone = e.clone(); - // let mut e_mut = e_clone.borrow_mut(); + if !rros_element_is_public(e.clone()) && !rros_element_has_coredev(e.clone()) { + let e_clone = e.clone(); + let mut e_mut = e_clone.borrow_mut(); + e_mut.refs += 1; + let filp = e_mut.fpriv.filp.as_mut().unwrap().get_ptr(); + pr_debug!("the address of filp location 7 is {:p}, {:p}", filp, &filp); + + // if (!rros_element_is_public(e) && !rros_element_has_coredev(e)) { + // if rros_element_is_public(e.clone()) == false && rros_element_has_coredev(e.clone()) == false { + // unsafe { bindings::fd_install(e_mut.fpriv.efd.reserved_fd(), filp) }; + // e.fpriv.efd.commit(File{ptr: filp}); + // } + fd_install(e_mut.fpriv.efd.reserved_fd(), filp); + pr_debug!("the address of filp location 8 is {:p}, {:p}", filp, &filp); + } Ok(0) } @@ -398,7 +396,6 @@ fn do_element_visibility( // { let e_clone = e.clone(); - let mut e_mut = e_clone.borrow_mut(); // let core_dev_res = rros_element_has_coredev(e.clone()); // let mm_res = Task::current().kernel(); @@ -437,6 +434,7 @@ fn do_element_visibility( if res == true { return Ok(0); } + let mut e_mut = e_clone.borrow_mut(); // struct file *filp; // int ret, efd; @@ -568,7 +566,10 @@ fn do_element_visibility( // } } -fn bind_file_to_element(filp: *mut bindings::file, e: Rc>) -> Result { +pub fn bind_file_to_element( + filp: *mut bindings::file, + e: Rc>, +) -> Result { // static int bind_file_to_element(struct file *filp, struct rros_element *e) // { // struct rros_file_binding *fbind; @@ -622,8 +623,7 @@ fn bind_file_to_element(filp: *mut bindings::file, e: Rc>) // } } -#[allow(dead_code)] -fn rros_create_core_element_device( +pub fn rros_create_core_element_device( e: Rc>, fac: &'static mut SpinLock, name: &'static CStr, @@ -766,138 +766,144 @@ fn rros_create_factory( let res = match fac_lock.inside { Some(ref mut inside) => { let mut idevname = CStr::from_bytes_with_nul("clone\0".as_bytes())?; - match flag { - RrosFactoryType::SINGLE => { - // RROS_FACTORY_SINGLE - idevname = name; - inside.class = Some(rros_class.clone()); - inside.minor_map = Some(0); - inside.sub_rdev = Some(class::DevT::new(0)); - match idevname.to_str() { - Ok("clock") => { - chrdev_reg.as_mut().register::()?; - } - Ok("control") => { - chrdev_reg.as_mut().register::()?; - } - Ok("poll") => { - chrdev_reg.as_mut().register::()?; - } - Ok(_) => { - pr_alert!("not yet implemented"); - } - Err(_e) => { - pr_err!("should not meet here"); - } + if let RrosFactoryType::SINGLE = flag { + // RROS_FACTORY_SINGLE + idevname = name; + inside.class = Some(rros_class.clone()); + inside.minor_map = Some(0); + inside.sub_rdev = Some(class::DevT::new(0)); + match idevname.to_str() { + Ok("control") => { + chrdev_reg.as_mut().register::()?; } - } - // We use cdev_alloc to replace cdev_init. alloc_chrdev + cdev_alloc + cdev_add - // chrdev_reg.as_mut().register::()?; - RrosFactoryType::CLONE => { - // RROS_FACTORY_CLONE - // create_element_class - inside.minor_map = - Some(bitmap_zalloc(nrdev.try_into().unwrap(), bindings::GFP_KERNEL) as u64); - if inside.minor_map == Some(0) { - return Err(kernel::Error::EINVAL); + Ok("poll") => { + chrdev_reg.as_mut().register::()?; + } + Ok(_) => { + pr_alert!("not yet implemented"); + } + Err(_e) => { + pr_err!("should not meet here"); } + } + } else { + // create_element_class + inside.minor_map = + Some(bitmap_zalloc(nrdev.try_into().unwrap(), bindings::GFP_KERNEL) as u64); + if inside.minor_map == Some(0) { + return Err(kernel::Error::EINVAL); + } - inside.class = Some(Arc::try_new(class::Class::new( - this_module, - name.as_char_ptr(), - )?)?); - let mut type_ = device::DeviceType::new().name(name.as_char_ptr()); - // TODO: ugly - type_.set_devnode::(); - inside.type_ = type_; - inside.kuid = Some(KuidT::global_root_uid()); - inside.kgid = Some(KgidT::global_root_gid()); - // here we cannot get the number from the nrdev, because this requires const - match name.to_str() { - Ok("thread") => { - let ele_chrdev_reg: Pin< - Box>, - > = chrdev::Registration::new_pinned(name, 0, this_module)?; - inside.register = Some(ele_chrdev_reg); - inside - .register - .as_mut() - .unwrap() - .as_mut() - .register::()?; - } - Ok("xbuf") => { - let ele_chrdev_reg: Pin< - Box>, - > = chrdev::Registration::new_pinned(name, 0, this_module)?; - inside.register = Some(ele_chrdev_reg); - inside - .register - .as_mut() - .unwrap() - .as_mut() - .register::()?; - } - Ok("proxy") => { - let ele_chrdev_reg: Pin< - Box>, - > = chrdev::Registration::new_pinned(name, 0, this_module)?; - inside.register = Some(ele_chrdev_reg); - inside - .register - .as_mut() - .unwrap() - .as_mut() - .register::()?; - } - Ok("observable") => { - unimplemented!(); - // pr_info!("[observable] in function: rros_create_factory"); - // let mut ele_chrdev_reg: Pin< - // Box< - // chrdev::Registration<{ observable::CONFIG_RROS_NR_OBSERVABLE }>, - // >, - // > = chrdev::Registration::new_pinned(name, 0, this_module)?; - // inside.register = Some(ele_chrdev_reg); - // inside - // .register - // .as_mut() - // .unwrap() - // .as_mut() - // .register::()?; - } - Ok(_) => { - pr_info!("not yet implemented"); - } - Err(_e) => { - pr_info!("should not meet here"); - } + inside.class = Some(Arc::try_new(class::Class::new( + this_module, + name.as_char_ptr(), + )?)?); + let mut type_ = device::DeviceType::new().name(name.as_char_ptr()); + // TODO: ugly + type_.set_devnode::(); + inside.type_ = type_; + inside.kuid = Some(KuidT::global_root_uid()); + inside.kgid = Some(KgidT::global_root_gid()); + // here we cannot get the number from the nrdev, because this requires const + match name.to_str() { + Ok("clock") => { + let ele_chrdev_reg: Pin< + Box>, + > = chrdev::Registration::new_pinned(name, 0, this_module)?; + inside.register = Some(ele_chrdev_reg); + // register monotonic clock + inside + .register + .as_mut() + .unwrap() + .as_mut() + .register::()?; + // register realtime clock + inside + .register + .as_mut() + .unwrap() + .as_mut() + .register::()?; + } + Ok("thread") => { + let ele_chrdev_reg: Pin< + Box>, + > = chrdev::Registration::new_pinned(name, 0, this_module)?; + inside.register = Some(ele_chrdev_reg); + inside + .register + .as_mut() + .unwrap() + .as_mut() + .register::()?; + } + Ok("xbuf") => { + let ele_chrdev_reg: Pin< + Box>, + > = chrdev::Registration::new_pinned(name, 0, this_module)?; + inside.register = Some(ele_chrdev_reg); + inside + .register + .as_mut() + .unwrap() + .as_mut() + .register::()?; + } + Ok("proxy") => { + let ele_chrdev_reg: Pin< + Box>, + > = chrdev::Registration::new_pinned(name, 0, this_module)?; + inside.register = Some(ele_chrdev_reg); + inside + .register + .as_mut() + .unwrap() + .as_mut() + .register::()?; + } + Ok("observable") => { + unimplemented!(); + // pr_info!("[observable] in function: rros_create_factory"); + // let mut ele_chrdev_reg: Pin< + // Box< + // chrdev::Registration<{ observable::CONFIG_RROS_NR_OBSERVABLE }>, + // >, + // > = chrdev::Registration::new_pinned(name, 0, this_module)?; + // inside.register = Some(ele_chrdev_reg); + // inside + // .register + // .as_mut() + // .unwrap() + // .as_mut() + // .register::()?; } - // no need to call register here - // ele_chrdev_reg.as_mut().register::()?; //alloc_chrdev + cdev_alloc + cdev_add - // inside.register = Some(ele_chrdev_reg); - // inside.register.as_mut().unwrap().as_mut().register::()?; - // create_element_class end + Ok(_) => { + pr_info!("not yet implemented"); + } + Err(_e) => { + pr_info!("should not meet here"); + } + } + // no need to call register here + // ele_chrdev_reg.as_mut().register::()?; //alloc_chrdev + cdev_alloc + cdev_add + // inside.register = Some(ele_chrdev_reg); + // inside.register.as_mut().unwrap().as_mut().register::()?; + // create_element_class end - // FIXME: this should be variable. But the `register` needs a const value. We just hack for now. If we need more - // factory, we need to change the code here. One way here is to use index to find the struct. + // FIXME: this should be variable. But the `register` needs a const value. We just hack for now. If we need more + // factory, we need to change the code here. One way here is to use index to find the struct. - // let factory_ops = fac.locked_data().into_inner(); + // let factory_ops = fac.locked_data().into_inner(); + if let RrosFactoryType::CLONE = flag { chrdev_reg.as_mut().register::()?; } - _ => { - let mut ele_chrdev_reg: Pin< - Box>, - > = chrdev::Registration::new_pinned(c_str!("clock"), 0, this_module)?; - ele_chrdev_reg.as_mut().register::()?; //for monotonic clock - ele_chrdev_reg.as_mut().register::()?; //for realtime clock - inside.register = Some(ele_chrdev_reg); - pr_alert!("not yet implemented"); - } } - let rdev = chrdev_reg.as_mut().last_registered_devt().unwrap(); - let dev = create_sys_device(rdev, inside, ptr::null_mut() as *mut u8, idevname); - inside.device = Some(dev); + if let RrosFactoryType::SINGLE | RrosFactoryType::CLONE = flag { + let rdev = chrdev_reg.as_mut().last_registered_devt().unwrap(); + let dev = create_sys_device(rdev, inside, ptr::null_mut() as *mut u8, idevname); + inside.device = Some(dev); + } let mut index = RrosIndex { rbroot: rbtree::RBTree::new(), @@ -1228,7 +1234,7 @@ extern "C" { ) -> c_types::c_ulong; } -pub fn ioctl_clone_device(_file: &File, _cmd: u32, arg: usize) -> Result { +pub fn ioctl_clone_device(file: &File, _cmd: u32, arg: usize) -> Result { // static long ioctl_clone_device(struct file *filp, unsigned int cmd, // unsigned long arg) // { @@ -1298,10 +1304,11 @@ pub fn ioctl_clone_device(_file: &File, _cmd: u32, arg: usize) -> Result let cstr_u_name = unsafe { CStr::from_char_ptr(u_name as *const c_types::c_char) }; // FIXME: update the cdev logic to use container_of && update the uname // fac = container_of(filp->f_inode->i_cdev, struct rros_factory, cdev); + let fdname = file.get_parent_name().unwrap(); pr_debug!("the value is {:?} ", cstr_u_name[0]); - pr_debug!("the value is {:?} ", cstr_u_name[0]); - let e: Rc> = if cstr_u_name[0] == 88 { - pr_debug!("x"); + pr_debug!("ioctl_clone_device: clone type is {}", fdname); + let e: Rc> = if fdname == "xbuf" { + pr_debug!("ioctl_clone_device: xbuf clone"); unsafe { (*xbuf::RROS_XBUF_FACTORY.locked_data().get()) .build @@ -1313,8 +1320,8 @@ pub fn ioctl_clone_device(_file: &File, _cmd: u32, arg: usize) -> Result &state_offset, ) } - } else if cstr_u_name[0] == 80 { - pr_debug!("p"); + } else if fdname == "proxy" { + pr_debug!("ioctl_clone_device: proxy clone"); unsafe { (*proxy::RROS_PROXY_FACTORY.locked_data().get()) .build @@ -1354,11 +1361,11 @@ pub fn ioctl_clone_device(_file: &File, _cmd: u32, arg: usize) -> Result // barrier(); // TODO: create the element device - let _ret = if cstr_u_name[0] == 88 { - pr_debug!("x"); + let _ret = if fdname == "xbuf" { + pr_debug!("ioctl_clone_device: xbuf element create"); create_element_device(e.clone(), unsafe { &mut xbuf::RROS_XBUF_FACTORY }) - } else if cstr_u_name[0] == 80 { - pr_debug!("p"); + } else if fdname == "proxy" { + pr_debug!("ioctl_clone_device: proxy element create"); create_element_device(e.clone(), unsafe { &mut proxy::RROS_PROXY_FACTORY }) } else { pr_debug!("maybe a thread"); diff --git a/kernel/rros/thread.rs b/kernel/rros/thread.rs index 52639e9e426a..8db8b92c4c4d 100644 --- a/kernel/rros/thread.rs +++ b/kernel/rros/thread.rs @@ -1207,8 +1207,7 @@ fn rros_sleep_until(timeout: ktime::KtimeT) -> Result { } } -#[allow(dead_code)] -fn rros_delay( +pub fn rros_delay( timeout: ktime::KtimeT, timeout_mode: timeout::RrosTmode, clock: &clock::RrosClock, diff --git a/rust/helpers.c b/rust/helpers.c index bd0c7d21a795..3fdb6cad2547 100644 --- a/rust/helpers.c +++ b/rust/helpers.c @@ -1144,6 +1144,16 @@ int rust_helper_pa(unsigned long x) { } EXPORT_SYMBOL_GPL(rust_helper_pa); +void rust_helper_schedule_work(struct work_struct*work){ + schedule_work(work); +} +EXPORT_SYMBOL_GPL(rust_helper_schedule_work); + +unsigned int rust_helper_minor(dev_t dev) { + return MINOR(dev); +} +EXPORT_SYMBOL_GPL(rust_helper_minor); + // void rust_helper_anon_inode_getfile(const char *name, // const struct file_operations *fops, // void *priv, int flags) { diff --git a/rust/kernel/ktime.rs b/rust/kernel/ktime.rs index e5c8bfa8fe6d..3d82eeedee4b 100644 --- a/rust/kernel/ktime.rs +++ b/rust/kernel/ktime.rs @@ -3,7 +3,7 @@ //! ktime //! //! C header: [`include/linux/ktime.h`](../../../../include/linux/ktime.h) -use crate::bindings; +use crate::{bindings, c_types::c_longlong}; /// The `KtimeT` type is a type alias for `i64`. It represents a ktime value in the kernel. pub type KtimeT = i64; @@ -24,6 +24,24 @@ extern "C" { #[repr(transparent)] pub struct Timespec64(pub bindings::timespec64); +impl Timespec64 { + /// Construct Timespec64 with `tv_sec` and `tv_nsec` + pub fn new(tv_sec: KtimeT, tv_nsec: c_longlong) -> Self { + Self(bindings::timespec64 { tv_sec, tv_nsec }) + } +} + +/// A wrapper for [`bindings::itimerspec64`] +#[derive(Default, Copy, Clone)] +#[repr(C)] +pub struct Itimerspec64 { + /// timer period + pub it_interval: Timespec64, + + /// timer expiration + pub it_value: Timespec64, +} + /// The function `timespec64_to_ktime` will call kernel's `ktime_set` to get a `KtimeT` from `Timespec64`. pub fn timespec64_to_ktime(u_ts: Timespec64) -> KtimeT { unsafe { rust_helper_timespec64_to_ktime(u_ts.0) }