diff --git a/common/include/minix/const.h b/common/include/minix/const.h index cdd13322b..137cc385b 100644 --- a/common/include/minix/const.h +++ b/common/include/minix/const.h @@ -158,6 +158,7 @@ #define INVAL_GID ((gid_t) -1) /* invalid gid value */ #define SERVARNAME "cttyline" +#define SERBAUDVARNAME "cttybaud" /* Bits for the system property flags in boot image processes. */ #define PROC_FULLVM 0x100 /* VM sets and manages full pagetable */ diff --git a/kernel/arch/i386/arch_system.c b/kernel/arch/i386/arch_system.c index 9cd9a6266..5148cd606 100644 --- a/kernel/arch/i386/arch_system.c +++ b/kernel/arch/i386/arch_system.c @@ -53,6 +53,9 @@ FORWARD _PROTOTYPE( void ser_debug, (int c)); #ifdef CONFIG_SMP FORWARD _PROTOTYPE( void ser_dump_proc_cpu, (void)); #endif +#if !CONFIG_OXPCIE +FORWARD _PROTOTYPE( void ser_init, (void)); +#endif PUBLIC __dead void arch_monitor(void) { @@ -371,6 +374,10 @@ PUBLIC void arch_init(void) tss_init(0, get_k_stack_top(0)); #endif +#if !CONFIG_OXPCIE + ser_init(); +#endif + acpi_init(); #if defined(CONFIG_APIC) && !defined(CONFIG_SMP) @@ -719,3 +726,30 @@ PUBLIC void fpu_sigcontext(struct proc *pr, struct sigframe *fr, struct sigconte * FPE_INTDIV */ } } + +#if !CONFIG_OXPCIE +PRIVATE void ser_init(void) +{ + unsigned char lcr; + unsigned divisor; + + /* keep BIOS settings if cttybaud is not set */ + if (serial_debug_baud <= 0) return; + + /* set DLAB to make baud accessible */ + lcr = LCR_8BIT | LCR_1STOP | LCR_NPAR; + outb(COM1_LCR, lcr | LCR_DLAB); + + /* set baud rate */ + divisor = UART_BASE_FREQ / serial_debug_baud; + if (divisor < 1) divisor = 1; + if (divisor > 65535) divisor = 65535; + + outb(COM1_DLL, divisor & 0xff); + outb(COM1_DLM, (divisor >> 8) & 0xff); + + /* clear DLAB */ + outb(COM1_LCR, lcr); +} +#endif + diff --git a/kernel/arch/i386/serial.h b/kernel/arch/i386/serial.h index 230fd8519..25957b6c4 100644 --- a/kernel/arch/i386/serial.h +++ b/kernel/arch/i386/serial.h @@ -2,19 +2,37 @@ #ifndef _KERN_SERIAL_H #define _KERN_SERIAL_H 1 -#define THRREG 0 -#define RBRREG 0 -#define FICRREG 2 -#define LSRREG 5 -#define LCRREG 3 +#define THRREG 0 /* transmitter holding, write-only, DLAB must be clear */ +#define RBRREG 0 /* receiver buffer, read-only, DLAB must be clear */ +#define DLLREG 0 /* divisor latch LSB, read/write, DLAB must be set */ +#define DLMREG 1 /* divisor latch MSB, read/write, DLAB must be set */ +#define FICRREG 2 /* FIFO control, write-only */ +#define LCRREG 3 /* line control, read/write */ +#define LSRREG 5 /* line status, read-only */ #define SPRREG 7 -#define COM1_BASE 0x3F8 -#define COM1_THR (COM1_BASE + THRREG) -#define COM1_RBR (COM1_BASE + RBRREG) -#define COM1_LSR (COM1_BASE + LSRREG) +#define COM1_BASE 0x3F8 +#define COM1_THR (COM1_BASE + THRREG) +#define COM1_RBR (COM1_BASE + RBRREG) +#define COM1_DLL (COM1_BASE + DLLREG) +#define COM1_DLM (COM1_BASE + DLMREG) +#define COM1_LCR (COM1_BASE + LCRREG) +#define LCR_5BIT 0x00 /* 5 bits per data word */ +#define LCR_6BIT 0x01 /* 6 bits per data word */ +#define LCR_7BIT 0x02 /* 7 bits per data word */ +#define LCR_8BIT 0x03 /* 8 bits per data word */ +#define LCR_1STOP 0x00 /* 1/1.5 stop bits */ +#define LCR_2STOP 0x04 /* 2 stop bits */ +#define LCR_NPAR 0x00 /* no parity */ +#define LCR_OPAR 0x08 /* odd parity */ +#define LCR_EPAR 0x18 /* even parity */ +#define LCR_BREAK 0x40 /* enable break */ +#define LCR_DLAB 0x80 /* access DLAB registers */ +#define COM1_LSR (COM1_BASE + LSRREG) #define LSR_DR 0x01 #define LSR_THRE 0x20 #define LCR_DLA 0x80 +#define UART_BASE_FREQ 115200U + #endif diff --git a/kernel/glo.h b/kernel/glo.h index 2446ca795..177a3b7a2 100644 --- a/kernel/glo.h +++ b/kernel/glo.h @@ -42,6 +42,7 @@ EXTERN u32_t system_hz; /* HZ value */ EXTERN reg_t mon_sp; /* boot monitor stack */ EXTERN int mon_return; /* true if we can return to monitor */ EXTERN int do_serial_debug; +EXTERN int serial_debug_baud; EXTERN time_t boottime; EXTERN char params_buffer[512]; /* boot monitor parameters */ EXTERN int minix_panicing; diff --git a/kernel/start.c b/kernel/start.c index a39ddb8ef..3c73c23d9 100644 --- a/kernel/start.c +++ b/kernel/start.c @@ -83,10 +83,16 @@ PUBLIC void cstart( system_hz = atoi(value); if(!value || system_hz < 2 || system_hz > 50000) /* sanity check */ system_hz = DEFAULT_HZ; + + /* Intitialize serial debugging */ value = env_get(SERVARNAME); - if(value && atoi(value) == 0) + if(value && atoi(value) == 0) { do_serial_debug=1; + value = env_get(SERBAUDVARNAME); + if (value) serial_debug_baud = atoi(value); + } + #ifdef CONFIG_APIC value = env_get("no_apic"); if(value)