Console.cpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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/Console.h>
  8. #include <Kernel/IO.h>
  9. #include <Kernel/SpinLock.h>
  10. #include <Kernel/kstdio.h>
  11. // Bytes output to 0xE9 end up on the Bochs console. It's very handy.
  12. #define CONSOLE_OUT_TO_E9
  13. static AK::Singleton<Console> s_the;
  14. static Kernel::SpinLock g_console_lock;
  15. UNMAP_AFTER_INIT void Console::initialize()
  16. {
  17. s_the.ensure_instance();
  18. }
  19. Console& Console::the()
  20. {
  21. return *s_the;
  22. }
  23. bool Console::is_initialized()
  24. {
  25. return s_the.is_initialized();
  26. }
  27. UNMAP_AFTER_INIT Console::Console()
  28. : CharacterDevice(5, 1)
  29. {
  30. }
  31. UNMAP_AFTER_INIT Console::~Console()
  32. {
  33. }
  34. bool Console::can_read(const Kernel::FileDescription&, size_t) const
  35. {
  36. return false;
  37. }
  38. Kernel::KResultOr<size_t> Console::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> Console::write(FileDescription&, u64, const Kernel::UserOrKernelBuffer& data, size_t size)
  45. {
  46. if (!size)
  47. return 0;
  48. ssize_t nread = data.read_buffered<256>(size, [&](const u8* bytes, size_t bytes_count) {
  49. for (size_t i = 0; i < bytes_count; i++)
  50. put_char((char)bytes[i]);
  51. return (ssize_t)bytes_count;
  52. });
  53. if (nread < 0)
  54. return Kernel::KResult((ErrnoCode)-nread);
  55. return (size_t)nread;
  56. }
  57. void Console::put_char(char ch)
  58. {
  59. Kernel::ScopedSpinLock lock(g_console_lock);
  60. #ifdef CONSOLE_OUT_TO_E9
  61. //if (ch != 27)
  62. IO::out8(0xe9, ch);
  63. #endif
  64. m_logbuffer.enqueue(ch);
  65. }