2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/hal/x86/printk.c
5 * PURPOSE: Writing to the console
6 * PROGRAMMER: David Welch (welch@mcmail.com)
9 * 05/06/98: Implemented BSOD
12 /* INCLUDES *****************************************************************/
14 #include <internal/ntoskrnl.h>
15 #include <internal/string.h>
16 #include <internal/mmhal.h>
17 #include <internal/halio.h>
19 //#define BOCHS_DEBUGGING 1
20 //#define SERIAL_DEBUGGING
21 #define SERIAL_PORT 0x03f8
22 #define SERIAL_BAUD_RATE 19200
23 #define SERIAL_LINE_CONTROL (SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO)
26 #include <internal/debug.h>
28 /* GLOBALS ******************************************************************/
30 #ifdef BOCHS_DEBUGGING
31 #define BOCHS_LOGGER_PORT (0x3ed)
34 #ifdef SERIAL_DEBUGGING
35 #define SER_RBR SERIAL_PORT + 0
36 #define SER_THR SERIAL_PORT + 0
37 #define SER_DLL SERIAL_PORT + 0
38 #define SER_IER SERIAL_PORT + 1
39 #define SER_DLM SERIAL_PORT + 1
40 #define SER_IIR SERIAL_PORT + 2
41 #define SER_LCR SERIAL_PORT + 3
42 #define SR_LCR_CS5 0x00
43 #define SR_LCR_CS6 0x01
44 #define SR_LCR_CS7 0x02
45 #define SR_LCR_CS8 0x03
46 #define SR_LCR_ST1 0x00
47 #define SR_LCR_ST2 0x04
48 #define SR_LCR_PNO 0x00
49 #define SR_LCR_POD 0x08
50 #define SR_LCR_PEV 0x18
51 #define SR_LCR_PMK 0x28
52 #define SR_LCR_PSP 0x38
53 #define SR_LCR_BRK 0x40
54 #define SR_LCR_DLAB 0x80
55 #define SER_MCR SERIAL_PORT + 4
56 #define SR_MCR_DTR 0x01
57 #define SR_MCR_RTS 0x02
58 #define SER_LSR SERIAL_PORT + 5
59 #define SR_LSR_TBE 0x20
60 #define SER_MSR SERIAL_PORT + 6
64 * PURPOSE: Current cursor position
66 static unsigned int cursorx
=0, cursory
=0;
67 static unsigned int lines_seen
= 0;
68 static unsigned char CharAttribute
= 0x17;
73 #define VIDMEM_BASE 0xb8000
76 * PURPOSE: Points to the base of text mode video memory
78 static char* vidmem
= (char *)(VIDMEM_BASE
+ IDMAP_BASE
);
80 #define CRTC_COMMAND 0x3d4
81 #define CRTC_DATA 0x3d5
82 #define CRTC_CURLO 0x0f
83 #define CRTC_CURHI 0x0e
86 * PURPOSE: This flag is set to true if the system is in HAL managed
87 * console mode. This is initially true then once the graphics drivers
88 * initialize, it is turned off, HAL console mode is reentered if a fatal
89 * error occurs or on system shutdown
91 static unsigned int in_hal_console
= 1;
94 * PURPOSE: Defines the hal console video mode
96 static unsigned char mode03
[] = {0x67,0x00,0x03,0x00,0x03,0x00,0x02,
97 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,
98 0x1f,0x00,0x4f,0x0e,0x0f,0x00,0x00,
99 0x00,0x00,0x9c,0x0e,0x8f,0x28,0x01,
100 0x96,0xb9,0xa3,0xff,0x00,0x00,0x00,
101 0x00,0x00,0x10,0x0e,0x00,0xff,0x00,
102 0x00,0x01,0x02,0x03,0x04,0x05,0x06,
103 0x07,0x10,0x11,0x12,0x13,0x14,0x15,
104 0x16,0x17,0x0c,0x00,0x0f,0x08,0x00};
106 /* FUNCTIONS ***************************************************************/
109 void HalSwitchToBlueScreen(void)
111 * FUNCTION: Switches the monitor to text mode and writes a blue background
112 * NOTE: This function is entirely self contained and can be used from any
125 * Reset the cursor position
131 * This code section is taken from the sample routines by
132 * Jeff Morgan (kinfira@hotmail.com)
138 NTSTATUS STDCALL
NtDisplayString(IN PUNICODE_STRING DisplayString
)
140 // DbgPrint("DisplayString %x\n",DisplayString);
141 DbgPrint("%s",DisplayString
);
142 // DbgPrint("Returning from NtDisplayString()\n");
143 return(STATUS_SUCCESS
);
146 void HalDisplayString(char* string
)
148 * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
149 * already and displays a string
151 * string = ASCII string to display
152 * NOTE: Use with care because there is no support for returning from BSOD
158 HalSwitchToBlueScreen();
163 static void putchar(char c
)
165 * FUNCTION: Writes a character to the console and updates the cursor position
167 * c = the character to write
168 * NOTE: This function handles newlines as well
175 #ifdef BOCHS_DEBUGGING
176 outb_p(BOCHS_LOGGER_PORT
,c
);
179 #ifdef SERIAL_DEBUGGING
180 while ((inb_p(SER_LSR
) & SR_LSR_TBE
) == 0)
194 vidmem
[(cursorx
* 2) + (cursory
* 80 * 2)] = c
;
195 vidmem
[(cursorx
* 2) + (cursory
* 80 * 2) + 1] = CharAttribute
;
197 if (cursorx
>= NR_COLUMNS
)
206 if (lines_seen
== 24)
208 char str
[] = "--- press escape to continue";
211 for (i
= 0; str
[i
] != 0; i
++)
213 vidmem
[NR_COLUMNS
*(NR_ROWS
-1)*2+i
*2] = str
[i
];
214 vidmem
[NR_COLUMNS
*(NR_ROWS
-1)*2+i
*2+1] = CharAttribute
;
217 while (inb_p(0x60)!=0x81);
218 memset(&vidmem
[NR_COLUMNS
*(NR_ROWS
-1)*2],0,NR_COLUMNS
*2);
222 if (cursory
>= NR_ROWS
)
224 unsigned short *LinePtr
;
227 &vidmem
[NR_COLUMNS
* 2],
228 NR_COLUMNS
* (NR_ROWS
- 1) * 2);
229 LinePtr
= (unsigned short *) &vidmem
[NR_COLUMNS
* (NR_ROWS
- 1) * 2];
230 for (i
= 0; i
< NR_COLUMNS
; i
++)
232 LinePtr
[i
] = CharAttribute
<< 8;
234 cursory
= NR_ROWS
- 1;
238 * Set the cursor position
241 offset
= cursory
* NR_COLUMNS
;
242 offset
= offset
+ cursorx
;
244 outb_p(CRTC_COMMAND
, CRTC_CURLO
);
245 outb_p(CRTC_DATA
, offset
);
246 outb_p(CRTC_COMMAND
, CRTC_CURHI
);
248 outb_p(CRTC_DATA
, offset
);
252 asmlinkage
void printk(const char* fmt
, ...)
254 * FUNCTION: Print a formatted string to the hal console
255 * ARGUMENTS: As for printf
256 * NOTE: So it can used from irq handlers this function disables interrupts
257 * during its execution, they are restored to the previous state on return
266 * Because this is used by alomost every subsystem including irqs it
267 * must be atomic. The following code sequence disables interrupts after
268 * saving the previous state of the interrupt flag
270 __asm__("pushf\n\tpop %0\n\tcli\n\t"
275 * Process the format string into a fixed length buffer using the
276 * standard C RTL function
279 vsprintf(buffer
,fmt
,ap
);
289 * Restore the interrupt flag
291 __asm__("push %0\n\tpopf\n\t"
296 int bad_user_access_length(void)
298 printk("Bad user access length\n");
301 ULONG
DbgPrint(PCH Format
, ...)
309 * Because this is used by alomost every subsystem including irqs it
310 * must be atomic. The following code sequence disables interrupts after
311 * saving the previous state of the interrupt flag
313 __asm__("pushf\n\tpop %0\n\tcli\n\t"
318 * Process the format string into a fixed length buffer using the
319 * standard C RTL function
322 vsprintf(buffer
,Format
,ap
);
332 * Restore the interrupt flag
334 __asm__("push %0\n\tpopf\n\t"
339 void HalInitConsole(boot_param
* bp
)
341 * FUNCTION: Initalize the console
343 * bp = Parameters setup by the boot loader
347 #ifdef SERIAL_DEBUGGING
348 /* turn on DTR and RTS */
349 outb_p(SER_MCR
, SR_MCR_DTR
| SR_MCR_RTS
);
350 /* set baud rate, line control */
351 outb_p(SER_LCR
, SERIAL_LINE_CONTROL
| SR_LCR_DLAB
);
352 outb_p(SER_DLL
, (115200 / SERIAL_BAUD_RATE
) & 0xff);
353 outb_p(SER_DLM
, ((115200 / SERIAL_BAUD_RATE
) >> 8) & 0xff);
354 outb_p(SER_LCR
, SERIAL_LINE_CONTROL
);