ConsoleDevice.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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/SpinLock.h>
  10. #include <Kernel/kstdio.h>
  11. // Output bytes to kernel debug port 0xE9 (Bochs console). It's very handy.
  12. #define CONSOLE_OUT_TO_BOCHS_DEBUG_PORT
  13. static AK::Singleton<ConsoleDevice> s_the;
  14. static Kernel::SpinLock g_console_lock;
  15. UNMAP_AFTER_INIT void ConsoleDevice::initialize()
  16. {
  17. s_the.ensure_instance();
  18. }
  19. ConsoleDevice& ConsoleDevice::the()
  20. {
  21. return *s_the;
  22. }
  23. bool ConsoleDevice::is_initialized()
  24. {
  25. return s_the.is_initialized();
  26. }
  27. UNMAP_AFTER_INIT ConsoleDevice::ConsoleDevice()
  28. : CharacterDevice(5, 1)
  29. {
  30. }
  31. UNMAP_AFTER_INIT ConsoleDevice::~ConsoleDevice()
  32. {
  33. }
  34. bool ConsoleDevice::can_read(const Kernel::FileDescription&, size_t) const
  35. {
  36. return false;
  37. }
  38. Kernel::KResultOr<size_t> ConsoleDevice::read(FileDescription&, u64, Kernel::UserOrKernelBuffer&, size_t)
  39. {
  40. // FIXME: Implement reading from the console.
  41. // Maybe we could use a ring buffer for this device?
  42. return 0;
  43. }
  44. Kernel::KResultOr<size_t> ConsoleDevice::write(FileDescription&, u64, const Kernel::UserOrKernelBuffer& data, size_t size)
  45. {
  46. if (!size)
  47. return 0;
  48. return data.read_buffered<256>(size, [&](u8 const* bytes, size_t bytes_count) {
  49. for (size_t i = 0; i < bytes_count; i++)
  50. put_char((char)bytes[i]);
  51. return bytes_count;
  52. });
  53. }
  54. void ConsoleDevice::put_char(char ch)
  55. {
  56. Kernel::ScopedSpinLock lock(g_console_lock);
  57. #ifdef CONSOLE_OUT_TO_BOCHS_DEBUG_PORT
  58. IO::out8(IO::BOCHS_DEBUG_PORT, ch);
  59. #endif
  60. m_logbuffer.enqueue(ch);
  61. }