@@ -10,8 +10,52 @@ pub fn create_vm() -> Result<(), Error> {
10
10
match_error_code ( unsafe { hv_vm_create ( null_mut ( ) ) } )
11
11
}
12
12
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
+
13
57
/// 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
15
59
pub fn map_mem ( mem : & [ u8 ] , ipa : u64 , mem_perm : MemPerm ) -> Result < ( ) , Error > {
16
60
match_error_code ( unsafe {
17
61
hv_vm_map (
@@ -75,8 +119,11 @@ impl From<hv_vcpu_exit_t> for VirtualCpuExitReason {
75
119
76
120
/// Virtual CPU
77
121
pub struct VirtualCpu {
122
+ /// Virtual CPU Id
123
+ id : u32 ,
124
+
78
125
/// Virtual CPU handle
79
- id : hv_vcpu_t ,
126
+ vcpu_handle : hv_vcpu_t ,
80
127
81
128
/// VirtualCPU exit informations.
82
129
vcpu_exit : * const hv_vcpu_exit_t ,
@@ -700,23 +747,35 @@ impl From<SystemRegister> for hv_sys_reg_t {
700
747
}
701
748
702
749
impl 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 > {
704
754
let handle: hv_vcpu_config_t = core:: ptr:: null_mut ( ) ;
705
755
let mut vcpu_handle: hv_vcpu_t = 0 ;
706
756
let mut vcpu_exit: * const hv_vcpu_exit_t = core:: ptr:: null_mut ( ) ;
707
757
708
758
match_error_code ( unsafe { hv_vcpu_create ( & mut vcpu_handle, & mut vcpu_exit, & handle) } ) ?;
709
759
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)
714
769
}
715
770
716
- pub fn get_id ( & self ) -> hv_vcpu_t {
771
+ pub fn get_id ( & self ) -> u32 {
717
772
self . id
718
773
}
719
774
775
+ pub fn get_handle ( & self ) -> hv_vcpu_t {
776
+ self . vcpu_handle
777
+ }
778
+
720
779
pub fn exit_reason ( & self ) -> VirtualCpuExitReason {
721
780
VirtualCpuExitReason :: from ( unsafe { * self . vcpu_exit } )
722
781
}
@@ -727,30 +786,119 @@ impl VirtualCpu {
727
786
let mut value: u64 = 0 ;
728
787
729
788
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 )
731
806
} ) ?;
732
807
733
808
Ok ( value)
734
809
}
735
810
736
811
/// Sets the value of an architectural x86 register of the VirtualCpu
737
812
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) } )
739
814
}
740
815
741
816
/// Gets a system register value.
742
817
pub fn read_system_register ( & self , reg : SystemRegister ) -> Result < u64 , Error > {
743
818
let mut value: u64 = 0 ;
744
819
745
820
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
+ )
747
826
} ) ?;
748
827
749
828
Ok ( value)
750
829
}
751
830
752
831
/// Gets a system register value.
753
832
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
+ )
755
903
}
756
904
}
0 commit comments