reactos/reactos/ntoskrnl/hal/x86/printk.c
Rex Jolliff 82d21c903e Changed include/hal/io.h to halio.h with i386/io.h
svn path=/trunk/; revision=106
1998-11-29 19:39:40 +00:00

350 lines
8.1 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/printk.c
* PURPOSE: Writing to the console
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* ??/??/??: Created
* 05/06/98: Implemented BSOD
*/
/* INCLUDES *****************************************************************/
#include <internal/ntoskrnl.h>
#include <internal/string.h>
#include <internal/mmhal.h>
#include <internal/halio.h>
//#define BOCHS_DEBUGGING 1
//#define SERIAL_DEBUGGING
#define SERIAL_PORT 0x03f8
#define SERIAL_BAUD_RATE 19200
#define SERIAL_LINE_CONTROL (SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO)
//#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
#ifdef BOCHS_DEBUGGING
#define BOCHS_LOGGER_PORT (0x3ed)
#endif
#ifdef SERIAL_DEBUGGING
#define SER_RBR SERIAL_PORT + 0
#define SER_THR SERIAL_PORT + 0
#define SER_DLL SERIAL_PORT + 0
#define SER_IER SERIAL_PORT + 1
#define SER_DLM SERIAL_PORT + 1
#define SER_IIR SERIAL_PORT + 2
#define SER_LCR SERIAL_PORT + 3
#define SR_LCR_CS5 0x00
#define SR_LCR_CS6 0x01
#define SR_LCR_CS7 0x02
#define SR_LCR_CS8 0x03
#define SR_LCR_ST1 0x00
#define SR_LCR_ST2 0x04
#define SR_LCR_PNO 0x00
#define SR_LCR_POD 0x08
#define SR_LCR_PEV 0x18
#define SR_LCR_PMK 0x28
#define SR_LCR_PSP 0x38
#define SR_LCR_BRK 0x40
#define SR_LCR_DLAB 0x80
#define SER_MCR SERIAL_PORT + 4
#define SR_MCR_DTR 0x01
#define SR_MCR_RTS 0x02
#define SER_LSR SERIAL_PORT + 5
#define SR_LSR_TBE 0x20
#define SER_MSR SERIAL_PORT + 6
#endif
/*
* PURPOSE: Current cursor position
*/
static unsigned int cursorx=0, cursory=0;
static unsigned int lines_seen = 0;
#define NR_ROWS 25
#define NR_COLUMNS 80
#define VIDMEM_BASE 0xb8000
/*
* PURPOSE: Points to the base of text mode video memory
*/
static char* vidmem = (char *)(VIDMEM_BASE + IDMAP_BASE);
#define CRTC_COMMAND 0x3d4
#define CRTC_DATA 0x3d5
#define CRTC_CURLO 0x0f
#define CRTC_CURHI 0x0e
/*
* PURPOSE: This flag is set to true if the system is in HAL managed
* console mode. This is initially true then once the graphics drivers
* initialize, it is turned off, HAL console mode is reentered if a fatal
* error occurs or on system shutdown
*/
static unsigned int in_hal_console = 1;
/*
* PURPOSE: Defines the hal console video mode
*/
static unsigned char mode03[] = {0x67,0x00,0x03,0x00,0x03,0x00,0x02,
0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,
0x1f,0x00,0x4f,0x0e,0x0f,0x00,0x00,
0x00,0x00,0x9c,0x0e,0x8f,0x28,0x01,
0x96,0xb9,0xa3,0xff,0x00,0x00,0x00,
0x00,0x00,0x10,0x0e,0x00,0xff,0x00,
0x00,0x01,0x02,0x03,0x04,0x05,0x06,
0x07,0x10,0x11,0x12,0x13,0x14,0x15,
0x16,0x17,0x0c,0x00,0x0f,0x08,0x00};
/* FUNCTIONS ***************************************************************/
void HalSwitchToBlueScreen(void)
/*
* FUNCTION: Switches the monitor to text mode and writes a blue background
* NOTE: This function is entirely self contained and can be used from any
* graphics mode.
*/
{
/*
* Sanity check
*/
if (in_hal_console)
{
return;
}
/*
* Reset the cursor position
*/
cursorx=0;
cursory=0;
/*
* This code section is taken from the sample routines by
* Jeff Morgan (kinfira@hotmail.com)
*/
}
NTSTATUS STDCALL NtDisplayString(IN PUNICODE_STRING DisplayString)
{
// DbgPrint("DisplayString %x\n",DisplayString);
DbgPrint("%s",DisplayString);
return(STATUS_SUCCESS);
}
void HalDisplayString(char* string)
/*
* FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
* already and displays a string
* ARGUMENT:
* string = ASCII string to display
* NOTE: Use with care because there is no support for returning from BSOD
* mode
*/
{
if (!in_hal_console)
{
HalSwitchToBlueScreen();
}
printk("%s",string);
}
static void putchar(char c)
/*
* FUNCTION: Writes a character to the console and updates the cursor position
* ARGUMENTS:
* c = the character to write
* NOTE: This function handles newlines as well
*/
{
char* address;
int offset;
int i;
#ifdef BOCHS_DEBUGGING
outb_p(BOCHS_LOGGER_PORT,c);
#endif
#ifdef SERIAL_DEBUGGING
while ((inb_p(SER_LSR) & SR_LSR_TBE) == 0)
;
outb_p(SER_THR, c);
#endif
switch(c)
{
case '\n':
cursory++;
cursorx=0;
lines_seen++;
break;
default:
vidmem[(cursorx*2) + (cursory*80*2)]=c;
vidmem[(cursorx*2) + (cursory*80*2)+1]=0x7;
cursorx++;
if (cursorx>=NR_COLUMNS)
{
cursory++;
lines_seen++;
cursorx=0;
}
}
#if 0
if (lines_seen == 24)
{
char str[] = "--- press escape to continue";
lines_seen = 0;
for (i=0;str[i]!=0;i++)
{
vidmem[NR_COLUMNS*(NR_ROWS-1)*2+i*2]=str[i];
vidmem[NR_COLUMNS*(NR_ROWS-1)*2+i*2+1]=0x7;
}
while (inb_p(0x60)!=0x81);
memset(&vidmem[NR_COLUMNS*(NR_ROWS-1)*2],0,NR_COLUMNS*2);
}
#endif
if (cursory>=NR_ROWS)
{
memcpy(vidmem,&vidmem[NR_COLUMNS*2],
NR_COLUMNS*(NR_ROWS-1)*2);
memset(&vidmem[NR_COLUMNS*(NR_ROWS-1)*2],0,NR_COLUMNS*2);
cursory=NR_ROWS-1;
}
/*
* Set the cursor position
*/
offset=cursory*NR_COLUMNS;
offset=offset+cursorx;
outb_p(CRTC_COMMAND,CRTC_CURLO);
outb_p(CRTC_DATA,offset);
outb_p(CRTC_COMMAND,CRTC_CURHI);
offset>>=8;
outb_p(CRTC_DATA,offset);
}
asmlinkage void printk(const char* fmt, ...)
/*
* FUNCTION: Print a formatted string to the hal console
* ARGUMENTS: As for printf
* NOTE: So it can used from irq handlers this function disables interrupts
* during its execution, they are restored to the previous state on return
*/
{
char buffer[256];
char* str=buffer;
va_list ap;
unsigned int eflags;
/*
* Because this is used by alomost every subsystem including irqs it
* must be atomic. The following code sequence disables interrupts after
* saving the previous state of the interrupt flag
*/
__asm__("pushf\n\tpop %0\n\tcli\n\t"
: "=m" (eflags)
: /* */);
/*
* Process the format string into a fixed length buffer using the
* standard C RTL function
*/
va_start(ap,fmt);
vsprintf(buffer,fmt,ap);
va_end(ap);
while ((*str)!=0)
{
putchar(*str);
str++;
}
/*
* Restore the interrupt flag
*/
__asm__("push %0\n\tpopf\n\t"
:
: "m" (eflags));
}
int bad_user_access_length(void)
{
printk("Bad user access length\n");
}
ULONG DbgPrint(PCH Format, ...)
{
char buffer[256];
char* str=buffer;
va_list ap;
unsigned int eflags;
/*
* Because this is used by alomost every subsystem including irqs it
* must be atomic. The following code sequence disables interrupts after
* saving the previous state of the interrupt flag
*/
__asm__("pushf\n\tpop %0\n\tcli\n\t"
: "=m" (eflags)
: /* */);
/*
* Process the format string into a fixed length buffer using the
* standard C RTL function
*/
va_start(ap,Format);
vsprintf(buffer,Format,ap);
va_end(ap);
while ((*str)!=0)
{
putchar(*str);
str++;
}
/*
* Restore the interrupt flag
*/
__asm__("push %0\n\tpopf\n\t"
:
: "m" (eflags));
}
void HalInitConsole(boot_param* bp)
/*
* FUNCTION: Initalize the console
* ARGUMENTS:
* bp = Parameters setup by the boot loader
*/
{
#ifdef SERIAL_DEBUGGING
/* turn on DTR and RTS */
outb_p(SER_MCR, SR_MCR_DTR | SR_MCR_RTS);
/* set baud rate, line control */
outb_p(SER_LCR, SERIAL_LINE_CONTROL | SR_LCR_DLAB);
outb_p(SER_DLL, (115200 / SERIAL_BAUD_RATE) & 0xff);
outb_p(SER_DLM, ((115200 / SERIAL_BAUD_RATE) >> 8) & 0xff);
outb_p(SER_LCR, SERIAL_LINE_CONTROL);
#endif
cursorx=bp->cursorx;
cursory=bp->cursory;
}