kprintf.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <AK/PrintfImplementation.h>
  2. #include <AK/Types.h>
  3. #include <Kernel/Console.h>
  4. #include <Kernel/IO.h>
  5. #include <Kernel/Process.h>
  6. #include <Kernel/kstdio.h>
  7. #include <LibC/stdarg.h>
  8. static bool serial_debug;
  9. void set_serial_debug(bool on_or_off)
  10. {
  11. serial_debug = on_or_off;
  12. }
  13. int get_serial_debug()
  14. {
  15. return serial_debug;
  16. }
  17. static void color_on()
  18. {
  19. IO::out8(0xe9, 0x1b);
  20. IO::out8(0xe9, '[');
  21. IO::out8(0xe9, '3');
  22. IO::out8(0xe9, '6');
  23. IO::out8(0xe9, 'm');
  24. }
  25. static void color_off()
  26. {
  27. IO::out8(0xe9, 0x1b);
  28. IO::out8(0xe9, '[');
  29. IO::out8(0xe9, '0');
  30. IO::out8(0xe9, 'm');
  31. }
  32. static void serial_putch(char ch)
  33. {
  34. static bool serial_ready = false;
  35. static bool was_cr = false;
  36. if (!serial_ready) {
  37. IO::out8(0x3F8 + 1, 0x00);
  38. IO::out8(0x3F8 + 3, 0x80);
  39. IO::out8(0x3F8 + 0, 0x02);
  40. IO::out8(0x3F8 + 1, 0x00);
  41. IO::out8(0x3F8 + 3, 0x03);
  42. IO::out8(0x3F8 + 2, 0xC7);
  43. IO::out8(0x3F8 + 4, 0x0B);
  44. serial_ready = true;
  45. }
  46. while ((IO::in8(0x3F8 + 5) & 0x20) == 0)
  47. ;
  48. if (ch == '\n' && !was_cr)
  49. IO::out8(0x3F8, '\r');
  50. IO::out8(0x3F8, ch);
  51. if (ch == '\r')
  52. was_cr = true;
  53. else
  54. was_cr = false;
  55. }
  56. static void console_putch(char*&, char ch)
  57. {
  58. if (serial_debug)
  59. serial_putch(ch);
  60. // It would be bad to reach the assert in Console()::the() and do a stack overflow
  61. if (Console::is_initialized()) {
  62. Console::the().put_char(ch);
  63. } else {
  64. IO::out8(0xe9, ch);
  65. }
  66. }
  67. int kprintf(const char* fmt, ...)
  68. {
  69. color_on();
  70. va_list ap;
  71. va_start(ap, fmt);
  72. int ret = printf_internal(console_putch, nullptr, fmt, ap);
  73. va_end(ap);
  74. color_off();
  75. return ret;
  76. }
  77. static void buffer_putch(char*& bufptr, char ch)
  78. {
  79. *bufptr++ = ch;
  80. }
  81. int ksprintf(char* buffer, const char* fmt, ...)
  82. {
  83. va_list ap;
  84. va_start(ap, fmt);
  85. int ret = printf_internal(buffer_putch, buffer, fmt, ap);
  86. buffer[ret] = '\0';
  87. va_end(ap);
  88. return ret;
  89. }
  90. static void debugger_out(char ch)
  91. {
  92. if (serial_debug)
  93. serial_putch(ch);
  94. IO::out8(0xe9, ch);
  95. }
  96. static void debugger_putch(char*&, char ch)
  97. {
  98. debugger_out(ch);
  99. }
  100. extern "C" int dbgputstr(const char* characters, int length)
  101. {
  102. for (int i = 0; i < length; ++i)
  103. debugger_out(characters[i]);
  104. return 0;
  105. }
  106. extern "C" int dbgprintf(const char* fmt, ...)
  107. {
  108. color_on();
  109. va_list ap;
  110. va_start(ap, fmt);
  111. int ret = printf_internal(debugger_putch, nullptr, fmt, ap);
  112. va_end(ap);
  113. color_off();
  114. return ret;
  115. }