@@ -10,8 +10,52 @@ pub fn create_vm() -> Result<(), Error> {
1010 match_error_code ( unsafe { hv_vm_create ( null_mut ( ) ) } )
1111}
1212
13+ #[ cfg( feature = "macos_15_0_0" ) ]
14+ /// Generic interrupt controller (GIC)
15+ pub struct Gic ( hv_gic_config_t ) ;
16+
17+ #[ cfg( feature = "macos_15_0_0" ) ]
18+ impl Gic {
19+ /// Creates a generic interrupt controller (GIC)
20+ pub fn new ( gicd_addr : u64 , gicr_base : u64 , msi_base : u64 ) -> Result < Self , Error > {
21+ let config = unsafe { hv_gic_config_create ( ) } ;
22+
23+ let mut intid_base: u32 = 0 ;
24+ let mut intid_count: u32 = 0 ;
25+ match_error_code ( unsafe {
26+ hv_gic_get_spi_interrupt_range ( & mut intid_base as * mut _ , & mut intid_count as * mut _ )
27+ } ) ?;
28+
29+ match_error_code ( unsafe { hv_gic_config_set_distributor_base ( config, gicd_addr) } ) ?;
30+ match_error_code ( unsafe { hv_gic_config_set_redistributor_base ( config, gicr_base) } ) ?;
31+ match_error_code ( unsafe { hv_gic_config_set_msi_region_base ( config, msi_base) } ) ?;
32+ match_error_code ( unsafe {
33+ hv_gic_config_set_msi_interrupt_range ( config, intid_base, intid_count)
34+ } ) ?;
35+ match_error_code ( unsafe { hv_gic_create ( config) } ) ?;
36+
37+ Ok ( Self ( config) )
38+ }
39+
40+ /// Resets the generic interrupt controller (GIC) device.
41+ pub fn reset ( & self ) -> Result < ( ) , Error > {
42+ match_error_code ( unsafe { hv_gic_reset ( ) } ) ?;
43+
44+ Ok ( ( ) )
45+ }
46+ }
47+
48+ #[ cfg( feature = "macos_15_0_0" ) ]
49+ impl Drop for Gic {
50+ fn drop ( & mut self ) {
51+ unsafe {
52+ os_release ( self . 0 ) ;
53+ }
54+ }
55+ }
56+
1357/// Maps a region in the virtual address space of the current task into the guest physical
14- /// address space of the virutal machine
58+ /// address space of the virtual machine
1559pub fn map_mem ( mem : & [ u8 ] , ipa : u64 , mem_perm : MemPerm ) -> Result < ( ) , Error > {
1660 match_error_code ( unsafe {
1761 hv_vm_map (
@@ -75,8 +119,11 @@ impl From<hv_vcpu_exit_t> for VirtualCpuExitReason {
75119
76120/// Virtual CPU
77121pub struct VirtualCpu {
122+ /// Virtual CPU Id
123+ id : u32 ,
124+
78125 /// Virtual CPU handle
79- id : hv_vcpu_t ,
126+ vcpu_handle : hv_vcpu_t ,
80127
81128 /// VirtualCPU exit informations.
82129 vcpu_exit : * const hv_vcpu_exit_t ,
@@ -700,23 +747,35 @@ impl From<SystemRegister> for hv_sys_reg_t {
700747}
701748
702749impl VirtualCpu {
703- pub fn new ( ) -> Result < VirtualCpu , Error > {
750+ /// Creates a VirtualCpu instance for the current thread
751+ ///
752+ /// `id` represents the internal numbering of the processor.
753+ pub fn new ( id : u32 ) -> Result < VirtualCpu , Error > {
704754 let handle: hv_vcpu_config_t = core:: ptr:: null_mut ( ) ;
705755 let mut vcpu_handle: hv_vcpu_t = 0 ;
706756 let mut vcpu_exit: * const hv_vcpu_exit_t = core:: ptr:: null_mut ( ) ;
707757
708758 match_error_code ( unsafe { hv_vcpu_create ( & mut vcpu_handle, & mut vcpu_exit, & handle) } ) ?;
709759
710- Ok ( VirtualCpu {
711- id : vcpu_handle,
712- vcpu_exit : vcpu_exit,
713- } )
760+ let vcpu = VirtualCpu {
761+ id,
762+ vcpu_handle,
763+ vcpu_exit,
764+ } ;
765+
766+ vcpu. write_system_register ( SystemRegister :: MPIDR_EL1 , ( id & 0xff ) . into ( ) ) ?;
767+
768+ Ok ( vcpu)
714769 }
715770
716- pub fn get_id ( & self ) -> hv_vcpu_t {
771+ pub fn get_id ( & self ) -> u32 {
717772 self . id
718773 }
719774
775+ pub fn get_handle ( & self ) -> hv_vcpu_t {
776+ self . vcpu_handle
777+ }
778+
720779 pub fn exit_reason ( & self ) -> VirtualCpuExitReason {
721780 VirtualCpuExitReason :: from ( unsafe { * self . vcpu_exit } )
722781 }
@@ -727,30 +786,119 @@ impl VirtualCpu {
727786 let mut value: u64 = 0 ;
728787
729788 match_error_code ( unsafe {
730- hv_vcpu_get_reg ( self . id , hv_reg_t:: from ( reg) , & mut value as * mut u64 )
789+ hv_vcpu_get_reg (
790+ self . vcpu_handle ,
791+ hv_reg_t:: from ( reg) ,
792+ & mut value as * mut u64 ,
793+ )
794+ } ) ?;
795+
796+ Ok ( value)
797+ }
798+
799+ /// Read a generic interrupt controller (GIC) redistributor register.
800+ #[ cfg( feature = "macos_15_0_0" ) ]
801+ pub fn read_redistributor_register ( & self , offset : u32 ) -> Result < u64 , Error > {
802+ let mut value: u64 = 0 ;
803+
804+ match_error_code ( unsafe {
805+ hv_gic_get_redistributor_reg ( self . vcpu_handle , offset, & mut value as * mut u64 )
731806 } ) ?;
732807
733808 Ok ( value)
734809 }
735810
736811 /// Sets the value of an architectural x86 register of the VirtualCpu
737812 pub fn write_register ( & self , reg : Register , value : u64 ) -> Result < ( ) , Error > {
738- match_error_code ( unsafe { hv_vcpu_set_reg ( self . id , hv_reg_t:: from ( reg) , value) } )
813+ match_error_code ( unsafe { hv_vcpu_set_reg ( self . vcpu_handle , hv_reg_t:: from ( reg) , value) } )
739814 }
740815
741816 /// Gets a system register value.
742817 pub fn read_system_register ( & self , reg : SystemRegister ) -> Result < u64 , Error > {
743818 let mut value: u64 = 0 ;
744819
745820 match_error_code ( unsafe {
746- hv_vcpu_get_sys_reg ( self . id , hv_sys_reg_t:: from ( reg) , & mut value as * mut u64 )
821+ hv_vcpu_get_sys_reg (
822+ self . vcpu_handle ,
823+ hv_sys_reg_t:: from ( reg) ,
824+ & mut value as * mut u64 ,
825+ )
747826 } ) ?;
748827
749828 Ok ( value)
750829 }
751830
752831 /// Gets a system register value.
753832 pub fn write_system_register ( & self , reg : SystemRegister , value : u64 ) -> Result < ( ) , Error > {
754- match_error_code ( unsafe { hv_vcpu_set_sys_reg ( self . id , hv_sys_reg_t:: from ( reg) , value) } )
833+ match_error_code ( unsafe {
834+ hv_vcpu_set_sys_reg ( self . vcpu_handle , hv_sys_reg_t:: from ( reg) , value)
835+ } )
836+ }
837+ }
838+
839+ impl core:: fmt:: Debug for VirtualCpu {
840+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
841+ let pc = self . read_register ( Register :: PC ) . unwrap ( ) ;
842+ let cpsr = self . read_register ( Register :: CPSR ) . unwrap ( ) ;
843+ let sp = self . read_system_register ( SystemRegister :: SP_EL1 ) . unwrap ( ) ;
844+ let sctlr = self
845+ . read_system_register ( SystemRegister :: SCTLR_EL1 )
846+ . unwrap ( ) ;
847+ let ttbr0 = self
848+ . read_system_register ( SystemRegister :: TTBR0_EL1 )
849+ . unwrap ( ) ;
850+ let lr = self . read_register ( Register :: LR ) . unwrap ( ) ;
851+ let x0 = self . read_register ( Register :: X0 ) . unwrap ( ) ;
852+ let x1 = self . read_register ( Register :: X1 ) . unwrap ( ) ;
853+ let x2 = self . read_register ( Register :: X2 ) . unwrap ( ) ;
854+ let x3 = self . read_register ( Register :: X3 ) . unwrap ( ) ;
855+ let x4 = self . read_register ( Register :: X4 ) . unwrap ( ) ;
856+ let x5 = self . read_register ( Register :: X5 ) . unwrap ( ) ;
857+ let x6 = self . read_register ( Register :: X6 ) . unwrap ( ) ;
858+ let x7 = self . read_register ( Register :: X7 ) . unwrap ( ) ;
859+ let x8 = self . read_register ( Register :: X8 ) . unwrap ( ) ;
860+ let x9 = self . read_register ( Register :: X9 ) . unwrap ( ) ;
861+ let x10 = self . read_register ( Register :: X10 ) . unwrap ( ) ;
862+ let x11 = self . read_register ( Register :: X11 ) . unwrap ( ) ;
863+ let x12 = self . read_register ( Register :: X12 ) . unwrap ( ) ;
864+ let x13 = self . read_register ( Register :: X13 ) . unwrap ( ) ;
865+ let x14 = self . read_register ( Register :: X14 ) . unwrap ( ) ;
866+ let x15 = self . read_register ( Register :: X15 ) . unwrap ( ) ;
867+ let x16 = self . read_register ( Register :: X16 ) . unwrap ( ) ;
868+ let x17 = self . read_register ( Register :: X17 ) . unwrap ( ) ;
869+ let x18 = self . read_register ( Register :: X18 ) . unwrap ( ) ;
870+ let x19 = self . read_register ( Register :: X19 ) . unwrap ( ) ;
871+ let x20 = self . read_register ( Register :: X20 ) . unwrap ( ) ;
872+ let x21 = self . read_register ( Register :: X21 ) . unwrap ( ) ;
873+ let x22 = self . read_register ( Register :: X22 ) . unwrap ( ) ;
874+ let x23 = self . read_register ( Register :: X23 ) . unwrap ( ) ;
875+ let x24 = self . read_register ( Register :: X24 ) . unwrap ( ) ;
876+ let x25 = self . read_register ( Register :: X25 ) . unwrap ( ) ;
877+ let x26 = self . read_register ( Register :: X26 ) . unwrap ( ) ;
878+ let x27 = self . read_register ( Register :: X27 ) . unwrap ( ) ;
879+ let x28 = self . read_register ( Register :: X28 ) . unwrap ( ) ;
880+ let x29 = self . read_register ( Register :: X29 ) . unwrap ( ) ;
881+ let x30 = self . read_register ( Register :: X30 ) . unwrap ( ) ;
882+
883+ writeln ! ( f, "\n Registers of CPU {}:" , ( * self ) . get_id( ) ) ?;
884+ writeln ! (
885+ f,
886+ "PC : {pc:016x} LR : {lr:016x} CPSR : {cpsr:016x}\n \
887+ SP : {sp:016x} SCTLR : {sctlr:016x} TTBR0 : {ttbr0:016x}",
888+ ) ?;
889+ writeln ! (
890+ f,
891+ "x0 : {x0:016x} x1 : {x1:016x} x2 : {x2:016x}\n \
892+ x3 : {x3:016x} x4 : {x4:016x} x5 : {x5:016x}\n \
893+ x6 : {x6:016x} x7 : {x7:016x} x8 : {x8:016x}\n \
894+ x9 : {x9:016x} x10 : {x10:016x} x11 : {x11:016x}\n \
895+ x12 : {x12:016x} x13 : {x13:016x} x14 : {x14:016x}\n \
896+ x15 : {x15:016x} x16 : {x16:016x} x17 : {x17:016x}\n \
897+ x18 : {x18:016x} x19 : {x19:016x} x20 : {x20:016x}\n \
898+ x21 : {x21:016x} x22 : {x22:016x} x23 : {x23:016x}\n \
899+ x24 : {x24:016x} x25 : {x25:016x} x26 : {x26:016x}\n \
900+ x27 : {x27:016x} x28 : {x28:016x} x29 : {x29:016x}\n \
901+ x30 : {x30:016x}\n ",
902+ )
755903 }
756904}
0 commit comments