x86_64.rs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. pub mod fpu;
  2. pub mod io;
  3. mod lock;
  4. pub mod msr;
  5. pub mod rand;
  6. pub mod reg;
  7. use core::{arch::asm, ops::Range};
  8. use bitop_ex::BitOpEx;
  9. use paging::LAddr;
  10. pub use self::lock::{mutex::*, rwlock::*, IntrState, PreemptState, PreemptStateGuard};
  11. /// The address space that should never be valid due to hardware constraints.
  12. pub const INCANONICAL: Range<LAddr> =
  13. LAddr::new(0x8000_0000_0000 as *mut u8)..LAddr::new(0xFFFF_8000_0000_0000 as *mut u8);
  14. /// Check if the address is not permanently invalid.
  15. pub fn canonical(addr: LAddr) -> bool {
  16. !INCANONICAL.contains(&addr)
  17. }
  18. /// Automatically fix an incanonical address to its most likely target location.
  19. ///
  20. /// NOTE: It should not be misused to hard-correct addresses
  21. pub fn fix_canonical(addr: LAddr) -> LAddr {
  22. let ret = LAddr::from(addr.val() & 0xFFFF_FFFF_FFFF);
  23. if canonical(ret) {
  24. ret
  25. } else {
  26. LAddr::new(unsafe { ret.add(0xFFFF_0000_0000_0000) })
  27. }
  28. }
  29. /// # Safety
  30. ///
  31. /// Invalid use of this function can cause CPU's unrecoverable fault.
  32. #[inline]
  33. pub unsafe fn halt() {
  34. asm!("hlt");
  35. }
  36. /// # Safety
  37. ///
  38. /// Invalid use of this function can cause CPU unrecoverable fault.
  39. #[inline]
  40. pub unsafe fn pause_intr() -> u64 {
  41. let rflags = reg::rflags::read();
  42. asm!("cli");
  43. rflags
  44. }
  45. /// # Safety
  46. ///
  47. /// Invalid use of this function can cause CPU unrecoverable fault.
  48. #[inline]
  49. pub unsafe fn resume_intr(rflags: Option<u64>) {
  50. if rflags.map_or(true, |rflags| rflags.contains_bit(reg::rflags::IF)) {
  51. asm!("sti");
  52. }
  53. }
  54. /// # Safety
  55. ///
  56. /// Invalid use of this function can cause CPU unrecoverable fault.
  57. #[inline(always)]
  58. pub unsafe fn halt_loop(intr_op: Option<bool>) -> ! {
  59. let f = match intr_op {
  60. Some(op) => {
  61. if op {
  62. || resume_intr(None)
  63. } else {
  64. || {
  65. pause_intr();
  66. }
  67. }
  68. }
  69. None => || {},
  70. };
  71. loop {
  72. f();
  73. halt();
  74. }
  75. }