#include <syslinux/adv.h>
#include <syslinux/config.h>
#include <dprintf.h>
+#include <ctype.h>
+#include <core.h>
+ #include <fs.h>
#include "menu.h"
#include "config.h"
onerror = refstrdup(m->onerror);
}
+ else if (looking_at(p, "pxeretry"))
+ PXERetry = atoi(skipspace(p + 8));
+
/* 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);
+ } else if (looking_at(p, "path")) {
+ /* PATH-based lookup */
+ char *new_path, *_p;
+ size_t len, new_len;
+
+ new_path = refstrdup(skipspace(p + 4));
+ len = strlen(PATH);
+ new_len = strlen(new_path);
+ _p = realloc(PATH, len + new_len + 2);
+ if (_p) {
+ strncpy(_p, PATH, len);
+ _p[len++] = ':';
+ strncpy(_p + len, new_path, new_len);
+ _p[len + new_len] = '\0';
+ PATH = _p;
+ } else
+ printf("Failed to realloc PATH\n");
}
}
}