Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Procedures for drawing on the screen early on in the boot process.
  4 *
  5 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
  6 */
  7#include <linux/kernel.h>
  8#include <linux/string.h>
  9#include <linux/init.h>
 10#include <linux/export.h>
 11#include <linux/font.h>
 12#include <linux/memblock.h>
 13#include <linux/pgtable.h>
 14#include <linux/of.h>
 15
 16#include <asm/sections.h>
 
 17#include <asm/btext.h>
 18#include <asm/page.h>
 19#include <asm/mmu.h>
 
 20#include <asm/io.h>
 21#include <asm/processor.h>
 22#include <asm/udbg.h>
 23
 24#define NO_SCROLL
 25
 26#ifndef NO_SCROLL
 27static void scrollscreen(void);
 28#endif
 29
 30#define __force_data __section(".data")
 
 
 
 
 
 31
 32static int g_loc_X __force_data;
 33static int g_loc_Y __force_data;
 34static int g_max_loc_X __force_data;
 35static int g_max_loc_Y __force_data;
 36
 37static int dispDeviceRowBytes __force_data;
 38static int dispDeviceDepth  __force_data;
 39static int dispDeviceRect[4] __force_data;
 40static unsigned char *dispDeviceBase __force_data;
 41static unsigned char *logicalDisplayBase __force_data;
 42
 43unsigned long disp_BAT[2] __initdata = {0, 0};
 44
 45static int boot_text_mapped __force_data;
 46
 47extern void rmci_on(void);
 48extern void rmci_off(void);
 49
 50static inline void rmci_maybe_on(void)
 51{
 52#if defined(CONFIG_PPC_EARLY_DEBUG_BOOTX) && defined(CONFIG_PPC64)
 53	if (!(mfmsr() & MSR_DR))
 54		rmci_on();
 55#endif
 56}
 57
 58static inline void rmci_maybe_off(void)
 59{
 60#if defined(CONFIG_PPC_EARLY_DEBUG_BOOTX) && defined(CONFIG_PPC64)
 61	if (!(mfmsr() & MSR_DR))
 62		rmci_off();
 63#endif
 64}
 65
 
 
 66
 67#ifdef CONFIG_PPC32
 68/* Calc BAT values for mapping the display and store them
 69 * in disp_BAT.  Those values are then used from head.S to map
 70 * the display during identify_machine() and MMU_Init()
 71 *
 72 * The display is mapped to virtual address 0xD0000000, rather
 73 * than 1:1, because some CHRP machines put the frame buffer
 74 * in the region starting at 0xC0000000 (PAGE_OFFSET).
 75 * This mapping is temporary and will disappear as soon as the
 76 * setup done by MMU_Init() is applied.
 77 *
 78 * For now, we align the BAT and then map 8Mb on 601 and 16Mb
 79 * on other PPCs. This may cause trouble if the framebuffer
 80 * is really badly aligned, but I didn't encounter this case
 81 * yet.
 82 */
 83void __init btext_prepare_BAT(void)
 84{
 85	unsigned long vaddr = PAGE_OFFSET + 0x10000000;
 86	unsigned long addr;
 87	unsigned long lowbits;
 88
 89	addr = (unsigned long)dispDeviceBase;
 90	if (!addr) {
 91		boot_text_mapped = 0;
 92		return;
 93	}
 94	lowbits = addr & ~0xFF000000UL;
 95	addr &= 0xFF000000UL;
 96	disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
 97	disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
 
 
 
 
 
 
 
 
 
 98	logicalDisplayBase = (void *) (vaddr + lowbits);
 99}
