mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 22:02:44 +00:00 
			
		
		
		
	Kernel/PCI: Split Access::rescan_hardware method
To ensure clarity, this method is essentially splitted to two methods to be called according to the access type being determined beforehand.
This commit is contained in:
		
							parent
							
								
									d395ac8f59
								
							
						
					
					
						commit
						40b1e6376b
					
				
					 2 changed files with 48 additions and 29 deletions
				
			
		|  | @ -44,7 +44,7 @@ UNMAP_AFTER_INIT bool Access::initialize_for_memory_access(PhysicalAddress mcfg_ | ||||||
|     auto* access = new Access(Access::AccessType::Memory); |     auto* access = new Access(Access::AccessType::Memory); | ||||||
|     if (!access->search_pci_domains_from_acpi_mcfg_table(mcfg_table)) |     if (!access->search_pci_domains_from_acpi_mcfg_table(mcfg_table)) | ||||||
|         return false; |         return false; | ||||||
|     access->rescan_hardware(); |     access->rescan_hardware_with_memory_addressing(); | ||||||
|     dbgln_if(PCI_DEBUG, "PCI: MMIO access initialised."); |     dbgln_if(PCI_DEBUG, "PCI: MMIO access initialised."); | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  | @ -86,7 +86,7 @@ UNMAP_AFTER_INIT bool Access::initialize_for_io_access() | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|     auto* access = new Access(Access::AccessType::IO); |     auto* access = new Access(Access::AccessType::IO); | ||||||
|     access->rescan_hardware(); |     access->rescan_hardware_with_io_addressing(); | ||||||
|     dbgln_if(PCI_DEBUG, "PCI: IO access initialised."); |     dbgln_if(PCI_DEBUG, "PCI: IO access initialised."); | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  | @ -305,37 +305,11 @@ u32 Access::read32_field(Address address, u32 field) | ||||||
|     VERIFY_NOT_REACHED(); |     VERIFY_NOT_REACHED(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| UNMAP_AFTER_INIT void Access::rescan_hardware() | UNMAP_AFTER_INIT void Access::rescan_hardware_with_memory_addressing() | ||||||
| { | { | ||||||
|     MutexLocker locker(m_scan_lock); |     MutexLocker locker(m_scan_lock); | ||||||
|     VERIFY(m_device_identifiers.is_empty()); |     VERIFY(m_device_identifiers.is_empty()); | ||||||
|     if (m_access_type == AccessType::IO) { |  | ||||||
|         dbgln_if(PCI_DEBUG, "PCI: IO enumerating hardware"); |  | ||||||
| 
 |  | ||||||
|         // First scan bus 0. Find any device on that bus, and if it's a PCI-to-PCI
 |  | ||||||
|         // bridge, recursively scan it too.
 |  | ||||||
|         m_enumerated_buses.set(0, true); |  | ||||||
|         enumerate_bus(-1, 0, true); |  | ||||||
| 
 |  | ||||||
|         // Handle Multiple PCI host bridges on slot 0, device 0.
 |  | ||||||
|         // If we happen to miss some PCI buses because they are not reachable through
 |  | ||||||
|         // recursive PCI-to-PCI bridges starting from bus 0, we might find them here.
 |  | ||||||
|         if ((read8_field(Address(), PCI::RegisterOffset::HEADER_TYPE) & 0x80) != 0) { |  | ||||||
|             for (int bus = 1; bus < 256; ++bus) { |  | ||||||
|                 if (read16_field(Address(0, 0, 0, bus), PCI::RegisterOffset::VENDOR_ID) == PCI::none_value) |  | ||||||
|                     continue; |  | ||||||
|                 if (read16_field(Address(0, 0, 0, bus), PCI::RegisterOffset::CLASS) != 0x6) |  | ||||||
|                     continue; |  | ||||||
|                 if (m_enumerated_buses.get(bus)) |  | ||||||
|                     continue; |  | ||||||
|                 enumerate_bus(-1, bus, false); |  | ||||||
|                 m_enumerated_buses.set(bus, true); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     VERIFY(m_access_type == AccessType::Memory); |     VERIFY(m_access_type == AccessType::Memory); | ||||||
| 
 |  | ||||||
|     for (u32 domain = 0; domain < m_domains.size(); domain++) { |     for (u32 domain = 0; domain < m_domains.size(); domain++) { | ||||||
|         dbgln_if(PCI_DEBUG, "PCI: Scan memory mapped domain {}", domain); |         dbgln_if(PCI_DEBUG, "PCI: Scan memory mapped domain {}", domain); | ||||||
|         // Single PCI host controller.
 |         // Single PCI host controller.
 | ||||||
|  | @ -353,6 +327,49 @@ UNMAP_AFTER_INIT void Access::rescan_hardware() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | UNMAP_AFTER_INIT void Access::rescan_hardware_with_io_addressing() | ||||||
|  | { | ||||||
|  |     MutexLocker locker(m_scan_lock); | ||||||
|  |     VERIFY(m_device_identifiers.is_empty()); | ||||||
|  |     VERIFY(m_access_type == AccessType::IO); | ||||||
|  |     dbgln_if(PCI_DEBUG, "PCI: IO enumerating hardware"); | ||||||
|  | 
 | ||||||
|  |     // First scan bus 0. Find any device on that bus, and if it's a PCI-to-PCI
 | ||||||
|  |     // bridge, recursively scan it too.
 | ||||||
|  |     m_enumerated_buses.set(0, true); | ||||||
|  |     enumerate_bus(-1, 0, true); | ||||||
|  | 
 | ||||||
|  |     // Handle Multiple PCI host bridges on slot 0, device 0.
 | ||||||
|  |     // If we happen to miss some PCI buses because they are not reachable through
 | ||||||
|  |     // recursive PCI-to-PCI bridges starting from bus 0, we might find them here.
 | ||||||
|  |     if ((read8_field(Address(), PCI::RegisterOffset::HEADER_TYPE) & 0x80) != 0) { | ||||||
|  |         for (int bus = 1; bus < 256; ++bus) { | ||||||
|  |             if (read16_field(Address(0, 0, 0, bus), PCI::RegisterOffset::VENDOR_ID) == PCI::none_value) | ||||||
|  |                 continue; | ||||||
|  |             if (read16_field(Address(0, 0, 0, bus), PCI::RegisterOffset::CLASS) != 0x6) | ||||||
|  |                 continue; | ||||||
|  |             if (m_enumerated_buses.get(bus)) | ||||||
|  |                 continue; | ||||||
|  |             enumerate_bus(-1, bus, false); | ||||||
|  |             m_enumerated_buses.set(bus, true); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | UNMAP_AFTER_INIT void Access::rescan_hardware() | ||||||
|  | { | ||||||
|  |     switch (m_access_type) { | ||||||
|  |     case AccessType::IO: | ||||||
|  |         rescan_hardware_with_io_addressing(); | ||||||
|  |         break; | ||||||
|  |     case AccessType::Memory: | ||||||
|  |         rescan_hardware_with_memory_addressing(); | ||||||
|  |         break; | ||||||
|  |     default: | ||||||
|  |         VERIFY_NOT_REACHED(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| UNMAP_AFTER_INIT Optional<u8> Access::get_capabilities_pointer(Address address) | UNMAP_AFTER_INIT Optional<u8> Access::get_capabilities_pointer(Address address) | ||||||
| { | { | ||||||
|     dbgln_if(PCI_DEBUG, "PCI: Getting capabilities pointer for {}", address); |     dbgln_if(PCI_DEBUG, "PCI: Getting capabilities pointer for {}", address); | ||||||
|  |  | ||||||
|  | @ -27,6 +27,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     void fast_enumerate(Function<void(DeviceIdentifier const&)>&) const; |     void fast_enumerate(Function<void(DeviceIdentifier const&)>&) const; | ||||||
|     void rescan_hardware(); |     void rescan_hardware(); | ||||||
|  |     void rescan_hardware_with_memory_addressing(); | ||||||
|  |     void rescan_hardware_with_io_addressing(); | ||||||
| 
 | 
 | ||||||
|     static Access& the(); |     static Access& the(); | ||||||
|     static bool is_initialized(); |     static bool is_initialized(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Liav A
						Liav A