1 // Copyright 2022 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use acpi_tables::aml; 6 use acpi_tables::aml::Aml; 7 use anyhow::anyhow; 8 use anyhow::Result; 9 use base::MemoryMapping; 10 use base::MemoryMappingBuilder; 11 use base::Protection; 12 use base::SharedMemory; 13 14 pub const SHM_OFFSET: u32 = 0x1000; 15 pub const SHM_SIZE: u32 = 0x1000; 16 17 pub struct DeviceVcfgRegister { 18 offset: u32, 19 shm: SharedMemory, 20 } 21 22 impl DeviceVcfgRegister { new(offset: u32) -> Result<DeviceVcfgRegister>23 pub fn new(offset: u32) -> Result<DeviceVcfgRegister> { 24 let shm = SharedMemory::new("VCFG register", SHM_SIZE as u64) 25 .map_err(|_| anyhow!("failed to create shared memory"))?; 26 Ok(DeviceVcfgRegister { offset, shm }) 27 } 28 create_shm_mmap(&self) -> Option<MemoryMapping>29 pub fn create_shm_mmap(&self) -> Option<MemoryMapping> { 30 MemoryMappingBuilder::new(SHM_SIZE as usize) 31 .from_shared_memory(&self.shm) 32 .offset(0) 33 .protection(Protection::read_write()) 34 .build() 35 .ok() 36 } 37 } 38 39 impl Aml for DeviceVcfgRegister { to_aml_bytes(&self, bytes: &mut Vec<u8>)40 fn to_aml_bytes(&self, bytes: &mut Vec<u8>) { 41 aml::OpRegion::new( 42 "VREG".into(), 43 aml::OpRegionSpace::SystemMemory, 44 &aml::Add::new(&aml::ZERO, &aml::Name::new_field_name("VCFG"), &self.offset), 45 &4096_usize, 46 ) 47 .to_aml_bytes(bytes); 48 aml::Field::new( 49 "VREG".into(), 50 aml::FieldAccessType::DWord, 51 aml::FieldLockRule::Lock, 52 aml::FieldUpdateRule::Preserve, 53 vec![aml::FieldEntry::Named(*b"PFPM", 32)], 54 ) 55 .to_aml_bytes(bytes); 56 aml::OpRegion::new( 57 "SHAM".into(), 58 aml::OpRegionSpace::SystemMemory, 59 &aml::Add::new( 60 &aml::ZERO, 61 &aml::Name::new_field_name("VCFG"), 62 &(self.offset + SHM_OFFSET), 63 ), 64 &SHM_SIZE, 65 ) 66 .to_aml_bytes(bytes); 67 } 68 } 69 70 pub struct PowerResourceMethod {} 71 72 impl Aml for PowerResourceMethod { to_aml_bytes(&self, aml: &mut Vec<u8>)73 fn to_aml_bytes(&self, aml: &mut Vec<u8>) { 74 aml::PowerResource::new( 75 "PRIC".into(), 76 0u8, 77 0u16, 78 vec![ 79 &aml::Name::new("_STA".into(), &aml::ONE), 80 &aml::Method::new( 81 "_ON_".into(), 82 0, 83 true, 84 vec![ 85 &aml::Store::new(&aml::Name::new_field_name("PFPM"), &aml::ONE), 86 &aml::Store::new(&aml::Name::new_field_name("_STA"), &aml::ONE), 87 ], 88 ), 89 &aml::Method::new( 90 "_OFF".into(), 91 0, 92 true, 93 vec![ 94 &aml::Store::new(&aml::Name::new_field_name("_STA"), &aml::ZERO), 95 &aml::Store::new(&aml::Name::new_field_name("PFPM"), &aml::ZERO), 96 ], 97 ), 98 ], 99 ) 100 .to_aml_bytes(aml); 101 aml::Name::new( 102 "_PR0".into(), 103 &aml::Package::new(vec![&aml::Name::new_field_name("PRIC")]), 104 ) 105 .to_aml_bytes(aml); 106 aml::Name::new( 107 "_PR3".into(), 108 &aml::Package::new(vec![&aml::Name::new_field_name("PRIC")]), 109 ) 110 .to_aml_bytes(aml); 111 } 112 } 113