ConsoleDevice.cpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Singleton.h>
  7. #include <Kernel/ConsoleDevice.h>
  8. #include <Kernel/IO.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 Singleton<ConsoleDevice> s_the;
  15. static Kernel::Spinlock g_console_lock;
  16. UNMAP_AFTER_INIT void ConsoleDevice::initialize()
  17. {
  18. s_the.ensure_instance();
  19. }
  20. ConsoleDevice& ConsoleDevice::the()
  21. {
  22. return *s_the;
  23. }
  24. bool ConsoleDevice::is_initialized()
  25. {
  26. return s_the.is_initialized();
  27. }
  28. UNMAP_AFTER_INIT ConsoleDevice::ConsoleDevice()
  29. : CharacterDevice(5, 1)
  30. {
  31. }
  32. UNMAP_AFTER_INIT ConsoleDevice::~ConsoleDevice()
  33. {
  34. }
  35. bool ConsoleDevice::can_read(const Kernel::FileDescription&, size_t) const
  36. {
  37. return false;
  38. }
  39. Kernel::KResultOr<size_t> ConsoleDevice::read(FileDescription&, u64, Kernel::UserOrKernelBuffer&, size_t)
  40. {
  41. // FIXME: Implement reading from the console.
  42. // Maybe we could use a ring buffer for this device?
  43. return 0;
  44. }
  45. Kernel::KResultOr<size_t> ConsoleDevice::write(FileDescription&, u64, const Kernel::UserOrKernelBuffer& data, size_t size)
  46. {
  47. if (!size)
  48. return 0;
  49. return data.read_buffered<256>(size, [&](u8 const* bytes, size_t bytes_count) {
  50. for (size_t i = 0; i < bytes_count; i++)
  51. put_char((char)bytes[i]);
  52. return bytes_count;
  53. });
  54. }
  55. void ConsoleDevice::put_char(char ch)
  56. {
  57. Kernel::SpinlockLocker lock(g_console_lock);
  58. #ifdef CONSOLE_OUT_TO_BOCHS_DEBUG_PORT
  59. IO::out8(IO::BOCHS_DEBUG_PORT, ch);
  60. #endif
  61. m_logbuffer.enqueue(ch);
  62. }