100#endif
101
102
103/* This function can be used to enable the early boot text when doing
104 * OF booting or within bootx init. It must be followed by a btext_unmap()
105 * call before the logical address becomes unusable
106 */
107void __init btext_setup_display(int width, int height, int depth, int pitch,
108				unsigned long address)
109{
110	g_loc_X = 0;
111	g_loc_Y = 0;
112	g_max_loc_X = width / 8;
113	g_max_loc_Y = height / 16;
114	logicalDisplayBase = (unsigned char *)address;
115	dispDeviceBase = (unsigned char *)address;
116	dispDeviceRowBytes = pitch;
117	dispDeviceDepth = depth == 15 ? 16 : depth;
118	dispDeviceRect[0] = dispDeviceRect[1] = 0;
119	dispDeviceRect[2] = width;
120	dispDeviceRect[3] = height;
121	boot_text_mapped = 1;
122}
123
124void __init btext_unmap(void)
125{
126	boot_text_mapped = 0;
127}
128
129/* Here's a small text engine to use during early boot
130 * or for debugging purposes
131 *
132 * todo:
133 *
134 *  - build some kind of vgacon with it to enable early printk
135 *  - move to a separate file
136 *  - add a few video driver hooks to keep in sync with display
137 *    changes.
138 */
139
140void btext_map(void)
141{
142	unsigned long base, offset, size;
143	unsigned char *vbase;
144
145	/* By default, we are no longer mapped */
146	boot_text_mapped = 0;
147	if (!dispDeviceBase)
148		return;
149	base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
150	offset = ((unsigned long) dispDeviceBase) - base;
151	size = dispDeviceRowBytes * dispDeviceRect[3] + offset
152		+ dispDeviceRect[0];
153	vbase = ioremap_wc(base, size);
154	if (!vbase)
155		return;
156	logicalDisplayBase = vbase + offset;
157	boot_text_mapped = 1;
158}
159
160static int __init btext_initialize(struct device_node *np)
161{
162	unsigned int width, height, depth, pitch;
163	unsigned long address = 0;
164	const u32 *prop;
165
166	prop = of_get_property(np, "linux,bootx-width", NULL);
167	if (prop == NULL)
168		prop = of_get_property(np, "width", NULL);
169	if (prop == NULL)
170		return -EINVAL;
171	width = *prop;
172	prop = of_get_property(np, "linux,bootx-height", NULL);
173	if (prop == NULL)
174		prop = of_get_property(np, "height", NULL);
175	if (prop == NULL)
176		return -EINVAL;
177	height = *prop;
178	prop = of_get_property(np, "linux,bootx-depth", NULL);
179	if (prop == NULL)
180		prop = of_get_property(np, "depth", NULL);
181	if (prop == NULL)
182		return -EINVAL;
183	depth = *prop;
184	pitch = width * ((depth + 7) / 8);
185	prop = of_get_property(np, "linux,bootx-linebytes", NULL);
186	if (prop == NULL)
187		prop = of_get_property(np, "linebytes", NULL);
188	if (prop && *prop != 0xffffffffu)
189		pitch = *prop;
190	if (pitch == 1)
191		pitch = 0x1000;
192	prop = of_get_property(np, "linux,bootx-addr", NULL);
193	if (prop == NULL)
194		prop = of_get_property(np, "address", NULL);
195	if (prop)
196		address = *prop;
197
198	/* FIXME: Add support for PCI reg properties. Right now, only
199	 * reliable on macs
200	 */
201	if (address == 0)
202		return -EINVAL;
203
204	g_loc_X = 0;
205	g_loc_Y = 0;
206	g_max_loc_X = width / 8;
207	g_max_loc_Y = height / 16;
208	dispDeviceBase = (unsigned char *)address;
209	dispDeviceRowBytes = pitch;
210	dispDeviceDepth = depth == 15 ? 16 : depth;
211	dispDeviceRect[0] = dispDeviceRect[1] = 0;
212	dispDeviceRect[2] = width;
213	dispDeviceRect[3] = height;
214
215	btext_map();
216
217	return 0;
218}
219
220int __init btext_find_display(int allow_nonstdout)
221{
222	struct device_node *np = of_stdout;
 
223	int rc = -ENODEV;
224
225	if (!of_node_is_type(np, "display")) {
226		printk("boot stdout isn't a display !\n");
227		np = NULL;
 
 
 
 
 
 
 
228	}
229	if (np)
230		rc = btext_initialize(np);
231	if (rc == 0 || !allow_nonstdout)
232		return rc;
233
234	for_each_node_by_type(np, "display") {
235		if (of_property_read_bool(np, "linux,opened")) {
236			printk("trying %pOF ...\n", np);
237			rc = btext_initialize(np);
238			printk("result: %d\n", rc);
239		}
240		if (rc == 0) {
241			of_node_put(np);
242			break;
243		}
244	}
245	return rc;
246}
247
248/* Calc the base address of a given point (x,y) */
249static unsigned char * calc_base(int x, int y)
250{
251	unsigned char *base;
252
253	base = logicalDisplayBase;
254	if (!base)
255		base = dispDeviceBase;
256	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
257	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
258	return base;
259}
260
261/* Adjust the display to a new resolution */
262void btext_update_display(unsigned long phys, int width, int height,
263			  int depth, int pitch)
264{
265	if (!dispDeviceBase)
266		return;
267
268	/* check it's the same frame buffer (within 256MB) */
269	if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
270		return;
271
272	dispDeviceBase = (__u8 *) phys;
273	dispDeviceRect[0] = 0;
274	dispDeviceRect[1] = 0;
275	dispDeviceRect[2] = width;
276	dispDeviceRect[3] = height;
277	dispDeviceDepth = depth;
278	dispDeviceRowBytes = pitch;
279	if (boot_text_mapped) {
280		iounmap(logicalDisplayBase);
281		boot_text_mapped = 0;
282	}
283	btext_map();
284	g_loc_X = 0;
285	g_loc_Y = 0;
286	g_max_loc_X = width / 8;
287	g_max_loc_Y = height / 16;
288}
289EXPORT_SYMBOL(btext_update_display);
290
291void __init btext_clearscreen(void)
292{
293	unsigned int *base	= (unsigned int *)calc_base(0, 0);
294	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
295					(dispDeviceDepth >> 3)) >> 2;
296	int i,j;
297
298	rmci_maybe_on();
299	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
300	{
301		unsigned int *ptr = base;
302		for(j=width; j; --j)
303			*(ptr++) = 0;
304		base += (dispDeviceRowBytes >> 2);
305	}
306	rmci_maybe_off();
307}
308
309void __init btext_flushscreen(void)
310{
311	unsigned int *base	= (unsigned int *)calc_base(0, 0);
312	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
313					(dispDeviceDepth >> 3)) >> 2;
314	int i,j;
315
316	for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
317	{
318		unsigned int *ptr = base;
319		for(j = width; j > 0; j -= 8) {
320			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
321			ptr += 8;
322		}
323		base += (dispDeviceRowBytes >> 2);
324	}
325	__asm__ __volatile__ ("sync" ::: "memory");
326}
327
328void __init btext_flushline(void)
329{
330	unsigned int *base	= (unsigned int *)calc_base(0, g_loc_Y << 4);
331	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
332					(dispDeviceDepth >> 3)) >> 2;
333	int i,j;
334
335	for (i=0; i < 16; i++)
336	{
337		unsigned int *ptr = base;
338		for(j = width; j > 0; j -= 8) {
339			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
340			ptr += 8;
341		}
342		base += (dispDeviceRowBytes >> 2);
343	}
344	__asm__ __volatile__ ("sync" ::: "memory");
345}
346
347
348#ifndef NO_SCROLL
349static void scrollscreen(void)
350{
351	unsigned int *src     	= (unsigned int *)calc_base(0,16);
352	unsigned int *dst     	= (unsigned int *)calc_base(0,0);
353	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
354				   (dispDeviceDepth >> 3)) >> 2;
355	int i,j;
356
357	rmci_maybe_on();
358
359	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
360	{
361		unsigned int *src_ptr = src;
362		unsigned int *dst_ptr = dst;
363		for(j=width; j; --j)
364			*(dst_ptr++) = *(src_ptr++);
365		src += (dispDeviceRowBytes >> 2);
366		dst += (dispDeviceRowBytes >> 2);
367	}
368	for (i=0; i<16; i++)
369	{
370		unsigned int *dst_ptr = dst;
371		for(j=width; j; --j)
372			*(dst_ptr++) = 0;
373		dst += (dispDeviceRowBytes >> 2);
374	}
375
376	rmci_maybe_off();
377}
378#endif /* ndef NO_SCROLL */
379
380static unsigned int expand_bits_8[16] = {
381	0x00000000,
382	0x000000ff,
383	0x0000ff00,
384	0x0000ffff,
385	0x00ff0000,
386	0x00ff00ff,
387	0x00ffff00,
388	0x00ffffff,
389	0xff000000,
390	0xff0000ff,
391	0xff00ff00,
392	0xff00ffff,
393	0xffff0000,
394	0xffff00ff,
395	0xffffff00,
396	0xffffffff
397};
398
399static unsigned int expand_bits_16[4] = {
400	0x00000000,
401	0x0000ffff,
402	0xffff0000,
403	0xffffffff
404};
405
406
407static void draw_byte_32(const unsigned char *font, unsigned int *base, int rb)
408{
409	int l, bits;
410	int fg = 0xFFFFFFFFUL;
411	int bg = 0x00000000UL;
412
413	for (l = 0; l < 16; ++l)
414	{
415		bits = *font++;
416		base[0] = (-(bits >> 7) & fg) ^ bg;
417		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
418		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
419		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
420		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
421		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
422		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
423		base[7] = (-(bits & 1) & fg) ^ bg;
424		base = (unsigned int *) ((char *)base + rb);
425	}
426}
427
428static inline void draw_byte_16(const unsigned char *font, unsigned int *base, int rb)
429{
430	int l, bits;
431	int fg = 0xFFFFFFFFUL;
432	int bg = 0x00000000UL;
433	unsigned int *eb = (int *)expand_bits_16;
434
435	for (l = 0; l < 16; ++l)
436	{
437		bits = *font++;
438		base[0] = (eb[bits >> 6] & fg) ^ bg;
439		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
440		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
441		base[3] = (eb[bits & 3] & fg) ^ bg;
442		base = (unsigned int *) ((char *)base + rb);
443	}
444}
445
446static inline void draw_byte_8(const unsigned char *font, unsigned int *base, int rb)
447{
448	int l, bits;
449	int fg = 0x0F0F0F0FUL;
450	int bg = 0x00000000UL;
451	unsigned int *eb = (int *)expand_bits_8;
452
453	for (l = 0; l < 16; ++l)
454	{
455		bits = *font++;
456		base[0] = (eb[bits >> 4] & fg) ^ bg;
457		base[1] = (eb[bits & 0xf] & fg) ^ bg;
458		base = (unsigned int *) ((char *)base + rb);
459	}
460}
461
462static noinline void draw_byte(unsigned char c, long locX, long locY)
463{
464	unsigned char *base	= calc_base(locX << 3, locY << 4);
465	unsigned int font_index = c * 16;
466	const unsigned char *font	= font_sun_8x16.data + font_index;
467	int rb			= dispDeviceRowBytes;
468
469	rmci_maybe_on();
470	switch(dispDeviceDepth) {
471	case 24:
472	case 32:
473		draw_byte_32(font, (unsigned int *)base, rb);
474		break;
475	case 15:
476	case 16:
477		draw_byte_16(font, (unsigned int *)base, rb);
478		break;
479	case 8:
480		draw_byte_8(font, (unsigned int *)base, rb);
481		break;
482	}
483	rmci_maybe_off();
484}
485
486void btext_drawchar(char c)
487{
488	int cline = 0;
489#ifdef NO_SCROLL
490	int x;
491#endif
492	if (!boot_text_mapped)
493		return;
494
495	switch (c) {
496	case '\b':
497		if (g_loc_X > 0)
498			--g_loc_X;
499		break;
500	case '\t':
501		g_loc_X = (g_loc_X & -8) + 8;
502		break;
503	case '\r':
504		g_loc_X = 0;
505		break;
506	case '\n':
507		g_loc_X = 0;
508		g_loc_Y++;
509		cline = 1;
510		break;
511	default:
512		draw_byte(c, g_loc_X++, g_loc_Y);
513	}
514	if (g_loc_X >= g_max_loc_X) {
515		g_loc_X = 0;
516		g_loc_Y++;
517		cline = 1;
518	}
519#ifndef NO_SCROLL
520	while (g_loc_Y >= g_max_loc_Y) {
521		scrollscreen();
522		g_loc_Y--;
523	}
524#else
525	/* wrap around from bottom to top of screen so we don't
526	   waste time scrolling each line.  -- paulus. */
527	if (g_loc_Y >= g_max_loc_Y)
528		g_loc_Y = 0;
529	if (cline) {
530		for (x = 0; x < g_max_loc_X; ++x)
531			draw_byte(' ', x, g_loc_Y);
532	}
533#endif
534}
535
536void btext_drawstring(const char *c)
537{
538	if (!boot_text_mapped)
539		return;
540	while (*c)
541		btext_drawchar(*c++);
542}
543
544void __init btext_drawtext(const char *c, unsigned int len)
545{
546	if (!boot_text_mapped)
547		return;
548	while (len--)
549		btext_drawchar(*c++);
550}
551
552void __init btext_drawhex(unsigned long v)
553{
554	if (!boot_text_mapped)
555		return;
556#ifdef CONFIG_PPC64
557	btext_drawchar(hex_asc_hi(v >> 56));
558	btext_drawchar(hex_asc_lo(v >> 56));
559	btext_drawchar(hex_asc_hi(v >> 48));
560	btext_drawchar(hex_asc_lo(v >> 48));
561	btext_drawchar(hex_asc_hi(v >> 40));
562	btext_drawchar(hex_asc_lo(v >> 40));
563	btext_drawchar(hex_asc_hi(v >> 32));
564	btext_drawchar(hex_asc_lo(v >> 32));
565#endif
566	btext_drawchar(hex_asc_hi(v >> 24));
567	btext_drawchar(hex_asc_lo(v >> 24));
568	btext_drawchar(hex_asc_hi(v >> 16));
569	btext_drawchar(hex_asc_lo(v >> 16));
570	btext_drawchar(hex_asc_hi(v >> 8));
571	btext_drawchar(hex_asc_lo(v >> 8));
572	btext_drawchar(hex_asc_hi(v));
573	btext_drawchar(hex_asc_lo(v));
574	btext_drawchar(' ');
575}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
577void __init udbg_init_btext(void)
578{
579	/* If btext is enabled, we might have a BAT setup for early display,
580	 * thus we do enable some very basic udbg output
581	 */
582	udbg_putc = btext_drawchar;
583}
v3.1
 
  1/*
  2 * Procedures for drawing on the screen early on in the boot process.
  3 *
  4 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
  5 */
  6#include <linux/kernel.h>
  7#include <linux/string.h>
  8#include <linux/init.h>
  9#include <linux/module.h>
 
 10#include <linux/memblock.h>
 
 
 11
 12#include <asm/sections.h>
 13#include <asm/prom.h>
 14#include <asm/btext.h>
 15#include <asm/page.h>
 16#include <asm/mmu.h>
 17#include <asm/pgtable.h>
 18#include <asm/io.h>
 19#include <asm/processor.h>
 20#include <asm/udbg.h>
 21
 22#define NO_SCROLL
 23
 24#ifndef NO_SCROLL
 25static void scrollscreen(void);
 26#endif
 27
 28static void draw_byte(unsigned char c, long locX, long locY);
 29static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
 30static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
 31static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
 32
 33#define __force_data __attribute__((__section__(".data")))
 34
 35static int g_loc_X __force_data;
 36static int g_loc_Y __force_data;
 37static int g_max_loc_X __force_data;
 38static int g_max_loc_Y __force_data;
 39
 40static int dispDeviceRowBytes __force_data;
 41static int dispDeviceDepth  __force_data;
 42static int dispDeviceRect[4] __force_data;
 43static unsigned char *dispDeviceBase __force_data;
 44static unsigned char *logicalDisplayBase __force_data;
 45
 46unsigned long disp_BAT[2] __initdata = {0, 0};
 47
 48#define cmapsz	(16*256)
 
 
 
 49
 50static unsigned char vga_font[cmapsz];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 51
 52int boot_text_mapped __force_data = 0;
 53int force_printk_to_btext = 0;
 54
 55#ifdef CONFIG_PPC32
 56/* Calc BAT values for mapping the display and store them
 57 * in disp_BAT.  Those values are then used from head.S to map
 58 * the display during identify_machine() and MMU_Init()
 59 *
 60 * The display is mapped to virtual address 0xD0000000, rather
 61 * than 1:1, because some some CHRP machines put the frame buffer
 62 * in the region starting at 0xC0000000 (PAGE_OFFSET).
 63 * This mapping is temporary and will disappear as soon as the
 64 * setup done by MMU_Init() is applied.
 65 *
 66 * For now, we align the BAT and then map 8Mb on 601 and 16Mb
 67 * on other PPCs. This may cause trouble if the framebuffer
 68 * is really badly aligned, but I didn't encounter this case
 69 * yet.
 70 */
 71void __init btext_prepare_BAT(void)
 72{
 73	unsigned long vaddr = PAGE_OFFSET + 0x10000000;
 74	unsigned long addr;
 75	unsigned long lowbits;
 76
 77	addr = (unsigned long)dispDeviceBase;
 78	if (!addr) {
 79		boot_text_mapped = 0;
 80		return;
 81	}
 82	if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
 83		/* 603, 604, G3, G4, ... */
 84		lowbits = addr & ~0xFF000000UL;
 85		addr &= 0xFF000000UL;
 86		disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
 87		disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);	
 88	} else {
 89		/* 601 */
 90		lowbits = addr & ~0xFF800000UL;
 91		addr &= 0xFF800000UL;
 92		disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
 93		disp_BAT[1] = addr | BL_8M | 0x40;
 94	}
 95	logicalDisplayBase = (void *) (vaddr + lowbits);
 96}
 97#endif
 98
 99
