1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:07:34 +00:00

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
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;
}
@ -199,11 +211,21 @@ UNMAP_AFTER_INIT bool GraphicsManagement::initialize()
* 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;
};
}