1/*
2 * Copyright 2022, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#ifndef _X86PCICONTROLLER_H_
8#define _X86PCICONTROLLER_H_
9
10#include <bus/PCI.h>
11
12#include <AutoDeleterOS.h>
13#include <lock.h>
14
15#include "../ecam/ECAMPCIController.h"
16
17
18#define CHECK_RET(err) {status_t _err = (err); if (_err < B_OK) return _err;}
19
20#define PCI_X86_DRIVER_MODULE_NAME "busses/pci/x86/driver_v1"
21
22
23class X86PCIController {
24public:
25	virtual ~X86PCIController() = default;
26
27	static float SupportsDevice(device_node* parent);
28	static status_t RegisterDevice(device_node* parent);
29	static status_t InitDriver(device_node* node, X86PCIController*& outDriver);
30	void UninitDriver();
31
32	virtual status_t ReadConfig(
33		uint8 bus, uint8 device, uint8 function,
34		uint16 offset, uint8 size, uint32 &value) = 0;
35
36	virtual status_t WriteConfig(
37		uint8 bus, uint8 device, uint8 function,
38		uint16 offset, uint8 size, uint32 value) = 0;
39
40	virtual status_t GetMaxBusDevices(int32& count) = 0;
41
42	virtual status_t GetRange(uint32 index, pci_resource_range* range);
43
44	virtual status_t Finalize() final;
45
46	status_t ReadIrq(
47		uint8 bus, uint8 device, uint8 function,
48		uint8 pin, uint8& irq);
49
50	status_t WriteIrq(
51		uint8 bus, uint8 device, uint8 function,
52		uint8 pin, uint8 irq);
53
54protected:
55	static status_t CreateDriver(device_node* node, X86PCIController* driver,
56		X86PCIController*& driverOut);
57	virtual status_t InitDriverInt(device_node* node);
58
59protected:
60	spinlock fLock = B_SPINLOCK_INITIALIZER;
61
62	device_node* fNode{};
63};
64
65
66class X86PCIControllerMeth1: public X86PCIController {
67public:
68	virtual ~X86PCIControllerMeth1() = default;
69
70	status_t InitDriverInt(device_node* node) override;
71
72	status_t ReadConfig(
73		uint8 bus, uint8 device, uint8 function,
74		uint16 offset, uint8 size, uint32 &value) override;
75
76	status_t WriteConfig(
77		uint8 bus, uint8 device, uint8 function,
78		uint16 offset, uint8 size, uint32 value) override;
79
80	status_t GetMaxBusDevices(int32& count) override;
81};
82
83
84class X86PCIControllerMeth2: public X86PCIController {
85public:
86	virtual ~X86PCIControllerMeth2() = default;
87
88	status_t InitDriverInt(device_node* node) final;
89
90	status_t ReadConfig(
91		uint8 bus, uint8 device, uint8 function,
92		uint16 offset, uint8 size, uint32 &value) final;
93
94	status_t WriteConfig(
95		uint8 bus, uint8 device, uint8 function,
96		uint16 offset, uint8 size, uint32 value) final;
97
98	status_t GetMaxBusDevices(int32& count) final;
99};
100
101
102class X86PCIControllerMethPcie: public X86PCIControllerMeth1 {
103public:
104	virtual ~X86PCIControllerMethPcie() = default;
105
106	status_t InitDriverInt(device_node* node) final;
107
108	status_t ReadConfig(
109		uint8 bus, uint8 device, uint8 function,
110		uint16 offset, uint8 size, uint32 &value) final;
111
112	status_t WriteConfig(
113		uint8 bus, uint8 device, uint8 function,
114		uint16 offset, uint8 size, uint32 value) final;
115
116	status_t GetMaxBusDevices(int32& count) final;
117
118	status_t GetRange(uint32 index, pci_resource_range* range) final;
119
120private:
121	ECAMPCIControllerACPI fECAMPCIController;
122};
123
124
125extern device_manager_info* gDeviceManager;
126
127#endif	// _X86PCICONTROLLER_H_
128