summaryrefslogtreecommitdiff
path: root/Kernel/Arch/x86/VGA/IOArbiter.cpp
blob: cf558150cea42b4cc8d0ae1799458c329636b48a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
 * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <AK/Try.h>
#include <Kernel/Arch/CPU.h>
#include <Kernel/Arch/Delay.h>
#include <Kernel/Arch/x86/IO.h>
#include <Kernel/Arch/x86/VGA/IOArbiter.h>

namespace Kernel {

NonnullOwnPtr<VGAIOArbiter> VGAIOArbiter::must_create(Badge<GraphicsManagement>)
{
    return MUST(adopt_nonnull_own_or_enomem(new (nothrow) VGAIOArbiter()));
}

VGAIOArbiter::~VGAIOArbiter() = default;
VGAIOArbiter::VGAIOArbiter() = default;

void VGAIOArbiter::disable_vga_emulation_access_permanently(Badge<GraphicsManagement>)
{
    SpinlockLocker locker(m_main_vga_lock);
    disable_vga_text_mode_console_cursor();
    IO::out8(0x3c4, 1);
    u8 sr1 = IO::in8(0x3c5);
    IO::out8(0x3c5, sr1 | 1 << 5);
    microseconds_delay(1000);
    m_vga_access_is_disabled = true;
}

void VGAIOArbiter::enable_vga_text_mode_console_cursor(Badge<GraphicsManagement>)
{
    enable_vga_text_mode_console_cursor();
}

void VGAIOArbiter::enable_vga_text_mode_console_cursor()
{
    SpinlockLocker locker(m_main_vga_lock);
    if (m_vga_access_is_disabled)
        return;
    IO::out8(0x3D4, 0xA);
    IO::out8(0x3D5, 0);
}

void VGAIOArbiter::disable_vga_text_mode_console_cursor(Badge<GraphicsManagement>)
{
    disable_vga_text_mode_console_cursor();
}

void VGAIOArbiter::disable_vga_text_mode_console_cursor()
{
    SpinlockLocker locker(m_main_vga_lock);
    if (m_vga_access_is_disabled)
        return;
    IO::out8(0x3D4, 0xA);
    IO::out8(0x3D5, 0x20);
}

void VGAIOArbiter::unblank_screen(Badge<GraphicsManagement>)
{
    SpinlockLocker locker(m_main_vga_lock);
    if (m_vga_access_is_disabled)
        return;
    IO::out8(0x3c0, 0x20);
}

void VGAIOArbiter::set_vga_text_mode_cursor(Badge<GraphicsManagement>, size_t console_width, size_t x, size_t y)
{
    SpinlockLocker locker(m_main_vga_lock);
    if (m_vga_access_is_disabled)
        return;
    enable_vga_text_mode_console_cursor();
    u16 value = y * console_width + x;
    IO::out8(0x3d4, 0x0e);
    IO::out8(0x3d5, MSB(value));
    IO::out8(0x3d4, 0x0f);
    IO::out8(0x3d5, LSB(value));
}

}