Linux Audio

Check our new training course

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