@@ -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,117 @@ 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
+ pub fn read_redistributor_register ( & self , offset : u32 ) -> Result < u64 , Error > {
800
+ let mut value: u64 = 0 ;
801
+
802
+ match_error_code ( unsafe {
803
+ hv_gic_get_redistributor_reg ( self . vcpu_handle , offset, & mut value as * mut u64 )
731
804
} ) ?;
732
805
733
806
Ok ( value)
734
807
}
735
808
736
809
/// Sets the value of an architectural x86 register of the VirtualCpu
737
810
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) } )
811
+ match_error_code ( unsafe { hv_vcpu_set_reg ( self . vcpu_handle , hv_reg_t:: from ( reg) , value) } )
739
812
}
740
813
741
814
/// Gets a system register value.
742
815
pub fn read_system_register ( & self , reg : SystemRegister ) -> Result < u64 , Error > {
743
816
let mut value: u64 = 0 ;
744
817
745
818
match_error_code ( unsafe {
746
- hv_vcpu_get_sys_reg ( self . id , hv_sys_reg_t:: from ( reg) , & mut value as * mut u64 )
819
+ hv_vcpu_get_sys_reg (
820
+ self . vcpu_handle ,
821
+ hv_sys_reg_t:: from ( reg) ,
822
+ & mut value as * mut u64 ,
823
+ )
747
824
} ) ?;
748
825
749
826
Ok ( value)
750
827
}
751
828
752
829
/// Gets a system register value.
753
830
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) } )
831
+ match_error_code ( unsafe {
832
+ hv_vcpu_set_sys_reg ( self . vcpu_handle , hv_sys_reg_t:: from ( reg) , value)
833
+ } )
834
+ }
835
+ }
836
+
837
+ impl core:: fmt:: Debug for VirtualCpu {
838
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
839
+ let pc = self . read_register ( Register :: PC ) . unwrap ( ) ;
840
+ let cpsr = self . read_register ( Register :: CPSR ) . unwrap ( ) ;
841
+ let sp = self . read_system_register ( SystemRegister :: SP_EL1 ) . unwrap ( ) ;
842
+ let sctlr = self
843
+ . read_system_register ( SystemRegister :: SCTLR_EL1 )
844
+ . unwrap ( ) ;
845
+ let ttbr0 = self
846
+ . read_system_register ( SystemRegister :: TTBR0_EL1 )
847
+ . unwrap ( ) ;
848
+ let lr = self . read_register ( Register :: LR ) . unwrap ( ) ;
849
+ let x0 = self . read_register ( Register :: X0 ) . unwrap ( ) ;
850
+ let x1 = self . read_register ( Register :: X1 ) . unwrap ( ) ;
851
+ let x2 = self . read_register ( Register :: X2 ) . unwrap ( ) ;
852
+ let x3 = self . read_register ( Register :: X3 ) . unwrap ( ) ;
853
+ let x4 = self . read_register ( Register :: X4 ) . unwrap ( ) ;
854
+ let x5 = self . read_register ( Register :: X5 ) . unwrap ( ) ;
855
+ let x6 = self . read_register ( Register :: X6 ) . unwrap ( ) ;
856
+ let x7 = self . read_register ( Register :: X7 ) . unwrap ( ) ;
857
+ let x8 = self . read_register ( Register :: X8 ) . unwrap ( ) ;
858
+ let x9 = self . read_register ( Register :: X9 ) . unwrap ( ) ;
859
+ let x10 = self . read_register ( Register :: X10 ) . unwrap ( ) ;
860
+ let x11 = self . read_register ( Register :: X11 ) . unwrap ( ) ;
861
+ let x12 = self . read_register ( Register :: X12 ) . unwrap ( ) ;
862
+ let x13 = self . read_register ( Register :: X13 ) . unwrap ( ) ;
863
+ let x14 = self . read_register ( Register :: X14 ) . unwrap ( ) ;
864
+ let x15 = self . read_register ( Register :: X15 ) . unwrap ( ) ;
865
+ let x16 = self . read_register ( Register :: X16 ) . unwrap ( ) ;
866
+ let x17 = self . read_register ( Register :: X17 ) . unwrap ( ) ;
867
+ let x18 = self . read_register ( Register :: X18 ) . unwrap ( ) ;
868
+ let x19 = self . read_register ( Register :: X19 ) . unwrap ( ) ;
869
+ let x20 = self . read_register ( Register :: X20 ) . unwrap ( ) ;
870
+ let x21 = self . read_register ( Register :: X21 ) . unwrap ( ) ;
871
+ let x22 = self . read_register ( Register :: X22 ) . unwrap ( ) ;
872
+ let x23 = self . read_register ( Register :: X23 ) . unwrap ( ) ;
873
+ let x24 = self . read_register ( Register :: X24 ) . unwrap ( ) ;
874
+ let x25 = self . read_register ( Register :: X25 ) . unwrap ( ) ;
875
+ let x26 = self . read_register ( Register :: X26 ) . unwrap ( ) ;
876
+ let x27 = self . read_register ( Register :: X27 ) . unwrap ( ) ;
877
+ let x28 = self . read_register ( Register :: X28 ) . unwrap ( ) ;
878
+ let x29 = self . read_register ( Register :: X29 ) . unwrap ( ) ;
879
+ let x30 = self . read_register ( Register :: X30 ) . unwrap ( ) ;
880
+
881
+ writeln ! ( f, "\n Registers of CPU {}:" , ( * self ) . get_id( ) ) ?;
882
+ writeln ! (
883
+ f,
884
+ "PC : {pc:016x} LR : {lr:016x} CPSR : {cpsr:016x}\n \
885
+ SP : {sp:016x} SCTLR : {sctlr:016x} TTBR0 : {ttbr0:016x}",
886
+ ) ?;
887
+ writeln ! (
888
+ f,
889
+ "x0 : {x0:016x} x1 : {x1:016x} x2 : {x2:016x}\n \
890
+ x3 : {x3:016x} x4 : {x4:016x} x5 : {x5:016x}\n \
891
+ x6 : {x6:016x} x7 : {x7:016x} x8 : {x8:016x}\n \
892
+ x9 : {x9:016x} x10 : {x10:016x} x11 : {x11:016x}\n \
893
+ x12 : {x12:016x} x13 : {x13:016x} x14 : {x14:016x}\n \
894
+ x15 : {x15:016x} x16 : {x16:016x} x17 : {x17:016x}\n \
895
+ x18 : {x18:016x} x19 : {x19:016x} x20 : {x20:016x}\n \
896
+ x21 : {x21:016x} x22 : {x22:016x} x23 : {x23:016x}\n \
897
+ x24 : {x24:016x} x25 : {x25:016x} x26 : {x26:016x}\n \
898
+ x27 : {x27:016x} x28 : {x28:016x} x29 : {x29:016x}\n \
899
+ x30 : {x30:016x}\n ",
900
+ )
755
901
}
756
902
}
0 commit comments