100/* This function can be used to enable the early boot text when doing
101 * OF booting or within bootx init. It must be followed by a btext_unmap()
102 * call before the logical address becomes unusable
103 */
104void __init btext_setup_display(int width, int height, int depth, int pitch,
105				unsigned long address)
106{
107	g_loc_X = 0;
108	g_loc_Y = 0;
109	g_max_loc_X = width / 8;
110	g_max_loc_Y = height / 16;
111	logicalDisplayBase = (unsigned char *)address;
112	dispDeviceBase = (unsigned char *)address;
113	dispDeviceRowBytes = pitch;
114	dispDeviceDepth = depth == 15 ? 16 : depth;
115	dispDeviceRect[0] = dispDeviceRect[1] = 0;
116	dispDeviceRect[2] = width;
117	dispDeviceRect[3] = height;
118	boot_text_mapped = 1;
119}
120
121void __init btext_unmap(void)
122{
123	boot_text_mapped = 0;
124}
125
126/* Here's a small text engine to use during early boot
127 * or for debugging purposes
128 *
129 * todo:
130 *
131 *  - build some kind of vgacon with it to enable early printk
132 *  - move to a separate file
133 *  - add a few video driver hooks to keep in sync with display
134 *    changes.
135 */
136
137static void map_boot_text(void)
138{
139	unsigned long base, offset, size;
140	unsigned char *vbase;
141
142	/* By default, we are no longer mapped */
143	boot_text_mapped = 0;
144	if (dispDeviceBase == 0)
145		return;
146	base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
147	offset = ((unsigned long) dispDeviceBase) - base;
148	size = dispDeviceRowBytes * dispDeviceRect[3] + offset
149		+ dispDeviceRect[0];
150	vbase = __ioremap(base, size, _PAGE_NO_CACHE);
151	if (vbase == 0)
152		return;
153	logicalDisplayBase = vbase + offset;
154	boot_text_mapped = 1;
155}
156
157int btext_initialize(struct device_node *np)
158{
159	unsigned int width, height, depth, pitch;
160	unsigned long address = 0;
161	const u32 *prop;
162
163	prop = of_get_property(np, "linux,bootx-width", NULL);
164	if (prop == NULL)
165		prop = of_get_property(np, "width", NULL);
166	if (prop == NULL)
167		return -EINVAL;
168	width = *prop;
169	prop = of_get_property(np, "linux,bootx-height", NULL);
170	if (prop == NULL)
171		prop = of_get_property(np, "height", NULL);
172	if (prop == NULL)
173		return -EINVAL;
174	height = *prop;
175	prop = of_get_property(np, "linux,bootx-depth", NULL);
176	if (prop == NULL)
177		prop = of_get_property(np, "depth", NULL);
178	if (prop == NULL)
179		return -EINVAL;
180	depth = *prop;
181	pitch = width * ((depth + 7) / 8);
182	prop = of_get_property(np, "linux,bootx-linebytes", NULL);
183	if (prop == NULL)
184		prop = of_get_property(np, "linebytes", NULL);
185	if (prop && *prop != 0xffffffffu)
186		pitch = *prop;
187	if (pitch == 1)
188		pitch = 0x1000;
189	prop = of_get_property(np, "linux,bootx-addr", NULL);
190	if (prop == NULL)
191		prop = of_get_property(np, "address", NULL);
192	if (prop)
193		address = *prop;
194
195	/* FIXME: Add support for PCI reg properties. Right now, only
196	 * reliable on macs
197	 */
198	if (address == 0)
199		return -EINVAL;
200
201	g_loc_X = 0;
202	g_loc_Y = 0;
203	g_max_loc_X = width / 8;
204	g_max_loc_Y = height / 16;
205	dispDeviceBase = (unsigned char *)address;
206	dispDeviceRowBytes = pitch;
207	dispDeviceDepth = depth == 15 ? 16 : depth;
208	dispDeviceRect[0] = dispDeviceRect[1] = 0;
209	dispDeviceRect[2] = width;
210	dispDeviceRect[3] = height;
211
212	map_boot_text();
213
214	return 0;
215}
216
217int __init btext_find_display(int allow_nonstdout)
218{
219	const char *name;
220	struct device_node *np = NULL; 
221	int rc = -ENODEV;
222
223	name = of_get_property(of_chosen, "linux,stdout-path", NULL);
224	if (name != NULL) {
225		np = of_find_node_by_path(name);
226		if (np != NULL) {
227			if (strcmp(np->type, "display") != 0) {
228				printk("boot stdout isn't a display !\n");
229				of_node_put(np);
230				np = NULL;
231			}
232		}
233	}
234	if (np)
235		rc = btext_initialize(np);
236	if (rc == 0 || !allow_nonstdout)
237		return rc;
238
239	for_each_node_by_type(np, "display") {
240		if (of_get_property(np, "linux,opened", NULL)) {
241			printk("trying %s ...\n", np->full_name);
242			rc = btext_initialize(np);
243			printk("result: %d\n", rc);
244		}
245		if (rc == 0)
 
246			break;
 
247	}
248	return rc;
249}
250
251/* Calc the base address of a given point (x,y) */
252static unsigned char * calc_base(int x, int y)
253{
254	unsigned char *base;
255
256	base = logicalDisplayBase;
257	if (base == 0)
258		base = dispDeviceBase;
259	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
260	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
261	return base;
262}
263
264/* Adjust the display to a new resolution */
265void btext_update_display(unsigned long phys, int width, int height,
266			  int depth, int pitch)
267{
268	if (dispDeviceBase == 0)
269		return;
270
271	/* check it's the same frame buffer (within 256MB) */
272	if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
273		return;
274
275	dispDeviceBase = (__u8 *) phys;
276	dispDeviceRect[0] = 0;
277	dispDeviceRect[1] = 0;
278	dispDeviceRect[2] = width;
279	dispDeviceRect[3] = height;
280	dispDeviceDepth = depth;
281	dispDeviceRowBytes = pitch;
282	if (boot_text_mapped) {
283		iounmap(logicalDisplayBase);
284		boot_text_mapped = 0;
285	}
286	map_boot_text();
287	g_loc_X = 0;
288	g_loc_Y = 0;
289	g_max_loc_X = width / 8;
290	g_max_loc_Y = height / 16;
291}
292EXPORT_SYMBOL(btext_update_display);
293
294void btext_clearscreen(void)
295{
296	unsigned int *base	= (unsigned int *)calc_base(0, 0);
297	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
298					(dispDeviceDepth >> 3)) >> 2;
299	int i,j;
300
 
