Fail* directories reorganized, Code-cleanup (-> coding-style), Typos+comments fixed.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1321 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
262
simulators/bochs/plex86/kernel/print-mon.c
Normal file
262
simulators/bochs/plex86/kernel/print-mon.c
Normal file
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* plex86: run multiple x86 operating systems concurrently
|
||||
* Copyright (C) 1999-2003 Kevin P. Lawton
|
||||
*
|
||||
* print-nexus.c: Monitor debug print facility
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "plex86.h"
|
||||
#define IN_MONITOR_SPACE
|
||||
#include "monitor.h"
|
||||
|
||||
int mon_vprint(vm_t *vm, char *fmt, va_list args);
|
||||
|
||||
static unsigned int power_of_ten[] = {
|
||||
1,
|
||||
10,
|
||||
100,
|
||||
1000,
|
||||
10000,
|
||||
100000,
|
||||
1000000,
|
||||
10000000,
|
||||
100000000,
|
||||
1000000000,
|
||||
};
|
||||
|
||||
int
|
||||
monprint(vm_t *vm, char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, fmt);
|
||||
ret = mon_vprint(vm, fmt, args);
|
||||
va_end(args);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int
|
||||
mon_vprint(vm_t *vm, char *fmt, va_list args)
|
||||
{
|
||||
unsigned offset, size;
|
||||
unsigned char *log_buff_p;
|
||||
int ret;
|
||||
|
||||
if (vm->log_buffer_info.locked)
|
||||
return 0;
|
||||
|
||||
vm->log_buffer_info.locked = 1;
|
||||
vm->log_buffer_info.event = 1;
|
||||
offset = vm->log_buffer_info.offset;
|
||||
|
||||
/* Sanity check */
|
||||
if (offset >= LOG_BUFF_SIZE) {
|
||||
vm->guest.addr.log_buffer[0] = 0; /* Null terminate. */
|
||||
resetPrintBuf(vm);
|
||||
return(0);
|
||||
}
|
||||
|
||||
size = LOG_BUFF_SIZE - offset;
|
||||
log_buff_p = &vm->guest.addr.log_buffer[offset];
|
||||
|
||||
ret = mon_vsnprintf(log_buff_p, size, fmt, args);
|
||||
|
||||
if (ret == -1) {
|
||||
/* Terminate current contents since new print request did not work. */
|
||||
*log_buff_p = 0;
|
||||
/* If we are in the monitor space, then we can request that the
|
||||
* current buffer contents be printed.
|
||||
*/
|
||||
resetPrintBuf(vm);
|
||||
sysFlushPrintBuf(vm);
|
||||
|
||||
/* Print request did not fit. dump buffer contents and try again
|
||||
* using whole buffer.
|
||||
*/
|
||||
size = LOG_BUFF_SIZE;
|
||||
log_buff_p = &vm->guest.addr.log_buffer[0];
|
||||
ret = mon_vsnprintf(log_buff_p, size, fmt, args);
|
||||
if (ret == -1) {
|
||||
/* We have serious problems. This print request will not even
|
||||
* fit in the whole buffer.
|
||||
*/
|
||||
vm->guest.addr.log_buffer[0] = 0; /* Null terminate. */
|
||||
resetPrintBuf(vm);
|
||||
/* xxx Put error in buffer here. */
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
vm->log_buffer_info.offset += ret;
|
||||
vm->log_buffer_info.locked = 0;
|
||||
#if 0 /* Fri Dec 27 21:43:05 EST 2002 */
|
||||
resetPrintBuf(vm);
|
||||
sysFlushPrintBuf(vm);
|
||||
#endif
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void
|
||||
resetPrintBuf(vm_t *vm)
|
||||
{
|
||||
vm->log_buffer_info.event = 0;
|
||||
vm->log_buffer_info.locked = 0;
|
||||
vm->log_buffer_info.offset = 0;
|
||||
vm->log_buffer_info.error = 0;
|
||||
}
|
||||
|
||||
|
||||
/* For now, this is a simple vsnprintf() type of function. We need
|
||||
* to fill this out a little.
|
||||
*/
|
||||
|
||||
int
|
||||
mon_vsnprintf(char *str, unsigned size, const char *fmt, va_list args)
|
||||
{
|
||||
int count = 0;
|
||||
unsigned format_width;
|
||||
unsigned char c;
|
||||
|
||||
while (*fmt) {
|
||||
switch (*fmt) {
|
||||
|
||||
case '%':
|
||||
format_width = 0;
|
||||
fmt++;
|
||||
c = *fmt++;
|
||||
/* Get optional field width */
|
||||
if ( (c>='0') && (c<='9') ) {
|
||||
do {
|
||||
format_width = (format_width * 10) + (c - '0');
|
||||
c = *fmt++;
|
||||
} while ( (c>='0') && (c<='9') );
|
||||
}
|
||||
/* %x: hexadecimal */
|
||||
if ( c == 'x' ) {
|
||||
unsigned int val, leadin;
|
||||
int j;
|
||||
unsigned nibble;
|
||||
|
||||
val = va_arg(args, unsigned int);
|
||||
leadin = 1;
|
||||
|
||||
for (j=7; j>=0; j--) {
|
||||
nibble = (val >> (4 * j)) & 0x0f;
|
||||
if (leadin && j && !format_width && !nibble)
|
||||
continue;
|
||||
if (leadin && j && format_width && ((j+1)>format_width) &&
|
||||
!nibble)
|
||||
continue;
|
||||
leadin = 0;
|
||||
if ( (count+2) >= size ) goto error;
|
||||
if (nibble <= 9)
|
||||
*str++ = nibble + '0';
|
||||
else
|
||||
*str++ = (nibble-10) + 'A';
|
||||
count++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* %c: character */
|
||||
if ( c == 'c' ) {
|
||||
unsigned char val;
|
||||
val = va_arg(args, unsigned);
|
||||
if ( (count+2) >= size ) goto error;
|
||||
*str++ = val;
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* %s: string */
|
||||
if ( c == 's' ) {
|
||||
unsigned char *s;
|
||||
s = va_arg(args, unsigned char *);
|
||||
if ( (count+2) >= size ) goto error;
|
||||
count++;
|
||||
while (*s) {
|
||||
if ( (count+2) >= size ) goto error;
|
||||
*str++ = *s++; /* Copy char from string to output buffer. */
|
||||
count++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* %u: unsigned int */
|
||||
if ( c == 'u' ) {
|
||||
unsigned int val, leadin;
|
||||
int j;
|
||||
unsigned digit;
|
||||
|
||||
val = va_arg(args, unsigned int);
|
||||
leadin = 1;
|
||||
|
||||
for (j=9; j>=0; j--) {
|
||||
if (leadin && j && !format_width && (val < power_of_ten[j]))
|
||||
continue;
|
||||
if (leadin && j && format_width && ((j+1)>format_width) &&
|
||||
(val < power_of_ten[j]))
|
||||
continue;
|
||||
leadin = 0;
|
||||
digit = (val / power_of_ten[j]);
|
||||
if ( (count+2) >= size ) goto error;
|
||||
*str++ = digit + '0';
|
||||
count++;
|
||||
val -= (digit * power_of_ten[j]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* %b : binary (non-standard but useful) */
|
||||
if ( c == 'b' ) {
|
||||
unsigned int val, bit, leadin;
|
||||
int j;
|
||||
val = va_arg(args, unsigned int);
|
||||
leadin = 1;
|
||||
for (j=31; j>=0; j--) {
|
||||
bit = (val >> j) & 1;
|
||||
if (leadin && j && !format_width && !bit)
|
||||
continue;
|
||||
if (leadin && j && format_width && ((j+1)>format_width) && !bit)
|
||||
continue;
|
||||
leadin = 0;
|
||||
if ( (count+2) >= size ) goto error;
|
||||
*str++ = bit + '0';
|
||||
count++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Error, unrecognized format char */
|
||||
goto error;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* pass char through */
|
||||
if ( (count+2) >= size ) goto error;
|
||||
*str++ = *fmt++;
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*str = 0; /* Complete string with null char */
|
||||
return(count);
|
||||
|
||||
error:
|
||||
return(-1);
|
||||
}
|
||||
Reference in New Issue
Block a user