@@ -17,7 +17,7 @@ limitations under the License.
1717use alloc:: format;
1818use alloc:: string:: ToString ;
1919use alloc:: vec:: Vec ;
20- use core:: arch:: global_asm ;
20+ use core:: arch;
2121
2222use hyperlight_common:: flatbuffer_wrappers:: function_call:: { FunctionCall , FunctionCallType } ;
2323use hyperlight_common:: flatbuffer_wrappers:: function_types:: {
@@ -79,21 +79,16 @@ pub fn outb(port: u16, data: &[u8]) {
7979 unsafe {
8080 match RUNNING_MODE {
8181 RunMode :: Hypervisor => {
82- for chunk in data. chunks ( 4 ) {
83- // Process the data in chunks of 4 bytes. If a chunk has fewer than 4 bytes,
84- // pad it with 0x7F to ensure it can be converted into a 4-byte array.
85- // The choice of 0x7F as the padding value is arbitrary and does not carry
86- // any special meaning; it simply ensures consistent chunk size.
87- let val = match chunk {
88- [ a, b, c, d] => u32:: from_le_bytes ( [ * a, * b, * c, * d] ) ,
89- [ a, b, c] => u32:: from_le_bytes ( [ * a, * b, * c, 0x7F ] ) ,
90- [ a, b] => u32:: from_le_bytes ( [ * a, * b, 0x7F , 0x7F ] ) ,
91- [ a] => u32:: from_le_bytes ( [ * a, 0x7F , 0x7F , 0x7F ] ) ,
92- [ ] => break ,
93- _ => unreachable ! ( ) ,
94- } ;
95-
96- hloutd ( val, port) ;
82+ let mut i = 0 ;
83+ while i < data. len ( ) {
84+ let remaining = data. len ( ) - i;
85+ let chunk_len = remaining. min ( 3 ) ;
86+ let mut chunk = [ 0u8 ; 4 ] ;
87+ chunk[ 0 ] = chunk_len as u8 ;
88+ chunk[ 1 ..1 + chunk_len] . copy_from_slice ( & data[ i..i + chunk_len] ) ;
89+ let val = u32:: from_le_bytes ( chunk) ;
90+ out32 ( port, val) ;
91+ i += chunk_len;
9792 }
9893 }
9994 RunMode :: InProcessLinux | RunMode :: InProcessWindows => {
@@ -119,11 +114,25 @@ pub fn outb(port: u16, data: &[u8]) {
119114 }
120115}
121116
122- extern "win64" {
123- fn hloutd ( value : u32 , port : u16 ) ;
117+ pub ( crate ) unsafe fn out32 ( port : u16 , val : u32 ) {
118+ arch :: asm! ( "out dx, eax" , in ( "dx" ) port, in ( "eax" ) val , options ( preserves_flags , nomem , nostack ) ) ;
124119}
125120
126- pub fn print_output_as_guest_function ( function_call : & FunctionCall ) -> Result < Vec < u8 > > {
121+ /// Prints a message using `OutBAction::DebugPrint`. It transmits bytes of a message
122+ /// through several VMExists and, with such, it is slower than
123+ /// `print_output_with_host_print`.
124+ ///
125+ /// This function should be used in debug mode only. This function does not
126+ /// require memory to be setup to be used.
127+ pub fn debug_print ( msg : & str ) {
128+ outb ( OutBAction :: DebugPrint as u16 , msg. as_bytes ( ) ) ;
129+ }
130+
131+ /// Print a message using the host's print function.
132+ ///
133+ /// This function requires memory to be setup to be used. In particular, the
134+ /// existence of the input and output memory regions.
135+ pub fn print_output_with_host_print ( function_call : & FunctionCall ) -> Result < Vec < u8 > > {
127136 if let ParameterValue :: String ( message) = function_call. parameters . clone ( ) . unwrap ( ) [ 0 ] . clone ( ) {
128137 call_host_function (
129138 "HostPrint" ,
@@ -135,20 +144,7 @@ pub fn print_output_as_guest_function(function_call: &FunctionCall) -> Result<Ve
135144 } else {
136145 Err ( HyperlightGuestError :: new (
137146 ErrorCode :: GuestError ,
138- "Wrong Parameters passed to print_output_as_guest_function " . to_string ( ) ,
147+ "Wrong Parameters passed to print_output_with_host_print " . to_string ( ) ,
139148 ) )
140149 }
141150}
142-
143- pub fn debug_print ( msg : & str ) {
144- outb ( OutBAction :: DebugPrint as u16 , msg. as_bytes ( ) ) ;
145- }
146-
147- global_asm ! (
148- ".global hloutd
149- hloutd:
150- mov eax, ecx
151- mov dx, dx
152- out dx, eax
153- ret"
154- ) ;
0 commit comments