freebsd-nq/sys/i386/boot/netboot/misc.c
Jordan K. Hubbard 68cbb04819 Many fixes from Bill Paul:
Smack the netboot program around so that it will allow the user to
  specify mount options.  [So that you can boot from a privileged port]

  Change the default boot image name in netboot to /kernel, then strip
  the leading slash when actually going out to get the NFS file handle.

  Added support for 3Com 3c503 cards. Also added another command to
  the (trans) that allows you to switch the 3Com's on-board transceiver
  on and off. (ether.c, ether.h, bootmenu.c)

  Modified the Makefile to support new compile-time options for 3c503
  cards:

  -DINCLUDE_3COM                Include support for 3c503
  -D_3COM_BASE=0x300            Define 3c503 base i/o address (if not
                                specified, 0x300 is the default)
  -D_3COM_USE_AUI               Disable the 3c503's transceiver by
                                default (without this flag the transceiver
                                is on by default)
1994-11-17 12:16:07 +00:00

284 lines
6.2 KiB
C

/**************************************************************************
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);
}
/**************************************************************************
SUBSTR (slightly wacky but functional)
**************************************************************************/
char *substr(a,b)
char *a,*b;
{
char *loc1;
char *loc2;
while (*a != '\0') {
loc1 = a;
loc2 = b;
while (*loc1 == *loc2++) {
if (*loc1 == '\0') return (0);
loc1++;
if (*loc2 == '\0') return (loc1);
}
a++;
}
return (0);
}
/**************************************************************************
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
}