Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/Platform.h>
8#if ARCH(X86_64)
9# include <Kernel/Arch/x86_64/BochsDebugOutput.h>
10#endif
11#include <Kernel/Devices/ConsoleDevice.h>
12#include <Kernel/Devices/DeviceManagement.h>
13#include <Kernel/Locking/Spinlock.h>
14#include <Kernel/Sections.h>
15#include <Kernel/kstdio.h>
16
17namespace Kernel {
18
19Spinlock<LockRank::None> g_console_lock {};
20
21UNMAP_AFTER_INIT NonnullLockRefPtr<ConsoleDevice> ConsoleDevice::must_create()
22{
23 auto device_or_error = DeviceManagement::try_create_device<ConsoleDevice>();
24 VERIFY(!device_or_error.is_error());
25 return device_or_error.release_value();
26}
27
28UNMAP_AFTER_INIT ConsoleDevice::ConsoleDevice()
29 : CharacterDevice(5, 1)
30{
31}
32
33UNMAP_AFTER_INIT ConsoleDevice::~ConsoleDevice() = default;
34
35bool ConsoleDevice::can_read(Kernel::OpenFileDescription const&, u64) const
36{
37 return false;
38}
39
40ErrorOr<size_t> ConsoleDevice::read(OpenFileDescription&, u64, Kernel::UserOrKernelBuffer&, size_t)
41{
42 // FIXME: Implement reading from the console.
43 // Maybe we could use a ring buffer for this device?
44 return 0;
45}
46
47ErrorOr<size_t> ConsoleDevice::write(OpenFileDescription&, u64, Kernel::UserOrKernelBuffer const& data, size_t size)
48{
49 if (!size)
50 return 0;
51
52 return data.read_buffered<256>(size, [&](ReadonlyBytes readonly_bytes) {
53 for (const auto& byte : readonly_bytes)
54 put_char(byte);
55 return readonly_bytes.size();
56 });
57}
58
59void ConsoleDevice::put_char(char ch)
60{
61 Kernel::SpinlockLocker lock(g_console_lock);
62 dbgputchar(ch);
63 m_logbuffer.enqueue(ch);
64}
65
66}