123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- /**************************************************************************
- MISC Support Routines
- **************************************************************************/
-
- #include "etherboot.h"
-
- /**************************************************************************
- SLEEP
- **************************************************************************/
- void sleep(int secs)
- {
- unsigned long tmo;
-
- for (tmo = currticks()+secs*TICKS_PER_SEC; currticks() < tmo; )
- /* Nothing */;
- }
-
- /**************************************************************************
- TWIDDLE
- **************************************************************************/
- void twiddle()
- {
- static unsigned long lastticks = 0;
- static int count=0;
- static const char tiddles[]="-\\|/";
- unsigned long ticks;
- if ((ticks = currticks()) == lastticks)
- return;
- lastticks = ticks;
- putchar(tiddles[(count++)&3]);
- putchar('\b');
- }
-
- /**************************************************************************
- STRCASECMP (not entirely correct, but this will do for our purposes)
- **************************************************************************/
- int strcasecmp(a,b)
- char *a, *b;
- {
- while (*a && *b && (*a & ~0x20) == (*b & ~0x20)) {a++; b++; }
- return((*a & ~0x20) - (*b & ~0x20));
- }
-
- /**************************************************************************
- PRINTF and friends
-
- Formats:
- %[#]X - 4 bytes long (8 hex digits)
- %[#]x - 2 bytes int (4 hex digits)
- - optional # prefixes 0x
- %b - 1 byte int (2 hex digits)
- %d - decimal int
- %c - char
- %s - string
- %I - Internet address in x.x.x.x notation
- Note: width specification not supported
- **************************************************************************/
- static char *do_printf(char *buf, const char *fmt, const int *dp)
- {
- register char *p;
- int alt;
- char tmp[16];
- static const char hex[]="0123456789ABCDEF";
-
- while (*fmt) {
- if (*fmt == '%') { /* switch() uses more space */
- alt = 0;
- fmt++;
- if (*fmt == '#') {
- alt = 1;
- fmt++;
- }
- if (*fmt == 'X') {
- const long *lp = (const long *)dp;
- register long h = *lp++;
- dp = (const int *)lp;
- if (alt) {
- *buf++ = '0';
- *buf++ = 'x';
- }
- *(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++);
- if (alt) {
- *buf++ = '0';
- *buf++ = 'x';
- }
- *(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') {
- union {
- long l;
- unsigned char c[4];
- } u;
- const long *lp = (const long *)dp;
- u.l = *lp++;
- dp = (const int *)lp;
- buf = sprintf(buf,"%d.%d.%d.%d",
- u.c[0], u.c[1], u.c[2], u.c[3]);
- }
- 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(char *buf, const char *fmt, ...)
- {
- return do_printf(buf, fmt, ((const int *)&fmt)+1);
- }
-
- void printf(const char *fmt, ...)
- {
- char buf[120], *p;
-
- p = buf;
- do_printf(buf, fmt, ((const int *)&fmt)+1);
- while (*p) putchar(*p++);
- }
-
- #ifdef IMAGE_MENU
- /**************************************************************************
- INET_ATON - Convert an ascii x.x.x.x to binary form
- **************************************************************************/
- int inet_aton(char *p, in_addr *i)
- {
- unsigned long 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->s_addr = htonl((ip << 8) | val);
- return(1);
- }
-
- #endif /* IMAGE_MENU */
-
- int getdec(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_SET_A20 0xdf /* enable A20,
- enable output buffer full interrupt
- enable data line
- disable clock line */
- #define KB_UNSET_A20 0xdd /* enable A20,
- enable output buffer full interrupt
- enable data line
- disable clock line */
- #ifndef IBM_L40
- static void empty_8042(void)
- {
- unsigned long time;
- char st;
-
- time = currticks() + TICKS_PER_SEC; /* max wait of 1 second */
- while ((((st = inb(K_CMD)) & K_OBUF_FUL) ||
- (st & K_IBUF_FUL)) &&
- currticks() < time)
- inb(K_RDWR);
- }
- #endif IBM_L40
-
- /*
- * Gate A20 for high memory
- */
- void gateA20_set(void)
- {
- #ifdef IBM_L40
- outb(0x2, 0x92);
- #else /* IBM_L40 */
- empty_8042();
- outb(KC_CMD_WOUT, K_CMD);
- empty_8042();
- outb(KB_SET_A20, K_RDWR);
- empty_8042();
- #endif /* IBM_L40 */
- }
-
- #ifdef TAGGED_IMAGE
- /*
- * Unset Gate A20 for high memory - some operating systems (mainly old 16 bit
- * ones) don't expect it to be set by the boot loader.
- */
- void gateA20_unset(void)
- {
- #ifdef IBM_L40
- outb(0x0, 0x92);
- #else /* IBM_L40 */
- empty_8042();
- outb(KC_CMD_WOUT, K_CMD);
- empty_8042();
- outb(KB_UNSET_A20, K_RDWR);
- empty_8042();
- #endif /* IBM_L40 */
- }
- #endif
-
- #ifdef ETHERBOOT32
- /* Serial console is only implemented in ETHERBOOT32 for now */
- void
- putchar(int c)
- {
- #ifndef ANSIESC
- if (c == '\n')
- putchar('\r');
- #endif
-
- #ifdef CONSOLE_CRT
- #ifdef ANSIESC
- handleansi(c);
- #else
- putc(c);
- #endif
- #endif
- #ifdef CONSOLE_SERIAL
- #ifdef ANSIESC
- if (c == '\n')
- serial_putc('\r');
- #endif
- serial_putc(c);
- #endif
- }
-
- /**************************************************************************
- GETCHAR - Read the next character from the console WITHOUT ECHO
- **************************************************************************/
- int
- getchar(void)
- {
- int c = 256;
-
- #if defined CONSOLE_CRT || defined CONSOLE_SERIAL
- do {
- #ifdef CONSOLE_CRT
- if (ischar())
- c = getc();
- #endif
- #ifdef CONSOLE_SERIAL
- if (serial_ischar())
- c = serial_getc();
- #endif
- } while (c==256);
- if (c == '\r')
- c = '\n';
- #endif
- return c;
- }
-
- int
- iskey(void)
- {
- #ifdef CONSOLE_CRT
- if (ischar())
- return 1;
- #endif
- #ifdef CONSOLE_SERIAL
- if (serial_ischar())
- return 1;
- #endif
- return 0;
- }
- #endif /* ETHERBOOT32 */
-
- /*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
- #include <asm/msr.h>
-
- #define CPUCLOCK 166
-
- unsigned long currticks(void)
- {
- register unsigned long l, h;
- long long unsigned p;
- long long unsigned hh,ll;
-
- rdtsc(l, h);
- ll = l, hh = h;
-
- p = (ll + hh * 0x100000000LL) * 182 / (CPUCLOCK * 100000LL);
- return (unsigned)p;
- }
|