Kernel/Graphics: Don't try to enumerate PCI adapters if PCI is disabled

If there's no PCI bus, then it's safe to assume that the x86 machine we
run on supports VGA text mode console output with an ISA VGA adapter.
If this is the case, we just instantiate a ISAVGAAdapter object that
assumes this situation and allows us to boot into VGA text mode console.
This commit is contained in:
Liav A 2022-01-21 16:15:46 +02:00 committed by Andreas Kling
parent 15315be55c
commit fafa339264
Notes: sideshowbarker 2024-07-17 23:00:03 +09:00
10 changed files with 197 additions and 72 deletions

View file

@ -82,10 +82,11 @@ set(KERNEL_SOURCES
Graphics/FramebufferDevice.cpp
Graphics/GraphicsManagement.cpp
Graphics/Intel/NativeGraphicsAdapter.cpp
Graphics/VGA/ISAAdapter.cpp
Graphics/VGA/PCIAdapter.cpp
Graphics/VirtIOGPU/FramebufferDevice.cpp
Graphics/VirtIOGPU/Console.cpp
Graphics/VirtIOGPU/GraphicsAdapter.cpp
Graphics/VGACompatibleAdapter.cpp
Graphics/GenericFramebufferDevice.cpp
SanCov.cpp
Storage/ATA/AHCIController.cpp

View file

@ -13,6 +13,8 @@
#include <Kernel/Graphics/Console/BootFramebufferConsole.h>
#include <Kernel/Graphics/GraphicsManagement.h>
#include <Kernel/Graphics/Intel/NativeGraphicsAdapter.h>
#include <Kernel/Graphics/VGA/ISAAdapter.h>
#include <Kernel/Graphics/VGA/PCIAdapter.h>
#include <Kernel/Graphics/VGACompatibleAdapter.h>
#include <Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h>
#include <Kernel/Memory/AnonymousVMObject.h>
@ -76,6 +78,16 @@ static inline bool is_display_controller_pci_device(PCI::DeviceIdentifier const&
return device_identifier.class_code().value() == 0x3;
}
UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_isa_graphics_device()
{
dmesgln("Graphics: Using a ISA VGA compatible generic adapter");
auto adapter = ISAVGAAdapter::initialize();
m_graphics_devices.append(*adapter);
adapter->enable_consoles();
m_vga_adapter = adapter;
return true;
}
UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_device(PCI::DeviceIdentifier const& device_identifier)
{
VERIFY(is_vga_compatible_pci_device(device_identifier) || is_display_controller_pci_device(device_identifier));
@ -99,7 +111,7 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
dmesgln("Graphics: The framebuffer set up by the bootloader is not RGB, ignoring fbdev argument");
} else {
dmesgln("Graphics: Using a preset resolution from the bootloader");
adapter = VGACompatibleAdapter::initialize_with_preset_resolution(device_identifier,
adapter = PCIVGACompatibleAdapter::initialize_with_preset_resolution(device_identifier,
multiboot_framebuffer_addr,
multiboot_framebuffer_width,
multiboot_framebuffer_height,
@ -145,8 +157,8 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
if (!m_vga_adapter && PCI::is_io_space_enabled(device_identifier.address())) {
create_bootloader_framebuffer_device();
} else {
dmesgln("Graphics: Using a VGA compatible generic adapter");
adapter = VGACompatibleAdapter::initialize(device_identifier);
dmesgln("Graphics: Using a PCI VGA compatible generic adapter");
adapter = PCIVGACompatibleAdapter::initialize(device_identifier);
}
break;
}
@ -168,7 +180,7 @@ UNMAP_AFTER_INIT bool GraphicsManagement::determine_and_initialize_graphics_devi
UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
{
/* Explanation on the flow when not requesting to force not creating any
/* Explanation on the flow when not requesting to force not creating any
* framebuffer devices:
* If the user wants to use a Console instead of the graphical environment,
* they doesn't need to request text mode.
@ -179,31 +191,41 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
* 1. The bootloader didn't specify settings of a pre-set framebuffer. The
* kernel has a native driver for a detected display adapter, therefore
* the kernel can still set a framebuffer.
* 2. The bootloader specified settings of a pre-set framebuffer, and the
* 2. The bootloader specified settings of a pre-set framebuffer, and the
* kernel has a native driver for a detected display adapter, therefore
* the kernel can still set a framebuffer and change the settings of it.
* In that situation, the kernel will simply ignore the Multiboot pre-set
* In that situation, the kernel will simply ignore the Multiboot pre-set
* framebuffer.
* 2. The bootloader specified settings of a pre-set framebuffer, and the
* kernel does not have a native driver for a detected display adapter,
* 2. The bootloader specified settings of a pre-set framebuffer, and the
* kernel does not have a native driver for a detected display adapter,
* therefore the kernel will use the pre-set framebuffer. Modesetting is not
* available in this situation.
* 3. The bootloader didn't specify settings of a pre-set framebuffer, and
* the kernel does not have a native driver for a detected display adapter,
* 3. The bootloader didn't specify settings of a pre-set framebuffer, and
* the kernel does not have a native driver for a detected display adapter,
* therefore the kernel will try to initialize a VGA text mode console.
* In that situation, the kernel will assume that VGA text mode was already
* initialized, but will still try to modeset it. No switching to graphical
* initialized, but will still try to modeset it. No switching to graphical
* environment is allowed in this case.
*
*
* By default, the kernel assumes that no framebuffer was created until it
* was proven that there's an existing framebuffer or we can modeset the
* was proven that there's an existing framebuffer or we can modeset the
* screen resolution to create a framebuffer.
*
*
* Special cases:
* 1. If the user disabled PCI access, the kernel behaves like it's running
* on a pure ISA PC machine and therefore the kernel will try to initialize
* a variant that is suitable for ISA VGA handling, and not PCI adapters.
*
* If the user requests to force no initialization of framebuffer devices
* the same flow above will happen, except that no framebuffer device will
* be created, so SystemServer will not try to initialize WindowServer.
*/
if (PCI::Access::is_disabled()) {
determine_and_initialize_isa_graphics_device();
return true;
}
if (framebuffer_devices_console_only())
dbgln("Forcing non-initialization of framebuffer devices (console only)");
else if (framebuffer_devices_use_bootloader_framebuffer())

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
* Copyright (c) 2021-2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -42,6 +42,7 @@ public:
private:
bool determine_and_initialize_graphics_device(PCI::DeviceIdentifier const&);
bool determine_and_initialize_isa_graphics_device();
NonnullRefPtrVector<GenericGraphicsAdapter> m_graphics_devices;
RefPtr<Graphics::Console> m_console;

View file

@ -178,7 +178,7 @@ Optional<IntelNativeGraphicsAdapter::PLLSettings> IntelNativeGraphicsAdapter::cr
}
IntelNativeGraphicsAdapter::IntelNativeGraphicsAdapter(PCI::Address address)
: VGACompatibleAdapter(address)
: PCIVGACompatibleAdapter(address)
, m_registers(PCI::get_BAR0(address) & 0xfffffffc)
, m_framebuffer_addr(PCI::get_BAR2(address) & 0xfffffffc)
{

View file

@ -10,7 +10,7 @@
#include <Kernel/Bus/PCI/Device.h>
#include <Kernel/Graphics/Definitions.h>
#include <Kernel/Graphics/FramebufferDevice.h>
#include <Kernel/Graphics/VGACompatibleAdapter.h>
#include <Kernel/Graphics/VGA/PCIAdapter.h>
#include <Kernel/PhysicalAddress.h>
#include <LibEDID/EDID.h>
@ -47,7 +47,7 @@ enum RegisterIndex {
}
class IntelNativeGraphicsAdapter final
: public VGACompatibleAdapter {
: public PCIVGACompatibleAdapter {
public:
struct PLLSettings {
bool is_valid() const { return (n != 0 && m1 != 0 && m2 != 0 && p1 != 0 && p2 != 0); }

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/Graphics/Console/ContiguousFramebufferConsole.h>
#include <Kernel/Graphics/Console/TextModeConsole.h>
#include <Kernel/Graphics/GraphicsManagement.h>
#include <Kernel/Graphics/VGA/ISAAdapter.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT NonnullRefPtr<ISAVGAAdapter> ISAVGAAdapter::initialize()
{
return adopt_ref(*new ISAVGAAdapter());
}
UNMAP_AFTER_INIT ISAVGAAdapter::ISAVGAAdapter()
{
m_framebuffer_console = Graphics::TextModeConsole::initialize();
GraphicsManagement::the().set_console(*m_framebuffer_console);
}
void ISAVGAAdapter::enable_consoles()
{
VERIFY(m_framebuffer_console);
m_framebuffer_console->enable();
}
void ISAVGAAdapter::disable_consoles()
{
VERIFY(m_framebuffer_console);
m_framebuffer_console->disable();
}
void ISAVGAAdapter::initialize_framebuffer_devices()
{
}
bool ISAVGAAdapter::try_to_set_resolution(size_t, size_t, size_t)
{
return false;
}
bool ISAVGAAdapter::set_y_offset(size_t, size_t)
{
return false;
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/Bus/PCI/Device.h>
#include <Kernel/Graphics/Console/Console.h>
#include <Kernel/Graphics/FramebufferDevice.h>
#include <Kernel/Graphics/GenericGraphicsAdapter.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {
class ISAVGAAdapter final : public VGACompatibleAdapter {
friend class GraphicsManagement;
public:
static NonnullRefPtr<ISAVGAAdapter> initialize();
// Note: We simply don't support old VGA framebuffer modes (like the 320x200 256-colors one)
virtual bool framebuffer_devices_initialized() const override { return false; }
virtual bool try_to_set_resolution(size_t output_port_index, size_t width, size_t height) override;
virtual bool set_y_offset(size_t output_port_index, size_t y) override;
private:
ISAVGAAdapter();
// ^GenericGraphicsAdapter
virtual void initialize_framebuffer_devices() override;
virtual void enable_consoles() override;
virtual void disable_consoles() override;
RefPtr<Graphics::Console> m_framebuffer_console;
};
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -7,22 +7,22 @@
#include <Kernel/Graphics/Console/ContiguousFramebufferConsole.h>
#include <Kernel/Graphics/Console/TextModeConsole.h>
#include <Kernel/Graphics/GraphicsManagement.h>
#include <Kernel/Graphics/VGACompatibleAdapter.h>
#include <Kernel/Graphics/VGA/PCIAdapter.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT NonnullRefPtr<VGACompatibleAdapter> VGACompatibleAdapter::initialize_with_preset_resolution(PCI::DeviceIdentifier const& pci_device_identifier, PhysicalAddress m_framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch)
UNMAP_AFTER_INIT NonnullRefPtr<PCIVGACompatibleAdapter> PCIVGACompatibleAdapter::initialize_with_preset_resolution(PCI::DeviceIdentifier const& pci_device_identifier, PhysicalAddress m_framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch)
{
return adopt_ref(*new VGACompatibleAdapter(pci_device_identifier.address(), m_framebuffer_address, framebuffer_width, framebuffer_height, framebuffer_pitch));
return adopt_ref(*new PCIVGACompatibleAdapter(pci_device_identifier.address(), m_framebuffer_address, framebuffer_width, framebuffer_height, framebuffer_pitch));
}
UNMAP_AFTER_INIT NonnullRefPtr<VGACompatibleAdapter> VGACompatibleAdapter::initialize(PCI::DeviceIdentifier const& pci_device_identifier)
UNMAP_AFTER_INIT NonnullRefPtr<PCIVGACompatibleAdapter> PCIVGACompatibleAdapter::initialize(PCI::DeviceIdentifier const& pci_device_identifier)
{
return adopt_ref(*new VGACompatibleAdapter(pci_device_identifier.address()));
return adopt_ref(*new PCIVGACompatibleAdapter(pci_device_identifier.address()));
}
UNMAP_AFTER_INIT void VGACompatibleAdapter::initialize_framebuffer_devices()
UNMAP_AFTER_INIT void PCIVGACompatibleAdapter::initialize_framebuffer_devices()
{
// We might not have any pre-set framebuffer, so if that's the case - don't try to initialize one.
if (m_framebuffer_address.is_null())
@ -36,14 +36,14 @@ UNMAP_AFTER_INIT void VGACompatibleAdapter::initialize_framebuffer_devices()
VERIFY(!m_framebuffer_device->try_to_initialize().is_error());
}
UNMAP_AFTER_INIT VGACompatibleAdapter::VGACompatibleAdapter(PCI::Address address)
UNMAP_AFTER_INIT PCIVGACompatibleAdapter::PCIVGACompatibleAdapter(PCI::Address address)
: PCI::Device(address)
{
m_framebuffer_console = Graphics::TextModeConsole::initialize();
GraphicsManagement::the().set_console(*m_framebuffer_console);
}
UNMAP_AFTER_INIT VGACompatibleAdapter::VGACompatibleAdapter(PCI::Address address, PhysicalAddress framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch)
UNMAP_AFTER_INIT PCIVGACompatibleAdapter::PCIVGACompatibleAdapter(PCI::Address address, PhysicalAddress framebuffer_address, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch)
: PCI::Device(address)
, m_framebuffer_address(framebuffer_address)
, m_framebuffer_width(framebuffer_width)
@ -54,14 +54,14 @@ UNMAP_AFTER_INIT VGACompatibleAdapter::VGACompatibleAdapter(PCI::Address address
GraphicsManagement::the().set_console(*m_framebuffer_console);
}
void VGACompatibleAdapter::enable_consoles()
void PCIVGACompatibleAdapter::enable_consoles()
{
VERIFY(m_framebuffer_console);
if (m_framebuffer_device)
m_framebuffer_device->deactivate_writes();
m_framebuffer_console->enable();
}
void VGACompatibleAdapter::disable_consoles()
void PCIVGACompatibleAdapter::disable_consoles()
{
VERIFY(m_framebuffer_device);
VERIFY(m_framebuffer_console);
@ -69,18 +69,4 @@ void VGACompatibleAdapter::disable_consoles()
m_framebuffer_device->activate_writes();
}
bool VGACompatibleAdapter::try_to_set_resolution(size_t, size_t, size_t)
{
return false;
}
bool VGACompatibleAdapter::set_y_offset(size_t, size_t)
{
return false;
}
ErrorOr<ByteBuffer> VGACompatibleAdapter::get_edid(size_t) const
{
return Error::from_errno(ENOTSUP);
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/Bus/PCI/Device.h>
#include <Kernel/Graphics/Console/Console.h>
#include <Kernel/Graphics/FramebufferDevice.h>
#include <Kernel/Graphics/GenericGraphicsAdapter.h>
#include <Kernel/PhysicalAddress.h>
namespace Kernel {
class PCIVGACompatibleAdapter : public VGACompatibleAdapter
, public PCI::Device {
public:
static NonnullRefPtr<PCIVGACompatibleAdapter> initialize_with_preset_resolution(PCI::DeviceIdentifier const&, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch);
static NonnullRefPtr<PCIVGACompatibleAdapter> initialize(PCI::DeviceIdentifier const&);
virtual bool framebuffer_devices_initialized() const override { return !m_framebuffer_device.is_null(); }
protected:
explicit PCIVGACompatibleAdapter(PCI::Address);
private:
PCIVGACompatibleAdapter(PCI::Address, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch);
// ^GenericGraphicsAdapter
virtual void initialize_framebuffer_devices() override;
virtual void enable_consoles() override;
virtual void disable_consoles() override;
protected:
PhysicalAddress m_framebuffer_address;
size_t m_framebuffer_width { 0 };
size_t m_framebuffer_height { 0 };
size_t m_framebuffer_pitch { 0 };
RefPtr<FramebufferDevice> m_framebuffer_device;
};
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
* Copyright (c) 2021-2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -15,43 +15,21 @@
namespace Kernel {
class VGACompatibleAdapter : public GenericGraphicsAdapter
, public PCI::Device {
class VGACompatibleAdapter : public GenericGraphicsAdapter {
public:
static NonnullRefPtr<VGACompatibleAdapter> initialize_with_preset_resolution(PCI::DeviceIdentifier const&, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch);
static NonnullRefPtr<VGACompatibleAdapter> initialize(PCI::DeviceIdentifier const&);
virtual bool framebuffer_devices_initialized() const override { return !m_framebuffer_device.is_null(); }
virtual bool modesetting_capable() const override { return false; }
virtual bool double_framebuffering_capable() const override { return false; }
virtual bool vga_compatible() const override final { return true; }
virtual bool try_to_set_resolution(size_t output_port_index, size_t width, size_t height) override;
virtual bool set_y_offset(size_t output_port_index, size_t y) override;
virtual bool try_to_set_resolution(size_t, size_t, size_t) override { return false; }
virtual bool set_y_offset(size_t, size_t) override { return false; }
ErrorOr<ByteBuffer> get_edid(size_t output_port_index) const override;
ErrorOr<ByteBuffer> get_edid(size_t) const override { return Error::from_errno(ENOTSUP); }
protected:
explicit VGACompatibleAdapter(PCI::Address);
VGACompatibleAdapter() = default;
private:
VGACompatibleAdapter(PCI::Address, PhysicalAddress, size_t framebuffer_width, size_t framebuffer_height, size_t framebuffer_pitch);
// ^GenericGraphicsAdapter
virtual void initialize_framebuffer_devices() override;
virtual void enable_consoles() override;
virtual void disable_consoles() override;
protected:
PhysicalAddress m_framebuffer_address;
size_t m_framebuffer_width { 0 };
size_t m_framebuffer_height { 0 };
size_t m_framebuffer_pitch { 0 };
RefPtr<FramebufferDevice> m_framebuffer_device;
RefPtr<Graphics::Console> m_framebuffer_console;
};
}