⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc-common.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
字号:
/* * arch/ppc/boot/common/misc-common.c *  * Misc. bootloader code (almost) all platforms can use * * Author: Johnnie Peters <jpeters@mvista.com> * Editor: Tom Rini <trini@mvista.com> * * Derived from arch/ppc/boot/prep/misc.c * * Copyright 2000-2001 MontaVista Software Inc. * * This program is free software; you can redistribute  it and/or modify it * under  the terms of  the GNU General  Public License as published by the * Free Software Foundation;  either version 2 of the  License, or (at your * option) any later version. * * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the  GNU General Public License along * with this program; if not, write  to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdarg.h>	/* for va_ bits */#include <linux/config.h>#include "zlib.h"#include "nonstdio.h"/* If we're on a ALL_PPC, assume we have a keyboard controller * Also note, if we're not ALL_PPC, we assume you are a serial * console - Tom */#if defined(CONFIG_ALL_PPC) && defined(CONFIG_VGA_CONSOLE)extern void cursor(int x, int y);extern void scroll(void);extern char *vidmem;extern int lines, cols;extern int orig_x, orig_y;extern int keyb_present;extern int CRT_tstc(void);extern int CRT_getc(void);#elseint cursor(int x, int y) {return 0;}void scroll(void) {}char vidmem[1];#define lines 0#define cols 0int orig_x = 0;int orig_y = 0;#define keyb_present 0int CRT_tstc(void) {return 0;}int CRT_getc(void) {return 0;}#endifextern char *avail_ram;extern char *end_avail;extern char _end[];void puts(const char *);void putc(const char c);void puthex(unsigned long val);void _bcopy(char *src, char *dst, int len);void gunzip(void *, int, unsigned char *, int *);static int _cvt(unsigned long val, char *buf, long radix, char *digits);void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);unsigned char *ISA_io = NULL;#if defined(CONFIG_SERIAL_CONSOLE)extern unsigned long com_port;extern int serial_tstc(unsigned long com_port);extern unsigned char serial_getc(unsigned long com_port);extern void serial_putc(unsigned long com_port, unsigned char c);#endifvoid pause(void){	puts("pause\n");}void exit(void){	puts("exit\n");	while(1); }int tstc(void){#if defined(CONFIG_SERIAL_CONSOLE)	if(keyb_present)		return (CRT_tstc() || serial_tstc(com_port));	else		return (serial_tstc(com_port));#else	return CRT_tstc();#endif}int getc(void){	while (1) {#if defined(CONFIG_SERIAL_CONSOLE)		if (serial_tstc(com_port))			return (serial_getc(com_port));#endif /* CONFIG_SERIAL_CONSOLE */		if (keyb_present)			if(CRT_tstc())				return (CRT_getc());	}}void putc(const char c){	int x,y;#if defined(CONFIG_SERIAL_CONSOLE)	serial_putc(com_port, c);	if ( c == '\n' )		serial_putc(com_port, '\r');#endif /* CONFIG_SERIAL_CONSOLE */	x = orig_x;	y = orig_y;	if ( c == '\n' ) {		x = 0;		if ( ++y >= lines ) {			scroll();			y--;		}	} else if (c == '\r') {		x = 0;	} else if (c == '\b') {		if (x > 0) {			x--;		}	} else {		vidmem [ ( x + cols * y ) * 2 ] = c; 		if ( ++x >= cols ) {			x = 0;			if ( ++y >= lines ) {				scroll();				y--;			}		}	}	cursor(x, y);	orig_x = x;	orig_y = y;}void puts(const char *s){	int x,y;	char c;	x = orig_x;	y = orig_y;	while ( ( c = *s++ ) != '\0' ) {#if defined(CONFIG_SERIAL_CONSOLE)	        serial_putc(com_port, c);	        if ( c == '\n' ) serial_putc(com_port, '\r');#endif /* CONFIG_SERIAL_CONSOLE */		if ( c == '\n' ) {			x = 0;			if ( ++y >= lines ) {				scroll();				y--;			}		} else if (c == '\b') {		  if (x > 0) {		    x--;		  }		} else {			vidmem [ ( x + cols * y ) * 2 ] = c; 			if ( ++x >= cols ) {				x = 0;				if ( ++y >= lines ) {					scroll();					y--;				}			}		}	}	cursor(x, y);	orig_x = x;	orig_y = y;}void error(char *x){	puts("\n\n");	puts(x);	puts("\n\n -- System halted");	while(1);	/* Halt */}void *zalloc(void *x, unsigned items, unsigned size){	void *p = avail_ram;		size *= items;	size = (size + 7) & -8;	avail_ram += size;	if (avail_ram > end_avail) {		puts("oops... out of memory\n");		pause();	}	return p;}void zfree(void *x, void *addr, unsigned nb){}#define HEAD_CRC	2#define EXTRA_FIELD	4#define ORIG_NAME	8#define COMMENT		0x10#define RESERVED	0xe0#define DEFLATED	8void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp){	z_stream s;	int r, i, flags;		/* skip header */	i = 10;	flags = src[3];	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {		puts("bad gzipped data\n");		exit();	}	if ((flags & EXTRA_FIELD) != 0)		i = 12 + src[10] + (src[11] << 8);	if ((flags & ORIG_NAME) != 0)		while (src[i++] != 0)			;	if ((flags & COMMENT) != 0)		while (src[i++] != 0)			;	if ((flags & HEAD_CRC) != 0)		i += 2;	if (i >= *lenp) {		puts("gunzip: ran out of data in header\n");		exit();	}		s.zalloc = zalloc;	s.zfree = zfree;	r = inflateInit2(&s, -MAX_WBITS);	if (r != Z_OK) {		puts("inflateInit2 returned "); puthex(r); puts("\n");		exit();	}	s.next_in = src + i;	s.avail_in = *lenp - i;	s.next_out = dst;	s.avail_out = dstlen;	r = inflate(&s, Z_FINISH);	if (r != Z_OK && r != Z_STREAM_END) {		puts("inflate returned "); puthex(r); puts("\n");		exit();	}	*lenp = s.next_out - (unsigned char *) dst;	inflateEnd(&s);}voidputhex(unsigned long val){	unsigned char buf[10];	int i;	for (i = 7;  i >= 0;  i--)	{		buf[i] = "0123456789ABCDEF"[val & 0x0F];		val >>= 4;	}	buf[8] = '\0';	puts(buf);}#define FALSE 0#define TRUE  1void_printk(char const *fmt, ...){	va_list ap;	va_start(ap, fmt);	_vprintk(putc, fmt, ap);	va_end(ap);	return;}#define is_digit(c) ((c >= '0') && (c <= '9'))void_vprintk(void(*putc)(const char), const char *fmt0, va_list ap){	char c, sign, *cp = 0;	int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;	char buf[32];	long val;	while ((c = *fmt0++))	{		if (c == '%')		{			c = *fmt0++;			left_prec = right_prec = pad_on_right = 0;			if (c == '-')			{				c = *fmt0++;				pad_on_right++;			}			if (c == '0')			{				zero_fill = TRUE;				c = *fmt0++;			} else			{				zero_fill = FALSE;			}			while (is_digit(c))			{				left_prec = (left_prec * 10) + (c - '0');				c = *fmt0++;			}			if (c == '.')			{				c = *fmt0++;				zero_fill++;				while (is_digit(c))				{					right_prec = (right_prec * 10) + (c - '0');					c = *fmt0++;				}			} else			{				right_prec = left_prec;			}			sign = '\0';			switch (c)			{			case 'd':			case 'x':			case 'X':				val = va_arg(ap, long);				switch (c)				{				case 'd':					if (val < 0)					{						sign = '-';						val = -val;					}					length = _cvt(val, buf, 10, "0123456789");					break;				case 'x':					length = _cvt(val, buf, 16, "0123456789abcdef");					break;				case 'X':					length = _cvt(val, buf, 16, "0123456789ABCDEF");					break;				}				cp = buf;				break;			case 's':				cp = va_arg(ap, char *);				length = strlen(cp);				break;			case 'c':				c = va_arg(ap, long /*char*/);				(*putc)(c);				continue;			default:				(*putc)('?');			}			pad = left_prec - length;			if (sign != '\0')			{				pad--;			}			if (zero_fill)			{				c = '0';				if (sign != '\0')				{					(*putc)(sign);					sign = '\0';				}			} else			{				c = ' ';			}			if (!pad_on_right)			{				while (pad-- > 0)				{					(*putc)(c);				}			}			if (sign != '\0')			{				(*putc)(sign);			}			while (length-- > 0)			{				(*putc)(c = *cp++);				if (c == '\n')				{					(*putc)('\r');				}			}			if (pad_on_right)			{				while (pad-- > 0)				{					(*putc)(c);				}			}		} else		{			(*putc)(c);			if (c == '\n')			{				(*putc)('\r');			}		}	}}int_cvt(unsigned long val, char *buf, long radix, char *digits){	char temp[80];	char *cp = temp;	int length = 0;	if (val == 0)	{ /* Special case */		*cp++ = '0';	} else		while (val)		{			*cp++ = digits[val % radix];			val /= radix;		}	while (cp != temp)	{		*buf++ = *--cp;		length++;	}	*buf = '\0';	return (length);}void_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base){	int i, c;	if ((unsigned int)s > (unsigned int)p)	{		s = (unsigned int)s - (unsigned int)p;	}	while (s > 0)	{		if (base)		{			_printk("%06X: ", (int)p - (int)base);		} else		{			_printk("%06X: ", p);		}		for (i = 0;  i < 16;  i++)		{			if (i < s)			{				_printk("%02X", p[i] & 0xFF);			} else			{				_printk("  ");			}			if ((i % 2) == 1) _printk(" ");			if ((i % 8) == 7) _printk(" ");		}		_printk(" |");		for (i = 0;  i < 16;  i++)		{			if (i < s)			{				c = p[i] & 0xFF;				if ((c < 0x20) || (c >= 0x7F)) c = '.';			} else			{				c = ' ';			}			_printk("%c", c);		}		_printk("|\n");		s -= 16;		p += 16;	}}void_dump_buf(unsigned char *p, int s){	_printk("\n");	_dump_buf_with_offset(p, s, 0);}/* Very simple inb/outb routines.  We declare ISA_io to be 0 above, and * then modify it on platforms which need to.  We do it like this * because on some platforms we give inb/outb an exact location, and * on others it's an offset from a given location. -- Tom */voidoutb(int port, unsigned char val){	/* Ensure I/O operations complete */	__asm__ volatile("eieio");	ISA_io[port] = val;}unsigned charinb(int port){	/* Ensure I/O operations complete */	__asm__ volatile("eieio");	return (ISA_io[port]);}/* * Local variables: *  c-indent-level: 8 *  c-basic-offset: 8 *  tab-width: 8 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -