summaryrefslogtreecommitdiff
path: root/sys/i386/boot/netboot/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/boot/netboot/misc.c')
-rw-r--r--sys/i386/boot/netboot/misc.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/sys/i386/boot/netboot/misc.c b/sys/i386/boot/netboot/misc.c
new file mode 100644
index 000000000000..814ddbf63d96
--- /dev/null
+++ b/sys/i386/boot/netboot/misc.c
@@ -0,0 +1,261 @@
+/**************************************************************************
+MISC Support Routines
+**************************************************************************/
+
+#include "netboot.h"
+
+#define NO_SWITCH /* saves space */
+
+/**************************************************************************
+TWIDDLE
+**************************************************************************/
+twiddle()
+{
+ static int count=0;
+ char tiddles[]="-\\|/";
+ putchar(tiddles[(count++)&3]);
+ putchar('\b');
+}
+
+/**************************************************************************
+BCOPY
+**************************************************************************/
+bcopy(s,d,n)
+ char *s, *d;
+ int n;
+{
+ while ((n--) > 0) {
+ *(d++) = *(s++);
+ }
+}
+
+/**************************************************************************
+BZERO
+**************************************************************************/
+bzero(d,n)
+ char *d;
+ int n;
+{
+ while ((n--) > 0) {
+ *(d++) = 0;
+ }
+}
+
+/**************************************************************************
+BCOMPARE
+**************************************************************************/
+bcompare(d,s,n)
+ char *d,*s;
+ int n;
+{
+ while ((n--) > 0) {
+ if (*(d++) != *(s++)) return(0);
+ }
+ return(1);
+}
+
+/**************************************************************************
+PRINTF and friends
+
+ Formats:
+ %X - 4 byte ASCII (8 hex digits)
+ %x - 2 byte ASCII (4 hex digits)
+ %b - 1 byte ASCII (2 hex digits)
+ %d - decimal
+ %c - ASCII char
+ %s - ASCII string
+ %I - Internet address in x.x.x.x notation
+ %L - Binary long
+ %S - String (multiple of 4 bytes) preceded with 4 byte
+ binary length
+ %M - Copy memory. Takes two args, len and ptr
+**************************************************************************/
+static char hex[]="0123456789ABCDEF";
+char *do_printf(buf, fmt, dp)
+ char *buf, *fmt;
+ int *dp;
+{
+ register char *p;
+ char tmp[16];
+ while (*fmt) {
+ if (*fmt == '%') { /* switch() uses more space */
+ fmt++;
+ if (*fmt == 'L') {
+ register int h = *(dp++);
+ *(buf++) = h>>24;
+ *(buf++) = h>>16;
+ *(buf++) = h>>8;
+ *(buf++) = h;
+ }
+ if (*fmt == 'S') {
+ register int len = 0;
+ char *lenptr = buf;
+ p = (char *)*dp++;
+ buf += 4;
+ while (*p) {
+ *(buf++) = *p++;
+ len ++;
+ }
+ *(lenptr++) = len>>24;
+ *(lenptr++) = len>>16;
+ *(lenptr++) = len>>8;
+ *lenptr = len;
+ while (len & 3) {
+ *(buf++) = 0;
+ len ++;
+ }
+ }
+ if (*fmt == 'M') {
+ register int len = *(dp++);
+ bcopy((char *)*dp++, buf, len);
+ buf += len;
+ }
+ if (*fmt == 'X') {
+ register int h = *(dp++);
+ *(buf++) = hex[(h>>28)& 0x0F];
+ *(buf++) = hex[(h>>24)& 0x0F];
+ *(buf++) = hex[(h>>20)& 0x0F];
+ *(buf++) = hex[(h>>16)& 0x0F];
+ *(buf++) = hex[(h>>12)& 0x0F];
+ *(buf++) = hex[(h>>8)& 0x0F];
+ *(buf++) = hex[(h>>4)& 0x0F];
+ *(buf++) = hex[h& 0x0F];
+ }
+ if (*fmt == 'x') {
+ register int h = *(dp++);
+ *(buf++) = hex[(h>>12)& 0x0F];
+ *(buf++) = hex[(h>>8)& 0x0F];
+ *(buf++) = hex[(h>>4)& 0x0F];
+ *(buf++) = hex[h& 0x0F];
+ }
+ if (*fmt == 'b') {
+ register int h = *(dp++);
+ *(buf++) = hex[(h>>4)& 0x0F];
+ *(buf++) = hex[h& 0x0F];
+ }
+ if (*fmt == 'd') {
+ register int dec = *(dp++);
+ p = tmp;
+ if (dec < 0) {
+ *(buf++) = '-';
+ dec = -dec;
+ }
+ do {
+ *(p++) = '0' + (dec%10);
+ dec = dec/10;
+ } while(dec);
+ while ((--p) >= tmp) *(buf++) = *p;
+ }
+ if (*fmt == 'I') {
+ buf = sprintf(buf,"%d.%d.%d.%d",
+ (*(dp)>>24) & 0x00FF,
+ (*(dp)>>16) & 0x00FF,
+ (*(dp)>>8) & 0x00FF,
+ *dp & 0x00FF);
+ dp++;
+ }
+ if (*fmt == 'c')
+ *(buf++) = *(dp++);
+ if (*fmt == 's') {
+ p = (char *)*dp++;
+ while (*p) *(buf++) = *p++;
+ }
+ } else *(buf++) = *fmt;
+ fmt++;
+ }
+ *buf = 0;
+ return(buf);
+}
+
+char *sprintf(buf, fmt, data)
+ char *fmt, *buf;
+ int data;
+{
+ return(do_printf(buf,fmt, &data));
+}
+
+printf(fmt,data)
+ char *fmt;
+ int data;
+{
+ char buf[80],*p;
+ p = buf;
+ do_printf(buf,fmt,&data);
+ while (*p) putchar(*p++);
+}
+
+/**************************************************************************
+SETIP - Convert an ascii x.x.x.x to binary form
+**************************************************************************/
+setip(p, i)
+ char *p;
+ unsigned *i;
+{
+ unsigned ip = 0;
+ int val;
+ if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
+ if (*p != '.') return(0);
+ p++;
+ ip = val;
+ if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
+ if (*p != '.') return(0);
+ p++;
+ ip = (ip << 8) | val;
+ if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
+ if (*p != '.') return(0);
+ p++;
+ ip = (ip << 8) | val;
+ if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
+ *i = (ip << 8) | val;
+ return(1);
+}
+
+getdec(ptr)
+ char **ptr;
+{
+ char *p = *ptr;
+ int ret=0;
+ if ((*p < '0') || (*p > '9')) return(-1);
+ while ((*p >= '0') && (*p <= '9')) {
+ ret = ret*10 + (*p - '0');
+ p++;
+ }
+ *ptr = p;
+ return(ret);
+}
+
+
+#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
+#define K_STATUS 0x64 /* keyboard status */
+#define K_CMD 0x64 /* keybd ctlr command (write-only) */
+
+#define K_OBUF_FUL 0x01 /* output buffer full */
+#define K_IBUF_FUL 0x02 /* input buffer full */
+
+#define KC_CMD_WIN 0xd0 /* read output port */
+#define KC_CMD_WOUT 0xd1 /* write output port */
+#define KB_A20 0x9f /* enable A20,
+ enable output buffer full interrupt
+ enable data line
+ disable clock line */
+
+/*
+ * Gate A20 for high memory
+ */
+unsigned char x_20 = KB_A20;
+gateA20()
+{
+#ifdef IBM_L40
+ outb(0x92, 0x2);
+#else IBM_L40
+ while (inb(K_STATUS) & K_IBUF_FUL);
+ while (inb(K_STATUS) & K_OBUF_FUL)
+ (void)inb(K_RDWR);
+
+ outb(K_CMD, KC_CMD_WOUT);
+ while (inb(K_STATUS) & K_IBUF_FUL);
+ outb(K_RDWR, x_20);
+ while (inb(K_STATUS) & K_IBUF_FUL);
+#endif IBM_L40
+}
+