301	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
302	{
303		unsigned int *ptr = base;
304		for(j=width; j; --j)
305			*(ptr++) = 0;
306		base += (dispDeviceRowBytes >> 2);
307	}
 
308}
309
310void btext_flushscreen(void)
311{
312	unsigned int *base	= (unsigned int *)calc_base(0, 0);
313	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
314					(dispDeviceDepth >> 3)) >> 2;
315	int i,j;
316
317	for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
318	{
319		unsigned int *ptr = base;
320		for(j = width; j > 0; j -= 8) {
321			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
322			ptr += 8;
323		}
324		base += (dispDeviceRowBytes >> 2);
325	}
326	__asm__ __volatile__ ("sync" ::: "memory");
327}
328
329void btext_flushline(void)
330{
331	unsigned int *base	= (unsigned int *)calc_base(0, g_loc_Y << 4);
332	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
333					(dispDeviceDepth >> 3)) >> 2;
334	int i,j;
335
336	for (i=0; i < 16; i++)
337	{
338		unsigned int *ptr = base;
339		for(j = width; j > 0; j -= 8) {
340			__asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
341			ptr += 8;
342		}
343		base += (dispDeviceRowBytes >> 2);
344	}
345	__asm__ __volatile__ ("sync" ::: "memory");
346}
347
348
349#ifndef NO_SCROLL
350static void scrollscreen(void)
351{
352	unsigned int *src     	= (unsigned int *)calc_base(0,16);
353	unsigned int *dst     	= (unsigned int *)calc_base(0,0);
354	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
355				   (dispDeviceDepth >> 3)) >> 2;
356	int i,j;
357
 
 
358	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
359	{
360		unsigned int *src_ptr = src;
361		unsigned int *dst_ptr = dst;
362		for(j=width; j; --j)
363			*(dst_ptr++) = *(src_ptr++);
364		src += (dispDeviceRowBytes >> 2);
365		dst += (dispDeviceRowBytes >> 2);
366	}
367	for (i=0; i<16; i++)
368	{
369		unsigned int *dst_ptr = dst;
370		for(j=width; j; --j)
371			*(dst_ptr++) = 0;
372		dst += (dispDeviceRowBytes >> 2);
373	}
 
 
374}
375#endif /* ndef NO_SCROLL */
376
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377void btext_drawchar(char c)
378{
379	int cline = 0;
380#ifdef NO_SCROLL
381	int x;
382#endif
383	if (!boot_text_mapped)
384		return;
385
386	switch (c) {
387	case '\b':
388		if (g_loc_X > 0)
389			--g_loc_X;
390		break;
391	case '\t':
392		g_loc_X = (g_loc_X & -8) + 8;
393		break;
394	case '\r':
395		g_loc_X = 0;
396		break;
397	case '\n':
398		g_loc_X = 0;
399		g_loc_Y++;
400		cline = 1;
401		break;
402	default:
403		draw_byte(c, g_loc_X++, g_loc_Y);
404	}
405	if (g_loc_X >= g_max_loc_X) {
406		g_loc_X = 0;
407		g_loc_Y++;
408		cline = 1;
409	}
410#ifndef NO_SCROLL
411	while (g_loc_Y >= g_max_loc_Y) {
412		scrollscreen();
413		g_loc_Y--;
414	}
415#else
416	/* wrap around from bottom to top of screen so we don't
417	   waste time scrolling each line.  -- paulus. */
418	if (g_loc_Y >= g_max_loc_Y)
419		g_loc_Y = 0;
420	if (cline) {
421		for (x = 0; x < g_max_loc_X; ++x)
422			draw_byte(' ', x, g_loc_Y);
423	}
424#endif
425}
426
427void btext_drawstring(const char *c)
428{
429	if (!boot_text_mapped)
430		return;
431	while (*c)
432		btext_drawchar(*c++);
433}
434
435void btext_drawtext(const char *c, unsigned int len)
436{
437	if (!boot_text_mapped)
438		return;
439	while (len--)
440		btext_drawchar(*c++);
441}
442
443void btext_drawhex(unsigned long v)
444{
445	if (!boot_text_mapped)
446		return;
447#ifdef CONFIG_PPC64
448	btext_drawchar(hex_asc_hi(v >> 56));
449	btext_drawchar(hex_asc_lo(v >> 56));
450	btext_drawchar(hex_asc_hi(v >> 48));
451	btext_drawchar(hex_asc_lo(v >> 48));
452	btext_drawchar(hex_asc_hi(v >> 40));
453	btext_drawchar(hex_asc_lo(v >> 40));
454	btext_drawchar(hex_asc_hi(v >> 32));
455	btext_drawchar(hex_asc_lo(v >> 32));
456#endif
457	btext_drawchar(hex_asc_hi(v >> 24));
458	btext_drawchar(hex_asc_lo(v >> 24));
459	btext_drawchar(hex_asc_hi(v >> 16));
460	btext_drawchar(hex_asc_lo(v >> 16));
461	btext_drawchar(hex_asc_hi(v >> 8));
462	btext_drawchar(hex_asc_lo(v >> 8));
463	btext_drawchar(hex_asc_hi(v));
464	btext_drawchar(hex_asc_lo(v));
465	btext_drawchar(' ');
466}
467
468static void draw_byte(unsigned char c, long locX, long locY)
469{
470	unsigned char *base	= calc_base(locX << 3, locY << 4);
471	unsigned char *font	= &vga_font[((unsigned int)c) * 16];
472	int rb			= dispDeviceRowBytes;
473
474	switch(dispDeviceDepth) {
475	case 24:
476	case 32:
477		draw_byte_32(font, (unsigned int *)base, rb);
478		break;
479	case 15:
480	case 16:
481		draw_byte_16(font, (unsigned int *)base, rb);
482		break;
483	case 8:
484		draw_byte_8(font, (unsigned int *)base, rb);
485		break;
486	}
487}
488
489static unsigned int expand_bits_8[16] = {
490	0x00000000,
491	0x000000ff,
492	0x0000ff00,
493	0x0000ffff,
494	0x00ff0000,
495	0x00ff00ff,
496	0x00ffff00,
497	0x00ffffff,
498	0xff000000,
499	0xff0000ff,
500	0xff00ff00,
501	0xff00ffff,
502	0xffff0000,
503	0xffff00ff,
504	0xffffff00,
505	0xffffffff
506};
507
508static unsigned int expand_bits_16[4] = {
509	0x00000000,
510	0x0000ffff,
511	0xffff0000,
512	0xffffffff
513};
514
515
516static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
517{
518	int l, bits;
519	int fg = 0xFFFFFFFFUL;
520	int bg = 0x00000000UL;
521
522	for (l = 0; l < 16; ++l)
523	{
524		bits = *font++;
525		base[0] = (-(bits >> 7) & fg) ^ bg;
526		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
527		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
528		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
529		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
530		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
531		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
532		base[7] = (-(bits & 1) & fg) ^ bg;
533		base = (unsigned int *) ((char *)base + rb);
534	}
535}
536
537static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
538{
539	int l, bits;
540	int fg = 0xFFFFFFFFUL;
541	int bg = 0x00000000UL;
542	unsigned int *eb = (int *)expand_bits_16;
543
544	for (l = 0; l < 16; ++l)
545	{
546		bits = *font++;
547		base[0] = (eb[bits >> 6] & fg) ^ bg;
548		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
549		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
550		base[3] = (eb[bits & 3] & fg) ^ bg;
551		base = (unsigned int *) ((char *)base + rb);
552	}
553}
554
555static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
556{
557	int l, bits;
558	int fg = 0x0F0F0F0FUL;
559	int bg = 0x00000000UL;
560	unsigned int *eb = (int *)expand_bits_8;
561
562	for (l = 0; l < 16; ++l)
563	{
564		bits = *font++;
565		base[0] = (eb[bits >> 4] & fg) ^ bg;
566		base[1] = (eb[bits & 0xf] & fg) ^ bg;
567		base = (unsigned int *) ((char *)base + rb);
568	}
569}
570
571static unsigned char vga_font[cmapsz] = {
5720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
5740x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
5750xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
5760x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
5770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
5780x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
5790x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
5800x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
5810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
5820x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
5830xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5840x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
5850x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
5860xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
5870x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
5880x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
5890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
5900x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
5910x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
5920x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
5930x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
5940xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
5950x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
5960x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
5970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
5980x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
5990xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
6000x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
6010x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6020xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
6030x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
6040x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
6050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
6060x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6070x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6080x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
6090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
6100xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6110x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6120x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
6130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
6140x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6160x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
6170x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
6180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
6190x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
6200x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
6210x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
6220x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
6230x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
6240x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
6260x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
6270x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
6280x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
6290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
6300x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6310x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
6320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
6330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6340x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6350x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
6360x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
6370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
6380x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
6390x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
6400x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
6410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
6420x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
6430xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6440x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
6450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
6460x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
6470xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6480x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
6490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
6500x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6510x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
6520x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
6530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
6540x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
6550x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
6560x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
6570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
6580xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
6590x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
6600x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
6610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
6620xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
6630x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
6640x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
6650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
6660x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
6670xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
6680x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
6700x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
6710x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
6720x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
6730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
6740x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
6750xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
6760x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
6770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6780xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
6790x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
6800x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
6810x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
6820x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
6830xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6840x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6860xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
6870xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
6880x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
6890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
6900x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
6910xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
6920x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
6930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
6940x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
6950xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
6960x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
6970x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
6980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
7000x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
7020xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
7030x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
7040x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
7050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
7060xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7070x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7080x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
7090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
7100xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
7110x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
7120x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
7130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
7140x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
7150x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
7160x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
7170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
7180xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7190x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
7200x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
7220x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
7230x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
7240x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
7250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
7260x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
7270x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
7280x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
7290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
7300xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7310x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
7320x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
7330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
7340xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
7350x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
7360x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
7370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
7380x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
7390x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
7400x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
7420xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
7430xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
7440x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
7450x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
7460xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
7470x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
7480x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
7490x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
7500xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
7510x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
7520x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
7530x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
7540xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
7550x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7560x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
7570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
7580x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
7590x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
7600x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
7610x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
7620xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
7630x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
7640x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
7650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
7660x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
7670xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
7680x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
7700xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
7710x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7720x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
7730x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
7740xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
7750x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
7760x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7770x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
7780xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
7790xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
7800x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
7810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
7820xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
7830x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
7840x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
7850xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
7860xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
7870x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
7880x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7890x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
7900xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
7910x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
7920x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
7930x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
7940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
7950x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7960x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
7970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
7980xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7990x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
8000x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
8010x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
8020x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
8030x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
8040x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
8050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
8060x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
8070x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
8080x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
8090x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
8100xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
8110x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8120x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
8130x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
8140x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
8150x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
8170x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
8180x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
8190x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8200x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8210x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
8220x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8230x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8240x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
8250x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
8260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8270x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8280x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
8290x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
8300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8310x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8320x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
8330x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
8340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
8350x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8360x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
8370x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
8380x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8390x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8400x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
8410x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
8420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8430x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8440x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
8450x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
8460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
8470x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8480x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
8490x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
8500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8510x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
8530x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
8540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
8550x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8560x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
8570x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
8580x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8590x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8600x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
8610x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
8620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8630x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8640xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8650xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
8660xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
8670xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
8680x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
8690x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
8700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8710x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
8720x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
8730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
8740xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8750xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
8760x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
8770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
8780xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8790x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
8800x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
8820x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
8830x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
8840x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
8850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
8860x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8870x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8880x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
8890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
8900x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
8910xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
8920x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
8930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
8940x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
8950x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
8960x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
8970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
8980x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8990x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
9000x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
9010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
9020x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
9030x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
9050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9060x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
9070x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
9080x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
9090x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
9100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9110x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
9120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9130x00, 0x00, 0x00, 0x00,
914};
915
916void __init udbg_init_btext(void)
917{
918	/* If btext is enabled, we might have a BAT setup for early display,
919	 * thus we do enable some very basic udbg output
920	 */
921	udbg_putc = btext_drawchar;
922}