[syslinux:elflink] ldlinux: Add support for parsing "serial" config directive
syslinux-bot for Matt Fleming
matt.fleming at linux.intel.com
Tue Jul 12 20:03:21 PDT 2011
Commit-ID: 79163251bab8079623d4ea9d55e275e7b8b4607c
Gitweb: http://syslinux.zytor.com/commit/79163251bab8079623d4ea9d55e275e7b8b4607c
Author: Matt Fleming <matt.fleming at linux.intel.com>
AuthorDate: Fri, 27 May 2011 17:10:32 +0100
Committer: Matt Fleming <matt.fleming at linux.intel.com>
CommitDate: Tue, 7 Jun 2011 20:02:55 +0100
ldlinux: Add support for parsing "serial" config directive
Signed-off-by: Matt Fleming <matt.fleming at linux.intel.com>
---
com32/elflink/ldlinux/readconfig.c | 159 +++++++++++++++++++++++++++++++++--
core/conio.inc | 2 +
core/diskfs.inc | 1 +
core/diskstart.inc | 1 +
core/include/core.h | 2 +
core/isolinux.asm | 1 +
core/parseconfig.inc | 1 +
core/pxelinux.asm | 1 +
core/serirq.inc | 2 +
9 files changed, 160 insertions(+), 10 deletions(-)
diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c
index add6994..f0e45e9 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -11,6 +11,7 @@
*
* ----------------------------------------------------------------------- */
+#include <sys/io.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -23,10 +24,12 @@
#include <syslinux/adv.h>
#include <syslinux/config.h>
#include <dprintf.h>
+#include <ctype.h>
#include "menu.h"
#include "config.h"
#include "getkey.h"
+#include "core.h"
const struct menu_parameter mparm[NPARAMS] = {
[P_WIDTH] = {"width", 0},
@@ -112,14 +115,6 @@ static struct menu *find_menu(const char *label)
#define MAX_LINE 4096
-static char *skipspace(char *p)
-{
- while (*p && my_isspace(*p))
- p++;
-
- return p;
-}
-
/* Strip ^ from a string, returning a new reference to the same refstring
if none present */
static const char *strip_caret(const char *str)
@@ -709,6 +704,30 @@ static char *is_fkey(char *cmdstr, int *fkeyno)
return q;
}
+extern uint8_t FlowIgnore;
+extern uint8_t FlowInput;
+extern uint8_t FlowOutput;
+extern uint16_t SerialPort;
+extern uint16_t BaudDivisor;
+extern uint8_t SerialNotice;
+
+#define DEFAULT_BAUD 9600
+#define BAUD_DIVISOR 115200
+#define serial_base 0x0400
+
+extern void sirq_cleanup_nowipe(void);
+extern void sirq_install(void);
+extern void write_serial_str(void);
+
+static inline void io_delay(void)
+{
+ outb(0, 0x80);
+ outb(0, 0x80);
+}
+
+extern char syslinux_banner[];
+extern char copyright_str[];
+
static void parse_config_file(FILE * f)
{
char line[MAX_LINE], *p, *ep, ch;
@@ -1130,10 +1149,126 @@ do_include:
/* serial setting, bps, flow control */
else if (looking_at(p, "serial")) {
- /* core/conio.inc
- * should be able to find some code in com32
+ com32sys_t ireg;
+ uint16_t port, flow;
+ uint32_t baud;
+
+ p = skipspace(p + 6);
+ port = atoi(p);
+
+ while (isalnum(*p))
+ p++;
+ p = skipspace(p);
+
+ /* Default to no flow control */
+ FlowOutput = 0;
+ FlowInput = 0;
+
+ baud = DEFAULT_BAUD;
+ if (isalnum(*p)) {
+ uint8_t ignore;
+
+ /* setup baud */
+ baud = atoi(p);
+ while (isalnum(*p))
+ p++;
+ p = skipspace(p);
+
+ ignore = 0;
+ flow = 0;
+ if (isalnum(*p)) {
+ /* flow control */
+ flow = atoi(p);
+ ignore = ((flow & 0x0F00) >> 4);
+ }
+
+ FlowIgnore = ignore;
+ flow = ((flow & 0xff) << 8) | (flow & 0xff);
+ flow &= 0xF00B;
+ FlowOutput = (flow & 0xff);
+ FlowInput = ((flow & 0xff00) >> 8);
+ }
+
+ /*
+ * Parse baud
*/
+ if (baud < 75) {
+ /* < 75 baud == bogus */
+ SerialPort = 0;
+ continue;
+ }
+
+ baud = BAUD_DIVISOR / baud;
+ baud &= 0xffff;
+ BaudDivisor = baud;
+
+ /*
+ * If port > 3 then port is I/O addr
+ */
+ if (port <= 3) {
+ /* Get the I/O port from the BIOS */
+ port <<= 1;
+ port = *(volatile uint16_t *)serial_base;
+ }
+
+
+ SerialPort = port;
+
+ /*
+ * Begin code to actually set up the serial port
+ */
+ memset(&ireg, 0, sizeof(ireg));
+ call16(sirq_cleanup_nowipe, &ireg, NULL);
+
+ outb(0x83, port + 3); /* Enable DLAB */
+ io_delay();
+
+ outb((baud & 0xff), port); /* write divisor to LS */
+ io_delay();
+
+ outb(((baud & 0xff00) >> 8), port + 1); /* write to MS */
+ io_delay();
+
+ outb(0x03, port + 3); /* Disable DLAB */
+ io_delay();
+
+ /*
+ * Read back LCR (detect missing hw). If nothing here
+ * we'll read 00 or FF.
+ */
+ if (inb(port + 3) != 0x03) {
+ /* Assume serial port busted */
+ SerialPort = 0;
+ continue;
+ }
+
+ outb(0x01, port + 2); /* Enable FIFOs if present */
+ io_delay();
+
+ /* Disable FIFO if unusable */
+ if (inb(port + 2) < 0x0C0) {
+ outb(0, port + 2);
+ io_delay();
+ }
+
+ /* Assert bits in MCR */
+ outb(FlowOutput, port + 4);
+ io_delay();
+
+ /* Enable interrupts if requested */
+ if (FlowOutput & 0x8)
+ call16(sirq_install, &ireg, NULL);
+ /* Show some life */
+ if (SerialNotice != 0) {
+ SerialNotice = 0;
+
+ ireg.esi.w[0] = syslinux_banner;
+ call16(write_serial_str, &ireg, NULL);
+
+ ireg.esi.w[0] = copyright_str;
+ call16(write_serial_str, &ireg, NULL);
+ }
} else if (looking_at(p, "say")) {
printf("%s\n", p + 4);
}
@@ -1166,6 +1301,10 @@ static int parse_one_config(const char *filename)
if (f)
goto config_found;
+ f = fopen("pxelinux.cfg/default", "r");
+ if (f)
+ goto config_found;
+
return -1;
config_found:
parse_config_file(f);
diff --git a/core/conio.inc b/core/conio.inc
index b450502..6d6f234 100644
--- a/core/conio.inc
+++ b/core/conio.inc
@@ -274,6 +274,7 @@ write_serial_str_displaymask:
test byte [DisplayMask], 04h
jz write_serial_str.end
+ global write_serial_str
write_serial_str:
.loop lodsb
and al,al
@@ -415,6 +416,7 @@ VidRows resb 1 ; Rows on screen-1
; loading a new config file to undo this setting.
section .data16
alignz 4
+ global SerialPort, BaudDivisor, FlowIgnore, FlowInput, FlowOutput
SerialPort dw 0 ; Serial port base (or 0 for no serial port)
BaudDivisor dw 115200/9600 ; Baud rate divisor
FlowControl equ $
diff --git a/core/diskfs.inc b/core/diskfs.inc
index 470aa42..2684328 100644
--- a/core/diskfs.inc
+++ b/core/diskfs.inc
@@ -125,6 +125,7 @@ kaboom2:
; -----------------------------------------------------------------------------
section .data16
+ global copyright_str
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
db ' H. Peter Anvin et al', CR, LF, 0
diff --git a/core/diskstart.inc b/core/diskstart.inc
index e0a710d..c8f7936 100644
--- a/core/diskstart.inc
+++ b/core/diskstart.inc
@@ -514,6 +514,7 @@ SuperInfo resq 16 ; The first 16 bytes expanded 8 times
; Banner information not needed in sector 1
;
section .data16
+ global syslinux_banner
syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR
late_banner db ' ', DATE_STR, 0
diff --git a/core/include/core.h b/core/include/core.h
index 6e6f7fb..4435922 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -14,6 +14,8 @@ extern char ConfigName[];
extern char KernelName[];
extern char cmd_line[];
extern char ConfigFile[];
+extern char syslinux_banner[];
+extern char copyright_str[];
/* diskstart.inc isolinux.asm*/
extern void getlinsec(void);
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 344cb1e..895468c 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -1034,6 +1034,7 @@ writestr_early equ writestr
; Data that needs to be in the first sector
; -----------------------------------------------------------------------------
+ global syslinux_banner, copyright_str
syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
diff --git a/core/parseconfig.inc b/core/parseconfig.inc
index 512f16b..f24efe4 100644
--- a/core/parseconfig.inc
+++ b/core/parseconfig.inc
@@ -432,6 +432,7 @@ commit_vk:
ret
section .data16
+ global SerialNotice
vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0
SerialNotice db 1 ; Only print this once
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 10fe72e..8c56022 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -518,6 +518,7 @@ writestr_early equ writestr
section .data16
+ global copyright_str, syslinux_banner
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
db ' H. Peter Anvin et al', CR, LF, 0
diff --git a/core/serirq.inc b/core/serirq.inc
index 47ccd50..bd08b69 100644
--- a/core/serirq.inc
+++ b/core/serirq.inc
@@ -96,6 +96,7 @@ IRQMask resw 1 ; PIC IRQ mask status
section .text16
+ global sirq_install
sirq_install:
pushad
@@ -155,6 +156,7 @@ sirq_install:
popad
ret
+ global sirq_cleanup_nowipe
sirq_cleanup_nowipe:
pushad
push ds
More information about the Syslinux-commits
mailing list