mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 01:02:45 +00:00 
			
		
		
		
	Kernel/PCI: Cache interrupt line and interrupt pin of a device
This allows us to remove the PCI::get_interrupt_line API function. As a result, this removes a bunch of not so great patterns that we used to cache PCI interrupt line in many IRQHandler derived classes instead of just using interrupt_number method of IRQHandler class.
This commit is contained in:
		
							parent
							
								
									057f5a12c2
								
							
						
					
					
						commit
						a411a44fda
					
				
					 17 changed files with 43 additions and 39 deletions
				
			
		|  | @ -64,11 +64,6 @@ void disable_interrupt_line(Address address) | ||||||
|     write16(address, PCI_COMMAND, read16(address, PCI_COMMAND) | 1 << 10); |     write16(address, PCI_COMMAND, read16(address, PCI_COMMAND) | 1 << 10); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u8 get_interrupt_line(Address address) |  | ||||||
| { |  | ||||||
|     return read8(address, PCI_INTERRUPT_LINE); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| u32 get_BAR0(Address address) | u32 get_BAR0(Address address) | ||||||
| { | { | ||||||
|     return read32(address, PCI_BAR0); |     return read32(address, PCI_BAR0); | ||||||
|  |  | ||||||
|  | @ -22,7 +22,6 @@ bool is_io_space_enabled(Address); | ||||||
| void enumerate(Function<void(Address, DeviceIdentifier const&)> callback); | void enumerate(Function<void(Address, DeviceIdentifier const&)> callback); | ||||||
| void enable_interrupt_line(Address); | void enable_interrupt_line(Address); | ||||||
| void disable_interrupt_line(Address); | void disable_interrupt_line(Address); | ||||||
| u8 get_interrupt_line(Address); |  | ||||||
| void raw_access(Address, u32, size_t, u32); | void raw_access(Address, u32, size_t, u32); | ||||||
| u32 get_BAR0(Address); | u32 get_BAR0(Address); | ||||||
| u32 get_BAR1(Address); | u32 get_BAR1(Address); | ||||||
|  |  | ||||||
|  | @ -388,7 +388,9 @@ UNMAP_AFTER_INIT void Access::enumerate_functions(int type, u8 bus, u8 device, u | ||||||
|         RevisionID revision_id = read8_field(address, PCI_REVISION_ID); |         RevisionID revision_id = read8_field(address, PCI_REVISION_ID); | ||||||
|         SubsystemID subsystem_id = read16_field(address, PCI_SUBSYSTEM_ID); |         SubsystemID subsystem_id = read16_field(address, PCI_SUBSYSTEM_ID); | ||||||
|         SubsystemVendorID subsystem_vendor_id = read16_field(address, PCI_SUBSYSTEM_VENDOR_ID); |         SubsystemVendorID subsystem_vendor_id = read16_field(address, PCI_SUBSYSTEM_VENDOR_ID); | ||||||
|         m_device_identifiers.append(DeviceIdentifier { address, id, revision_id, class_code, subclass_code, prog_if, subsystem_id, subsystem_vendor_id, get_capabilities(address) }); |         InterruptLine interrupt_line = read8_field(address, PCI_INTERRUPT_LINE); | ||||||
|  |         InterruptPin interrupt_pin = read8_field(address, PCI_INTERRUPT_PIN); | ||||||
|  |         m_device_identifiers.append(DeviceIdentifier { address, id, revision_id, class_code, subclass_code, prog_if, subsystem_id, subsystem_vendor_id, interrupt_line, interrupt_pin, get_capabilities(address) }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (read_type == PCI_TYPE_BRIDGE && recursive && (!m_enumerated_buses.get(read8_field(address, PCI_SECONDARY_BUS)))) { |     if (read_type == PCI_TYPE_BRIDGE && recursive && (!m_enumerated_buses.get(read8_field(address, PCI_SECONDARY_BUS)))) { | ||||||
|  |  | ||||||
|  | @ -36,6 +36,7 @@ namespace Kernel { | ||||||
| #define PCI_SUBSYSTEM_ID 0x2E         // u16
 | #define PCI_SUBSYSTEM_ID 0x2E         // u16
 | ||||||
| #define PCI_CAPABILITIES_POINTER 0x34 // u8
 | #define PCI_CAPABILITIES_POINTER 0x34 // u8
 | ||||||
| #define PCI_INTERRUPT_LINE 0x3C       // byte
 | #define PCI_INTERRUPT_LINE 0x3C       // byte
 | ||||||
|  | #define PCI_INTERRUPT_PIN 0x3D        // byte
 | ||||||
| #define PCI_SECONDARY_BUS 0x19        // byte
 | #define PCI_SECONDARY_BUS 0x19        // byte
 | ||||||
| #define PCI_HEADER_TYPE_DEVICE 0 | #define PCI_HEADER_TYPE_DEVICE 0 | ||||||
| #define PCI_HEADER_TYPE_BRIDGE 1 | #define PCI_HEADER_TYPE_BRIDGE 1 | ||||||
|  | @ -187,11 +188,13 @@ TYPEDEF_DISTINCT_ORDERED_ID(u8, ProgrammingInterface); | ||||||
| TYPEDEF_DISTINCT_ORDERED_ID(u8, RevisionID); | TYPEDEF_DISTINCT_ORDERED_ID(u8, RevisionID); | ||||||
| TYPEDEF_DISTINCT_ORDERED_ID(u16, SubsystemID); | TYPEDEF_DISTINCT_ORDERED_ID(u16, SubsystemID); | ||||||
| TYPEDEF_DISTINCT_ORDERED_ID(u16, SubsystemVendorID); | TYPEDEF_DISTINCT_ORDERED_ID(u16, SubsystemVendorID); | ||||||
|  | TYPEDEF_DISTINCT_ORDERED_ID(u8, InterruptLine); | ||||||
|  | TYPEDEF_DISTINCT_ORDERED_ID(u8, InterruptPin); | ||||||
| 
 | 
 | ||||||
| class Access; | class Access; | ||||||
| class DeviceIdentifier { | class DeviceIdentifier { | ||||||
| public: | public: | ||||||
|     DeviceIdentifier(Address address, HardwareID hardware_id, RevisionID revision_id, ClassCode class_code, SubclassCode subclass_code, ProgrammingInterface prog_if, SubsystemID subsystem_id, SubsystemVendorID subsystem_vendor_id, Vector<Capability> capabilities) |     DeviceIdentifier(Address address, HardwareID hardware_id, RevisionID revision_id, ClassCode class_code, SubclassCode subclass_code, ProgrammingInterface prog_if, SubsystemID subsystem_id, SubsystemVendorID subsystem_vendor_id, InterruptLine interrupt_line, InterruptPin interrupt_pin, Vector<Capability> capabilities) | ||||||
|         : m_address(address) |         : m_address(address) | ||||||
|         , m_hardware_id(hardware_id) |         , m_hardware_id(hardware_id) | ||||||
|         , m_revision_id(revision_id) |         , m_revision_id(revision_id) | ||||||
|  | @ -200,6 +203,8 @@ public: | ||||||
|         , m_prog_if(prog_if) |         , m_prog_if(prog_if) | ||||||
|         , m_subsystem_id(subsystem_id) |         , m_subsystem_id(subsystem_id) | ||||||
|         , m_subsystem_vendor_id(subsystem_vendor_id) |         , m_subsystem_vendor_id(subsystem_vendor_id) | ||||||
|  |         , m_interrupt_line(interrupt_line) | ||||||
|  |         , m_interrupt_pin(interrupt_pin) | ||||||
|         , m_capabilities(capabilities) |         , m_capabilities(capabilities) | ||||||
|     { |     { | ||||||
|         if constexpr (PCI_DEBUG) { |         if constexpr (PCI_DEBUG) { | ||||||
|  | @ -219,6 +224,9 @@ public: | ||||||
|     SubsystemID subsystem_id() const { return m_subsystem_id; } |     SubsystemID subsystem_id() const { return m_subsystem_id; } | ||||||
|     SubsystemVendorID subsystem_vendor_id() const { return m_subsystem_vendor_id; } |     SubsystemVendorID subsystem_vendor_id() const { return m_subsystem_vendor_id; } | ||||||
| 
 | 
 | ||||||
|  |     InterruptLine interrupt_line() const { return m_interrupt_line; } | ||||||
|  |     InterruptPin interrupt_pin() const { return m_interrupt_pin; } | ||||||
|  | 
 | ||||||
|     void apply_subclass_code_change(Badge<Access>, SubclassCode new_subclass) |     void apply_subclass_code_change(Badge<Access>, SubclassCode new_subclass) | ||||||
|     { |     { | ||||||
|         m_subclass_code = new_subclass; |         m_subclass_code = new_subclass; | ||||||
|  | @ -239,6 +247,9 @@ private: | ||||||
|     SubsystemID m_subsystem_id; |     SubsystemID m_subsystem_id; | ||||||
|     SubsystemVendorID m_subsystem_vendor_id; |     SubsystemVendorID m_subsystem_vendor_id; | ||||||
| 
 | 
 | ||||||
|  |     InterruptLine m_interrupt_line; | ||||||
|  |     InterruptPin m_interrupt_pin; | ||||||
|  | 
 | ||||||
|     Vector<Capability> m_capabilities; |     Vector<Capability> m_capabilities; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -65,7 +65,7 @@ static constexpr u16 UHCI_NUMBER_OF_FRAMES = 1024; | ||||||
| KResultOr<NonnullRefPtr<UHCIController>> UHCIController::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier) | KResultOr<NonnullRefPtr<UHCIController>> UHCIController::try_to_initialize(PCI::DeviceIdentifier const& pci_device_identifier) | ||||||
| { | { | ||||||
|     // NOTE: This assumes that address is pointing to a valid UHCI controller.
 |     // NOTE: This assumes that address is pointing to a valid UHCI controller.
 | ||||||
|     auto controller = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) UHCIController(pci_device_identifier.address()))); |     auto controller = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) UHCIController(pci_device_identifier))); | ||||||
|     TRY(controller->initialize()); |     TRY(controller->initialize()); | ||||||
|     return controller; |     return controller; | ||||||
| } | } | ||||||
|  | @ -74,7 +74,7 @@ KResult UHCIController::initialize() | ||||||
| { | { | ||||||
|     dmesgln("UHCI: Controller found {} @ {}", PCI::get_hardware_id(pci_address()), pci_address()); |     dmesgln("UHCI: Controller found {} @ {}", PCI::get_hardware_id(pci_address()), pci_address()); | ||||||
|     dmesgln("UHCI: I/O base {}", m_io_base); |     dmesgln("UHCI: I/O base {}", m_io_base); | ||||||
|     dmesgln("UHCI: Interrupt line: {}", PCI::get_interrupt_line(pci_address())); |     dmesgln("UHCI: Interrupt line: {}", interrupt_number()); | ||||||
| 
 | 
 | ||||||
|     spawn_port_proc(); |     spawn_port_proc(); | ||||||
| 
 | 
 | ||||||
|  | @ -82,9 +82,9 @@ KResult UHCIController::initialize() | ||||||
|     return start(); |     return start(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::Address address) | UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::DeviceIdentifier const& pci_device_identifier) | ||||||
|     : PCI::Device(address) |     : PCI::Device(pci_device_identifier.address()) | ||||||
|     , IRQHandler(PCI::get_interrupt_line(address)) |     , IRQHandler(pci_device_identifier.interrupt_line().value()) | ||||||
|     , m_io_base(PCI::get_BAR4(pci_address()) & ~1) |     , m_io_base(PCI::get_BAR4(pci_address()) & ~1) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -53,7 +53,7 @@ public: | ||||||
|     KResult clear_port_feature(Badge<UHCIRootHub>, u8, HubFeatureSelector); |     KResult clear_port_feature(Badge<UHCIRootHub>, u8, HubFeatureSelector); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     explicit UHCIController(PCI::Address); |     explicit UHCIController(PCI::DeviceIdentifier const& pci_device_identifier); | ||||||
| 
 | 
 | ||||||
|     u16 read_usbcmd() { return m_io_base.offset(0).in<u16>(); } |     u16 read_usbcmd() { return m_io_base.offset(0).in<u16>(); } | ||||||
|     u16 read_usbsts() { return m_io_base.offset(0x2).in<u16>(); } |     u16 read_usbsts() { return m_io_base.offset(0x2).in<u16>(); } | ||||||
|  |  | ||||||
|  | @ -152,7 +152,7 @@ UNMAP_AFTER_INIT void Device::initialize() | ||||||
| 
 | 
 | ||||||
| UNMAP_AFTER_INIT VirtIO::Device::Device(PCI::DeviceIdentifier const& device_identifier) | UNMAP_AFTER_INIT VirtIO::Device::Device(PCI::DeviceIdentifier const& device_identifier) | ||||||
|     : PCI::Device(device_identifier.address()) |     : PCI::Device(device_identifier.address()) | ||||||
|     , IRQHandler(PCI::get_interrupt_line(device_identifier.address())) |     , IRQHandler(device_identifier.interrupt_line().value()) | ||||||
|     , m_io_base(IOAddress(PCI::get_BAR0(pci_address()) & ~1)) |     , m_io_base(IOAddress(PCI::get_BAR0(pci_address()) & ~1)) | ||||||
|     , m_class_name(VirtIO::determine_device_class(device_identifier)) |     , m_class_name(VirtIO::determine_device_class(device_identifier)) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -186,7 +186,7 @@ UNMAP_AFTER_INIT RefPtr<E1000ENetworkAdapter> E1000ENetworkAdapter::try_to_initi | ||||||
|         return {}; |         return {}; | ||||||
|     if (!is_valid_device_id(pci_device_identifier.hardware_id().device_id)) |     if (!is_valid_device_id(pci_device_identifier.hardware_id().device_id)) | ||||||
|         return {}; |         return {}; | ||||||
|     u8 irq = PCI::get_interrupt_line(pci_device_identifier.address()); |     u8 irq = pci_device_identifier.interrupt_line().value(); | ||||||
|     auto adapter = adopt_ref_if_nonnull(new (nothrow) E1000ENetworkAdapter(pci_device_identifier.address(), irq)); |     auto adapter = adopt_ref_if_nonnull(new (nothrow) E1000ENetworkAdapter(pci_device_identifier.address(), irq)); | ||||||
|     if (!adapter) |     if (!adapter) | ||||||
|         return {}; |         return {}; | ||||||
|  | @ -210,11 +210,10 @@ UNMAP_AFTER_INIT bool E1000ENetworkAdapter::initialize() | ||||||
|     m_mmio_region = region_or_error.release_value(); |     m_mmio_region = region_or_error.release_value(); | ||||||
|     m_mmio_base = m_mmio_region->vaddr(); |     m_mmio_base = m_mmio_region->vaddr(); | ||||||
|     m_use_mmio = true; |     m_use_mmio = true; | ||||||
|     m_interrupt_line = PCI::get_interrupt_line(pci_address()); |  | ||||||
|     dmesgln("E1000e: port base: {}", m_io_base); |     dmesgln("E1000e: port base: {}", m_io_base); | ||||||
|     dmesgln("E1000e: MMIO base: {}", PhysicalAddress(PCI::get_BAR0(pci_address()) & 0xfffffffc)); |     dmesgln("E1000e: MMIO base: {}", PhysicalAddress(PCI::get_BAR0(pci_address()) & 0xfffffffc)); | ||||||
|     dmesgln("E1000e: MMIO base size: {} bytes", mmio_base_size); |     dmesgln("E1000e: MMIO base size: {} bytes", mmio_base_size); | ||||||
|     dmesgln("E1000e: Interrupt line: {}", m_interrupt_line); |     dmesgln("E1000e: Interrupt line: {}", interrupt_number()); | ||||||
|     detect_eeprom(); |     detect_eeprom(); | ||||||
|     dmesgln("E1000e: Has EEPROM? {}", m_has_eeprom); |     dmesgln("E1000e: Has EEPROM? {}", m_has_eeprom); | ||||||
|     read_mac_address(); |     read_mac_address(); | ||||||
|  |  | ||||||
|  | @ -164,7 +164,7 @@ UNMAP_AFTER_INIT RefPtr<E1000NetworkAdapter> E1000NetworkAdapter::try_to_initial | ||||||
|         return {}; |         return {}; | ||||||
|     if (!is_valid_device_id(pci_device_identifier.hardware_id().device_id)) |     if (!is_valid_device_id(pci_device_identifier.hardware_id().device_id)) | ||||||
|         return {}; |         return {}; | ||||||
|     u8 irq = PCI::get_interrupt_line(pci_device_identifier.address()); |     u8 irq = pci_device_identifier.interrupt_line().value(); | ||||||
|     auto adapter = adopt_ref_if_nonnull(new (nothrow) E1000NetworkAdapter(pci_device_identifier.address(), irq)); |     auto adapter = adopt_ref_if_nonnull(new (nothrow) E1000NetworkAdapter(pci_device_identifier.address(), irq)); | ||||||
|     if (!adapter) |     if (!adapter) | ||||||
|         return {}; |         return {}; | ||||||
|  | @ -201,11 +201,10 @@ UNMAP_AFTER_INIT bool E1000NetworkAdapter::initialize() | ||||||
|     m_mmio_region = region_or_error.release_value(); |     m_mmio_region = region_or_error.release_value(); | ||||||
|     m_mmio_base = m_mmio_region->vaddr(); |     m_mmio_base = m_mmio_region->vaddr(); | ||||||
|     m_use_mmio = true; |     m_use_mmio = true; | ||||||
|     m_interrupt_line = PCI::get_interrupt_line(pci_address()); |  | ||||||
|     dmesgln("E1000: port base: {}", m_io_base); |     dmesgln("E1000: port base: {}", m_io_base); | ||||||
|     dmesgln("E1000: MMIO base: {}", PhysicalAddress(PCI::get_BAR0(pci_address()) & 0xfffffffc)); |     dmesgln("E1000: MMIO base: {}", PhysicalAddress(PCI::get_BAR0(pci_address()) & 0xfffffffc)); | ||||||
|     dmesgln("E1000: MMIO base size: {} bytes", mmio_base_size); |     dmesgln("E1000: MMIO base size: {} bytes", mmio_base_size); | ||||||
|     dmesgln("E1000: Interrupt line: {}", m_interrupt_line); |     dmesgln("E1000: Interrupt line: {}", interrupt_number()); | ||||||
|     detect_eeprom(); |     detect_eeprom(); | ||||||
|     dmesgln("E1000: Has EEPROM? {}", m_has_eeprom); |     dmesgln("E1000: Has EEPROM? {}", m_has_eeprom); | ||||||
|     read_mac_address(); |     read_mac_address(); | ||||||
|  |  | ||||||
|  | @ -91,7 +91,6 @@ protected: | ||||||
|     Array<void*, number_of_rx_descriptors> m_rx_buffers; |     Array<void*, number_of_rx_descriptors> m_rx_buffers; | ||||||
|     Array<void*, number_of_tx_descriptors> m_tx_buffers; |     Array<void*, number_of_tx_descriptors> m_tx_buffers; | ||||||
|     OwnPtr<Memory::Region> m_mmio_region; |     OwnPtr<Memory::Region> m_mmio_region; | ||||||
|     u8 m_interrupt_line { 0 }; |  | ||||||
|     bool m_has_eeprom { false }; |     bool m_has_eeprom { false }; | ||||||
|     bool m_use_mmio { false }; |     bool m_use_mmio { false }; | ||||||
|     EntropySource m_entropy_source; |     EntropySource m_entropy_source; | ||||||
|  |  | ||||||
|  | @ -156,7 +156,7 @@ UNMAP_AFTER_INIT RefPtr<NE2000NetworkAdapter> NE2000NetworkAdapter::try_to_initi | ||||||
|     }; |     }; | ||||||
|     if (!ne2k_ids.span().contains_slow(pci_device_identifier.hardware_id())) |     if (!ne2k_ids.span().contains_slow(pci_device_identifier.hardware_id())) | ||||||
|         return {}; |         return {}; | ||||||
|     u8 irq = PCI::get_interrupt_line(pci_device_identifier.address()); |     u8 irq = pci_device_identifier.interrupt_line().value(); | ||||||
|     return adopt_ref_if_nonnull(new (nothrow) NE2000NetworkAdapter(pci_device_identifier.address(), irq)); |     return adopt_ref_if_nonnull(new (nothrow) NE2000NetworkAdapter(pci_device_identifier.address(), irq)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -169,9 +169,8 @@ UNMAP_AFTER_INIT NE2000NetworkAdapter::NE2000NetworkAdapter(PCI::Address address | ||||||
| 
 | 
 | ||||||
|     dmesgln("NE2000: Found @ {}", pci_address()); |     dmesgln("NE2000: Found @ {}", pci_address()); | ||||||
| 
 | 
 | ||||||
|     m_interrupt_line = PCI::get_interrupt_line(pci_address()); |  | ||||||
|     dmesgln("NE2000: Port base: {}", m_io_base); |     dmesgln("NE2000: Port base: {}", m_io_base); | ||||||
|     dmesgln("NE2000: Interrupt line: {}", m_interrupt_line); |     dmesgln("NE2000: Interrupt line: {}", interrupt_number()); | ||||||
| 
 | 
 | ||||||
|     int ram_errors = ram_test(); |     int ram_errors = ram_test(); | ||||||
|     dmesgln("NE2000: RAM test {}, got {} byte errors", (ram_errors == 0 ? "OK" : "KO"), ram_errors); |     dmesgln("NE2000: RAM test {}, got {} byte errors", (ram_errors == 0 ? "OK" : "KO"), ram_errors); | ||||||
|  |  | ||||||
|  | @ -117,7 +117,7 @@ UNMAP_AFTER_INIT RefPtr<RTL8139NetworkAdapter> RTL8139NetworkAdapter::try_to_ini | ||||||
|     constexpr PCI::HardwareID rtl8139_id = { 0x10EC, 0x8139 }; |     constexpr PCI::HardwareID rtl8139_id = { 0x10EC, 0x8139 }; | ||||||
|     if (pci_device_identifier.hardware_id() != rtl8139_id) |     if (pci_device_identifier.hardware_id() != rtl8139_id) | ||||||
|         return {}; |         return {}; | ||||||
|     u8 irq = PCI::get_interrupt_line(pci_device_identifier.address()); |     u8 irq = pci_device_identifier.interrupt_line().value(); | ||||||
|     return adopt_ref_if_nonnull(new (nothrow) RTL8139NetworkAdapter(pci_device_identifier.address(), irq)); |     return adopt_ref_if_nonnull(new (nothrow) RTL8139NetworkAdapter(pci_device_identifier.address(), irq)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -135,9 +135,8 @@ UNMAP_AFTER_INIT RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address addre | ||||||
| 
 | 
 | ||||||
|     enable_bus_mastering(pci_address()); |     enable_bus_mastering(pci_address()); | ||||||
| 
 | 
 | ||||||
|     m_interrupt_line = PCI::get_interrupt_line(pci_address()); |  | ||||||
|     dmesgln("RTL8139: I/O port base: {}", m_io_base); |     dmesgln("RTL8139: I/O port base: {}", m_io_base); | ||||||
|     dmesgln("RTL8139: Interrupt line: {}", m_interrupt_line); |     dmesgln("RTL8139: Interrupt line: {}", interrupt_number()); | ||||||
| 
 | 
 | ||||||
|     // we add space to account for overhang from the last packet - the rtl8139
 |     // we add space to account for overhang from the last packet - the rtl8139
 | ||||||
|     // can optionally guarantee that packets will be contiguous by
 |     // can optionally guarantee that packets will be contiguous by
 | ||||||
|  |  | ||||||
|  | @ -187,7 +187,7 @@ UNMAP_AFTER_INIT RefPtr<RTL8168NetworkAdapter> RTL8168NetworkAdapter::try_to_ini | ||||||
|         return {}; |         return {}; | ||||||
|     if (pci_device_identifier.hardware_id().device_id != 0x8168) |     if (pci_device_identifier.hardware_id().device_id != 0x8168) | ||||||
|         return {}; |         return {}; | ||||||
|     u8 irq = PCI::get_interrupt_line(pci_device_identifier.address()); |     u8 irq = pci_device_identifier.interrupt_line().value(); | ||||||
|     return adopt_ref_if_nonnull(new (nothrow) RTL8168NetworkAdapter(pci_device_identifier.address(), irq)); |     return adopt_ref_if_nonnull(new (nothrow) RTL8168NetworkAdapter(pci_device_identifier.address(), irq)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ namespace Kernel { | ||||||
| 
 | 
 | ||||||
| NonnullRefPtr<AHCIController> AHCIController::initialize(PCI::DeviceIdentifier const& pci_device_identifier) | NonnullRefPtr<AHCIController> AHCIController::initialize(PCI::DeviceIdentifier const& pci_device_identifier) | ||||||
| { | { | ||||||
|     return adopt_ref(*new AHCIController(pci_device_identifier.address())); |     return adopt_ref(*new AHCIController(pci_device_identifier)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool AHCIController::reset() | bool AHCIController::reset() | ||||||
|  | @ -79,13 +79,13 @@ volatile AHCI::HBA& AHCIController::hba() const | ||||||
|     return static_cast<volatile AHCI::HBA&>(*(volatile AHCI::HBA*)(m_hba_region->vaddr().as_ptr())); |     return static_cast<volatile AHCI::HBA&>(*(volatile AHCI::HBA*)(m_hba_region->vaddr().as_ptr())); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| AHCIController::AHCIController(PCI::Address address) | AHCIController::AHCIController(PCI::DeviceIdentifier const& pci_device_identifier) | ||||||
|     : StorageController() |     : StorageController() | ||||||
|     , PCI::Device(address) |     , PCI::Device(pci_device_identifier.address()) | ||||||
|     , m_hba_region(default_hba_region()) |     , m_hba_region(default_hba_region()) | ||||||
|     , m_capabilities(capabilities()) |     , m_capabilities(capabilities()) | ||||||
| { | { | ||||||
|     initialize(); |     initialize_hba(pci_device_identifier); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| AHCI::HBADefinedCapabilities AHCIController::capabilities() const | AHCI::HBADefinedCapabilities AHCIController::capabilities() const | ||||||
|  | @ -134,7 +134,7 @@ AHCIController::~AHCIController() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AHCIController::initialize() | void AHCIController::initialize_hba(PCI::DeviceIdentifier const& pci_device_identifier) | ||||||
| { | { | ||||||
|     if (!reset()) { |     if (!reset()) { | ||||||
|         dmesgln("{}: AHCI controller reset failed", pci_address()); |         dmesgln("{}: AHCI controller reset failed", pci_address()); | ||||||
|  | @ -150,7 +150,7 @@ void AHCIController::initialize() | ||||||
|     PCI::enable_interrupt_line(pci_address()); |     PCI::enable_interrupt_line(pci_address()); | ||||||
|     PCI::enable_bus_mastering(pci_address()); |     PCI::enable_bus_mastering(pci_address()); | ||||||
|     enable_global_interrupts(); |     enable_global_interrupts(); | ||||||
|     m_handlers.append(AHCIPortHandler::create(*this, PCI::get_interrupt_line(pci_address()), |     m_handlers.append(AHCIPortHandler::create(*this, pci_device_identifier.interrupt_line().value(), | ||||||
|         AHCI::MaskedBitField((volatile u32&)(hba().control_regs.pi)))); |         AHCI::MaskedBitField((volatile u32&)(hba().control_regs.pi)))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -41,8 +41,8 @@ private: | ||||||
|     void disable_global_interrupts() const; |     void disable_global_interrupts() const; | ||||||
|     void enable_global_interrupts() const; |     void enable_global_interrupts() const; | ||||||
| 
 | 
 | ||||||
|     UNMAP_AFTER_INIT explicit AHCIController(PCI::Address address); |     UNMAP_AFTER_INIT explicit AHCIController(PCI::DeviceIdentifier const&); | ||||||
|     UNMAP_AFTER_INIT void initialize(); |     UNMAP_AFTER_INIT void initialize_hba(PCI::DeviceIdentifier const&); | ||||||
| 
 | 
 | ||||||
|     AHCI::HBADefinedCapabilities capabilities() const; |     AHCI::HBADefinedCapabilities capabilities() const; | ||||||
|     RefPtr<StorageDevice> device_by_port(u32 index) const; |     RefPtr<StorageDevice> device_by_port(u32 index) const; | ||||||
|  |  | ||||||
|  | @ -55,6 +55,7 @@ UNMAP_AFTER_INIT IDEController::IDEController(PCI::DeviceIdentifier const& devic | ||||||
|     : StorageController() |     : StorageController() | ||||||
|     , PCI::Device(device_identifier.address()) |     , PCI::Device(device_identifier.address()) | ||||||
|     , m_prog_if(device_identifier.prog_if()) |     , m_prog_if(device_identifier.prog_if()) | ||||||
|  |     , m_interrupt_line(device_identifier.interrupt_line()) | ||||||
| { | { | ||||||
|     PCI::enable_io_space(device_identifier.address()); |     PCI::enable_io_space(device_identifier.address()); | ||||||
|     PCI::enable_memory_space(device_identifier.address()); |     PCI::enable_memory_space(device_identifier.address()); | ||||||
|  | @ -114,7 +115,7 @@ UNMAP_AFTER_INIT void IDEController::initialize(bool force_pio) | ||||||
| { | { | ||||||
|     auto bus_master_base = IOAddress(PCI::get_BAR4(pci_address()) & (~1)); |     auto bus_master_base = IOAddress(PCI::get_BAR4(pci_address()) & (~1)); | ||||||
|     dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base); |     dbgln("IDE controller @ {}: bus master base was set to {}", pci_address(), bus_master_base); | ||||||
|     dbgln("IDE controller @ {}: interrupt line was set to {}", pci_address(), PCI::get_interrupt_line(pci_address())); |     dbgln("IDE controller @ {}: interrupt line was set to {}", pci_address(), m_interrupt_line.value()); | ||||||
|     dbgln("IDE controller @ {}: {}", pci_address(), detect_controller_type(m_prog_if.value())); |     dbgln("IDE controller @ {}: {}", pci_address(), detect_controller_type(m_prog_if.value())); | ||||||
|     dbgln("IDE controller @ {}: primary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2).in<u8>() >> 5) & 0b11)); |     dbgln("IDE controller @ {}: primary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2).in<u8>() >> 5) & 0b11)); | ||||||
|     dbgln("IDE controller @ {}: secondary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2 + 8).in<u8>() >> 5) & 0b11)); |     dbgln("IDE controller @ {}: secondary channel DMA capable? {}", pci_address(), ((bus_master_base.offset(2 + 8).in<u8>() >> 5) & 0b11)); | ||||||
|  | @ -131,7 +132,7 @@ UNMAP_AFTER_INIT void IDEController::initialize(bool force_pio) | ||||||
|     auto bar3 = PCI::get_BAR3(pci_address()); |     auto bar3 = PCI::get_BAR3(pci_address()); | ||||||
|     auto secondary_control_io = (bar3 == 0x1 || bar3 == 0) ? IOAddress(0x376) : IOAddress(bar3 & (~1)); |     auto secondary_control_io = (bar3 == 0x1 || bar3 == 0) ? IOAddress(0x376) : IOAddress(bar3 & (~1)); | ||||||
| 
 | 
 | ||||||
|     auto irq_line = PCI::get_interrupt_line(pci_address()); |     auto irq_line = m_interrupt_line.value(); | ||||||
|     if (is_pci_native_mode_enabled()) { |     if (is_pci_native_mode_enabled()) { | ||||||
|         VERIFY(irq_line != 0); |         VERIFY(irq_line != 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -46,5 +46,6 @@ private: | ||||||
|     NonnullRefPtrVector<IDEChannel> m_channels; |     NonnullRefPtrVector<IDEChannel> m_channels; | ||||||
|     // FIXME: Find a better way to get the ProgrammingInterface
 |     // FIXME: Find a better way to get the ProgrammingInterface
 | ||||||
|     PCI::ProgrammingInterface m_prog_if; |     PCI::ProgrammingInterface m_prog_if; | ||||||
|  |     PCI::InterruptLine m_interrupt_line; | ||||||
| }; | }; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Liav A
						Liav A