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>
16 #include <internal/string.h>
17 #include <internal/mmhal.h>
18 #include <internal/halio.h>
20 //#define BOCHS_DEBUGGING 1
21 //#define SERIAL_DEBUGGING
22 #define SERIAL_PORT 0x03f8
23 #define SERIAL_BAUD_RATE 19200
24 #define SERIAL_LINE_CONTROL (SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO)
27 #include <internal/debug.h>
29 /* GLOBALS ******************************************************************/
31 #define IDMAP_BASE (0xd0000000)
34 * Return a linear address which can be used to access the physical memory
37 extern inline unsigned int physical_to_linear(unsigned int x
)
42 extern inline unsigned int linear_to_physical(unsigned int x
)
48 #ifdef BOCHS_DEBUGGING
49 #define BOCHS_LOGGER_PORT (0x3ed)
52 #ifdef SERIAL_DEBUGGING
53 #define SER_RBR SERIAL_PORT + 0
54 #define SER_THR SERIAL_PORT + 0
55 #define SER_DLL SERIAL_PORT + 0
56 #define SER_IER SERIAL_PORT + 1
57 #define SER_DLM SERIAL_PORT + 1
58 #define SER_IIR SERIAL_PORT + 2
59 #define SER_LCR SERIAL_PORT + 3
60 #define SR_LCR_CS5 0x00
61 #define SR_LCR_CS6 0x01
62 #define SR_LCR_CS7 0x02
63 #define SR_LCR_CS8 0x03
64 #define SR_LCR_ST1 0x00
65 #define SR_LCR_ST2 0x04
66 #define SR_LCR_PNO 0x00
67 #define SR_LCR_POD 0x08
68 #define SR_LCR_PEV 0x18
69 #define SR_LCR_PMK 0x28
70 #define SR_LCR_PSP 0x38
71 #define SR_LCR_BRK 0x40
72 #define SR_LCR_DLAB 0x80
73 #define SER_MCR SERIAL_PORT + 4
74 #define SR_MCR_DTR 0x01
75 #define SR_MCR_RTS 0x02
76 #define SER_LSR SERIAL_PORT + 5
77 #define SR_LSR_TBE 0x20
78 #define SER_MSR SERIAL_PORT + 6
82 * PURPOSE: Current cursor position
84 static unsigned int cursorx
=0, cursory
=0;
85 static unsigned int lines_seen
= 0;
86 static unsigned char CharAttribute
= 0x17;
91 #define VIDMEM_BASE 0xb8000
94 * PURPOSE: Points to the base of text mode video memory
96 static char* vidmem
= (char *)(VIDMEM_BASE
+ IDMAP_BASE
);
98 #define CRTC_COMMAND 0x3d4
99 #define CRTC_DATA 0x3d5
100 #define CRTC_CURLO 0x0f
101 #define CRTC_CURHI 0x0e
104 * PURPOSE: This flag is set to true if the system is in HAL managed
105 * console mode. This is initially true then once the graphics drivers
106 * initialize, it is turned off, HAL console mode is reentered if a fatal
107 * error occurs or on system shutdown
109 static unsigned int in_hal_console
= 1;
111 /* FUNCTIONS ***************************************************************/
114 void HalSwitchToBlueScreen(void)
116 * FUNCTION: Switches the monitor to text mode and writes a blue background
117 * NOTE: This function is entirely self contained and can be used from any
130 * Reset the cursor position
135 outb_p(CRTC_COMMAND
, CRTC_CURLO
);
136 outb_p(CRTC_DATA
, 0);
137 outb_p(CRTC_COMMAND
, CRTC_CURHI
);
138 outb_p(CRTC_DATA
, 0);
141 * This code section is taken from the sample routines by
142 * Jeff Morgan (kinfira@hotmail.com)
148 NTSTATUS STDCALL
NtDisplayString(IN PUNICODE_STRING DisplayString
)
150 // DbgPrint("NtDisplayString(%w)\n",DisplayString->Buffer);
151 DbgPrint("%w",DisplayString
->Buffer
);
152 return(STATUS_SUCCESS
);
155 void HalDisplayString(char* string
)
157 * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
158 * already and displays a string
160 * string = ASCII string to display
161 * NOTE: Use with care because there is no support for returning from BSOD
167 HalSwitchToBlueScreen();
172 void __putchar(char c
)
174 * FUNCTION: Writes a character to the console and updates the cursor position
176 * c = the character to write
177 * NOTE: This function handles newlines as well
183 #ifdef BOCHS_DEBUGGING
184 outb_p(BOCHS_LOGGER_PORT
,c
);
187 #ifdef SERIAL_DEBUGGING
188 while ((inb_p(SER_LSR
) & SR_LSR_TBE
) == 0)
193 outb_p(CRTC_COMMAND
, CRTC_CURHI
);
194 offset
= inb_p(CRTC_DATA
)<<8;
195 outb_p(CRTC_COMMAND
, CRTC_CURLO
);
196 offset
+= inb_p(CRTC_DATA
);
198 cursory
= offset
/ NR_COLUMNS
;
199 cursorx
= offset
% NR_COLUMNS
;
210 vidmem
[(cursorx
* 2) + (cursory
* 80 * 2)] = c
;
211 vidmem
[(cursorx
* 2) + (cursory
* 80 * 2) + 1] = CharAttribute
;
213 if (cursorx
>= NR_COLUMNS
)
222 if (lines_seen
== 24)
224 char str
[] = "--- press escape to continue";
227 for (i
= 0; str
[i
] != 0; i
++)
229 vidmem
[NR_COLUMNS
*(NR_ROWS
-1)*2+i
*2] = str
[i
];
230 vidmem
[NR_COLUMNS
*(NR_ROWS
-1)*2+i
*2+1] = CharAttribute
;
233 while (inb_p(0x60)!=0x81);
234 memset(&vidmem
[NR_COLUMNS
*(NR_ROWS
-1)*2],0,NR_COLUMNS
*2);
238 if (cursory
>= NR_ROWS
)
240 unsigned short *LinePtr
;
243 &vidmem
[NR_COLUMNS
* 2],
244 NR_COLUMNS
* (NR_ROWS
- 1) * 2);
245 LinePtr
= (unsigned short *) &vidmem
[NR_COLUMNS
* (NR_ROWS
- 1) * 2];
246 for (i
= 0; i
< NR_COLUMNS
; i
++)
248 LinePtr
[i
] = CharAttribute
<< 8;
250 cursory
= NR_ROWS
- 1;
254 * Set the cursor position
257 offset
= (cursory
* NR_COLUMNS
) + cursorx
;
259 outb_p(CRTC_COMMAND
, CRTC_CURLO
);
260 outb_p(CRTC_DATA
, offset
);
261 outb_p(CRTC_COMMAND
, CRTC_CURHI
);
263 outb_p(CRTC_DATA
, offset
);
266 asmlinkage
void printk(const char* fmt
, ...)
268 * FUNCTION: Print a formatted string to the hal console
269 * ARGUMENTS: As for printf
270 * NOTE: So it can used from irq handlers this function disables interrupts
271 * during its execution, they are restored to the previous state on return
280 * Because this is used by alomost every subsystem including irqs it
281 * must be atomic. The following code sequence disables interrupts after
282 * saving the previous state of the interrupt flag
284 __asm__("pushf\n\tpop %0\n\tcli\n\t"
289 * Process the format string into a fixed length buffer using the
290 * standard C RTL function
293 vsprintf(buffer
,fmt
,ap
);
303 * Restore the interrupt flag
305 __asm__("push %0\n\tpopf\n\t"
311 ULONG
DbgPrint(PCH Format
, ...)
319 * Because this is used by alomost every subsystem including irqs it
320 * must be atomic. The following code sequence disables interrupts after
321 * saving the previous state of the interrupt flag
323 __asm__("pushf\n\tpop %0\n\tcli\n\t"
328 * Process the format string into a fixed length buffer using the
329 * standard C RTL function
332 vsprintf(buffer
,Format
,ap
);
342 * Restore the interrupt flag
344 __asm__("push %0\n\tpopf\n\t"
347 return(strlen(buffer
));
350 void HalInitConsole(boot_param
* bp
)
352 * FUNCTION: Initalize the console
354 * bp = Parameters setup by the boot loader
358 #ifdef SERIAL_DEBUGGING
359 /* turn on DTR and RTS */
360 outb_p(SER_MCR
, SR_MCR_DTR
| SR_MCR_RTS
);
361 /* set baud rate, line control */
362 outb_p(SER_LCR
, SERIAL_LINE_CONTROL
| SR_LCR_DLAB
);
363 outb_p(SER_DLL
, (115200 / SERIAL_BAUD_RATE
) & 0xff);
364 outb_p(SER_DLM
, ((115200 / SERIAL_BAUD_RATE
) >> 8) & 0xff);
365 outb_p(SER_LCR
, SERIAL_LINE_CONTROL
);
368 /* Set cursor position */
374 offset
= (cursory
* NR_COLUMNS
) + cursorx
;
375 outb_p(CRTC_COMMAND
, CRTC_CURLO
);
376 outb_p(CRTC_DATA
, offset
);
377 outb_p(CRTC_COMMAND
, CRTC_CURHI
);
379 outb_p(CRTC_DATA
, offset
);