forked from Bananymous/banan-os
				
			
			update main #1
			
				
			
		
		
		
	| 
						 | 
				
			
			@ -58,6 +58,8 @@ namespace Kernel::PCI
 | 
			
		|||
		uint8_t  read_byte(uint8_t) const;
 | 
			
		||||
 | 
			
		||||
		void write_dword(uint8_t, uint32_t);
 | 
			
		||||
		void write_word(uint8_t, uint16_t);
 | 
			
		||||
		void write_byte(uint8_t, uint8_t);
 | 
			
		||||
 | 
			
		||||
		uint8_t bus() const { return m_bus; }
 | 
			
		||||
		uint8_t dev() const { return m_dev; }
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +111,14 @@ namespace Kernel::PCI
 | 
			
		|||
		
 | 
			
		||||
		const BAN::Vector<PCI::Device>& devices() const { return m_devices; }
 | 
			
		||||
 | 
			
		||||
		static uint32_t read_config_dword(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset);
 | 
			
		||||
		static uint16_t read_config_word(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset);
 | 
			
		||||
		static uint8_t read_config_byte(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset);
 | 
			
		||||
 | 
			
		||||
		static void write_config_dword(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset, uint32_t value);
 | 
			
		||||
		static void write_config_word(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset, uint16_t value);
 | 
			
		||||
		static void write_config_byte(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset, uint8_t value);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		PCIManager() = default;
 | 
			
		||||
		void check_function(uint8_t bus, uint8_t dev, uint8_t func);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,29 +18,63 @@ namespace Kernel::PCI
 | 
			
		|||
 | 
			
		||||
	static PCIManager* s_instance = nullptr;
 | 
			
		||||
 | 
			
		||||
	static uint32_t read_config_dword(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset)
 | 
			
		||||
	uint32_t PCIManager::read_config_dword(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset % 4 == 0);
 | 
			
		||||
		uint32_t config_addr = 0x80000000 | ((uint32_t)bus << 16) | ((uint32_t)dev << 11) | ((uint32_t)func << 8) | offset;
 | 
			
		||||
		IO::outl(CONFIG_ADDRESS, config_addr);
 | 
			
		||||
		return IO::inl(CONFIG_DATA);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static void write_config_dword(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset, uint32_t value)
 | 
			
		||||
	uint16_t PCIManager::read_config_word(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset % 2 == 0);
 | 
			
		||||
		uint32_t dword = read_config_dword(bus, dev, func, offset & ~3);
 | 
			
		||||
		return (dword >> ((offset & 3) * 8)) & 0xFFFF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uint8_t PCIManager::read_config_byte(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset)
 | 
			
		||||
	{
 | 
			
		||||
		uint32_t dword = read_config_dword(bus, dev, func, offset & ~3);
 | 
			
		||||
		return (dword >> ((offset & 3) * 8)) & 0xFF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void PCIManager::write_config_dword(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset, uint32_t value)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset % 4 == 0);
 | 
			
		||||
		uint32_t config_addr = 0x80000000 | ((uint32_t)bus << 16) | ((uint32_t)dev << 11) | ((uint32_t)func << 8) | offset;
 | 
			
		||||
		IO::outl(CONFIG_ADDRESS, config_addr);
 | 
			
		||||
		IO::outl(CONFIG_DATA, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void PCIManager::write_config_word(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset, uint16_t value)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset % 2 == 0);
 | 
			
		||||
		uint32_t byte = (offset & 3) * 8;
 | 
			
		||||
		uint32_t temp = read_config_dword(bus, dev, func, offset & ~3);
 | 
			
		||||
		temp &= ~(0xFFFF << byte);
 | 
			
		||||
		temp |= (uint32_t)value << byte;
 | 
			
		||||
		write_config_dword(bus, dev, func, offset & ~3, temp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void PCIManager::write_config_byte(uint8_t bus, uint8_t dev, uint8_t func, uint8_t offset, uint8_t value)
 | 
			
		||||
	{
 | 
			
		||||
		uint32_t byte = (offset & 3) * 8;
 | 
			
		||||
		uint32_t temp = read_config_dword(bus, dev, func, offset & ~3);
 | 
			
		||||
		temp &= ~(0xFF << byte);
 | 
			
		||||
		temp |= (uint32_t)value << byte;
 | 
			
		||||
		write_config_dword(bus, dev, func, offset, temp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static uint16_t get_vendor_id(uint8_t bus, uint8_t dev, uint8_t func)
 | 
			
		||||
	{
 | 
			
		||||
		uint32_t dword = read_config_dword(bus, dev, func, 0x00);
 | 
			
		||||
		uint32_t dword = PCIManager::read_config_dword(bus, dev, func, 0x00);
 | 
			
		||||
		return dword & 0xFFFF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static uint8_t get_header_type(uint8_t bus, uint8_t dev, uint8_t func)
 | 
			
		||||
	{
 | 
			
		||||
		uint32_t dword = read_config_dword(bus, dev, func, 0x0C);
 | 
			
		||||
		uint32_t dword = PCIManager::read_config_dword(bus, dev, func, 0x0C);
 | 
			
		||||
		return (dword >> 16) & 0xFF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -289,27 +323,36 @@ namespace Kernel::PCI
 | 
			
		|||
 | 
			
		||||
	uint32_t PCI::Device::read_dword(uint8_t offset) const
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT((offset & 0x03) == 0);
 | 
			
		||||
		return read_config_dword(m_bus, m_dev, m_func, offset);
 | 
			
		||||
		ASSERT(offset % 4 == 0);
 | 
			
		||||
		return PCIManager::read_config_dword(m_bus, m_dev, m_func, offset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uint16_t PCI::Device::read_word(uint8_t offset) const
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT((offset & 0x01) == 0);
 | 
			
		||||
		uint32_t dword = read_config_dword(m_bus, m_dev, m_func, offset & 0xFC);
 | 
			
		||||
		return (uint16_t)(dword >> (8 * (offset & 0x03)));
 | 
			
		||||
		ASSERT(offset % 2 == 0);
 | 
			
		||||
		return PCIManager::read_config_word(m_bus, m_dev, m_func, offset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uint8_t PCI::Device::read_byte(uint8_t offset) const
 | 
			
		||||
	{
 | 
			
		||||
		uint32_t dword = read_config_dword(m_bus, m_dev, m_func, offset & 0xFC);
 | 
			
		||||
		return (uint8_t)(dword >> (8 * (offset & 0x03)));
 | 
			
		||||
		return PCIManager::read_config_byte(m_bus, m_dev, m_func, offset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void PCI::Device::write_dword(uint8_t offset, uint32_t value)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT((offset & 0x03) == 0);
 | 
			
		||||
		write_config_dword(m_bus, m_dev, m_func, offset, value);
 | 
			
		||||
		ASSERT(offset % 4 == 0);
 | 
			
		||||
		PCIManager::write_config_dword(m_bus, m_dev, m_func, offset, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void PCI::Device::write_word(uint8_t offset, uint16_t value)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset % 2 == 0);
 | 
			
		||||
		PCIManager::write_config_word(m_bus, m_dev, m_func, offset, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void PCI::Device::write_byte(uint8_t offset, uint8_t value)
 | 
			
		||||
	{
 | 
			
		||||
		PCIManager::write_config_byte(m_bus, m_dev, m_func, offset, value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<BAN::UniqPtr<BarRegion>> PCI::Device::allocate_bar_region(uint8_t bar_num)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue