ConsoleDevice.cpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Kernel/Arch/x86/IO.h>
  7. #include <Kernel/Devices/ConsoleDevice.h>
  8. #include <Kernel/Devices/DeviceManagement.h>
  9. #include <Kernel/Locking/Spinlock.h>
  10. #include <Kernel/Sections.h>
  11. #include <Kernel/kstdio.h>
  12. // Output bytes to kernel debug port 0xE9 (Bochs console). It's very handy.
  13. #define CONSOLE_OUT_TO_BOCHS_DEBUG_PORT
  14. static Kernel::Spinlock g_console_lock { LockRank::None };
  15. UNMAP_AFTER_INIT NonnullRefPtr<ConsoleDevice> ConsoleDevice::must_create()
  16. {
  17. auto device_or_error = DeviceManagement::try_create_device<ConsoleDevice>();
  18. VERIFY(!device_or_error.is_error());
  19. return device_or_error.release_value();
  20. }
  21. UNMAP_AFTER_INIT ConsoleDevice::ConsoleDevice()
  22. : CharacterDevice(5, 1)
  23. {
  24. }
  25. UNMAP_AFTER_INIT ConsoleDevice::~ConsoleDevice() = default;
  26. bool ConsoleDevice::can_read(Kernel::OpenFileDescription const&, u64) const
  27. {
  28. return false;
  29. }
  30. ErrorOr<size_t> ConsoleDevice::read(OpenFileDescription&, u64, Kernel::UserOrKernelBuffer&, size_t)
  31. {
  32. // FIXME: Implement reading from the console.
  33. // Maybe we could use a ring buffer for this device?
  34. return 0;
  35. }
  36. ErrorOr<size_t> ConsoleDevice::write(OpenFileDescription&, u64, Kernel::UserOrKernelBuffer const& data, size_t size)
  37. {
  38. if (!size)
  39. return 0;
  40. return data.read_buffered<256>(size, [&](ReadonlyBytes readonly_bytes) {
  41. for (const auto& byte : readonly_bytes)
  42. put_char(byte);
  43. return readonly_bytes.size();
  44. });
  45. }
  46. void ConsoleDevice::put_char(char ch)
  47. {
  48. Kernel::SpinlockLocker lock(g_console_lock);
  49. #ifdef CONSOLE_OUT_TO_BOCHS_DEBUG_PORT
  50. IO::out8(IO::BOCHS_DEBUG_PORT, ch);
  51. #endif
  52. m_logbuffer.enqueue(ch);
  53. }