@@ -14,6 +14,30 @@ pub enum Resource {
1414 Dma ( DMADescriptor ) ,
1515}
1616
17+ const UNSUPPORTED_LARGE_RESOURCE_DESCRIPTORS : & [ ( u8 , & str ) ] = & [
18+ ( 0x01 , "24-bit Memory Range Descriptor" ) ,
19+ ( 0x02 , "Generic Register Descriptor" ) ,
20+ ( 0x03 , "0x03 Reserved" ) ,
21+ ( 0x04 , "Vendor-defined Descriptor" ) ,
22+ ( 0x05 , "32-bit Memory Range Descriptor" ) ,
23+ ( 0x0b , "Extended Address Space Descriptor" ) ,
24+ ( 0x0c , "GPIO Connection Descriptor" ) ,
25+ ( 0x0d , "Pin Function Descriptor" ) ,
26+ ( 0x0e , "GenericSerialBus Connection Descriptor" ) ,
27+ ( 0x0f , "Pin Configuration Descriptor" ) ,
28+ ( 0x10 , "Pin Group Descriptor" ) ,
29+ ( 0x11 , "Pin Group Function Descriptor" ) ,
30+ ( 0x12 , "Pin Group Configuration Descriptor" ) ,
31+ ] ;
32+
33+ const UNSUPPORTED_SMALL_RESOURCE_DESCRIPTORS : & [ ( u8 , & str ) ] = & [
34+ ( 0x06 , "Start Dependent Functions Descriptor" ) ,
35+ ( 0x07 , "End Dependent Functions Descriptor" ) ,
36+ ( 0x09 , "Fixed Location IO Port Descriptor" ) ,
37+ ( 0x0a , "Fixed DMA Descriptor" ) ,
38+ ( 0x0e , "Vendor Defined Descriptor" ) ,
39+ ] ;
40+
1741/// Parse a `ResourceDescriptor` buffer into a list of resources.
1842pub fn resource_descriptor_list ( descriptor : WrappedObject ) -> Result < Vec < Resource > , AmlError > {
1943 if let Object :: Buffer ( ref bytes) = * descriptor {
@@ -25,10 +49,8 @@ pub fn resource_descriptor_list(descriptor: WrappedObject) -> Result<Vec<Resourc
2549
2650 if let Some ( descriptor) = descriptor {
2751 descriptors. push ( descriptor) ;
28- bytes = remaining_bytes;
29- } else {
30- break ;
3152 }
53+ bytes = remaining_bytes;
3254 }
3355
3456 Ok ( descriptors)
@@ -37,6 +59,20 @@ pub fn resource_descriptor_list(descriptor: WrappedObject) -> Result<Vec<Resourc
3759 }
3860}
3961
62+ fn unsupported_resource_descriptor_name ( descriptors : & [ ( u8 , & ' static str ) ] , descriptor_type : u8 ) -> Option < & ' static str > {
63+ descriptors. iter ( ) . find_map ( |( typ, name) | ( * typ == descriptor_type) . then_some ( * name) )
64+ }
65+
66+ fn skip_unsupported_resource < ' a > (
67+ size : & str ,
68+ descriptor_type : u8 ,
69+ descriptor_name : & str ,
70+ remaining_bytes : & ' a [ u8 ] ,
71+ ) -> Result < ( Option < Resource > , & ' a [ u8 ] ) , AmlError > {
72+ log:: warn!( "skipping unsupported {size} resource descriptor type {descriptor_type:#x}: {descriptor_name}" ) ;
73+ Ok ( ( None , remaining_bytes) )
74+ }
75+
4076fn resource_descriptor ( bytes : & [ u8 ] ) -> Result < ( Option < Resource > , & [ u8 ] ) , AmlError > {
4177 /*
4278 * If bit 7 of Byte 0 is set, it's a large descriptor. If not, it's a small descriptor.
@@ -73,27 +109,19 @@ fn resource_descriptor(bytes: &[u8]) -> Result<(Option<Resource>, &[u8]), AmlErr
73109 let ( descriptor_bytes, remaining_bytes) = bytes. split_at ( length + 3 ) ;
74110
75111 let descriptor = match descriptor_type {
76- 0x01 => unimplemented ! ( "24-bit Memory Range Descriptor" ) ,
77- 0x02 => unimplemented ! ( "Generic Register Descriptor" ) ,
78- 0x03 => unimplemented ! ( "0x03 Reserved" ) ,
79- 0x04 => unimplemented ! ( "Vendor-defined Descriptor" ) ,
80- 0x05 => unimplemented ! ( "32-bit Memory Range Descriptor" ) ,
81112 0x06 => fixed_memory_descriptor ( descriptor_bytes) ,
82113 0x07 => address_space_descriptor :: < u32 > ( descriptor_bytes) ,
83114 0x08 => address_space_descriptor :: < u16 > ( descriptor_bytes) ,
84115 0x09 => extended_interrupt_descriptor ( descriptor_bytes) ,
85116 0x0a => address_space_descriptor :: < u64 > ( descriptor_bytes) ,
86- 0x0b => unimplemented ! ( "Extended Address Space Descriptor" ) ,
87- 0x0c => unimplemented ! ( "GPIO Connection Descriptor" ) ,
88- 0x0d => unimplemented ! ( "Pin Function Descriptor" ) ,
89- 0x0e => unimplemented ! ( "GenericSerialBus Connection Descriptor" ) ,
90- 0x0f => unimplemented ! ( "Pin Configuration Descriptor" ) ,
91- 0x10 => unimplemented ! ( "Pin Group Descriptor" ) ,
92- 0x11 => unimplemented ! ( "Pin Group Function Descriptor" ) ,
93- 0x12 => unimplemented ! ( "Pin Group Configuration Descriptor" ) ,
94117
95118 0x00 | 0x13 ..=0x7f => Err ( AmlError :: InvalidResourceDescriptor ) ,
96119 0x80 ..=0xff => unreachable ! ( ) ,
120+ _ => {
121+ let descriptor_name =
122+ unsupported_resource_descriptor_name ( UNSUPPORTED_LARGE_RESOURCE_DESCRIPTORS , descriptor_type) . unwrap ( ) ;
123+ return skip_unsupported_resource ( "large" , descriptor_type, descriptor_name, remaining_bytes) ;
124+ }
97125 } ?;
98126
99127 Ok ( ( Some ( descriptor) , remaining_bytes) )
@@ -127,15 +155,15 @@ fn resource_descriptor(bytes: &[u8]) -> Result<(Option<Resource>, &[u8]), AmlErr
127155 0x00 ..=0x03 => Err ( AmlError :: InvalidResourceDescriptor ) ,
128156 0x04 => irq_format_descriptor ( descriptor_bytes) ,
129157 0x05 => dma_format_descriptor ( descriptor_bytes) ,
130- 0x06 => unimplemented ! ( "Start Dependent Functions Descriptor" ) ,
131- 0x07 => unimplemented ! ( "End Dependent Functions Descriptor" ) ,
132158 0x08 => io_port_descriptor ( descriptor_bytes) ,
133- 0x09 => unimplemented ! ( "Fixed Location IO Port Descriptor" ) ,
134- 0x0A => unimplemented ! ( "Fixed DMA Descriptor" ) ,
135159 0x0B ..=0x0D => Err ( AmlError :: InvalidResourceDescriptor ) ,
136- 0x0E => unimplemented ! ( "Vendor Defined Descriptor" ) ,
137160 0x0F => return Ok ( ( None , & [ ] ) ) ,
138161 0x10 ..=0xFF => unreachable ! ( ) ,
162+ _ => {
163+ let descriptor_name =
164+ unsupported_resource_descriptor_name ( UNSUPPORTED_SMALL_RESOURCE_DESCRIPTORS , descriptor_type) . unwrap ( ) ;
165+ return skip_unsupported_resource ( "small" , descriptor_type, descriptor_name, remaining_bytes) ;
166+ }
139167 } ?;
140168
141169 Ok ( ( Some ( descriptor) , remaining_bytes) )
@@ -760,6 +788,31 @@ mod tests {
760788 ) ;
761789 }
762790
791+ #[ test]
792+ fn skips_unsupported_large_resource_descriptors ( ) {
793+ let bytes: Vec < u8 > = [
794+ // GenericSerialBus descriptor with one byte of payload.
795+ 0x8e , 0x01 , 0x00 , 0x00 ,
796+ // Memory32Fixed(ReadWrite, 0x1000, 0x1000)
797+ 0x86 , 0x09 , 0x00 , 0x01 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 ,
798+ // End tag.
799+ 0x79 , 0x00 ,
800+ ]
801+ . to_vec ( ) ;
802+
803+ let value = Object :: Buffer ( bytes) . wrap ( ) ;
804+ let resources = resource_descriptor_list ( value) . unwrap ( ) ;
805+
806+ assert_eq ! (
807+ resources,
808+ Vec :: from( [ Resource :: MemoryRange ( MemoryRangeDescriptor :: FixedLocation {
809+ is_writable: true ,
810+ base_address: 0x1000 ,
811+ range_length: 0x1000 ,
812+ } ) ] )
813+ ) ;
814+ }
815+
763816 #[ test]
764817 fn test_fdc_crs ( ) {
765818 let bytes: Vec < u8 > = [
0 commit comments