@@ -50,6 +50,7 @@ pub(crate) mod misc;
5050pub ( crate ) mod name_object;
5151pub ( crate ) mod namespace;
5252pub ( crate ) mod opcode;
53+ pub mod opregion;
5354pub ( crate ) mod parser;
5455pub mod pci_routing;
5556pub ( crate ) mod pkg_length;
@@ -387,189 +388,6 @@ impl AmlContext {
387388 }
388389 }
389390
390- /// Read from an operation-region, performing only standard-sized reads (supported powers-of-2 only. If a field
391- /// is not one of these sizes, it may need to be masked, or multiple reads may need to be performed).
392- pub ( crate ) fn read_region (
393- & mut self ,
394- region_handle : AmlHandle ,
395- offset : u64 ,
396- length : u64 ,
397- ) -> Result < u64 , AmlError > {
398- use bit_field:: BitField ;
399- use core:: convert:: TryInto ;
400- use value:: RegionSpace ;
401-
402- let ( region_space, region_base, _region_length, parent_device) = {
403- if let AmlValue :: OpRegion { region, offset, length, parent_device } =
404- self . namespace . get ( region_handle) ?. clone ( )
405- {
406- ( region, offset, length, parent_device)
407- } else {
408- return Err ( AmlError :: FieldRegionIsNotOpRegion ) ;
409- }
410- } ;
411-
412- match region_space {
413- RegionSpace :: SystemMemory => {
414- let address = ( region_base + offset) . try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?;
415- match length {
416- 8 => Ok ( self . handler . read_u8 ( address) as u64 ) ,
417- 16 => Ok ( self . handler . read_u16 ( address) as u64 ) ,
418- 32 => Ok ( self . handler . read_u32 ( address) as u64 ) ,
419- 64 => Ok ( self . handler . read_u64 ( address) ) ,
420- _ => Err ( AmlError :: FieldInvalidAccessSize ) ,
421- }
422- }
423-
424- RegionSpace :: SystemIo => {
425- let port = ( region_base + offset) . try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?;
426- match length {
427- 8 => Ok ( self . handler . read_io_u8 ( port) as u64 ) ,
428- 16 => Ok ( self . handler . read_io_u16 ( port) as u64 ) ,
429- 32 => Ok ( self . handler . read_io_u32 ( port) as u64 ) ,
430- _ => Err ( AmlError :: FieldInvalidAccessSize ) ,
431- }
432- }
433-
434- RegionSpace :: PciConfig => {
435- /*
436- * First, we need to get some extra information out of objects in the parent object. Both
437- * `_SEG` and `_BBN` seem optional, with defaults that line up with legacy PCI implementations
438- * (e.g. systems with a single segment group and a single root, respectively).
439- */
440- let parent_device = parent_device. as_ref ( ) . unwrap ( ) ;
441- let seg = match self . invoke_method (
442- & AmlName :: from_str ( "_SEG" ) . unwrap ( ) . resolve ( parent_device) . unwrap ( ) ,
443- Args :: EMPTY ,
444- ) {
445- Ok ( seg) => seg. as_integer ( self ) ?. try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?,
446- Err ( AmlError :: ValueDoesNotExist ( _) ) => 0 ,
447- Err ( err) => return Err ( err) ,
448- } ;
449- let bbn = match self . invoke_method (
450- & AmlName :: from_str ( "_BBN" ) . unwrap ( ) . resolve ( parent_device) . unwrap ( ) ,
451- Args :: EMPTY ,
452- ) {
453- Ok ( bbn) => bbn. as_integer ( self ) ?. try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?,
454- Err ( AmlError :: ValueDoesNotExist ( _) ) => 0 ,
455- Err ( err) => return Err ( err) ,
456- } ;
457- let adr = {
458- let adr = self . invoke_method (
459- & AmlName :: from_str ( "_ADR" ) . unwrap ( ) . resolve ( parent_device) . unwrap ( ) ,
460- Args :: EMPTY ,
461- ) ?;
462- adr. as_integer ( self ) ?
463- } ;
464-
465- let device = adr. get_bits ( 16 ..24 ) as u8 ;
466- let function = adr. get_bits ( 0 ..8 ) as u8 ;
467- let offset = ( region_base + offset) . try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?;
468-
469- match length {
470- 8 => Ok ( self . handler . read_pci_u8 ( seg, bbn, device, function, offset) as u64 ) ,
471- 16 => Ok ( self . handler . read_pci_u16 ( seg, bbn, device, function, offset) as u64 ) ,
472- 32 => Ok ( self . handler . read_pci_u32 ( seg, bbn, device, function, offset) as u64 ) ,
473- _ => Err ( AmlError :: FieldInvalidAccessSize ) ,
474- }
475- }
476-
477- // TODO
478- _ => unimplemented ! ( ) ,
479- }
480- }
481-
482- pub ( crate ) fn write_region (
483- & mut self ,
484- region_handle : AmlHandle ,
485- offset : u64 ,
486- length : u64 ,
487- value : u64 ,
488- ) -> Result < ( ) , AmlError > {
489- use bit_field:: BitField ;
490- use core:: convert:: TryInto ;
491- use value:: RegionSpace ;
492-
493- let ( region_space, region_base, _region_length, parent_device) = {
494- if let AmlValue :: OpRegion { region, offset, length, parent_device } =
495- self . namespace . get ( region_handle) ?. clone ( )
496- {
497- ( region, offset, length, parent_device)
498- } else {
499- return Err ( AmlError :: FieldRegionIsNotOpRegion ) ;
500- }
501- } ;
502-
503- match region_space {
504- RegionSpace :: SystemMemory => {
505- let address = ( region_base + offset) . try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?;
506- match length {
507- 8 => Ok ( self . handler . write_u8 ( address, value as u8 ) ) ,
508- 16 => Ok ( self . handler . write_u16 ( address, value as u16 ) ) ,
509- 32 => Ok ( self . handler . write_u32 ( address, value as u32 ) ) ,
510- 64 => Ok ( self . handler . write_u64 ( address, value) ) ,
511- _ => Err ( AmlError :: FieldInvalidAccessSize ) ,
512- }
513- }
514-
515- RegionSpace :: SystemIo => {
516- let port = ( region_base + offset) . try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?;
517- match length {
518- 8 => Ok ( self . handler . write_io_u8 ( port, value as u8 ) ) ,
519- 16 => Ok ( self . handler . write_io_u16 ( port, value as u16 ) ) ,
520- 32 => Ok ( self . handler . write_io_u32 ( port, value as u32 ) ) ,
521- _ => Err ( AmlError :: FieldInvalidAccessSize ) ,
522- }
523- }
524-
525- RegionSpace :: PciConfig => {
526- /*
527- * First, we need to get some extra information out of objects in the parent object. Both
528- * `_SEG` and `_BBN` seem optional, with defaults that line up with legacy PCI implementations
529- * (e.g. systems with a single segment group and a single root, respectively).
530- */
531- let parent_device = parent_device. as_ref ( ) . unwrap ( ) ;
532- let seg = match self . invoke_method (
533- & AmlName :: from_str ( "_SEG" ) . unwrap ( ) . resolve ( parent_device) . unwrap ( ) ,
534- Args :: EMPTY ,
535- ) {
536- Ok ( seg) => seg. as_integer ( self ) ?. try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?,
537- Err ( AmlError :: ValueDoesNotExist ( _) ) => 0 ,
538- Err ( err) => return Err ( err) ,
539- } ;
540- let bbn = match self . invoke_method (
541- & AmlName :: from_str ( "_BBN" ) . unwrap ( ) . resolve ( parent_device) . unwrap ( ) ,
542- Args :: EMPTY ,
543- ) {
544- Ok ( bbn) => bbn. as_integer ( self ) ?. try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?,
545- Err ( AmlError :: ValueDoesNotExist ( _) ) => 0 ,
546- Err ( err) => return Err ( err) ,
547- } ;
548- let adr = {
549- let adr = self . invoke_method (
550- & AmlName :: from_str ( "_ADR" ) . unwrap ( ) . resolve ( parent_device) . unwrap ( ) ,
551- Args :: EMPTY ,
552- ) ?;
553- adr. as_integer ( self ) ?
554- } ;
555-
556- let device = adr. get_bits ( 16 ..24 ) as u8 ;
557- let function = adr. get_bits ( 0 ..8 ) as u8 ;
558- let offset = ( region_base + offset) . try_into ( ) . map_err ( |_| AmlError :: FieldInvalidAddress ) ?;
559-
560- match length {
561- 8 => Ok ( self . handler . write_pci_u8 ( seg, bbn, device, function, offset, value as u8 ) ) ,
562- 16 => Ok ( self . handler . write_pci_u16 ( seg, bbn, device, function, offset, value as u16 ) ) ,
563- 32 => Ok ( self . handler . write_pci_u32 ( seg, bbn, device, function, offset, value as u32 ) ) ,
564- _ => Err ( AmlError :: FieldInvalidAccessSize ) ,
565- }
566- }
567-
568- // TODO
569- _ => unimplemented ! ( ) ,
570- }
571- }
572-
573391 fn add_predefined_objects ( & mut self ) {
574392 /*
575393 * These are the scopes predefined by the spec. Some tables will try to access them without defining them
0 commit comments