misc-common.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:10k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * arch/ppc/boot/common/misc-common.c
  3.  * 
  4.  * Misc. bootloader code (almost) all platforms can use
  5.  *
  6.  * Author: Johnnie Peters <jpeters@mvista.com>
  7.  * Editor: Tom Rini <trini@mvista.com>
  8.  *
  9.  * Derived from arch/ppc/boot/prep/misc.c
  10.  *
  11.  * Copyright 2000-2001 MontaVista Software Inc.
  12.  *
  13.  * This program is free software; you can redistribute  it and/or modify it
  14.  * under  the terms of  the GNU General  Public License as published by the
  15.  * Free Software Foundation;  either version 2 of the  License, or (at your
  16.  * option) any later version.
  17.  *
  18.  * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
  19.  * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  20.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  21.  * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
  22.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23.  * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
  24.  * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  26.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28.  *
  29.  * You should have received a copy of the  GNU General Public License along
  30.  * with this program; if not, write  to the Free Software Foundation, Inc.,
  31.  * 675 Mass Ave, Cambridge, MA 02139, USA.
  32.  */
  33. #include <stdarg.h> /* for va_ bits */
  34. #include <linux/config.h>
  35. #include "zlib.h"
  36. #include "nonstdio.h"
  37. /* If we're on a ALL_PPC, assume we have a keyboard controller
  38.  * Also note, if we're not ALL_PPC, we assume you are a serial
  39.  * console - Tom */
  40. #if defined(CONFIG_ALL_PPC) && defined(CONFIG_VGA_CONSOLE)
  41. extern void cursor(int x, int y);
  42. extern void scroll(void);
  43. extern char *vidmem;
  44. extern int lines, cols;
  45. extern int orig_x, orig_y;
  46. extern int keyb_present;
  47. extern int CRT_tstc(void);
  48. extern int CRT_getc(void);
  49. #else
  50. int cursor(int x, int y) {return 0;}
  51. void scroll(void) {}
  52. char vidmem[1];
  53. #define lines 0
  54. #define cols 0
  55. int orig_x = 0;
  56. int orig_y = 0;
  57. #define keyb_present 0
  58. int CRT_tstc(void) {return 0;}
  59. int CRT_getc(void) {return 0;}
  60. #endif
  61. extern char *avail_ram;
  62. extern char *end_avail;
  63. extern char _end[];
  64. void puts(const char *);
  65. void putc(const char c);
  66. void puthex(unsigned long val);
  67. void _bcopy(char *src, char *dst, int len);
  68. void gunzip(void *, int, unsigned char *, int *);
  69. static int _cvt(unsigned long val, char *buf, long radix, char *digits);
  70. void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);
  71. unsigned char *ISA_io = NULL;
  72. #if defined(CONFIG_SERIAL_CONSOLE)
  73. extern unsigned long com_port;
  74. extern int serial_tstc(unsigned long com_port);
  75. extern unsigned char serial_getc(unsigned long com_port);
  76. extern void serial_putc(unsigned long com_port, unsigned char c);
  77. #endif
  78. void pause(void)
  79. {
  80. puts("pausen");
  81. }
  82. void exit(void)
  83. {
  84. puts("exitn");
  85. while(1); 
  86. }
  87. int tstc(void)
  88. {
  89. #if defined(CONFIG_SERIAL_CONSOLE)
  90. if(keyb_present)
  91. return (CRT_tstc() || serial_tstc(com_port));
  92. else
  93. return (serial_tstc(com_port));
  94. #else
  95. return CRT_tstc();
  96. #endif
  97. }
  98. int getc(void)
  99. {
  100. while (1) {
  101. #if defined(CONFIG_SERIAL_CONSOLE)
  102. if (serial_tstc(com_port))
  103. return (serial_getc(com_port));
  104. #endif /* CONFIG_SERIAL_CONSOLE */
  105. if (keyb_present)
  106. if(CRT_tstc())
  107. return (CRT_getc());
  108. }
  109. }
  110. void 
  111. putc(const char c)
  112. {
  113. int x,y;
  114. #if defined(CONFIG_SERIAL_CONSOLE)
  115. serial_putc(com_port, c);
  116. if ( c == 'n' )
  117. serial_putc(com_port, 'r');
  118. #endif /* CONFIG_SERIAL_CONSOLE */
  119. x = orig_x;
  120. y = orig_y;
  121. if ( c == 'n' ) {
  122. x = 0;
  123. if ( ++y >= lines ) {
  124. scroll();
  125. y--;
  126. }
  127. } else if (c == 'r') {
  128. x = 0;
  129. } else if (c == 'b') {
  130. if (x > 0) {
  131. x--;
  132. }
  133. } else {
  134. vidmem [ ( x + cols * y ) * 2 ] = c; 
  135. if ( ++x >= cols ) {
  136. x = 0;
  137. if ( ++y >= lines ) {
  138. scroll();
  139. y--;
  140. }
  141. }
  142. }
  143. cursor(x, y);
  144. orig_x = x;
  145. orig_y = y;
  146. }
  147. void puts(const char *s)
  148. {
  149. int x,y;
  150. char c;
  151. x = orig_x;
  152. y = orig_y;
  153. while ( ( c = *s++ ) != '' ) {
  154. #if defined(CONFIG_SERIAL_CONSOLE)
  155.         serial_putc(com_port, c);
  156.         if ( c == 'n' ) serial_putc(com_port, 'r');
  157. #endif /* CONFIG_SERIAL_CONSOLE */
  158. if ( c == 'n' ) {
  159. x = 0;
  160. if ( ++y >= lines ) {
  161. scroll();
  162. y--;
  163. }
  164. } else if (c == 'b') {
  165.   if (x > 0) {
  166.     x--;
  167.   }
  168. } else {
  169. vidmem [ ( x + cols * y ) * 2 ] = c; 
  170. if ( ++x >= cols ) {
  171. x = 0;
  172. if ( ++y >= lines ) {
  173. scroll();
  174. y--;
  175. }
  176. }
  177. }
  178. }
  179. cursor(x, y);
  180. orig_x = x;
  181. orig_y = y;
  182. }
  183. void error(char *x)
  184. {
  185. puts("nn");
  186. puts(x);
  187. puts("nn -- System halted");
  188. while(1); /* Halt */
  189. }
  190. void *zalloc(void *x, unsigned items, unsigned size)
  191. {
  192. void *p = avail_ram;
  193. size *= items;
  194. size = (size + 7) & -8;
  195. avail_ram += size;
  196. if (avail_ram > end_avail) {
  197. puts("oops... out of memoryn");
  198. pause();
  199. }
  200. return p;
  201. }
  202. void zfree(void *x, void *addr, unsigned nb)
  203. {
  204. }
  205. #define HEAD_CRC 2
  206. #define EXTRA_FIELD 4
  207. #define ORIG_NAME 8
  208. #define COMMENT 0x10
  209. #define RESERVED 0xe0
  210. #define DEFLATED 8
  211. void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
  212. {
  213. z_stream s;
  214. int r, i, flags;
  215. /* skip header */
  216. i = 10;
  217. flags = src[3];
  218. if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
  219. puts("bad gzipped datan");
  220. exit();
  221. }
  222. if ((flags & EXTRA_FIELD) != 0)
  223. i = 12 + src[10] + (src[11] << 8);
  224. if ((flags & ORIG_NAME) != 0)
  225. while (src[i++] != 0)
  226. ;
  227. if ((flags & COMMENT) != 0)
  228. while (src[i++] != 0)
  229. ;
  230. if ((flags & HEAD_CRC) != 0)
  231. i += 2;
  232. if (i >= *lenp) {
  233. puts("gunzip: ran out of data in headern");
  234. exit();
  235. }
  236. s.zalloc = zalloc;
  237. s.zfree = zfree;
  238. r = inflateInit2(&s, -MAX_WBITS);
  239. if (r != Z_OK) {
  240. puts("inflateInit2 returned "); puthex(r); puts("n");
  241. exit();
  242. }
  243. s.next_in = src + i;
  244. s.avail_in = *lenp - i;
  245. s.next_out = dst;
  246. s.avail_out = dstlen;
  247. r = inflate(&s, Z_FINISH);
  248. if (r != Z_OK && r != Z_STREAM_END) {
  249. puts("inflate returned "); puthex(r); puts("n");
  250. exit();
  251. }
  252. *lenp = s.next_out - (unsigned char *) dst;
  253. inflateEnd(&s);
  254. }
  255. void
  256. puthex(unsigned long val)
  257. {
  258. unsigned char buf[10];
  259. int i;
  260. for (i = 7;  i >= 0;  i--)
  261. {
  262. buf[i] = "0123456789ABCDEF"[val & 0x0F];
  263. val >>= 4;
  264. }
  265. buf[8] = '';
  266. puts(buf);
  267. }
  268. #define FALSE 0
  269. #define TRUE  1
  270. void
  271. _printk(char const *fmt, ...)
  272. {
  273. va_list ap;
  274. va_start(ap, fmt);
  275. _vprintk(putc, fmt, ap);
  276. va_end(ap);
  277. return;
  278. }
  279. #define is_digit(c) ((c >= '0') && (c <= '9'))
  280. void
  281. _vprintk(void(*putc)(const char), const char *fmt0, va_list ap)
  282. {
  283. char c, sign, *cp = 0;
  284. int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;
  285. char buf[32];
  286. long val;
  287. while ((c = *fmt0++))
  288. {
  289. if (c == '%')
  290. {
  291. c = *fmt0++;
  292. left_prec = right_prec = pad_on_right = 0;
  293. if (c == '-')
  294. {
  295. c = *fmt0++;
  296. pad_on_right++;
  297. }
  298. if (c == '0')
  299. {
  300. zero_fill = TRUE;
  301. c = *fmt0++;
  302. } else
  303. {
  304. zero_fill = FALSE;
  305. }
  306. while (is_digit(c))
  307. {
  308. left_prec = (left_prec * 10) + (c - '0');
  309. c = *fmt0++;
  310. }
  311. if (c == '.')
  312. {
  313. c = *fmt0++;
  314. zero_fill++;
  315. while (is_digit(c))
  316. {
  317. right_prec = (right_prec * 10) + (c - '0');
  318. c = *fmt0++;
  319. }
  320. } else
  321. {
  322. right_prec = left_prec;
  323. }
  324. sign = '';
  325. switch (c)
  326. {
  327. case 'd':
  328. case 'x':
  329. case 'X':
  330. val = va_arg(ap, long);
  331. switch (c)
  332. {
  333. case 'd':
  334. if (val < 0)
  335. {
  336. sign = '-';
  337. val = -val;
  338. }
  339. length = _cvt(val, buf, 10, "0123456789");
  340. break;
  341. case 'x':
  342. length = _cvt(val, buf, 16, "0123456789abcdef");
  343. break;
  344. case 'X':
  345. length = _cvt(val, buf, 16, "0123456789ABCDEF");
  346. break;
  347. }
  348. cp = buf;
  349. break;
  350. case 's':
  351. cp = va_arg(ap, char *);
  352. length = strlen(cp);
  353. break;
  354. case 'c':
  355. c = va_arg(ap, long /*char*/);
  356. (*putc)(c);
  357. continue;
  358. default:
  359. (*putc)('?');
  360. }
  361. pad = left_prec - length;
  362. if (sign != '')
  363. {
  364. pad--;
  365. }
  366. if (zero_fill)
  367. {
  368. c = '0';
  369. if (sign != '')
  370. {
  371. (*putc)(sign);
  372. sign = '';
  373. }
  374. } else
  375. {
  376. c = ' ';
  377. }
  378. if (!pad_on_right)
  379. {
  380. while (pad-- > 0)
  381. {
  382. (*putc)(c);
  383. }
  384. }
  385. if (sign != '')
  386. {
  387. (*putc)(sign);
  388. }
  389. while (length-- > 0)
  390. {
  391. (*putc)(c = *cp++);
  392. if (c == 'n')
  393. {
  394. (*putc)('r');
  395. }
  396. }
  397. if (pad_on_right)
  398. {
  399. while (pad-- > 0)
  400. {
  401. (*putc)(c);
  402. }
  403. }
  404. } else
  405. {
  406. (*putc)(c);
  407. if (c == 'n')
  408. {
  409. (*putc)('r');
  410. }
  411. }
  412. }
  413. }
  414. int
  415. _cvt(unsigned long val, char *buf, long radix, char *digits)
  416. {
  417. char temp[80];
  418. char *cp = temp;
  419. int length = 0;
  420. if (val == 0)
  421. { /* Special case */
  422. *cp++ = '0';
  423. } else
  424. while (val)
  425. {
  426. *cp++ = digits[val % radix];
  427. val /= radix;
  428. }
  429. while (cp != temp)
  430. {
  431. *buf++ = *--cp;
  432. length++;
  433. }
  434. *buf = '';
  435. return (length);
  436. }
  437. void
  438. _dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
  439. {
  440. int i, c;
  441. if ((unsigned int)s > (unsigned int)p)
  442. {
  443. s = (unsigned int)s - (unsigned int)p;
  444. }
  445. while (s > 0)
  446. {
  447. if (base)
  448. {
  449. _printk("%06X: ", (int)p - (int)base);
  450. } else
  451. {
  452. _printk("%06X: ", p);
  453. }
  454. for (i = 0;  i < 16;  i++)
  455. {
  456. if (i < s)
  457. {
  458. _printk("%02X", p[i] & 0xFF);
  459. } else
  460. {
  461. _printk("  ");
  462. }
  463. if ((i % 2) == 1) _printk(" ");
  464. if ((i % 8) == 7) _printk(" ");
  465. }
  466. _printk(" |");
  467. for (i = 0;  i < 16;  i++)
  468. {
  469. if (i < s)
  470. {
  471. c = p[i] & 0xFF;
  472. if ((c < 0x20) || (c >= 0x7F)) c = '.';
  473. } else
  474. {
  475. c = ' ';
  476. }
  477. _printk("%c", c);
  478. }
  479. _printk("|n");
  480. s -= 16;
  481. p += 16;
  482. }
  483. }
  484. void
  485. _dump_buf(unsigned char *p, int s)
  486. {
  487. _printk("n");
  488. _dump_buf_with_offset(p, s, 0);
  489. }
  490. /* Very simple inb/outb routines.  We declare ISA_io to be 0 above, and
  491.  * then modify it on platforms which need to.  We do it like this
  492.  * because on some platforms we give inb/outb an exact location, and
  493.  * on others it's an offset from a given location. -- Tom
  494.  */
  495. void
  496. outb(int port, unsigned char val)
  497. {
  498. /* Ensure I/O operations complete */
  499. __asm__ volatile("eieio");
  500. ISA_io[port] = val;
  501. }
  502. unsigned char
  503. inb(int port)
  504. {
  505. /* Ensure I/O operations complete */
  506. __asm__ volatile("eieio");
  507. return (ISA_io[port]);
  508. }
  509. /*
  510.  * Local variables:
  511.  *  c-indent-level: 8
  512.  *  c-basic-offset: 8
  513.  *  tab-width: 8
  514.  * End:
  515.  */