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

Kernel/Graphics: Ensure VMWare and VirtualBox EDIDs have manufacturer ID

This commit is contained in:
Liav A 2022-06-10 22:33:07 +03:00 committed by Linus Groh
parent 3d36b194d1
commit 20c9e4c05c
7 changed files with 24 additions and 11 deletions

View file

@ -14,13 +14,16 @@
namespace Kernel { namespace Kernel {
NonnullRefPtr<BochsDisplayConnector> BochsDisplayConnector::must_create(PhysicalAddress framebuffer_address, size_t framebuffer_resource_size) NonnullRefPtr<BochsDisplayConnector> BochsDisplayConnector::must_create(PhysicalAddress framebuffer_address, size_t framebuffer_resource_size, bool virtual_box_hardware)
{ {
auto device_or_error = DeviceManagement::try_create_device<BochsDisplayConnector>(framebuffer_address, framebuffer_resource_size); auto device_or_error = DeviceManagement::try_create_device<BochsDisplayConnector>(framebuffer_address, framebuffer_resource_size);
VERIFY(!device_or_error.is_error()); VERIFY(!device_or_error.is_error());
auto connector = device_or_error.release_value(); auto connector = device_or_error.release_value();
MUST(connector->create_attached_framebuffer_console()); MUST(connector->create_attached_framebuffer_console());
MUST(connector->initialize_edid_for_generic_monitor()); if (virtual_box_hardware)
MUST(connector->initialize_edid_for_generic_monitor(Array<u8, 3> { 'V', 'B', 'X' }));
else
MUST(connector->initialize_edid_for_generic_monitor({}));
return connector; return connector;
} }

View file

@ -24,7 +24,7 @@ class BochsDisplayConnector
public: public:
TYPEDEF_DISTINCT_ORDERED_ID(u16, IndexID); TYPEDEF_DISTINCT_ORDERED_ID(u16, IndexID);
static NonnullRefPtr<BochsDisplayConnector> must_create(PhysicalAddress framebuffer_address, size_t framebuffer_resource_size); static NonnullRefPtr<BochsDisplayConnector> must_create(PhysicalAddress framebuffer_address, size_t framebuffer_resource_size, bool virtual_box_hardware);
virtual IndexID index_id() const; virtual IndexID index_id() const;

View file

@ -43,10 +43,10 @@ UNMAP_AFTER_INIT ErrorOr<void> BochsGraphicsAdapter::initialize_adapter(PCI::Dev
// Note: If we use VirtualBox graphics adapter (which is based on Bochs one), we need to use IO ports // Note: If we use VirtualBox graphics adapter (which is based on Bochs one), we need to use IO ports
// Note: Bochs (the real bochs graphics adapter in the Bochs emulator) uses revision ID of 0x0 // Note: Bochs (the real bochs graphics adapter in the Bochs emulator) uses revision ID of 0x0
// and doesn't support memory-mapped IO registers. // and doesn't support memory-mapped IO registers.
bool virtual_box_hardware = (pci_device_identifier.hardware_id().vendor_id == 0x80ee && pci_device_identifier.hardware_id().device_id == 0xbeef);
auto bar0_space_size = PCI::get_BAR_space_size(pci_device_identifier.address(), 0); auto bar0_space_size = PCI::get_BAR_space_size(pci_device_identifier.address(), 0);
if (pci_device_identifier.revision_id().value() == 0x0 if (pci_device_identifier.revision_id().value() == 0x0 || virtual_box_hardware) {
|| (pci_device_identifier.hardware_id().vendor_id == 0x80ee && pci_device_identifier.hardware_id().device_id == 0xbeef)) { m_display_connector = BochsDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), bar0_space_size, virtual_box_hardware);
m_display_connector = BochsDisplayConnector::must_create(PhysicalAddress(PCI::get_BAR0(pci_device_identifier.address()) & 0xfffffff0), bar0_space_size);
} else { } else {
auto registers_mapping = TRY(Memory::map_typed_writable<BochsDisplayMMIORegisters volatile>(PhysicalAddress(PCI::get_BAR2(pci_device_identifier.address()) & 0xfffffff0))); auto registers_mapping = TRY(Memory::map_typed_writable<BochsDisplayMMIORegisters volatile>(PhysicalAddress(PCI::get_BAR2(pci_device_identifier.address()) & 0xfffffff0)));
VERIFY(registers_mapping.region); VERIFY(registers_mapping.region);

View file

@ -112,11 +112,21 @@ void DisplayConnector::set_display_mode(Badge<GraphicsManagement>, DisplayMode m
} }
} }
ErrorOr<void> DisplayConnector::initialize_edid_for_generic_monitor() ErrorOr<void> DisplayConnector::initialize_edid_for_generic_monitor(Optional<Array<u8, 3>> possible_manufacturer_id_string)
{ {
u8 raw_manufacturer_id[2] = { 0x0, 0x0 };
if (possible_manufacturer_id_string.has_value()) {
Array<u8, 3> manufacturer_id_string = possible_manufacturer_id_string.release_value();
u8 byte1 = (((static_cast<u8>(manufacturer_id_string[0]) - '@') & 0x1f) << 2) | (((static_cast<u8>(manufacturer_id_string[1]) - '@') >> 3) & 3);
u8 byte2 = ((static_cast<u8>(manufacturer_id_string[2]) - '@') & 0x1f) | (((static_cast<u8>(manufacturer_id_string[1]) - '@') << 5) & 0xe0);
Array<u8, 2> manufacturer_id_string_packed_bytes = { byte1, byte2 };
raw_manufacturer_id[0] = manufacturer_id_string_packed_bytes[1];
raw_manufacturer_id[1] = manufacturer_id_string_packed_bytes[0];
}
Array<u8, 128> virtual_monitor_edid = { Array<u8, 128> virtual_monitor_edid = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
0x0, 0x0, /* manufacturer */ raw_manufacturer_id[1], raw_manufacturer_id[0], /* manufacturer */
0x00, 0x00, /* product code */ 0x00, 0x00, /* product code */
0x00, 0x00, 0x00, 0x00, /* serial number goes here */ 0x00, 0x00, 0x00, 0x00, /* serial number goes here */
0x01, /* week of manufacture */ 0x01, /* week of manufacture */

View file

@ -112,7 +112,7 @@ protected:
virtual ErrorOr<void> flush_first_surface() = 0; virtual ErrorOr<void> flush_first_surface() = 0;
virtual ErrorOr<void> flush_rectangle(size_t buffer_index, FBRect const& rect); virtual ErrorOr<void> flush_rectangle(size_t buffer_index, FBRect const& rect);
ErrorOr<void> initialize_edid_for_generic_monitor(); ErrorOr<void> initialize_edid_for_generic_monitor(Optional<Array<u8, 3>> manufacturer_id_string);
mutable Spinlock m_control_lock; mutable Spinlock m_control_lock;
mutable Mutex m_flushing_lock; mutable Mutex m_flushing_lock;

View file

@ -19,7 +19,7 @@ NonnullRefPtr<GenericDisplayConnector> GenericDisplayConnector::must_create_with
VERIFY(!device_or_error.is_error()); VERIFY(!device_or_error.is_error());
auto connector = device_or_error.release_value(); auto connector = device_or_error.release_value();
MUST(connector->create_attached_framebuffer_console()); MUST(connector->create_attached_framebuffer_console());
MUST(connector->initialize_edid_for_generic_monitor()); MUST(connector->initialize_edid_for_generic_monitor({}));
return connector; return connector;
} }

View file

@ -16,7 +16,7 @@ NonnullRefPtr<VMWareDisplayConnector> VMWareDisplayConnector::must_create(VMWare
{ {
auto connector = MUST(DeviceManagement::try_create_device<VMWareDisplayConnector>(parent_adapter, framebuffer_address, framebuffer_resource_size)); auto connector = MUST(DeviceManagement::try_create_device<VMWareDisplayConnector>(parent_adapter, framebuffer_address, framebuffer_resource_size));
MUST(connector->create_attached_framebuffer_console()); MUST(connector->create_attached_framebuffer_console());
MUST(connector->initialize_edid_for_generic_monitor()); MUST(connector->initialize_edid_for_generic_monitor(Array<u8, 3> { 'V', 'M', 'W' }));
return connector; return connector;
} }