@@ -51,6 +51,8 @@ pub const CPU_CONTAINER_ACPI_SIZE: usize = 0xC;
5151
5252const CPU_ENABLE_BIT : u8 = 1 << 0 ;
5353const CPU_INSERTING_BIT : u8 = 1 << 1 ;
54+ const CPU_REMOVING_BIT : u8 = 1 << 2 ;
55+ const CPU_EJECT_BIT : u8 = 1 << 3 ;
5456
5557const CPU_SELECTION_OFFSET : u64 = 0 ;
5658const CPU_STATUS_OFFSET : u64 = 4 ;
@@ -94,6 +96,7 @@ impl CpuContainer {
9496 cpu_id : i,
9597 active : i < boot_count,
9698 inserting : false ,
99+ removing : false ,
97100 } )
98101 }
99102
@@ -123,6 +126,9 @@ impl CpuContainer {
123126 if cpu_device. inserting {
124127 data[ 0 ] |= CPU_INSERTING_BIT ;
125128 }
129+ if cpu_device. removing {
130+ data[ 0 ] |= CPU_REMOVING_BIT ;
131+ }
126132 } else {
127133 error ! ( "Out of range vCPU id: {}" , self . selected_cpu)
128134 }
@@ -143,6 +149,10 @@ impl CpuContainer {
143149 if data[ 0 ] & CPU_ENABLE_BIT != 0 {
144150 cpu_device. active = true ;
145151 }
152+ if data[ 0 ] & CPU_EJECT_BIT != 0 {
153+ cpu_device. active = false ;
154+ // TODO: Remove vCPU handle from VMM
155+ }
146156 } else {
147157 error ! ( "Out of range vCPU id: {}" , self . selected_cpu)
148158 }
@@ -215,7 +225,9 @@ impl Aml for CpuContainer {
215225 aml:: FieldEntry :: Reserved ( 32 ) ,
216226 aml:: FieldEntry :: Named ( * b"CPEN" , 1 ) ,
217227 aml:: FieldEntry :: Named ( * b"CINS" , 1 ) ,
218- aml:: FieldEntry :: Reserved ( 6 ) ,
228+ aml:: FieldEntry :: Named ( * b"CRMV" , 1 ) ,
229+ aml:: FieldEntry :: Named ( * b"CEJ0" , 1 ) ,
230+ aml:: FieldEntry :: Reserved ( 4 ) ,
219231 aml:: FieldEntry :: Named ( * b"CCMD" , 8 ) ,
220232 ] ,
221233 ) ,
@@ -270,6 +282,8 @@ pub struct CpuDevice {
270282 pub active : bool ,
271283 /// Whether this CPU is in the process of being inserted
272284 pub inserting : bool ,
285+ /// Whether this CPU is in the process of being removed
286+ pub removing : bool ,
273287}
274288
275289impl CpuDevice {
@@ -305,6 +319,16 @@ impl Aml for CpuDevice {
305319 ) ) ] ,
306320 ) ,
307321 & aml:: Name :: new( "_MAT" . into( ) , & aml:: Buffer :: new( mat_data) ) ,
322+ & aml:: Method :: new(
323+ "_EJ0" . into( ) ,
324+ 1 ,
325+ false ,
326+ // Call into CEJ0 method which will actually eject device
327+ vec![ & aml:: MethodCall :: new(
328+ "\\ _SB_.CPUS.CEJ0" . into( ) ,
329+ vec![ & self . cpu_id] ,
330+ ) ] ,
331+ ) ,
308332 ] ,
309333 )
310334 . append_aml_bytes ( v)
@@ -320,7 +344,7 @@ impl Aml for CpuNotify {
320344 let object = aml:: Path :: new ( & format ! ( "C{:03X}" , self . cpu_id) ) ;
321345 aml:: If :: new (
322346 & aml:: Equal :: new ( & aml:: Arg ( 0 ) , & self . cpu_id ) ,
323- vec ! [ & aml:: Notify :: new( & object, & 1u8 ) ] ,
347+ vec ! [ & aml:: Notify :: new( & object, & aml :: Arg ( 1 ) ) ] ,
324348 )
325349 . append_aml_bytes ( v)
326350 }
@@ -369,6 +393,21 @@ impl Aml for CpuMethods {
369393
370394 aml:: Method :: new ( "CTFY" . into ( ) , 2 , true , cpu_notifies_refs) . append_aml_bytes ( v) ;
371395
396+ aml:: Method :: new (
397+ "CEJ0" . into ( ) ,
398+ 1 ,
399+ true ,
400+ vec ! [
401+ & aml:: Acquire :: new( "\\ _SB_.PRES.CPLK" . into( ) , 0xffff ) ,
402+ // Write CPU number (in first argument) to I/O port via field
403+ & aml:: Store :: new( & aml:: Path :: new( "\\ _SB_.PRES.CSEL" ) , & aml:: Arg ( 0 ) ) ,
404+ // Set CEJ0 bit
405+ & aml:: Store :: new( & aml:: Path :: new( "\\ _SB_.PRES.CEJ0" ) , & aml:: ONE ) ,
406+ & aml:: Release :: new( "\\ _SB_.PRES.CPLK" . into( ) ) ,
407+ ] ,
408+ )
409+ . append_aml_bytes ( v) ;
410+
372411 aml:: Method :: new (
373412 "CSCN" . into ( ) ,
374413 0 ,
@@ -396,6 +435,15 @@ impl Aml for CpuMethods {
396435 & aml:: Store :: new( & aml:: Path :: new( "\\ _SB_.PRES.CINS" ) , & aml:: ONE ) ,
397436 ] ,
398437 ) ,
438+ & aml:: If :: new(
439+ & aml:: Equal :: new( & aml:: Path :: new( "\\ _SB_.PRES.CRMV" ) , & aml:: ONE ) ,
440+ // Notify device if it is (with the eject constant 0x3)
441+ vec![
442+ & aml:: MethodCall :: new( "CTFY" . into( ) , vec![ & aml:: Local ( 0 ) , & 3u8 ] ) ,
443+ // Reset CRMV bit
444+ & aml:: Store :: new( & aml:: Path :: new( "\\ _SB_.PRES.CRMV" ) , & aml:: ONE ) ,
445+ ] ,
446+ ) ,
399447 & aml:: Add :: new( & aml:: Local ( 0 ) , & aml:: Local ( 0 ) , & aml:: ONE ) ,
400448 ] ,
401449 ) ,
0 commit comments