@@ -50,6 +50,7 @@ pub(crate) mod misc;
50
50
pub ( crate ) mod name_object;
51
51
pub ( crate ) mod namespace;
52
52
pub ( crate ) mod opcode;
53
+ pub mod opregion;
53
54
pub ( crate ) mod parser;
54
55
pub mod pci_routing;
55
56
pub ( crate ) mod pkg_length;
@@ -387,189 +388,6 @@ impl AmlContext {
387
388
}
388
389
}
389
390
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
-
573
391
fn add_predefined_objects ( & mut self ) {
574
392
/*
575
393
* These are the scopes predefined by the spec. Some tables will try to access them without defining them
0 commit comments