Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 17639 Details for
Bug 28625
Support for bootsplash in ac-sources
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
bootsplash patch for current ac-sources-2.4.22-r1
bootsplash-2.4.22-ac1.patch (text/plain), 105.91 KB, created by
Mario Vazquez
on 2003-09-13 10:19:51 UTC
(
hide
)
Description:
bootsplash patch for current ac-sources-2.4.22-r1
Filename:
MIME Type:
Creator:
Mario Vazquez
Created:
2003-09-13 10:19:51 UTC
Size:
105.91 KB
patch
obsolete
>diff -urN linux-2.4.22-rc2-ac3/drivers/char/console.c linux-2.4.22-rc2-ac3-new/drivers/char/console.c >--- linux-2.4.22-rc2-ac3/drivers/char/console.c 2003-08-21 07:31:58.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/char/console.c 2003-08-21 17:00:01.000000000 -0400 >@@ -3007,6 +3007,31 @@ > return 0; > } > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+void con_remap_def_color(int currcons, int new_color) >+{ >+ unsigned short *sbuf = screenbuf; >+ unsigned c, len = screenbuf_size >> 1; >+ int old_color; >+ >+ if (sbuf) { >+ old_color = def_color << 8; >+ new_color <<= 8; >+ while(len--) { >+ c = *sbuf; >+ if (((c ^ old_color) & 0xf000) == 0) >+ *sbuf ^= (old_color ^ new_color) & 0xf000; >+ if (((c ^ old_color) & 0x0f00) == 0) >+ *sbuf ^= (old_color ^ new_color) & 0x0f00; >+ sbuf++; >+ } >+ new_color >>= 8; >+ } >+ def_color = color = new_color; >+ update_attr(currcons); >+} >+#endif >+ > /* > * Visible symbols for modules > */ >diff -urN linux-2.4.22-rc2-ac3/drivers/char/keyboard.c linux-2.4.22-rc2-ac3-new/drivers/char/keyboard.c >--- linux-2.4.22-rc2-ac3/drivers/char/keyboard.c 2003-08-21 07:31:58.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/char/keyboard.c 2003-08-21 17:00:01.000000000 -0400 >@@ -263,6 +263,15 @@ > } else > rep = test_and_set_bit(keycode, key_down); > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ /* This code has to be redone for some non-x86 platforms */ >+ if (keycode == 0x3c || keycode == 0x01) { /* F2 and ESC on a PC keyboard */ >+ extern int splash_verbose(void); >+ if (splash_verbose()) >+ goto out; >+ } >+#endif >+ > #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ > if (keycode == SYSRQ_KEY) { > sysrq_pressed = !up_flag; >diff -urN linux-2.4.22-rc2-ac3/drivers/char/n_tty.c linux-2.4.22-rc2-ac3-new/drivers/char/n_tty.c >--- linux-2.4.22-rc2-ac3/drivers/char/n_tty.c 2003-08-21 07:31:58.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/char/n_tty.c 2003-08-21 17:00:01.000000000 -0400 >@@ -45,6 +45,7 @@ > #include <linux/string.h> > #include <linux/slab.h> > #include <linux/poll.h> >+#include <linux/config.h> > > #include <asm/uaccess.h> > #include <asm/system.h> >@@ -971,6 +972,16 @@ > return -EIO; > } > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (file->f_dentry->d_inode->i_rdev == CONSOLE_DEV || >+ file->f_dentry->d_inode->i_rdev == SYSCONS_DEV || >+ file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,0) || >+ file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,1)) { >+ extern int splash_verbose(void); >+ (void)splash_verbose(); >+ } >+#endif >+ > /* Job control check -- must be done at start and after > every sleep (POSIX.1 7.1.1.4). */ > /* NOTE: not yet done after every sleep pending a thorough >diff -urN linux-2.4.22-rc2-ac3/drivers/video/Config.in linux-2.4.22-rc2-ac3-new/drivers/video/Config.in >--- linux-2.4.22-rc2-ac3/drivers/video/Config.in 2003-08-21 07:31:58.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/video/Config.in 2003-08-21 17:00:01.000000000 -0400 >@@ -238,13 +238,20 @@ > tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL > fi > >+ dep_bool ' Use splash screen instead of boot logo' CONFIG_FBCON_SPLASHSCREEN $CONFIG_BLK_DEV_INITRD >+ if [ "$CONFIG_FBCON_SPLASHSCREEN" = "y" ]; then >+ define_bool CONFIG_FBCON_CFB16 y >+ fi >+ > bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED > if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then > tristate ' Monochrome support' CONFIG_FBCON_MFB > tristate ' 2 bpp packed pixels support' CONFIG_FBCON_CFB2 > tristate ' 4 bpp packed pixels support' CONFIG_FBCON_CFB4 > tristate ' 8 bpp packed pixels support' CONFIG_FBCON_CFB8 >- tristate ' 16 bpp packed pixels support' CONFIG_FBCON_CFB16 >+ if [ "$CONFIG_FBCON_SPLASHSCREEN" != "y" ]; then >+ tristate ' 16 bpp packed pixels support' CONFIG_FBCON_CFB16 >+ fi > tristate ' 24 bpp packed pixels support' CONFIG_FBCON_CFB24 > tristate ' 32 bpp packed pixels support' CONFIG_FBCON_CFB32 > tristate ' Amiga bitplanes support' CONFIG_FBCON_AFB >@@ -353,7 +360,9 @@ > "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \ > "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \ > "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" ]; then >- define_tristate CONFIG_FBCON_CFB16 y >+ if [ "$CONFIG_FBCON_CFB16" != "m" ]; then >+ define_tristate CONFIG_FBCON_CFB16 y >+ fi > else > if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ > "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ >@@ -371,7 +380,9 @@ > "$CONFIG_FB_INTEL" = "m" -o \ > "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \ > "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then >- define_tristate CONFIG_FBCON_CFB16 m >+ if [ "$CONFIG_FBCON_CFB16" != "y" ]; then >+ define_tristate CONFIG_FBCON_CFB16 m >+ fi > fi > fi > if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ >diff -urN linux-2.4.22-rc2-ac3/drivers/video/Makefile linux-2.4.22-rc2-ac3-new/drivers/video/Makefile >--- linux-2.4.22-rc2-ac3/drivers/video/Makefile 2003-08-21 07:31:58.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/video/Makefile 2003-08-21 17:00:01.000000000 -0400 >@@ -14,7 +14,7 @@ > fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \ > fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \ > fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \ >- fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \ >+ fbcon-cfb8.o fbcon-splash16.o fbcon-mac.o fbcon-mfb.o \ > cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o > > # Each configuration option enables a list of files. >@@ -153,6 +153,10 @@ > obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o > obj-$(CONFIG_FBCON_STI) += fbcon-sti.o > >+obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-splash.o >+obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-splash16.o >+obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-jpegdec.o >+ > include $(TOPDIR)/Rules.make > > clean: >diff -urN linux-2.4.22-rc2-ac3/drivers/video/fbcon-jpegdec.c linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-jpegdec.c >--- linux-2.4.22-rc2-ac3/drivers/video/fbcon-jpegdec.c 1969-12-31 20:00:00.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-jpegdec.c 2003-08-21 17:00:01.000000000 -0400 >@@ -0,0 +1,960 @@ >+/* >+ * linux/drivers/video/fbcon-jpegdec.c - a tiny jpeg decoder. >+ * >+ * (w) August 2001 by Michael Schroeder, <mls@suse.de> >+ * >+ */ >+ >+#include <linux/config.h> >+#include <linux/string.h> >+#include <asm/byteorder.h> >+ >+struct display; >+#include "fbcon-splash.h" >+#include "fbcon-jpegdec.h" >+ >+#define ISHIFT 11 >+ >+#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5)) >+#define IMULT(a, b) (((a) * (b)) >> ISHIFT) >+#define ITOINT(a) ((a) >> ISHIFT) >+ >+#ifndef __P >+# define __P(x) x >+#endif >+ >+/* special markers */ >+#define M_BADHUFF -1 >+#define M_EOF 0x80 >+ >+struct in { >+ unsigned char *p; >+ unsigned int bits; >+ int left; >+ int marker; >+ >+ int (*func) __P((void *)); >+ void *data; >+}; >+ >+/*********************************/ >+struct dec_hufftbl; >+struct enc_hufftbl; >+ >+union hufftblp { >+ struct dec_hufftbl *dhuff; >+ struct enc_hufftbl *ehuff; >+}; >+ >+struct scan { >+ int dc; /* old dc value */ >+ >+ union hufftblp hudc; >+ union hufftblp huac; >+ int next; /* when to switch to next scan */ >+ >+ int cid; /* component id */ >+ int hv; /* horiz/vert, copied from comp */ >+ int tq; /* quant tbl, copied from comp */ >+}; >+ >+/*********************************/ >+ >+#define DECBITS 10 /* seems to be the optimum */ >+ >+struct dec_hufftbl { >+ int maxcode[17]; >+ int valptr[16]; >+ unsigned char vals[256]; >+ unsigned int llvals[1 << DECBITS]; >+}; >+ >+static void decode_mcus __P((struct in *, int *, int, struct scan *, int *)); >+static int dec_readmarker __P((struct in *)); >+static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *)); >+ >+static void setinput __P((struct in *, unsigned char *)); >+/*********************************/ >+ >+#undef PREC >+#define PREC int >+ >+static void idctqtab __P((unsigned char *, PREC *)); >+static void idct __P((int *, int *, PREC *, PREC, int)); >+static void scaleidctqtab __P((PREC *, PREC)); >+ >+/*********************************/ >+ >+static void initcol __P((PREC[][64])); >+ >+static void col221111 __P((int *, unsigned char *, int)); >+static void col221111_16 __P((int *, unsigned char *, int)); >+ >+/*********************************/ >+ >+#define M_SOI 0xd8 >+#define M_APP0 0xe0 >+#define M_DQT 0xdb >+#define M_SOF0 0xc0 >+#define M_DHT 0xc4 >+#define M_DRI 0xdd >+#define M_SOS 0xda >+#define M_RST0 0xd0 >+#define M_EOI 0xd9 >+#define M_COM 0xfe >+ >+static unsigned char *datap; >+ >+static int getbyte(void) >+{ >+ return *datap++; >+} >+ >+static int getword(void) >+{ >+ int c1, c2; >+ c1 = *datap++; >+ c2 = *datap++; >+ return c1 << 8 | c2; >+} >+ >+struct comp { >+ int cid; >+ int hv; >+ int tq; >+}; >+ >+#define MAXCOMP 4 >+struct jpginfo { >+ int nc; /* number of components */ >+ int ns; /* number of scans */ >+ int dri; /* restart interval */ >+ int nm; /* mcus til next marker */ >+ int rm; /* next restart marker */ >+}; >+ >+static struct jpginfo info; >+static struct comp comps[MAXCOMP]; >+ >+static struct scan dscans[MAXCOMP]; >+ >+static unsigned char quant[4][64]; >+ >+static struct dec_hufftbl dhuff[4]; >+ >+#define dec_huffdc (dhuff + 0) >+#define dec_huffac (dhuff + 2) >+ >+static struct in in; >+ >+static int readtables(int till) >+{ >+ int m, l, i, j, lq, pq, tq; >+ int tc, th, tt; >+ >+ for (;;) { >+ if (getbyte() != 0xff) >+ return -1; >+ if ((m = getbyte()) == till) >+ break; >+ >+ switch (m) { >+ case 0xc2: >+ return 0; >+ >+ case M_DQT: >+ lq = getword(); >+ while (lq > 2) { >+ pq = getbyte(); >+ tq = pq & 15; >+ if (tq > 3) >+ return -1; >+ pq >>= 4; >+ if (pq != 0) >+ return -1; >+ for (i = 0; i < 64; i++) >+ quant[tq][i] = getbyte(); >+ lq -= 64 + 1; >+ } >+ break; >+ >+ case M_DHT: >+ l = getword(); >+ while (l > 2) { >+ int hufflen[16], k; >+ unsigned char huffvals[256]; >+ >+ tc = getbyte(); >+ th = tc & 15; >+ tc >>= 4; >+ tt = tc * 2 + th; >+ if (tc > 1 || th > 1) >+ return -1; >+ for (i = 0; i < 16; i++) >+ hufflen[i] = getbyte(); >+ l -= 1 + 16; >+ k = 0; >+ for (i = 0; i < 16; i++) { >+ for (j = 0; j < hufflen[i]; j++) >+ huffvals[k++] = getbyte(); >+ l -= hufflen[i]; >+ } >+ dec_makehuff(dhuff + tt, hufflen, >+ huffvals); >+ } >+ break; >+ >+ case M_DRI: >+ l = getword(); >+ info.dri = getword(); >+ break; >+ >+ default: >+ l = getword(); >+ while (l-- > 2) >+ getbyte(); >+ break; >+ } >+ } >+ return 0; >+} >+ >+static void dec_initscans(void) >+{ >+ int i; >+ >+ info.nm = info.dri + 1; >+ info.rm = M_RST0; >+ for (i = 0; i < info.ns; i++) >+ dscans[i].dc = 0; >+} >+ >+static int dec_checkmarker(void) >+{ >+ int i; >+ >+ if (dec_readmarker(&in) != info.rm) >+ return -1; >+ info.nm = info.dri; >+ info.rm = (info.rm + 1) & ~0x08; >+ for (i = 0; i < info.ns; i++) >+ dscans[i].dc = 0; >+ return 0; >+} >+ >+int jpeg_check_size(unsigned char *buf, int width, int height) >+{ >+ datap = buf; >+ getbyte(); >+ getbyte(); >+ readtables(M_SOF0); >+ getword(); >+ getbyte(); >+ if (height != getword() || width != getword()) >+ return 0; >+ return 1; >+} >+ >+int jpeg_decode(buf, pic, width, height, depth, decdata) >+unsigned char *buf, *pic; >+int width, height, depth; >+struct jpeg_decdata *decdata; >+{ >+ int i, j, m, tac, tdc; >+ int mcusx, mcusy, mx, my; >+ int max[6]; >+ >+ if (!decdata) >+ return -1; >+ datap = buf; >+ if (getbyte() != 0xff) >+ return ERR_NO_SOI; >+ if (getbyte() != M_SOI) >+ return ERR_NO_SOI; >+ if (readtables(M_SOF0)) >+ return ERR_BAD_TABLES; >+ getword(); >+ i = getbyte(); >+ if (i != 8) >+ return ERR_NOT_8BIT; >+ if (((getword() + 15) & ~15) != height) >+ return ERR_HEIGHT_MISMATCH; >+ if (((getword() + 15) & ~15) != width) >+ return ERR_WIDTH_MISMATCH; >+ if ((height & 15) || (width & 15)) >+ return ERR_BAD_WIDTH_OR_HEIGHT; >+ info.nc = getbyte(); >+ if (info.nc > MAXCOMP) >+ return ERR_TOO_MANY_COMPPS; >+ for (i = 0; i < info.nc; i++) { >+ int h, v; >+ comps[i].cid = getbyte(); >+ comps[i].hv = getbyte(); >+ v = comps[i].hv & 15; >+ h = comps[i].hv >> 4; >+ comps[i].tq = getbyte(); >+ if (h > 3 || v > 3) >+ return ERR_ILLEGAL_HV; >+ if (comps[i].tq > 3) >+ return ERR_QUANT_TABLE_SELECTOR; >+ } >+ if (readtables(M_SOS)) >+ return ERR_BAD_TABLES; >+ getword(); >+ info.ns = getbyte(); >+ if (info.ns != 3) >+ return ERR_NOT_YCBCR_221111; >+ for (i = 0; i < 3; i++) { >+ dscans[i].cid = getbyte(); >+ tdc = getbyte(); >+ tac = tdc & 15; >+ tdc >>= 4; >+ if (tdc > 1 || tac > 1) >+ return ERR_QUANT_TABLE_SELECTOR; >+ for (j = 0; j < info.nc; j++) >+ if (comps[j].cid == dscans[i].cid) >+ break; >+ if (j == info.nc) >+ return ERR_UNKNOWN_CID_IN_SCAN; >+ dscans[i].hv = comps[j].hv; >+ dscans[i].tq = comps[j].tq; >+ dscans[i].hudc.dhuff = dec_huffdc + tdc; >+ dscans[i].huac.dhuff = dec_huffac + tac; >+ } >+ >+ i = getbyte(); >+ j = getbyte(); >+ m = getbyte(); >+ >+ if (i != 0 || j != 63 || m != 0) >+ return ERR_NOT_SEQUENTIAL_DCT; >+ >+ if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3) >+ return ERR_NOT_YCBCR_221111; >+ >+ if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11 || dscans[2].hv != 0x11) >+ return ERR_NOT_YCBCR_221111; >+ >+ mcusx = width >> 4; >+ mcusy = height >> 4; >+ >+ >+ idctqtab(quant[dscans[0].tq], decdata->dquant[0]); >+ idctqtab(quant[dscans[1].tq], decdata->dquant[1]); >+ idctqtab(quant[dscans[2].tq], decdata->dquant[2]); >+ initcol(decdata->dquant); >+ setinput(&in, datap); >+ >+#if 0 >+ /* landing zone */ >+ img[len] = 0; >+ img[len + 1] = 0xff; >+ img[len + 2] = M_EOF; >+#endif >+ >+ dec_initscans(); >+ >+ dscans[0].next = 6 - 4; >+ dscans[1].next = 6 - 4 - 1; >+ dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */ >+ for (my = 0; my < mcusy; my++) { >+ for (mx = 0; mx < mcusx; mx++) { >+ if (info.dri && !--info.nm) >+ if (dec_checkmarker()) >+ return ERR_WRONG_MARKER; >+ >+ decode_mcus(&in, decdata->dcts, 6, dscans, max); >+ idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); >+ idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]); >+ idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]); >+ idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]); >+ idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]); >+ idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]); >+ >+ switch (depth) { >+ case 24: >+ col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3); >+ break; >+ case 16: >+ col221111_16(decdata->out, pic + (my * 16 * mcusx + mx) * (16 * 2), mcusx * (16 * 2)); >+ break; >+ default: >+ return ERR_DEPTH_MISMATCH; >+ break; >+ } >+ } >+ } >+ >+ m = dec_readmarker(&in); >+ if (m != M_EOI) >+ return ERR_NO_EOI; >+ >+ return 0; >+} >+ >+/****************************************************************/ >+/************** huffman decoder ***************/ >+/****************************************************************/ >+ >+static int fillbits __P((struct in *, int, unsigned int)); >+static int dec_rec2 >+__P((struct in *, struct dec_hufftbl *, int *, int, int)); >+ >+static void setinput(in, p) >+struct in *in; >+unsigned char *p; >+{ >+ in->p = p; >+ in->left = 0; >+ in->bits = 0; >+ in->marker = 0; >+} >+ >+static int fillbits(in, le, bi) >+struct in *in; >+int le; >+unsigned int bi; >+{ >+ int b, m; >+ >+ if (in->marker) { >+ if (le <= 16) >+ in->bits = bi << 16, le += 16; >+ return le; >+ } >+ while (le <= 24) { >+ b = *in->p++; >+ if (b == 0xff && (m = *in->p++) != 0) { >+ if (m == M_EOF) { >+ if (in->func && (m = in->func(in->data)) == 0) >+ continue; >+ } >+ in->marker = m; >+ if (le <= 16) >+ bi = bi << 16, le += 16; >+ break; >+ } >+ bi = bi << 8 | b; >+ le += 8; >+ } >+ in->bits = bi; /* tmp... 2 return values needed */ >+ return le; >+} >+ >+static int dec_readmarker(in) >+struct in *in; >+{ >+ int m; >+ >+ in->left = fillbits(in, in->left, in->bits); >+ if ((m = in->marker) == 0) >+ return 0; >+ in->left = 0; >+ in->marker = 0; >+ return m; >+} >+ >+#define LEBI_DCL int le, bi >+#define LEBI_GET(in) (le = in->left, bi = in->bits) >+#define LEBI_PUT(in) (in->left = le, in->bits = bi) >+ >+#define GETBITS(in, n) ( \ >+ (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \ >+ (le -= (n)), \ >+ bi >> le & ((1 << (n)) - 1) \ >+) >+ >+#define UNGETBITS(in, n) ( \ >+ le += (n) \ >+) >+ >+ >+static int dec_rec2(in, hu, runp, c, i) >+struct in *in; >+struct dec_hufftbl *hu; >+int *runp; >+int c, i; >+{ >+ LEBI_DCL; >+ >+ LEBI_GET(in); >+ if (i) { >+ UNGETBITS(in, i & 127); >+ *runp = i >> 8 & 15; >+ i >>= 16; >+ } else { >+ for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++); >+ if (i >= 16) { >+ in->marker = M_BADHUFF; >+ return 0; >+ } >+ i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2]; >+ *runp = i >> 4; >+ i &= 15; >+ } >+ if (i == 0) { /* sigh, 0xf0 is 11 bit */ >+ LEBI_PUT(in); >+ return 0; >+ } >+ /* receive part */ >+ c = GETBITS(in, i); >+ if (c < (1 << (i - 1))) >+ c += (-1 << i) + 1; >+ LEBI_PUT(in); >+ return c; >+} >+ >+#define DEC_REC(in, hu, r, i) ( \ >+ r = GETBITS(in, DECBITS), \ >+ i = hu->llvals[r], \ >+ i & 128 ? \ >+ ( \ >+ UNGETBITS(in, i & 127), \ >+ r = i >> 8 & 15, \ >+ i >> 16 \ >+ ) \ >+ : \ >+ ( \ >+ LEBI_PUT(in), \ >+ i = dec_rec2(in, hu, &r, r, i), \ >+ LEBI_GET(in), \ >+ i \ >+ ) \ >+) >+ >+static void decode_mcus(in, dct, n, sc, maxp) >+struct in *in; >+int *dct; >+int n; >+struct scan *sc; >+int *maxp; >+{ >+ struct dec_hufftbl *hu; >+ int i, r, t; >+ LEBI_DCL; >+ >+ memset(dct, 0, n * 64 * sizeof(*dct)); >+ LEBI_GET(in); >+ while (n-- > 0) { >+ hu = sc->hudc.dhuff; >+ *dct++ = (sc->dc += DEC_REC(in, hu, r, t)); >+ >+ hu = sc->huac.dhuff; >+ i = 63; >+ while (i > 0) { >+ t = DEC_REC(in, hu, r, t); >+ if (t == 0 && r == 0) { >+ dct += i; >+ break; >+ } >+ dct += r; >+ *dct++ = t; >+ i -= r + 1; >+ } >+ *maxp++ = 64 - i; >+ if (n == sc->next) >+ sc++; >+ } >+ LEBI_PUT(in); >+} >+ >+static void dec_makehuff(hu, hufflen, huffvals) >+struct dec_hufftbl *hu; >+int *hufflen; >+unsigned char *huffvals; >+{ >+ int code, k, i, j, d, x, c, v; >+ for (i = 0; i < (1 << DECBITS); i++) >+ hu->llvals[i] = 0; >+ >+/* >+ * llvals layout: >+ * >+ * value v already known, run r, backup u bits: >+ * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu >+ * value unknown, size b bits, run r, backup u bits: >+ * 000000000000bbbb 0000 rrrr 0 uuuuuuu >+ * value and size unknown: >+ * 0000000000000000 0000 0000 0 0000000 >+ */ >+ code = 0; >+ k = 0; >+ for (i = 0; i < 16; i++, code <<= 1) { /* sizes */ >+ hu->valptr[i] = k; >+ for (j = 0; j < hufflen[i]; j++) { >+ hu->vals[k] = *huffvals++; >+ if (i < DECBITS) { >+ c = code << (DECBITS - 1 - i); >+ v = hu->vals[k] & 0x0f; /* size */ >+ for (d = 1 << (DECBITS - 1 - i); --d >= 0;) { >+ if (v + i < DECBITS) { /* both fit in table */ >+ x = d >> (DECBITS - 1 - v - >+ i); >+ if (v && x < (1 << (v - 1))) >+ x += (-1 << v) + 1; >+ x = x << 16 | (hu-> vals[k] & 0xf0) << 4 | >+ (DECBITS - (i + 1 + v)) | 128; >+ } else >+ x = v << 16 | (hu-> vals[k] & 0xf0) << 4 | >+ (DECBITS - (i + 1)); >+ hu->llvals[c | d] = x; >+ } >+ } >+ code++; >+ k++; >+ } >+ hu->maxcode[i] = code; >+ } >+ hu->maxcode[16] = 0x20000; /* always terminate decode */ >+} >+ >+/****************************************************************/ >+/************** idct ***************/ >+/****************************************************************/ >+ >+#define ONE ((PREC)IFIX(1.)) >+#define S2 ((PREC)IFIX(0.382683432)) >+#define C2 ((PREC)IFIX(0.923879532)) >+#define C4 ((PREC)IFIX(0.707106781)) >+ >+#define S22 ((PREC)IFIX(2 * 0.382683432)) >+#define C22 ((PREC)IFIX(2 * 0.923879532)) >+#define IC4 ((PREC)IFIX(1 / 0.707106781)) >+ >+#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */ >+#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */ >+#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */ >+ >+#define XPP(a,b) (t = a + b, b = a - b, a = t) >+#define XMP(a,b) (t = a - b, b = a + b, a = t) >+#define XPM(a,b) (t = a + b, b = b - a, a = t) >+ >+#define ROT(a,b,s,c) ( t = IMULT(a + b, s), \ >+ a = IMULT(a, c - s) + t, \ >+ b = IMULT(b, c + s) - t) >+ >+#define IDCT \ >+( \ >+ XPP(t0, t1), \ >+ XMP(t2, t3), \ >+ t2 = IMULT(t2, IC4) - t3, \ >+ XPP(t0, t3), \ >+ XPP(t1, t2), \ >+ XMP(t4, t7), \ >+ XPP(t5, t6), \ >+ XMP(t5, t7), \ >+ t5 = IMULT(t5, IC4), \ >+ ROT(t4, t6, S22, C22),\ >+ t6 -= t7, \ >+ t5 -= t6, \ >+ t4 -= t5, \ >+ XPP(t0, t7), \ >+ XPP(t1, t6), \ >+ XPP(t2, t5), \ >+ XPP(t3, t4) \ >+) >+ >+static unsigned char zig2[64] = { >+ 0, 2, 3, 9, 10, 20, 21, 35, >+ 14, 16, 25, 31, 39, 46, 50, 57, >+ 5, 7, 12, 18, 23, 33, 37, 48, >+ 27, 29, 41, 44, 52, 55, 59, 62, >+ 15, 26, 30, 40, 45, 51, 56, 58, >+ 1, 4, 8, 11, 19, 22, 34, 36, >+ 28, 42, 43, 53, 54, 60, 61, 63, >+ 6, 13, 17, 24, 32, 38, 47, 49 >+}; >+ >+void idct(in, out, quant, off, max) >+int *in; >+int *out; >+PREC *quant; >+PREC off; >+int max; >+{ >+ PREC t0, t1, t2, t3, t4, t5, t6, t7, t; >+ PREC tmp[64], *tmpp; >+ int i, j; >+ unsigned char *zig2p; >+ >+ t0 = off; >+ if (max == 1) { >+ t0 += in[0] * quant[0]; >+ for (i = 0; i < 64; i++) >+ out[i] = ITOINT(t0); >+ return; >+ } >+ zig2p = zig2; >+ tmpp = tmp; >+ for (i = 0; i < 8; i++) { >+ j = *zig2p++; >+ t0 += in[j] * quant[j]; >+ j = *zig2p++; >+ t5 = in[j] * quant[j]; >+ j = *zig2p++; >+ t2 = in[j] * quant[j]; >+ j = *zig2p++; >+ t7 = in[j] * quant[j]; >+ j = *zig2p++; >+ t1 = in[j] * quant[j]; >+ j = *zig2p++; >+ t4 = in[j] * quant[j]; >+ j = *zig2p++; >+ t3 = in[j] * quant[j]; >+ j = *zig2p++; >+ t6 = in[j] * quant[j]; >+ IDCT; >+ tmpp[0 * 8] = t0; >+ tmpp[1 * 8] = t1; >+ tmpp[2 * 8] = t2; >+ tmpp[3 * 8] = t3; >+ tmpp[4 * 8] = t4; >+ tmpp[5 * 8] = t5; >+ tmpp[6 * 8] = t6; >+ tmpp[7 * 8] = t7; >+ tmpp++; >+ t0 = 0; >+ } >+ for (i = 0; i < 8; i++) { >+ t0 = tmp[8 * i + 0]; >+ t1 = tmp[8 * i + 1]; >+ t2 = tmp[8 * i + 2]; >+ t3 = tmp[8 * i + 3]; >+ t4 = tmp[8 * i + 4]; >+ t5 = tmp[8 * i + 5]; >+ t6 = tmp[8 * i + 6]; >+ t7 = tmp[8 * i + 7]; >+ IDCT; >+ out[8 * i + 0] = ITOINT(t0); >+ out[8 * i + 1] = ITOINT(t1); >+ out[8 * i + 2] = ITOINT(t2); >+ out[8 * i + 3] = ITOINT(t3); >+ out[8 * i + 4] = ITOINT(t4); >+ out[8 * i + 5] = ITOINT(t5); >+ out[8 * i + 6] = ITOINT(t6); >+ out[8 * i + 7] = ITOINT(t7); >+ } >+} >+ >+static unsigned char zig[64] = { >+ 0, 1, 5, 6, 14, 15, 27, 28, >+ 2, 4, 7, 13, 16, 26, 29, 42, >+ 3, 8, 12, 17, 25, 30, 41, 43, >+ 9, 11, 18, 24, 31, 40, 44, 53, >+ 10, 19, 23, 32, 39, 45, 52, 54, >+ 20, 22, 33, 38, 46, 51, 55, 60, >+ 21, 34, 37, 47, 50, 56, 59, 61, >+ 35, 36, 48, 49, 57, 58, 62, 63 >+}; >+ >+static PREC aaidct[8] = { >+ IFIX(0.3535533906), IFIX(0.4903926402), >+ IFIX(0.4619397663), IFIX(0.4157348062), >+ IFIX(0.3535533906), IFIX(0.2777851165), >+ IFIX(0.1913417162), IFIX(0.0975451610) >+}; >+ >+ >+static void idctqtab(qin, qout) >+unsigned char *qin; >+PREC *qout; >+{ >+ int i, j; >+ >+ for (i = 0; i < 8; i++) >+ for (j = 0; j < 8; j++) >+ qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] * >+ IMULT(aaidct[i], aaidct[j]); >+} >+ >+static void scaleidctqtab(q, sc) >+PREC *q; >+PREC sc; >+{ >+ int i; >+ >+ for (i = 0; i < 64; i++) >+ q[i] = IMULT(q[i], sc); >+} >+ >+/****************************************************************/ >+/************** color decoder ***************/ >+/****************************************************************/ >+ >+#define ROUND >+ >+/* >+ * YCbCr Color transformation: >+ * >+ * y:0..255 Cb:-128..127 Cr:-128..127 >+ * >+ * R = Y + 1.40200 * Cr >+ * G = Y - 0.34414 * Cb - 0.71414 * Cr >+ * B = Y + 1.77200 * Cb >+ * >+ * => >+ * Cr *= 1.40200; >+ * Cb *= 1.77200; >+ * Cg = 0.19421 * Cb + .50937 * Cr; >+ * R = Y + Cr; >+ * G = Y - Cg; >+ * B = Y + Cb; >+ * >+ * => >+ * Cg = (50 * Cb + 130 * Cr + 128) >> 8; >+ */ >+ >+static void initcol(q) >+PREC q[][64]; >+{ >+ scaleidctqtab(q[1], IFIX(1.77200)); >+ scaleidctqtab(q[2], IFIX(1.40200)); >+} >+ >+/* This is optimized for the stupid sun SUNWspro compiler. */ >+#define STORECLAMP(a,x) \ >+( \ >+ (a) = (x), \ >+ (unsigned int)(x) >= 256 ? \ >+ ((a) = (x) < 0 ? 0 : 255) \ >+ : \ >+ 0 \ >+) >+ >+#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x)) >+ >+#ifdef ROUND >+ >+#define CBCRCG(yin, xin) \ >+( \ >+ cb = outc[0 +yin*8+xin], \ >+ cr = outc[64+yin*8+xin], \ >+ cg = (50 * cb + 130 * cr + 128) >> 8 \ >+) >+ >+#else >+ >+#define CBCRCG(yin, xin) \ >+( \ >+ cb = outc[0 +yin*8+xin], \ >+ cr = outc[64+yin*8+xin], \ >+ cg = (3 * cb + 8 * cr) >> 4 \ >+) >+ >+#endif >+ >+#define PIC(yin, xin, p, xout) \ >+( \ >+ y = outy[(yin) * 8 + xin], \ >+ STORECLAMP(p[(xout) * 3 + 0], y + cr), \ >+ STORECLAMP(p[(xout) * 3 + 1], y - cg), \ >+ STORECLAMP(p[(xout) * 3 + 2], y + cb) \ >+) >+ >+#ifdef __LITTLE_ENDIAN >+#define PIC_16(yin, xin, p, xout, add) \ >+( \ >+ y = outy[(yin) * 8 + xin], \ >+ y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \ >+ ((CLAMP(y - cg + add ) & 0xfc) << 3) | \ >+ ((CLAMP(y + cb + add*2+1) ) >> 3), \ >+ p[(xout) * 2 + 0] = y & 0xff, \ >+ p[(xout) * 2 + 1] = y >> 8 \ >+) >+#else >+#ifdef CONFIG_PPC >+#define PIC_16(yin, xin, p, xout, add) \ >+( \ >+ y = outy[(yin) * 8 + xin], \ >+ y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \ >+ ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \ >+ ((CLAMP(y + cb + add*2+1) ) >> 3), \ >+ p[(xout) * 2 + 0] = y >> 8, \ >+ p[(xout) * 2 + 1] = y & 0xff \ >+) >+#else >+#define PIC_16(yin, xin, p, xout, add) \ >+( \ >+ y = outy[(yin) * 8 + xin], \ >+ y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \ >+ ((CLAMP(y - cg + add ) & 0xfc) << 3) | \ >+ ((CLAMP(y + cb + add*2+1) ) >> 3), \ >+ p[(xout) * 2 + 0] = y >> 8, \ >+ p[(xout) * 2 + 1] = y & 0xff \ >+) >+#endif >+#endif >+ >+#define PIC221111(xin) \ >+( \ >+ CBCRCG(0, xin), \ >+ PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \ >+ PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \ >+ PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \ >+ PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \ >+) >+ >+#define PIC221111_16(xin) \ >+( \ >+ CBCRCG(0, xin), \ >+ PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \ >+ PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \ >+ PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \ >+ PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \ >+) >+ >+static void col221111(out, pic, width) >+int *out; >+unsigned char *pic; >+int width; >+{ >+ int i, j, k; >+ unsigned char *pic0, *pic1; >+ int *outy, *outc; >+ int cr, cg, cb, y; >+ >+ pic0 = pic; >+ pic1 = pic + width; >+ outy = out; >+ outc = out + 64 * 4; >+ for (i = 2; i > 0; i--) { >+ for (j = 4; j > 0; j--) { >+ for (k = 0; k < 8; k++) { >+ PIC221111(k); >+ } >+ outc += 8; >+ outy += 16; >+ pic0 += 2 * width; >+ pic1 += 2 * width; >+ } >+ outy += 64 * 2 - 16 * 4; >+ } >+} >+ >+static void col221111_16(out, pic, width) >+int *out; >+unsigned char *pic; >+int width; >+{ >+ int i, j, k; >+ unsigned char *pic0, *pic1; >+ int *outy, *outc; >+ int cr, cg, cb, y; >+ >+ pic0 = pic; >+ pic1 = pic + width; >+ outy = out; >+ outc = out + 64 * 4; >+ for (i = 2; i > 0; i--) { >+ for (j = 4; j > 0; j--) { >+ for (k = 0; k < 8; k++) { >+ PIC221111_16(k); >+ } >+ outc += 8; >+ outy += 16; >+ pic0 += 2 * width; >+ pic1 += 2 * width; >+ } >+ outy += 64 * 2 - 16 * 4; >+ } >+} >diff -urN linux-2.4.22-rc2-ac3/drivers/video/fbcon-jpegdec.h linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-jpegdec.h >--- linux-2.4.22-rc2-ac3/drivers/video/fbcon-jpegdec.h 1969-12-31 20:00:00.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-jpegdec.h 2003-08-21 17:00:01.000000000 -0400 >@@ -0,0 +1,24 @@ >+#define ERR_NO_SOI 1 >+#define ERR_NOT_8BIT 2 >+#define ERR_HEIGHT_MISMATCH 3 >+#define ERR_WIDTH_MISMATCH 4 >+#define ERR_BAD_WIDTH_OR_HEIGHT 5 >+#define ERR_TOO_MANY_COMPPS 6 >+#define ERR_ILLEGAL_HV 7 >+#define ERR_QUANT_TABLE_SELECTOR 8 >+#define ERR_NOT_YCBCR_221111 9 >+#define ERR_UNKNOWN_CID_IN_SCAN 10 >+#define ERR_NOT_SEQUENTIAL_DCT 11 >+#define ERR_WRONG_MARKER 12 >+#define ERR_NO_EOI 13 >+#define ERR_BAD_TABLES 14 >+#define ERR_DEPTH_MISMATCH 15 >+ >+struct jpeg_decdata { >+ int dcts[6 * 64 + 16]; >+ int out[64 * 6]; >+ int dquant[3][64]; >+}; >+ >+extern int jpeg_decode(unsigned char *, unsigned char *, int, int, int, struct jpeg_decdata *); >+extern int jpeg_check_size(unsigned char *, int, int); >diff -urN linux-2.4.22-rc2-ac3/drivers/video/fbcon-splash.c linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-splash.c >--- linux-2.4.22-rc2-ac3/drivers/video/fbcon-splash.c 1969-12-31 20:00:00.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-splash.c 2003-08-21 17:00:01.000000000 -0400 >@@ -0,0 +1,848 @@ >+/* >+ * linux/drivers/video/fbcon-splash.c - splash screen handling functions. >+ * >+ * (w) 2001-2003 by Volker Poplawski, <volker@suse.de> >+ * Stefan Reinauer, <stepan@suse.de> >+ * Steffen Winterfeldt, <snwint@suse.de> >+ * >+ * Ideas & SuSE screen work by Ken Wimer, <wimer@suse.de> >+ */ >+ >+#include <linux/version.h> >+#include <linux/config.h> >+#include <linux/module.h> >+#include <linux/fb.h> >+#include <linux/vt_kern.h> >+#include <linux/vmalloc.h> >+ >+#include <asm/irq.h> >+#include <asm/system.h> >+ >+#include <video/fbcon.h> >+#include <video/font.h> >+#include <video/fbcon-cfb16.h> /* for fbcon_cfb16 */ >+ >+#include "fbcon-splash.h" >+#include "fbcon-jpegdec.h" >+ >+#define SPLASH_VERSION "3.0.7-2003/03/10" >+ >+#ifdef CONFIG_BLK_DEV_INITRD >+unsigned char signature[] = "BOOTSPL1SPL2SPL3"; >+#endif >+ >+/* from drivers/char/console.c */ >+extern void con_remap_def_color(int currcons, int new_color); >+ >+/* from drivers/video/fbcon-splash16.c */ >+extern void splashfill(u8 *dest, u8 *src, int width, int height, >+ int dest_linesize, int src_linesize); >+ >+/* internal control states and data pointers */ >+struct splash_data splash_data; >+ >+unsigned char *linux_splash; /* decoded picture */ >+int linux_splash_size = 0; >+ >+static struct jpeg_decdata *decdata = 0; /* private decoder data */ >+ >+int splash_bytes; /* bytes per line in linux_splash */ >+int splash_shown = 0; /* is the splash onscreen? */ >+int splash_usesilent = 0; /* shall we display the silentjpeg */ >+int splash_default = 0xf01; >+ >+static int splash_status(struct display *p); >+static int splash_recolor(struct display *p); >+static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth); >+ >+extern struct display_switch fbcon_splash16; >+ >+int __init splash_init(char *options) >+{ >+ if(!strncmp("silent",options,6)) { >+ printk(KERN_INFO "bootsplash: silent mode.\n"); >+ splash_usesilent = 1; >+ /* skip "silent," */ >+ if (strlen(options)==6) >+ return 0; >+ options+=7; >+ } >+ if(!strncmp("verbose",options,7)) { >+ printk(KERN_INFO "bootsplash: verbose mode.\n"); >+ splash_usesilent = 0; >+ return 0; >+ } >+ >+ splash_default = simple_strtoul(options, NULL, 0); >+ >+ return 0; >+} >+ >+__setup("splash=", splash_init); >+ >+ >+static int splash_hasinter(unsigned char *buf, int num) >+{ >+ unsigned char *bufend = buf + num * 12; >+ while(buf < bufend) { >+ if (buf[1] > 127) /* inter? */ >+ return 1; >+ buf += buf[3] > 127 ? 24 : 12; /* blend? */ >+ } >+ return 0; >+} >+ >+static int boxextract(unsigned char *buf, unsigned short *dp, unsigned char *cols, int *blendp) >+{ >+ dp[0] = buf[0] | buf[1] << 8; >+ dp[1] = buf[2] | buf[3] << 8; >+ dp[2] = buf[4] | buf[5] << 8; >+ dp[3] = buf[6] | buf[7] << 8; >+ *(unsigned int *)(cols + 0) = >+ *(unsigned int *)(cols + 4) = >+ *(unsigned int *)(cols + 8) = >+ *(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 8); >+ if (dp[1] > 32767) { >+ dp[1] = ~dp[1]; >+ *(unsigned int *)(cols + 4) = *(unsigned int *)(buf + 12); >+ *(unsigned int *)(cols + 8) = *(unsigned int *)(buf + 16); >+ *(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 20); >+ *blendp = 1; >+ return 24; >+ } >+ return 12; >+} >+ >+static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num, int percent, int overpaint) >+{ >+ int x, y, i, p, doblend, r, g, b, a, add; >+ unsigned short data1[4]; >+ unsigned char cols1[16]; >+ unsigned short data2[4]; >+ unsigned char cols2[16]; >+ unsigned char *bufend; >+ unsigned short *picp; >+ >+ if (num == 0) >+ return; >+ bufend = buf + num * 12; >+ while(buf < bufend) { >+ doblend = 0; >+ buf += boxextract(buf, data1, cols1, &doblend); >+ if (data1[0] > 32767) >+ buf += boxextract(buf, data2, cols2, &doblend); >+ if (data1[2] > 32767) { >+ if (overpaint) >+ continue; >+ data1[2] = ~data1[2]; >+ } >+ if (data1[3] > 32767) { >+ if (percent == 65536) >+ continue; >+ data1[3] = ~data1[3]; >+ } >+ if (data1[0] > 32767) { >+ data1[0] = ~data1[0]; >+ for (i = 0; i < 4; i++) >+ data1[i] = (data1[i] * (65536 - percent) + data2[i] * percent) >> 16; >+ for (i = 0; i < 16; i++) >+ cols1[i] = (cols1[i] * (65536 - percent) + cols2[i] * percent) >> 16; >+ } >+ *(unsigned int *)cols2 = *(unsigned int *)cols1; >+ a = cols2[3]; >+ if (a == 0 && !doblend) >+ continue; >+ for (y = data1[1]; y <= data1[3]; y++) { >+ if (doblend) { >+ if ((p = data1[3] - data1[1]) != 0) >+ p = ((y - data1[1]) << 16) / p; >+ for (i = 0; i < 8; i++) >+ cols2[i + 8] = (cols1[i] * (65536 - p) + cols1[i + 8] * p) >> 16; >+ } >+ add = (data1[0] & 1); >+ add ^= (add ^ y) & 1 ? 1 : 3; /* 2x2 ordered dithering */ >+ picp = (unsigned short *)(pic + data1[0] * 2 + y * bytes); >+ for (x = data1[0]; x <= data1[2]; x++) { >+ if (doblend) { >+ if ((p = data1[2] - data1[0]) != 0) >+ p = ((x - data1[0]) << 16) / p; >+ for (i = 0; i < 4; i++) >+ cols2[i] = (cols2[i + 8] * (65536 - p) + cols2[i + 12] * p) >> 16; >+ a = cols2[3]; >+ } >+ r = cols2[0]; >+ g = cols2[1]; >+ b = cols2[2]; >+ if (a != 255) { >+ i = *picp; >+ r = ((i >> 8 & 0xf8) * (255 - a) + r * a) / 255; >+ g = ((i >> 3 & 0xfc) * (255 - a) + g * a) / 255; >+ b = ((i << 3 & 0xf8) * (255 - a) + b * a) / 255; >+ } >+ #define CLAMP(x) ((x) >= 256 ? 255 : (x)) >+ i = ((CLAMP(r + add*2+1) & 0xf8) << 8) | >+ ((CLAMP(g + add ) & 0xfc) << 3) | >+ ((CLAMP(b + add*2+1) ) >> 3); >+ *picp++ = i; >+ add ^= 3; >+ } >+ } >+ } >+} >+ >+static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth) >+{ >+ int size, err; >+ unsigned char *mem; >+ >+ size = ((width + 15) & ~15) * ((height + 15) & ~15) * (depth >> 3); >+ mem = vmalloc(size); >+ if (!mem) { >+ printk(KERN_INFO "No memory for decoded picture!\n"); >+ return -1; >+ } >+ if (!decdata) >+ decdata = vmalloc(sizeof(*decdata)); >+ if ((err = jpeg_decode(jpeg, mem, ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) >+ printk(KERN_INFO "error %d while decompressing picture.\n",err); >+ vfree(mem); >+ return err ? -1 : 0; >+} >+ >+static void splash_free(struct display * p) >+{ >+ if (!p->splash_data) >+ return; >+ if (p->splash_data->oldscreen_base) >+ p->screen_base = p->splash_data->oldscreen_base; >+ if (p->splash_data->olddispsw) >+ p->dispsw = p->splash_data->olddispsw; >+ if (p->splash_data->splash_silentjpeg) >+ vfree(p->splash_data->splash_sboxes); >+ vfree(p->splash_data); >+ p->splash_data = 0; >+} >+ >+static int splash_mkpenguin(struct splash_data *data, int pxo, int pyo, int pwi, int phe, int pr, int pg, int pb) >+{ >+ unsigned char *buf; >+ int i; >+ >+ if (pwi ==0 || phe == 0) >+ return 0; >+ buf = (unsigned char *)data + sizeof(*data); >+ pwi += pxo - 1; >+ phe += pyo - 1; >+ *buf++ = pxo; >+ *buf++ = pxo >> 8; >+ *buf++ = pyo; >+ *buf++ = pyo >> 8; >+ *buf++ = pwi; >+ *buf++ = pwi >> 8; >+ *buf++ = phe; >+ *buf++ = phe >> 8; >+ *buf++ = pr; >+ *buf++ = pg; >+ *buf++ = pb; >+ *buf++ = 0; >+ for (i = 0; i < 12; i++, buf++) >+ *buf = buf[-12]; >+ buf[-24] ^= 0xff; >+ buf[-23] ^= 0xff; >+ buf[-1] = 0xff; >+ return 2; >+} >+ >+int splash_getraw(unsigned char *start, unsigned char *end) >+{ >+ unsigned char *ndata; >+ int found = 0; >+ int splash_size = 0; >+ void *splash_start = 0; >+ int unit = 0; >+ int width = 0, height = 0; >+ int silentsize; >+ int boxcount = 0; >+ int sboxcount = 0; >+ int palcnt = 0; >+ struct display *p; >+ >+ printk(KERN_INFO "Looking for splash picture..."); >+ >+ p = &fb_display[0]; >+ silentsize = 0; >+ >+ for (ndata = start; ndata < end; ndata++) { >+ if (*((unsigned int *)ndata) != *((unsigned int *)signature)) >+ continue; >+ if (*((unsigned int *)(ndata+4))==*((unsigned int *)(signature+4))) { >+ printk("."); >+ unit = 0; >+ p = &fb_display[0]; >+ width = p->var.xres; >+ height = p->var.yres; >+ >+ splash_size = ndata[16] + (ndata[17] << 8) + (ndata[18] << 16) + (ndata[19] << 24); >+ if (ndata + 20 + splash_size > end) { >+ printk(" found, but truncated!\n"); >+ return -1; >+ } >+ if (!jpeg_check_size(ndata + 20, width, height)) { >+ ndata += 20 - 1 + splash_size; >+ continue; >+ } >+ if (splash_check_jpeg(ndata + 20, width, height, p->var.bits_per_pixel)) >+ return -1; >+ if (p->splash_data) >+ splash_free(p); >+ p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24); >+ if (!p->splash_data) >+ break; >+ >+ p->splash_data->oldscreen_base = 0; >+ p->splash_data->olddispsw = 0; >+ p->splash_data->splash_silentjpeg = 0; >+ >+ p->splash_data->splash_text_xo = ndata[ 8] + (ndata[ 9] << 8); >+ p->splash_data->splash_text_yo = ndata[10] + (ndata[11] << 8); >+ p->splash_data->splash_text_wi = ndata[12] + (ndata[13] << 8); >+ p->splash_data->splash_text_he = ndata[14] + (ndata[15] << 8); >+ /* use 8x16 font... */ >+ p->splash_data->splash_text_xo *= 8; >+ p->splash_data->splash_text_wi *= 8; >+ p->splash_data->splash_text_yo *= 16; >+ p->splash_data->splash_text_he *= 16; >+ p->splash_data->splash_color = (splash_default >> 8) & 0x0f; >+ p->splash_data->splash_fg_color = (splash_default >> 4) & 0x0f; >+ p->splash_data->splash_state = splash_default & 1; >+ p->splash_data->splash_percent = 0; >+ p->splash_data->splash_overpaintok = 0; >+ boxcount = splash_mkpenguin(p->splash_data, p->splash_data->splash_text_xo + 10, p->splash_data->splash_text_yo + 10, p->splash_data->splash_text_wi - 20, p->splash_data->splash_text_he - 20, 0xf0, 0xf0, 0xf0); >+ splash_start = ndata + 20; >+ found = 1; >+ break; >+ } >+ if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+8))) { >+ printk("."); >+ unit = ndata[8]; >+ if (unit >= MAX_NR_CONSOLES) >+ continue; >+ if (unit) >+ vc_allocate(unit); >+ p = &fb_display[unit]; >+ width = fb_display[unit].var.xres; >+ height = fb_display[unit].var.yres; >+ splash_size = ndata[12] + (ndata[13] << 8) + (ndata[14] << 16) + (ndata[15] << 24); >+ if (splash_size == -1) { >+ printk(" found, updating values.\n"); >+ if (p->splash_data) { >+ if (ndata[9] != 255) >+ p->splash_data->splash_state = ndata[9]; >+ if (ndata[10] != 255) >+ p->splash_data->splash_fg_color = ndata[10]; >+ if (ndata[11] != 255) >+ p->splash_data->splash_color = ndata[11]; >+ } >+ return unit; >+ } >+ if (splash_size == 0) { >+ printk(" found, freeing memory.\n"); >+ if (p->splash_data) >+ splash_free(p); >+ return unit; >+ } >+ if (ndata + 35 + splash_size > end) { >+ printk(" found, but truncated!\n"); >+ return -1; >+ } >+ if (!jpeg_check_size(ndata + 35, width, height)) { >+ ndata += 35 - 1 + splash_size; >+ continue; >+ } >+ if (splash_check_jpeg(ndata + 35, width, height, p->var.bits_per_pixel)) >+ return -1; >+ if (p->splash_data) >+ splash_free(p); >+ p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24); >+ if (!p->splash_data) >+ break; >+ >+ p->splash_data->oldscreen_base = 0; >+ p->splash_data->olddispsw = 0; >+ p->splash_data->splash_silentjpeg = 0; >+ >+ p->splash_data->splash_state = ndata[9]; >+ p->splash_data->splash_fg_color = ndata[10]; >+ p->splash_data->splash_color = ndata[11]; >+ p->splash_data->splash_text_xo = ndata[16] + (ndata[17] << 8); >+ p->splash_data->splash_text_yo = ndata[18] + (ndata[19] << 8); >+ p->splash_data->splash_text_wi = ndata[20] + (ndata[21] << 8); >+ p->splash_data->splash_text_he = ndata[22] + (ndata[23] << 8); >+ p->splash_data->splash_percent = 0; >+ p->splash_data->splash_overpaintok = 0; >+ boxcount = splash_mkpenguin(p->splash_data, ndata[24] + (ndata[25] << 8), ndata[26] + (ndata[27] << 8), ndata[28] + (ndata[29] << 8), ndata[30] + (ndata[31] << 8), ndata[32], ndata[33], ndata[34]); >+ splash_start = ndata + 35; >+ found = 2; >+ break; >+ } >+ if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+12))) { >+ printk("."); >+ unit = ndata[8]; >+ if (unit >= MAX_NR_CONSOLES) >+ continue; >+ if (unit) >+ vc_allocate(unit); >+ p = &fb_display[unit]; >+ width = p->var.xres; >+ height = p->var.yres; >+ splash_size = ndata[12] + (ndata[13] << 8) + (ndata[14] << 16) + (ndata[15] << 24); >+ if (splash_size == -1) { >+ printk(" found, updating values.\n"); >+ if (p->splash_data) { >+ if (ndata[9] != 255) >+ p->splash_data->splash_state = ndata[9]; >+ if (ndata[10] != 255) >+ p->splash_data->splash_fg_color = ndata[10]; >+ if (ndata[11] != 255) >+ p->splash_data->splash_color = ndata[11]; >+ } >+ return unit; >+ } >+ if (splash_size == 0) { >+ printk(" found, freeing memory.\n"); >+ if (p->splash_data) >+ splash_free(p); >+ return unit; >+ } >+ boxcount = ndata[24] + (ndata[25] << 8); >+ palcnt = ndata[37] * 3; >+ if (ndata + 38 + splash_size > end) { >+ printk(" found, but truncated!\n"); >+ return -1; >+ } >+ if (!jpeg_check_size(ndata + 38 + boxcount * 12 + palcnt, width, height)) { >+ ndata += 38 - 1 + splash_size; >+ continue; >+ } >+ if (splash_check_jpeg(ndata + 38 + boxcount * 12 + palcnt, width, height, p->var.bits_per_pixel)) >+ return -1; >+ silentsize = ndata[28] + (ndata[29] << 8) + (ndata[30] << 16) + (ndata[31] << 24); >+ if (silentsize) >+ printk(" silenjpeg size %d bytes,", silentsize); >+ if (silentsize >= splash_size) { >+ printk(" bigger than splashsize!\n"); >+ return -1; >+ } >+ splash_size -= silentsize; >+ if (!splash_usesilent || !p->fb_info->fbops->fb_get_fix ) { >+ silentsize = 0; >+ } else { >+ struct fb_fix_screeninfo fix; >+ p->fb_info->fbops->fb_get_fix(&fix, unit, 0); >+ if (height * 2 * p->next_line > fix.smem_len) { >+ printk(" does not fit into framebuffer.\n"); >+ silentsize = 0; >+ } >+ } >+ >+ sboxcount = ndata[32] + (ndata[33] << 8); >+ if (silentsize) { >+ char *simage=ndata + 38 + splash_size + 12 * sboxcount; >+ if (!jpeg_check_size(simage, width, height) || >+ splash_check_jpeg(simage, width, height, p->var.bits_per_pixel)) { >+ printk(" error in silent jpeg.\n"); >+ silentsize = 0; >+ } >+ } >+ if (p->splash_data) >+ splash_free(p); >+ p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size); >+ if (!p->splash_data) >+ break; >+ p->splash_data->oldscreen_base = 0; >+ p->splash_data->olddispsw = 0; >+ p->splash_data->splash_silentjpeg = 0; >+ if (silentsize) { >+ p->splash_data->splash_silentjpeg = vmalloc(silentsize); >+ if (p->splash_data->splash_silentjpeg) { >+ memcpy(p->splash_data->splash_silentjpeg, ndata + 38 + splash_size, silentsize); >+ p->splash_data->splash_sboxes = p->splash_data->splash_silentjpeg; >+ p->splash_data->splash_silentjpeg += 12 * sboxcount; >+ p->splash_data->splash_sboxcount = sboxcount; >+ } >+ } >+ p->splash_data->splash_state = ndata[9]; >+ p->splash_data->splash_fg_color = ndata[10]; >+ p->splash_data->splash_color = ndata[11]; >+ p->splash_data->splash_overpaintok = ndata[36]; >+ p->splash_data->splash_text_xo = ndata[16] + (ndata[17] << 8); >+ p->splash_data->splash_text_yo = ndata[18] + (ndata[19] << 8); >+ p->splash_data->splash_text_wi = ndata[20] + (ndata[21] << 8); >+ p->splash_data->splash_text_he = ndata[22] + (ndata[23] << 8); >+ p->splash_data->splash_percent = ndata[34] + (ndata[35] << 8); >+ p->splash_data->splash_percent += p->splash_data->splash_percent > 32767; >+ splash_start = ndata + 38; >+ found = 3; >+ break; >+ } >+ } >+ >+ if (!found) { >+ printk(" no good signature found.\n"); >+ return -1; >+ } >+ if (p->splash_data->splash_text_xo + p->splash_data->splash_text_wi > width || p->splash_data->splash_text_yo + p->splash_data->splash_text_he > height) { >+ splash_free(p); >+ p->splash_data = 0; >+ printk(" found, but has oversized text area!\n"); >+ return -1; >+ } >+ if (p->dispsw->setup != fbcon_cfb16.setup) { >+ splash_free(p); >+ p->splash_data = 0; >+ printk(" found, but framebuffer can't handle it!\n"); >+ return -1; >+ } >+ printk(" found (%dx%d, %d bytes, v%d).\n", width, height, splash_size, found); >+ >+ if (found==1) { >+ printk(KERN_WARNING "bootsplash: Using deprecated v1 header. Updating your splash utility recommended.\n"); >+ printk(KERN_INFO "bootsplash: Find the latest version at ftp.suse.com/pub/people/stepan/bootsplash/\n"); >+ } >+ >+ /* copy data so that initrd memory can be freed. */ >+ memcpy((char *)p->splash_data + sizeof(*p->splash_data) + (found < 3 ? boxcount * 12 : 0), splash_start, splash_size); >+ p->splash_data->splash_boxcount = boxcount; >+ p->splash_data->splash_boxes = (unsigned char *)p->splash_data + sizeof(*p->splash_data); >+ p->splash_data->splash_jpeg = (unsigned char *)p->splash_data + sizeof(*p->splash_data) + boxcount * 12 + palcnt; >+ p->splash_data->splash_palette = (unsigned char *)p->splash_data + sizeof(*p->splash_data) + boxcount * 12; >+ p->splash_data->splash_palcnt = palcnt / 3; >+ p->splash_data->splash_dosilent = p->splash_data->splash_silentjpeg != 0; >+ return unit; >+} >+ >+int splash_verbose(void) >+{ >+ struct display *p; >+ >+ p = &fb_display[0]; >+ if (!p || !p->splash_data || !p->splash_data->splash_state || !p->conp) >+ return 0; >+ if (fg_console != p->conp->vc_num) >+ return 0; >+ if (!p->splash_data->splash_silentjpeg || !p->splash_data->splash_dosilent) >+ return 0; >+ if (!p->splash_data->oldscreen_base) >+ return 0; >+ >+ p->splash_data->splash_dosilent = 0; >+ >+ splashfill(p->splash_data->oldscreen_base, p->screen_base, p->var.xres, p->var.yres, p->next_line, p->next_line); >+ p->screen_base = p->splash_data->oldscreen_base; >+ >+ return 1; >+} >+ >+static void splash_off(struct display *p) >+{ >+ if (p->splash_data && p->splash_data->oldscreen_base) >+ p->screen_base = p->splash_data->oldscreen_base; >+ if (p->splash_data && p->splash_data->olddispsw) >+ p->dispsw = p->splash_data->olddispsw; >+ splash_shown = 0; >+} >+ >+int splash_prepare(struct display *p) >+{ >+ int err; >+ int width, height, depth, size, sbytes; >+ >+ if (!p->splash_data || !p->splash_data->splash_state) { >+ if (linux_splash) >+ vfree(linux_splash); >+ if (decdata) >+ vfree(decdata); >+ linux_splash = 0; >+ decdata = 0; >+ linux_splash_size = 0; >+ splash_off(p); >+ return -1; >+ } >+ >+ width = p->var.xres; >+ height = p->var.yres; >+ depth = p->var.bits_per_pixel; >+ if (depth != 16) { /* Other targets might need fixing */ >+ splash_off(p); >+ return -2; >+ } >+ >+ sbytes = ((width + 15) & ~15) * (depth >> 3); >+ size = sbytes * ((height + 15) & ~15); >+ if (size != linux_splash_size) { >+ if (linux_splash) >+ vfree(linux_splash); >+ linux_splash_size = 0; >+ linux_splash = 0; >+ splash_off(p); >+ } >+ if (!linux_splash) >+ linux_splash = vmalloc(size); >+ >+ if (!linux_splash) { >+ linux_splash_size = 0; >+ printk(KERN_INFO "Not enough memory for splash screen.\n"); >+ splash_off(p); >+ return -3; >+ } >+ >+ if (!decdata) >+ decdata = vmalloc(sizeof(*decdata)); >+ >+ if (!p->splash_data->oldscreen_base) >+ p->splash_data->oldscreen_base = p->screen_base; >+ >+ if (p->splash_data->splash_silentjpeg && p->splash_data->splash_dosilent) { >+ printk(KERN_INFO "Got silent jpeg.\n"); >+ /* fill area after framebuffer with other jpeg */ >+ if ((err = jpeg_decode(p->splash_data->splash_silentjpeg, linux_splash, >+ ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) { >+ printk(KERN_INFO "Error %d while decompressing silent jpeg.\n", err); >+ p->screen_base = p->splash_data->oldscreen_base; >+ p->splash_data->splash_dosilent = 0; >+ } else { >+ if (p->splash_data->splash_sboxcount) >+ boxit(linux_splash, sbytes, p->splash_data->splash_sboxes, >+ p->splash_data->splash_sboxcount, p->splash_data->splash_percent, 0); >+ >+ splashfill(p->screen_base, linux_splash, p->var.xres, p->var.yres, p->next_line, sbytes); >+ p->screen_base = p->splash_data->oldscreen_base + p->next_line * p->var.yres; >+ } >+ } else >+ p->screen_base = p->splash_data->oldscreen_base; >+ >+ if ((err = jpeg_decode(p->splash_data->splash_jpeg, linux_splash, >+ ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) { >+ printk(KERN_INFO "Error %d while decompressing splash screen.\n", err); >+ vfree(linux_splash); >+ linux_splash = 0; >+ linux_splash_size = 0; >+ splash_off(p); >+ return -4; >+ } >+ linux_splash_size = size; >+ splash_bytes = sbytes; >+ if (p->splash_data->splash_boxcount) >+ boxit(linux_splash, sbytes, p->splash_data->splash_boxes, p->splash_data->splash_boxcount, p->splash_data->splash_percent, 0); >+ splash_data = *p->splash_data; >+ splash_shown = p->splash_data->splash_state; >+ if (splash_shown) { >+ if (p->dispsw != &fbcon_splash16) >+ p->splash_data->olddispsw = p->dispsw; >+ p->dispsw = &fbcon_splash16; >+ } else >+ splash_off(p); >+ return 0; >+} >+ >+ >+#ifdef CONFIG_PROC_FS >+#include <linux/proc_fs.h> >+ >+struct proc_dir_entry *proc_splash; >+int splash_read_proc(char *buffer, char **start, off_t offset, int size, >+ int *eof, void *data); >+int splash_write_proc(struct file *file, const char *buffer, >+ unsigned long count, void *data); >+ >+int splash_read_proc(char *buffer, char **start, off_t offset, int size, >+ int *eof, void *data) >+{ >+ int len = 0; >+ >+ off_t begin = 0; >+ struct display *p = &fb_display[0]; >+ >+ int color = p->splash_data ? p->splash_data->splash_color << 4 | >+ p->splash_data->splash_fg_color : splash_default >> 4; >+ int status = p->splash_data ? p->splash_data->splash_state & 1 : 0; >+ len += sprintf(buffer + len, "Splash screen v%s (0x%02x, %dx%d%s): %s\n", >+ SPLASH_VERSION, color, p->var.xres, p->var.yres, >+ (p->splash_data ? p->splash_data->splash_dosilent : 0)? ", silent" : "", >+ status ? "on" : "off"); >+ if (offset >= begin + len) >+ return 0; >+ >+ *start = buffer + (begin - offset); >+ >+ return (size < begin + len - offset ? size : begin + len - offset); >+} >+ >+static int splash_recolor(struct display *p) >+{ >+ if (!p->splash_data) >+ return -1; >+ if (!p->splash_data->splash_state) >+ return 0; >+ con_remap_def_color(p->conp->vc_num, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color); >+ if (fg_console == p->conp->vc_num) { >+ splash_data = *p->splash_data; >+ update_region(fg_console, >+ p->conp->vc_origin + >+ p->conp->vc_size_row * >+ p->conp->vc_top, >+ p->conp->vc_size_row * >+ (p->conp->vc_bottom - >+ p->conp->vc_top) / 2); >+ } >+ return 0; >+} >+ >+static int splash_status(struct display *p) >+{ >+ printk(KERN_INFO "Splash status on console %d changed to %s\n", p->conp->vc_num, p->splash_data && p->splash_data->splash_state ? "on" : "off"); >+ >+ if (fg_console == p->conp->vc_num) >+ splash_prepare(p); >+ if (p->splash_data && p->splash_data->splash_state) { >+ con_remap_def_color(p->conp->vc_num, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color); >+ /* resize_con also calls con_switch which resets yscroll */ >+ vc_resize_con(p->splash_data->splash_text_he / fontheight(p), >+ p->splash_data->splash_text_wi / fontwidth(p), >+ p->conp->vc_num); >+ if (fg_console == p->conp->vc_num) { >+ update_region(fg_console, >+ p->conp->vc_origin + >+ p->conp->vc_size_row * >+ p->conp->vc_top, >+ p->conp->vc_size_row * >+ (p->conp->vc_bottom - >+ p->conp->vc_top) / 2); >+ fbcon_splash16.clear_margins(p->conp, p, 0); >+ } >+ } else { >+ /* Switch bootsplash off */ >+ con_remap_def_color(p->conp->vc_num, 0x07); >+ vc_resize_con(p->var.yres / fontheight(p), >+ p->var.xres / fontwidth(p), >+ p->conp->vc_num); >+ } >+ return 0; >+} >+ >+int splash_write_proc(struct file *file, const char *buffer, >+ unsigned long count, void *data) >+{ >+ int new, unit; >+ struct display *p; >+ >+ if (!buffer || !splash_default) >+ return count; >+ >+ if (!strncmp(buffer, "show", 4) || !strncmp(buffer, "hide", 4)) { >+ int pe; >+ >+ p = &fb_display[0]; >+ if (buffer[4] == ' ' && buffer[5] == 'p') >+ pe = 0; >+ else if (buffer[4] == '\n') >+ pe = 65535; >+ else >+ pe = simple_strtoul(buffer + 5, NULL, 0); >+ if (pe < 0) >+ pe = 0; >+ if (pe > 65535) >+ pe = 65535; >+ if (*buffer == 'h') >+ pe = 65535 - pe; >+ pe += pe > 32767; >+ if (p->splash_data && p->splash_data->splash_percent != pe) { >+ p->splash_data->splash_percent = pe; >+ if (fg_console != p->conp->vc_num || !p->splash_data->splash_state) >+ return count; >+ if (!p->splash_data->splash_overpaintok || p->splash_data->splash_percent == 65536) { >+ if (splash_hasinter(p->splash_data->splash_boxes, p->splash_data->splash_boxcount)) >+ splash_status(p); >+ else >+ splash_prepare(p); >+ } else { >+ if (p->splash_data->splash_silentjpeg && p->splash_data->splash_dosilent && p->splash_data->oldscreen_base) >+ boxit(p->splash_data->oldscreen_base, p->next_line, p->splash_data->splash_sboxes, p->splash_data->splash_sboxcount, p->splash_data->splash_percent, 1); >+ boxit(p->screen_base, p->next_line, p->splash_data->splash_boxes, p->splash_data->splash_boxcount, p->splash_data->splash_percent, 1); >+ } >+ } >+ return count; >+ } >+ if (!strncmp(buffer,"silent\n",7) || !strncmp(buffer,"verbose\n",8)) { >+ p = &fb_display[0]; >+ if (p->splash_data && p->splash_data->splash_silentjpeg) { >+ if (p->splash_data->splash_dosilent != (buffer[0] == 's')) { >+ p->splash_data->splash_dosilent = buffer[0] == 's'; >+ splash_status(p); >+ } >+ } >+ return count; >+ } >+ if (!strncmp(buffer,"freesilent\n",11)) { >+ p = &fb_display[0]; >+ if (p->splash_data && p->splash_data->splash_silentjpeg) { >+ printk(KERN_INFO "bootsplash: freeing silent jpeg\n"); >+ p->splash_data->splash_silentjpeg = 0; >+ vfree(p->splash_data->splash_sboxes); >+ p->splash_data->splash_sboxes = 0; >+ p->splash_data->splash_sboxcount = 0; >+ if (p->splash_data->splash_dosilent) >+ splash_status(p); >+ p->splash_data->splash_dosilent = 0; >+ } >+ return count; >+ } >+ >+ if (!strncmp(buffer, signature, 7)) { >+ unit = splash_getraw((unsigned char *)buffer, (unsigned char *)buffer + count); >+ if (unit >= 0) { >+ p = &fb_display[unit]; >+ splash_status(p); >+ } >+ return count; >+ } >+ p = &fb_display[0]; >+ if (!p->splash_data) >+ return count; >+ if (buffer[0] == 't') { >+ p->splash_data->splash_state ^= 1; >+ splash_status(p); >+ return count; >+ } >+ new = simple_strtoul(buffer, NULL, 0); >+ if (new > 1) { >+ /* expert user */ >+ p->splash_data->splash_color = new >> 8 & 0xff; >+ p->splash_data->splash_fg_color = new >> 4 & 0x0f; >+ } >+ if ((new & 1) == p->splash_data->splash_state) >+ splash_recolor(p); >+ else { >+ p->splash_data->splash_state = new & 1; >+ splash_status(p); >+ } >+ return count; >+} >+ >+int splash_proc_register(void) >+{ >+ if ((proc_splash = create_proc_entry("splash", 0, 0))) { >+ proc_splash->read_proc = splash_read_proc; >+ proc_splash->write_proc = splash_write_proc; >+ return 0; >+ } >+ return 1; >+} >+ >+int splash_proc_unregister(void) >+{ >+ if (proc_splash) >+ remove_proc_entry("splash", 0); >+ return 0; >+} >+#endif >diff -urN linux-2.4.22-rc2-ac3/drivers/video/fbcon-splash.h linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-splash.h >--- linux-2.4.22-rc2-ac3/drivers/video/fbcon-splash.h 1969-12-31 20:00:00.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-splash.h 2003-08-21 17:00:01.000000000 -0400 >@@ -0,0 +1,18 @@ >+/* >+ * linux/drivers/video/splash.h - splash screen definition. >+ * >+ * (w) 2001-2003 by Volker Poplawski, <volker@suse.de> >+ * Stefan Reinauer, <stepan@suse.de> >+ * >+ * >+ * idea and SuSE screen work by Ken Wimer, <wimer@suse.de> >+ */ >+ >+extern int splash_getraw(unsigned char *, unsigned char *); >+extern int splash_prepare(struct display *); >+ >+extern int splash_shown; /* is splash shown? */ >+extern struct splash_data splash_data; /* image data, copied over >+ from display */ >+extern unsigned char *linux_splash; /* decoded pic data */ >+extern int splash_bytes; /* bytes per line */ >diff -urN linux-2.4.22-rc2-ac3/drivers/video/fbcon-splash16.c linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-splash16.c >--- linux-2.4.22-rc2-ac3/drivers/video/fbcon-splash16.c 1969-12-31 20:00:00.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/video/fbcon-splash16.c 2003-08-21 17:00:01.000000000 -0400 >@@ -0,0 +1,488 @@ >+/* >+ * linux/drivers/video/fbcon-splash16.c -- Low level frame buffer operations for 16 bpp >+ * framebuffer operation. Modified to present >+ * boot splash screen. 2002/11/7 stepan@suse.de >+ * >+ * Based on linux/drivers/video/fbcon-cfb16.c, which is >+ * >+ * Created 5 Apr 1997 by Geert Uytterhoeven >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive for >+ * more details. >+ */ >+ >+#include <linux/module.h> >+#include <linux/config.h> >+#include <linux/tty.h> >+#include <linux/console.h> >+#include <linux/string.h> >+#include <linux/fb.h> >+#include <asm/io.h> >+ >+#include <video/fbcon.h> >+#include <video/fbcon-cfb16.h> >+ >+#include "fbcon-splash.h" >+ >+ /* >+ * 16 bpp packed pixels >+ */ >+ >+static u32 tab_cfb16[] = { >+#if defined(__BIG_ENDIAN) >+ 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff >+#elif defined(__LITTLE_ENDIAN) >+ 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff >+#else >+#error FIXME: No endianness?? >+#endif >+}; >+ >+void fbcon_splash16_bmove(struct display *p, int sy, int sx, int dy, int dx, >+ int height, int width) >+{ >+ int bytes = p->next_line, linesize = bytes * fontheight(p), rows; >+ u8 *src, *dst; >+ >+ if (sx == 0 && dx == 0 && width * fontwidth(p) * 2 == bytes) { >+ fb_memmove(p->screen_base + dy * linesize, >+ p->screen_base + sy * linesize, >+ height * linesize); >+ return; >+ } >+ if (fontwidthlog(p)) { >+ sx <<= fontwidthlog(p)+1; >+ dx <<= fontwidthlog(p)+1; >+ width <<= fontwidthlog(p)+1; >+ } else { >+ sx *= fontwidth(p)*2; >+ dx *= fontwidth(p)*2; >+ width *= fontwidth(p)*2; >+ } >+ sx += splash_data.splash_text_xo*2 + splash_data.splash_text_yo * bytes; >+ dx += splash_data.splash_text_xo*2 + splash_data.splash_text_yo * bytes; >+ if (dy < sy || (dy == sy && dx < sx)) { >+ src = p->screen_base + sy * linesize + sx; >+ dst = p->screen_base + dy * linesize + dx; >+ for (rows = height * fontheight(p); rows--;) { >+ fb_memmove(dst, src, width); >+ src += bytes; >+ dst += bytes; >+ } >+ } else { >+ src = p->screen_base + (sy+height) * linesize + sx - bytes; >+ dst = p->screen_base + (dy+height) * linesize + dx - bytes; >+ for (rows = height * fontheight(p); rows--;) { >+ fb_memmove(dst, src, width); >+ src -= bytes; >+ dst -= bytes; >+ } >+ } >+} >+ >+static inline void rectfill(u8 *dest, int width, int height, u32 data, >+ int linesize) >+{ >+ int i; >+ >+ data |= data<<16; >+ >+ while (height-- > 0) { >+ u32 *p = (u32 *)dest; >+ for (i = 0; i < width/4; i++) { >+ fb_writel(data, p++); >+ fb_writel(data, p++); >+ } >+ if (width & 2) >+ fb_writel(data, p++); >+ if (width & 1) >+ fb_writew(data, (u16*)p); >+ dest += linesize; >+ } >+} >+ >+void splashfill(u8 *dest, u8 *src, int width, int height, >+ int dest_linesize, int src_linesize) >+{ >+ >+ int i; >+ >+ while (height-- > 0) { >+ u32 *p = (u32 *)dest; >+ u32 *q = (u32 *)src; >+ >+ for (i=0; i < width/4; i++) { >+ fb_writel(*q++,p++); >+ fb_writel(*q++,p++); >+ } >+ if (width & 2) >+ fb_writel(*q++,p++); >+ if (width & 1) >+ fb_writew(*(u16*)q,(u16*)p); >+ dest += dest_linesize; >+ src += src_linesize; >+ } >+} >+ >+void fbcon_splash16_clear(struct vc_data *conp, struct display *p, int sy, int sx, >+ int height, int width) >+{ >+ u8 *dest; >+ int bytes = p->next_line, lines = height * fontheight(p); >+ u32 bgx; >+ int offset, transparent=0; >+ >+ dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2; >+ >+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]; >+ >+ width *= fontwidth(p)/4; >+ >+ dest += splash_data.splash_text_yo * bytes + >+ splash_data.splash_text_xo * 2; >+ >+ transparent = (splash_data.splash_color == attr_bgcol_ec(p, conp)); >+ >+ if (transparent) { >+ offset = (sy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes + >+ (sx * fontwidth(p) + splash_data.splash_text_xo) * 2; >+ >+ if ((width * 8 == bytes && splash_bytes == bytes)) >+ splashfill(dest,linux_splash + offset, lines * width * 4, >+ 1, bytes, splash_bytes); >+ else >+ splashfill(dest,linux_splash + offset, width*4, lines, >+ bytes, splash_bytes); >+ } else { >+ if (width * 8 == bytes) >+ rectfill(dest, lines * width * 4, 1, bgx, bytes); >+ else >+ rectfill(dest, width * 4, lines, bgx, bytes); >+ } >+} >+ >+ >+/* >+ * Helper function to read the background from the splashscreen >+ */ >+# define SPLASH_BGX(off) \ >+ if (transparent) { \ >+ bgx = *(u32*)(splashbgx + (off)); \ >+ eorx = fgx ^ bgx; \ >+ } >+ >+ >+void fbcon_splash16_putc(struct vc_data *conp, struct display *p, int c, int yy, >+ int xx) >+{ >+ u8 *dest, *cdat, bits; >+ int bytes = p->next_line, rows; >+ u32 eorx, fgx, bgx; >+ int transparent = 0; >+ u8 *splashbgx = 0; >+ >+ dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2; >+ >+ fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)]; >+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)]; >+ >+ transparent = (splash_data.splash_color == attr_bgcol(p, c)); >+ >+ dest += splash_data.splash_text_xo * 2 + splash_data.splash_text_yo * bytes; >+ splashbgx = linux_splash + >+ (yy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes + >+ (xx * fontwidth(p) + splash_data.splash_text_xo) * 2; >+ >+ if (transparent && splash_data.splash_color == 0xf) { >+ if (fgx == 0xffea) >+ fgx = 0xfe4a; >+ else if (fgx == 0x57ea) >+ fgx = 0x0540; >+ else if (fgx == 0xffff) >+ fgx = 0x52aa; >+ } >+ >+ fgx |= (fgx << 16); >+ bgx |= (bgx << 16); >+ eorx = fgx ^ bgx; >+ >+ switch (fontwidth(p)) { >+ case 4: >+ case 8: >+ cdat = p->fontdata + (c & p->charmask) * fontheight(p); >+ for (rows = fontheight(p); rows--; dest += bytes) { >+ bits = *cdat++; >+ SPLASH_BGX(0); >+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest); >+ SPLASH_BGX(4); >+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4); >+ if (fontwidth(p) == 8) { >+ SPLASH_BGX(8); >+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8); >+ SPLASH_BGX(12); >+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12); >+ } >+ >+ splashbgx += splash_bytes; >+ >+ } >+ break; >+ case 12: >+ case 16: >+ cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1); >+ for (rows = fontheight(p); rows--; dest += bytes) { >+ bits = *cdat++; >+ SPLASH_BGX(0); >+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest); >+ SPLASH_BGX(4); >+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4); >+ SPLASH_BGX(8); >+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8); >+ SPLASH_BGX(12); >+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12); >+ bits = *cdat++; >+ SPLASH_BGX(16); >+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16); >+ SPLASH_BGX(20); >+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20); >+ if (fontwidth(p) == 16) { >+ SPLASH_BGX(24); >+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24); >+ SPLASH_BGX(28); >+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28); >+ } >+ } >+ break; >+ } >+} >+ >+void fbcon_splash16_putcs(struct vc_data *conp, struct display *p, >+ const unsigned short *s, int count, int yy, int xx) >+{ >+ u8 *cdat, *dest, *dest0; >+ u16 c; >+ int rows, bytes = p->next_line; >+ u32 eorx, fgx, bgx; >+ int transparent = 0; >+ u8 *splashbgx0 = 0, *splashbgx; >+ >+ dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2; >+ c = scr_readw(s); >+ fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)]; >+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)]; >+ >+ transparent = (splash_data.splash_color == attr_bgcol(p, c)); >+ >+ dest0 += splash_data.splash_text_xo * 2 + splash_data.splash_text_yo * bytes; >+ splashbgx0 = linux_splash + >+ (yy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes + >+ (xx * fontwidth(p) + splash_data.splash_text_xo) * 2; >+ >+ if (transparent && splash_data.splash_color == 0xf) { >+ if (fgx == 0xffea) >+ fgx = 0xfe4a; >+ else if (fgx == 0x57ea) >+ fgx = 0x0540; >+ else if (fgx == 0xffff) >+ fgx = 0x52aa; >+ } >+ >+ fgx |= (fgx << 16); >+ bgx |= (bgx << 16); >+ eorx = fgx ^ bgx; >+ >+ switch (fontwidth(p)) { >+ case 4: >+ case 8: >+ while (count--) { >+ c = scr_readw(s++) & p->charmask; >+ cdat = p->fontdata + c * fontheight(p); >+ >+ splashbgx = splashbgx0; >+ >+ for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) { >+ u8 bits = *cdat++; >+ SPLASH_BGX(0); >+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest); >+ SPLASH_BGX(4); >+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4); >+ if (fontwidth(p) == 8) { >+ SPLASH_BGX(8); >+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8); >+ SPLASH_BGX(12); >+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12); >+ } >+ splashbgx += splash_bytes; >+ } >+ >+ dest0 += fontwidth(p)*2; >+ splashbgx0 += fontwidth(p) * 2; >+ } >+ >+ break; >+ case 12: >+ case 16: >+ while (count--) { >+ c = scr_readw(s++) & p->charmask; >+ cdat = p->fontdata + (c * fontheight(p) << 1); >+ >+ splashbgx = splashbgx0; >+ >+ for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) { >+ u8 bits = *cdat++; >+ SPLASH_BGX(0); >+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest); >+ SPLASH_BGX(4); >+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4); >+ SPLASH_BGX(8); >+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8); >+ SPLASH_BGX(12); >+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12); >+ bits = *cdat++; >+ SPLASH_BGX(16); >+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16); >+ SPLASH_BGX(20); >+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20); >+ if (fontwidth(p) == 16) { >+ SPLASH_BGX(24); >+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24); >+ SPLASH_BGX(28); >+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28); >+ } >+ splashbgx += splash_bytes; >+ } >+ >+ dest0 += fontwidth(p)*2; >+ splashbgx0 += fontwidth(p) * 2; >+ } >+ >+ break; >+ } >+} >+ >+void fbcon_splash16_revc(struct display *p, int xx, int yy) >+{ >+ u8 *dest; >+ int bytes = p->next_line, rows; >+ >+ dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2; >+ dest += splash_data.splash_text_yo * bytes + splash_data.splash_text_xo * 2; >+ >+ for (rows = fontheight(p); rows--; dest += bytes) { >+ switch (fontwidth(p)) { >+ case 16: >+ fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24); >+ fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28); >+ /* FALL THROUGH */ >+ case 12: >+ fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16); >+ fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20); >+ /* FALL THROUGH */ >+ case 8: >+ fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8); >+ fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12); >+ /* FALL THROUGH */ >+ case 4: >+ fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0); >+ fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4); >+ } >+ } >+} >+ >+void fbcon_splash16_clear_margins(struct vc_data *conp, struct display *p, >+ int bottom_only) >+{ >+ int bytes = p->next_line; >+ u32 bgx; >+ >+ unsigned int right_start = conp->vc_cols*fontwidth(p); >+ unsigned int bottom_start = conp->vc_rows*fontheight(p); >+ unsigned int right_width, bottom_width; >+ >+ int left_margin_width = splash_data.splash_text_xo; >+ int text_width = conp->vc_cols * fontwidth(p); >+ int right_margin_width = p->var.xres - text_width - left_margin_width; >+ int top_margin_height = splash_data.splash_text_yo; >+ int text_height = conp->vc_rows * fontheight(p); >+ int bottom_margin_height = p->var.yres - text_height - top_margin_height; >+ >+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]; >+ >+ if (bottom_only == -1) { >+ printk(KERN_DEBUG "Called with bottom-only\n"); >+ splashfill(p->screen_base, linux_splash, p->var.xres, p->var.yres, bytes, splash_bytes); >+ return; >+ } >+ >+ if (!bottom_only && (right_width = p->var.xres-right_start)) { >+ /* left margin */ >+ splashfill(p->screen_base + top_margin_height * bytes, >+ linux_splash + top_margin_height * >+ splash_bytes, left_margin_width, >+ text_height, bytes, splash_bytes); >+ >+ /* right margin */ >+ splashfill(p->screen_base + left_margin_width*2 + text_width*2 + >+ top_margin_height * bytes, linux_splash + >+ left_margin_width*2 + text_width*2 + top_margin_height * >+ splash_bytes, right_margin_width, text_height, >+ bytes, splash_bytes); >+ } >+ >+ if ((bottom_width = p->var.yres-bottom_start)) >+ /* bottom margin */ >+ splashfill(p->screen_base + (top_margin_height + text_height) * >+ bytes, linux_splash + (top_margin_height + >+ text_height) * splash_bytes, p->var.xres, >+ bottom_margin_height, bytes, splash_bytes); >+ >+ /* top margin */ >+ splashfill(p->screen_base, linux_splash, >+ p->var.xres, top_margin_height, >+ bytes, splash_bytes); >+ >+ /* leave function if work is done */ >+ return; >+} >+ >+ >+ /* >+ * `switch' for the low level operations >+ */ >+ >+struct display_switch fbcon_splash16 = { >+ bmove: fbcon_splash16_bmove, >+ clear: fbcon_splash16_clear, >+ putc: fbcon_splash16_putc, >+ putcs: fbcon_splash16_putcs, >+ revc: fbcon_splash16_revc, >+ clear_margins: fbcon_splash16_clear_margins, >+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) >+}; >+ >+ >+#ifdef MODULE >+MODULE_LICENSE("GPL"); >+ >+int init_module(void) >+{ >+ return 0; >+} >+ >+void cleanup_module(void) >+{} >+#endif /* MODULE */ >+ >+ >+ /* >+ * Visible symbols for modules >+ */ >+ >+EXPORT_SYMBOL(fbcon_splash16); >+EXPORT_SYMBOL(fbcon_splash16_bmove); >+EXPORT_SYMBOL(fbcon_splash16_clear); >+EXPORT_SYMBOL(fbcon_splash16_putc); >+EXPORT_SYMBOL(fbcon_splash16_putcs); >+EXPORT_SYMBOL(fbcon_splash16_revc); >+EXPORT_SYMBOL(fbcon_splash16_clear_margins); >diff -urN linux-2.4.22-rc2-ac3/drivers/video/fbcon.c linux-2.4.22-rc2-ac3-new/drivers/video/fbcon.c >--- linux-2.4.22-rc2-ac3/drivers/video/fbcon.c 2003-08-21 07:31:58.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/drivers/video/fbcon.c 2003-08-21 17:00:01.000000000 -0400 >@@ -76,6 +76,7 @@ > #include <linux/smp.h> > #include <linux/init.h> > #include <linux/pm.h> >+#include <linux/vmalloc.h> > > #include <asm/irq.h> > #include <asm/system.h> >@@ -104,6 +105,23 @@ > #include <video/fbcon-mac.h> /* for 6x11 font on mac */ > #include <video/font.h> > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+#include <video/fbcon-cfb16.h> /* for fbcon_cfb16 */ >+#include "fbcon-splash.h" >+ >+extern void con_remap_def_color(int currcons, int new_color); >+ >+extern int splash_default; >+extern int splash_shown; >+ >+extern struct display_switch fbcon_splash16; >+ >+#ifdef CONFIG_PROC_FS >+int splash_proc_register(void); >+int splash_proc_unregister(void); >+#endif >+#endif >+ > #ifdef FBCONDEBUG > # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) > #else >@@ -477,7 +495,9 @@ > return display_desc; > } > >- >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+static int splash_registered=0; >+#endif > static void fbcon_init(struct vc_data *conp, int init) > { > int unit = conp->vc_num; >@@ -501,6 +521,26 @@ > fb_display[unit].cmap.green = 0; > fb_display[unit].cmap.blue = 0; > fb_display[unit].cmap.transp = 0; >+ >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (!splash_registered && fb_display[unit].var.bits_per_pixel == 16 ) { >+ if (unit == 0 && !fb_display[unit].splash_data) { >+ extern unsigned long initrd_start, initrd_end; >+ >+ if (initrd_start && !splash_getraw((unsigned char *)initrd_start, (unsigned char *)initrd_end) && fb_display[unit].splash_data) >+ fb_display[unit].splash_data->splash_state = splash_default & 1; >+ } >+ splash_registered = 1; >+#ifdef CONFIG_PROC_FS >+ splash_proc_register(); >+#endif >+ } >+ if (fb_display[unit].splash_data && fb_display[unit].var.bits_per_pixel != 16 ) { >+ vfree(fb_display[unit].splash_data); >+ fb_display[unit].splash_data = 0; >+ } >+#endif >+ > fbcon_setup(unit, init, !init); > /* Must be done after fbcon_setup to prevent excess updates */ > conp->vc_display_fg = &info->display_fg; >@@ -517,6 +557,15 @@ > fbcon_free_font(p); > p->dispsw = &fbcon_dummy; > p->conp = 0; >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (splash_registered) { >+#ifdef CONFIG_PROC_FS >+ splash_proc_unregister(); >+#endif >+ splash_registered = 0; >+ } >+#endif >+ > } > > >@@ -657,7 +706,14 @@ > > nr_cols = p->var.xres/fontwidth(p); > nr_rows = p->var.yres/fontheight(p); >- >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (p->splash_data && p->splash_data->splash_state) { >+ nr_cols = p->splash_data->splash_text_wi / fontwidth(p); >+ nr_rows = p->splash_data->splash_text_he / fontheight(p); >+ logo = 0; >+ } >+#endif >+ > if (logo) { > /* Need to make room for the logo */ > int cnt; >@@ -734,6 +790,11 @@ > p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1; > p->bgcol = 0; > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if(p->splash_data && p->splash_data->splash_state) >+ con_remap_def_color(con, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color); >+#endif >+ > if (!init) { > if (conp->vc_cols != nr_cols || conp->vc_rows != nr_rows) > vc_resize_con(nr_rows, nr_cols, con); >@@ -1323,6 +1384,9 @@ > if (softback_top) > fbcon_softback_note(conp, t, count); > if (logo_shown >= 0) goto redraw_up; >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (splash_shown) goto redraw_up; >+#endif > switch (p->scrollmode & __SCROLL_YMASK) { > case __SCROLL_YMOVE: > p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count, >@@ -1383,6 +1447,9 @@ > case SM_DOWN: > if (count > conp->vc_rows) /* Maximum realistic size */ > count = conp->vc_rows; >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (splash_shown) goto redraw_down; >+#endif > switch (p->scrollmode & __SCROLL_YMASK) { > case __SCROLL_YMOVE: > p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count, >@@ -1499,6 +1566,13 @@ > } > return; > } >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (splash_shown && sy == dy) { >+ /* must use slower redraw bmove to keep background pic intact */ >+ fbcon_redraw_bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width); >+ return; >+ } >+#endif > p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width); > } > >@@ -1509,6 +1583,10 @@ > struct display *p = &fb_display[unit]; > struct fb_info *info = p->fb_info; > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ splash_prepare(p); >+#endif >+ > if (softback_top) { > int l = fbcon_softback_size / conp->vc_size_row; > if (softback_lines) >@@ -1568,14 +1646,41 @@ > { > struct display *p = &fb_display[conp->vc_num]; > struct fb_info *info = p->fb_info; >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ struct display_switch *olddispsw=NULL; >+ char *oldscreen_base=NULL; >+#endif >+ > > if (blank < 0) /* Entering graphics mode */ > return 0; > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ >+ if (p->splash_data && p->splash_data->oldscreen_base) { >+ oldscreen_base = p->screen_base; >+ p->screen_base = p->splash_data->oldscreen_base; >+ } >+ if (p->splash_data && p->splash_data->olddispsw) { >+ olddispsw = p->dispsw; >+ p->dispsw = p->splash_data->olddispsw; >+ } >+#endif >+ > fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW); > > if (!p->can_soft_blank) { > if (blank) { >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (p->splash_data && p->splash_data->oldscreen_base) { >+ oldscreen_base = p->screen_base; >+ p->screen_base = p->splash_data->oldscreen_base; >+ } >+ if (p->splash_data && p->splash_data->olddispsw) { >+ olddispsw = p->dispsw; >+ p->dispsw = p->splash_data->olddispsw; >+ } >+#endif > if (p->visual == FB_VISUAL_MONO01) { > if (p->screen_base) > fb_memset255(p->screen_base, >@@ -1583,25 +1688,39 @@ > p->var.bits_per_pixel>>3); > } else { > unsigned short oldc; >- u_int height; >+ u_int height, width; > u_int y_break; > > oldc = conp->vc_video_erase_char; > conp->vc_video_erase_char &= p->charmask; > height = conp->vc_rows; >+ width = conp->vc_cols; > y_break = p->vrows-p->yscroll; >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (splash_shown) { >+ width=p->var.xres/fontwidth(p); >+ height=p->var.yres/fontheight(p); >+ } >+#endif > if (height > y_break) { >- p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, conp->vc_cols); >- p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, conp->vc_cols); >+ p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, width); >+ p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, width); > } else >- p->dispsw->clear(conp, p, real_y(p, 0), 0, height, conp->vc_cols); >+ p->dispsw->clear(conp, p, real_y(p, 0), 0, height, width); > conp->vc_video_erase_char = oldc; > } >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if(oldscreen_base) >+ p->screen_base=oldscreen_base; >+ if(olddispsw) >+ p->dispsw=olddispsw; >+#endif > return 0; > } else { > /* Tell console.c that it has to restore the screen itself */ > return 1; > } >+ > } > (*info->blank)(blank, info); > return 0; >@@ -1762,13 +1881,21 @@ > > if (resize) { > struct vc_data *conp = p->conp; >+ __u32 xres = p->var.xres, yres = p->var.yres; >+ > /* reset wrap/pan */ > p->var.xoffset = p->var.yoffset = p->yscroll = 0; > p->vrows = p->var.yres_virtual/h; >- if ((p->var.yres % h) && (p->var.yres_virtual % h < p->var.yres % h)) >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (p->splash_data && p->splash_data->splash_state) { >+ xres = p->splash_data->splash_text_wi; >+ yres = p->splash_data->splash_text_he; >+ } >+#endif >+ if ((yres % h) && (p->var.yres_virtual % h < p->var.yres % h)) > p->vrows--; > updatescrollmode(p); >- vc_resize_con( p->var.yres/h, p->var.xres/w, unit ); >+ vc_resize_con( yres/h, xres/w, unit ); > if (CON_IS_VISIBLE(conp) && softback_buf) { > int l = fbcon_softback_size / conp->vc_size_row; > if (l > 5) >@@ -2189,6 +2316,9 @@ > if (p->fb_info->fbops->fb_rasterimg) > p->fb_info->fbops->fb_rasterimg(p->fb_info, 1); > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ if (!splash_shown) { >+#endif > for (x = 0; x < smp_num_cpus * (LOGO_W + 8) && > x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) { > >@@ -2450,7 +2580,10 @@ > } > #endif > } >- >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ } >+#endif >+ > if (p->fb_info->fbops->fb_rasterimg) > p->fb_info->fbops->fb_rasterimg(p->fb_info, 0); > >diff -urN linux-2.4.22-rc2-ac3/include/video/fbcon.h linux-2.4.22-rc2-ac3-new/include/video/fbcon.h >--- linux-2.4.22-rc2-ac3/include/video/fbcon.h 2003-08-21 07:31:58.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/include/video/fbcon.h 2003-08-21 17:00:01.000000000 -0400 >@@ -42,6 +42,35 @@ > unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */ > }; > >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+struct splash_data { >+ int splash_state; /* show splash? */ >+ int splash_color; /* transparent color */ >+ int splash_fg_color; /* foreground color */ >+ int splash_width; /* width of image */ >+ int splash_height; /* height of image */ >+ int splash_text_xo; /* text area origin */ >+ int splash_text_yo; >+ int splash_text_wi; /* text area size */ >+ int splash_text_he; >+ int splash_showtext; /* silent/verbose mode */ >+ int splash_boxcount; >+ int splash_percent; >+ int splash_overpaintok; /* is it ok to overpaint boxes */ >+ int splash_palcnt; >+ struct display_switch *olddispsw; /* old dispsw, normally &fbcon_cfb16*/ >+ char *oldscreen_base; /* pointer to top of virtual screen */ >+ unsigned char *splash_boxes; >+ unsigned char *splash_jpeg; /* jpeg */ >+ unsigned char *splash_palette; /* palette for 8-bit */ >+ >+ int splash_dosilent; /* show silent jpeg */ >+ unsigned char *splash_silentjpeg; >+ unsigned char *splash_sboxes; >+ int splash_sboxcount; >+}; >+#endif >+ > extern struct display_switch fbcon_dummy; > > /* >@@ -95,6 +124,10 @@ > short yscroll; /* Hardware scrolling */ > unsigned char fgshift, bgshift; > unsigned short charmask; /* 0xff or 0x1ff */ >+ >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ struct splash_data *splash_data; >+#endif > }; > > /* drivers/video/fbcon.c */ >diff -urN linux-2.4.22-rc2-ac3/include/video/fbcon.h.orig linux-2.4.22-rc2-ac3-new/include/video/fbcon.h.orig >--- linux-2.4.22-rc2-ac3/include/video/fbcon.h.orig 1969-12-31 20:00:00.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/include/video/fbcon.h.orig 2003-08-21 16:22:18.000000000 -0400 >@@ -0,0 +1,837 @@ >+/* >+ * linux/drivers/video/fbcon.h -- Low level frame buffer based console driver >+ * >+ * Copyright (C) 1997 Geert Uytterhoeven >+ * >+ * This file is subject to the terms and conditions of the GNU General Public >+ * License. See the file COPYING in the main directory of this archive >+ * for more details. >+ */ >+ >+#ifndef _VIDEO_FBCON_H >+#define _VIDEO_FBCON_H >+ >+#include <linux/config.h> >+#include <linux/types.h> >+#include <linux/console_struct.h> >+#include <linux/vt_buffer.h> >+ >+#include <asm/io.h> >+ >+ >+ /* >+ * `switch' for the Low Level Operations >+ */ >+ >+struct display_switch { >+ void (*setup)(struct display *p); >+ void (*bmove)(struct display *p, int sy, int sx, int dy, int dx, >+ int height, int width); >+ /* for clear, conp may be NULL, which means use a blanking (black) color */ >+ void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx, >+ int height, int width); >+ void (*putc)(struct vc_data *conp, struct display *p, int c, int yy, >+ int xx); >+ void (*putcs)(struct vc_data *conp, struct display *p, const unsigned short *s, >+ int count, int yy, int xx); >+ void (*revc)(struct display *p, int xx, int yy); >+ void (*cursor)(struct display *p, int mode, int xx, int yy); >+ int (*set_font)(struct display *p, int width, int height); >+ void (*clear_margins)(struct vc_data *conp, struct display *p, >+ int bottom_only); >+ unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */ >+}; >+ >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+struct splash_data { >+ int splash_state; /* show splash? */ >+ int splash_color; /* transparent color */ >+ int splash_fg_color; /* foreground color */ >+ int splash_width; /* width of image */ >+ int splash_height; /* height of image */ >+ int splash_text_xo; /* text area origin */ >+ int splash_text_yo; >+ int splash_text_wi; /* text area size */ >+ int splash_text_he; >+ int splash_showtext; /* silent/verbose mode */ >+ int splash_boxcount; >+ int splash_percent; >+ int splash_overpaintok; /* is it ok to overpaint boxes */ >+ int splash_palcnt; >+ struct display_switch *olddispsw; /* old dispsw, normally &fbcon_cfb16*/ >+ char *oldscreen_base; /* pointer to top of virtual screen */ >+ unsigned char *splash_boxes; >+ unsigned char *splash_jpeg; /* jpeg */ >+ unsigned char *splash_palette; /* palette for 8-bit */ >+ >+ int splash_dosilent; /* show silent jpeg */ >+ unsigned char *splash_silentjpeg; >+ unsigned char *splash_sboxes; >+ int splash_sboxcount; >+}; >+#endif >+ >+extern struct display_switch fbcon_dummy; >+ >+ /* >+ * This is the interface between the low-level console driver and the >+ * low-level frame buffer device >+ */ >+ >+struct display { >+ /* Filled in by the frame buffer device */ >+ >+ struct fb_var_screeninfo var; /* variable infos. yoffset and vmode */ >+ /* are updated by fbcon.c */ >+ struct fb_cmap cmap; /* colormap */ >+ char *screen_base; /* pointer to top of virtual screen */ >+ /* (virtual address) */ >+ int visual; >+ int type; /* see FB_TYPE_* */ >+ int type_aux; /* Interleave for interleaved Planes */ >+ u_short ypanstep; /* zero if no hardware ypan */ >+ u_short ywrapstep; /* zero if no hardware ywrap */ >+ u_long line_length; /* length of a line in bytes */ >+ u_short can_soft_blank; /* zero if no hardware blanking */ >+ u_short inverse; /* != 0 text black on white as default */ >+ struct display_switch *dispsw; /* low level operations */ >+ void *dispsw_data; /* optional dispsw helper data */ >+ >+#if 0 >+ struct fb_fix_cursorinfo fcrsr; >+ struct fb_var_cursorinfo *vcrsr; >+ struct fb_cursorstate crsrstate; >+#endif >+ >+ /* Filled in by the low-level console driver */ >+ >+ struct vc_data *conp; /* pointer to console data */ >+ struct fb_info *fb_info; /* frame buffer for this console */ >+ int vrows; /* number of virtual rows */ >+ unsigned short cursor_x; /* current cursor position */ >+ unsigned short cursor_y; >+ int fgcol; /* text colors */ >+ int bgcol; >+ u_long next_line; /* offset to one line below */ >+ u_long next_plane; /* offset to next plane */ >+ u_char *fontdata; /* Font associated to this display */ >+ unsigned short _fontheightlog; >+ unsigned short _fontwidthlog; >+ unsigned short _fontheight; >+ unsigned short _fontwidth; >+ int userfont; /* != 0 if fontdata kmalloc()ed */ >+ u_short scrollmode; /* Scroll Method */ >+ short yscroll; /* Hardware scrolling */ >+ unsigned char fgshift, bgshift; >+ unsigned short charmask; /* 0xff or 0x1ff */ >+ >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ struct splash_data *splash_data; >+#endif >+}; >+ >+/* drivers/video/fbcon.c */ >+extern struct display fb_display[MAX_NR_CONSOLES]; >+extern char con2fb_map[MAX_NR_CONSOLES]; >+extern int PROC_CONSOLE(const struct fb_info *info); >+extern void set_con2fb_map(int unit, int newidx); >+extern int set_all_vcs(int fbidx, struct fb_ops *fb, >+ struct fb_var_screeninfo *var, struct fb_info *info); >+ >+#define fontheight(p) ((p)->_fontheight) >+#define fontheightlog(p) ((p)->_fontheightlog) >+ >+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY >+ >+/* fontwidth w is supported by dispsw */ >+#define FONTWIDTH(w) (1 << ((8) - 1)) >+/* fontwidths w1-w2 inclusive are supported by dispsw */ >+#define FONTWIDTHRANGE(w1,w2) FONTWIDTH(8) >+ >+#define fontwidth(p) (8) >+#define fontwidthlog(p) (0) >+ >+#else >+ >+/* fontwidth w is supported by dispsw */ >+#define FONTWIDTH(w) (1 << ((w) - 1)) >+/* fontwidths w1-w2 inclusive are supported by dispsw */ >+#define FONTWIDTHRANGE(w1,w2) (FONTWIDTH(w2+1) - FONTWIDTH(w1)) >+ >+#define fontwidth(p) ((p)->_fontwidth) >+#define fontwidthlog(p) ((p)->_fontwidthlog) >+ >+#endif >+ >+ /* >+ * Attribute Decoding >+ */ >+ >+/* Color */ >+#define attr_fgcol(p,s) \ >+ (((s) >> ((p)->fgshift)) & 0x0f) >+#define attr_bgcol(p,s) \ >+ (((s) >> ((p)->bgshift)) & 0x0f) >+#define attr_bgcol_ec(p,conp) \ >+ ((conp) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0) >+ >+/* Monochrome */ >+#define attr_bold(p,s) \ >+ ((s) & 0x200) >+#define attr_reverse(p,s) \ >+ (((s) & 0x800) ^ ((p)->inverse ? 0x800 : 0)) >+#define attr_underline(p,s) \ >+ ((s) & 0x400) >+#define attr_blink(p,s) \ >+ ((s) & 0x8000) >+ >+ /* >+ * Scroll Method >+ */ >+ >+/* Internal flags */ >+#define __SCROLL_YPAN 0x001 >+#define __SCROLL_YWRAP 0x002 >+#define __SCROLL_YMOVE 0x003 >+#define __SCROLL_YREDRAW 0x004 >+#define __SCROLL_YMASK 0x00f >+#define __SCROLL_YFIXED 0x010 >+#define __SCROLL_YNOMOVE 0x020 >+#define __SCROLL_YPANREDRAW 0x040 >+#define __SCROLL_YNOPARTIAL 0x080 >+ >+/* Only these should be used by the drivers */ >+/* Which one should you use? If you have a fast card and slow bus, >+ then probably just 0 to indicate fbcon should choose between >+ YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus >+ and even better if your card can do fonting (1->8/32bit painting), >+ you should consider either SCROLL_YREDRAW (if your card is >+ able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE. >+ The best is to test it with some real life scrolling (usually, not >+ all lines on the screen are filled completely with non-space characters, >+ and REDRAW performs much better on such lines, so don't cat a file >+ with every line covering all screen columns, it would not be the right >+ benchmark). >+ */ >+#define SCROLL_YREDRAW (__SCROLL_YFIXED|__SCROLL_YREDRAW) >+#define SCROLL_YNOMOVE (__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW) >+ >+/* SCROLL_YNOPARTIAL, used in combination with the above, is for video >+ cards which can not handle using panning to scroll a portion of the >+ screen without excessive flicker. Panning will only be used for >+ whole screens. >+ */ >+/* Namespace consistency */ >+#define SCROLL_YNOPARTIAL __SCROLL_YNOPARTIAL >+ >+ >+#if defined(__sparc__) >+ >+/* We map all of our framebuffers such that big-endian accesses >+ * are what we want, so the following is sufficient. >+ */ >+ >+#define fb_readb sbus_readb >+#define fb_readw sbus_readw >+#define fb_readl sbus_readl >+#define fb_writeb sbus_writeb >+#define fb_writew sbus_writew >+#define fb_writel sbus_writel >+#define fb_memset sbus_memset_io >+ >+#elif defined(__i386__) || defined(__alpha__) || \ >+ defined(__x86_64__) || defined(__hppa__) || \ >+ defined(__powerpc64__) >+ >+#define fb_readb __raw_readb >+#define fb_readw __raw_readw >+#define fb_readl __raw_readl >+#define fb_writeb __raw_writeb >+#define fb_writew __raw_writew >+#define fb_writel __raw_writel >+#define fb_memset memset_io >+ >+#else >+ >+#define fb_readb(addr) (*(volatile u8 *) (addr)) >+#define fb_readw(addr) (*(volatile u16 *) (addr)) >+#define fb_readl(addr) (*(volatile u32 *) (addr)) >+#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b)) >+#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b)) >+#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b)) >+#define fb_memset memset >+ >+#endif >+ >+ >+extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int); >+extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int); >+ >+ >+/* ================================================================= */ >+/* Utility Assembler Functions */ >+/* ================================================================= */ >+ >+ >+#if defined(__mc68000__) >+ >+/* ====================================================================== */ >+ >+/* Those of a delicate disposition might like to skip the next couple of >+ * pages. >+ * >+ * These functions are drop in replacements for memmove and >+ * memset(_, 0, _). However their five instances add at least a kilobyte >+ * to the object file. You have been warned. >+ * >+ * Not a great fan of assembler for the sake of it, but I think >+ * that these routines are at least 10 times faster than their C >+ * equivalents for large blits, and that's important to the lowest level of >+ * a graphics driver. Question is whether some scheme with the blitter >+ * would be faster. I suspect not for simple text system - not much >+ * asynchrony. >+ * >+ * Code is very simple, just gruesome expansion. Basic strategy is to >+ * increase data moved/cleared at each step to 16 bytes to reduce >+ * instruction per data move overhead. movem might be faster still >+ * For more than 15 bytes, we try to align the write direction on a >+ * longword boundary to get maximum speed. This is even more gruesome. >+ * Unaligned read/write used requires 68020+ - think this is a problem? >+ * >+ * Sorry! >+ */ >+ >+ >+/* ++roman: I've optimized Robert's original versions in some minor >+ * aspects, e.g. moveq instead of movel, let gcc choose the registers, >+ * use movem in some places... >+ * For other modes than 1 plane, lots of more such assembler functions >+ * were needed (e.g. the ones using movep or expanding color values). >+ */ >+ >+/* ++andreas: more optimizations: >+ subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc >+ addal is faster than addaw >+ movep is rather expensive compared to ordinary move's >+ some functions rewritten in C for clarity, no speed loss */ >+ >+static __inline__ void *fb_memclear_small(void *s, size_t count) >+{ >+ if (!count) >+ return(0); >+ >+ __asm__ __volatile__( >+ "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t" >+ "1:" >+ : "=a" (s), "=d" (count) >+ : "d" (0), "0" ((char *)s+count), "1" (count) >+ ); >+ __asm__ __volatile__( >+ "subql #1,%1 ; jcs 3f\n\t" >+ "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t" >+ "2: moveml %2/%%d4/%%d5/%%d6,%0@-\n\t" >+ "dbra %1,2b\n\t" >+ "3:" >+ : "=a" (s), "=d" (count) >+ : "d" (0), "0" (s), "1" (count) >+ : "d4", "d5", "d6" >+ ); >+ >+ return(0); >+} >+ >+ >+static __inline__ void *fb_memclear(void *s, size_t count) >+{ >+ if (!count) >+ return(0); >+ >+ if (count < 16) { >+ __asm__ __volatile__( >+ "lsrl #1,%1 ; jcc 1f ; clrb %0@+\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; clrw %0@+\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+\n\t" >+ "1:" >+ : "=a" (s), "=d" (count) >+ : "0" (s), "1" (count) >+ ); >+ } else { >+ long tmp; >+ __asm__ __volatile__( >+ "movel %1,%2\n\t" >+ "lsrl #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t" >+ "lsrl #1,%2 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/ >+ "clrw %0@+ ; subqw #2,%1 ; jra 2f\n\t" >+ "1: lsrl #1,%2 ; jcc 2f\n\t" >+ "clrw %0@+ ; subqw #2,%1\n\t" >+ "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t" >+ "lsrl #1,%1 ; jcc 3f ; clrl %0@+\n\t" >+ "3: lsrl #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t" >+ "4: subql #1,%1 ; jcs 6f\n\t" >+ "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t" >+ "dbra %1,5b ; clrw %1; subql #1,%1; jcc 5b\n\t" >+ "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t" >+ "7: ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t" >+ "8:" >+ : "=a" (s), "=d" (count), "=d" (tmp) >+ : "0" (s), "1" (count) >+ ); >+ } >+ >+ return(0); >+} >+ >+ >+static __inline__ void *fb_memset255(void *s, size_t count) >+{ >+ if (!count) >+ return(0); >+ >+ __asm__ __volatile__( >+ "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t" >+ "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t" >+ "1:" >+ : "=a" (s), "=d" (count) >+ : "d" (-1), "0" ((char *)s+count), "1" (count) >+ ); >+ __asm__ __volatile__( >+ "subql #1,%1 ; jcs 3f\n\t" >+ "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t" >+ "2: moveml %2/%%d4/%%d5/%%d6,%0@-\n\t" >+ "dbra %1,2b\n\t" >+ "3:" >+ : "=a" (s), "=d" (count) >+ : "d" (-1), "0" (s), "1" (count) >+ : "d4", "d5", "d6" >+ ); >+ >+ return(0); >+} >+ >+ >+static __inline__ void *fb_memmove(void *d, const void *s, size_t count) >+{ >+ if (d < s) { >+ if (count < 16) { >+ __asm__ __volatile__( >+ "lsrl #1,%2 ; jcc 1f ; moveb %1@+,%0@+\n\t" >+ "1: lsrl #1,%2 ; jcc 1f ; movew %1@+,%0@+\n\t" >+ "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+\n\t" >+ "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t" >+ "1:" >+ : "=a" (d), "=a" (s), "=d" (count) >+ : "0" (d), "1" (s), "2" (count) >+ ); >+ } else { >+ long tmp; >+ __asm__ __volatile__( >+ "movel %0,%3\n\t" >+ "lsrl #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t" >+ "lsrl #1,%3 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/ >+ "movew %1@+,%0@+ ; subqw #2,%2 ; jra 2f\n\t" >+ "1: lsrl #1,%3 ; jcc 2f\n\t" >+ "movew %1@+,%0@+ ; subqw #2,%2\n\t" >+ "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t" >+ "lsrl #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t" >+ "3: lsrl #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t" >+ "4: subql #1,%2 ; jcs 6f\n\t" >+ "5: movel %1@+,%0@+;movel %1@+,%0@+\n\t" >+ "movel %1@+,%0@+;movel %1@+,%0@+\n\t" >+ "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t" >+ "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t" >+ "7: ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t" >+ "8:" >+ : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp) >+ : "0" (d), "1" (s), "2" (count) >+ ); >+ } >+ } else { >+ if (count < 16) { >+ __asm__ __volatile__( >+ "lsrl #1,%2 ; jcc 1f ; moveb %1@-,%0@-\n\t" >+ "1: lsrl #1,%2 ; jcc 1f ; movew %1@-,%0@-\n\t" >+ "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@-\n\t" >+ "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t" >+ "1:" >+ : "=a" (d), "=a" (s), "=d" (count) >+ : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count) >+ ); >+ } else { >+ long tmp; >+ __asm__ __volatile__( >+ "movel %0,%3\n\t" >+ "lsrl #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t" >+ "lsrl #1,%3 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/ >+ "movew %1@-,%0@- ; subqw #2,%2 ; jra 2f\n\t" >+ "1: lsrl #1,%3 ; jcc 2f\n\t" >+ "movew %1@-,%0@- ; subqw #2,%2\n\t" >+ "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t" >+ "lsrl #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t" >+ "3: lsrl #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t" >+ "4: subql #1,%2 ; jcs 6f\n\t" >+ "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t" >+ "movel %1@-,%0@-;movel %1@-,%0@-\n\t" >+ "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t" >+ "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t" >+ "7: ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t" >+ "8:" >+ : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp) >+ : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count) >+ ); >+ } >+ } >+ >+ return(0); >+} >+ >+ >+/* ++andreas: Simple and fast version of memmove, assumes size is >+ divisible by 16, suitable for moving the whole screen bitplane */ >+static __inline__ void fast_memmove(char *dst, const char *src, size_t size) >+{ >+ if (!size) >+ return; >+ if (dst < src) >+ __asm__ __volatile__ >+ ("1:" >+ " moveml %0@+,%/d0/%/d1/%/a0/%/a1\n" >+ " moveml %/d0/%/d1/%/a0/%/a1,%1@\n" >+ " addql #8,%1; addql #8,%1\n" >+ " dbra %2,1b\n" >+ " clrw %2; subql #1,%2\n" >+ " jcc 1b" >+ : "=a" (src), "=a" (dst), "=d" (size) >+ : "0" (src), "1" (dst), "2" (size / 16 - 1) >+ : "d0", "d1", "a0", "a1", "memory"); >+ else >+ __asm__ __volatile__ >+ ("1:" >+ " subql #8,%0; subql #8,%0\n" >+ " moveml %0@,%/d0/%/d1/%/a0/%/a1\n" >+ " moveml %/d0/%/d1/%/a0/%/a1,%1@-\n" >+ " dbra %2,1b\n" >+ " clrw %2; subql #1,%2\n" >+ " jcc 1b" >+ : "=a" (src), "=a" (dst), "=d" (size) >+ : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1) >+ : "d0", "d1", "a0", "a1", "memory"); >+} >+ >+#elif defined(CONFIG_SUN4) >+ >+/* You may think that I'm crazy and that I should use generic >+ routines. No, I'm not: sun4's framebuffer crashes if we std >+ into it, so we cannot use memset. */ >+ >+static __inline__ void *sun4_memset(void *s, char val, size_t count) >+{ >+ int i; >+ for(i=0; i<count;i++) >+ ((char *) s) [i] = val; >+ return s; >+} >+ >+static __inline__ void *fb_memset255(void *s, size_t count) >+{ >+ return sun4_memset(s, 255, count); >+} >+ >+static __inline__ void *fb_memclear(void *s, size_t count) >+{ >+ return sun4_memset(s, 0, count); >+} >+ >+static __inline__ void *fb_memclear_small(void *s, size_t count) >+{ >+ return sun4_memset(s, 0, count); >+} >+ >+/* To be honest, this is slow_memmove :). But sun4 is crappy, so what we can do. */ >+static __inline__ void fast_memmove(void *d, const void *s, size_t count) >+{ >+ int i; >+ if (d<s) { >+ for (i=0; i<count; i++) >+ ((char *) d)[i] = ((char *) s)[i]; >+ } else >+ for (i=0; i<count; i++) >+ ((char *) d)[count-i-1] = ((char *) s)[count-i-1]; >+} >+ >+static __inline__ void *fb_memmove(char *dst, const char *src, size_t size) >+{ >+ fast_memmove(dst, src, size); >+ return dst; >+} >+ >+#else >+ >+static __inline__ void *fb_memclear_small(void *s, size_t count) >+{ >+ char *xs = (char *) s; >+ >+ while (count--) >+ fb_writeb(0, xs++); >+ >+ return s; >+} >+ >+static __inline__ void *fb_memclear(void *s, size_t count) >+{ >+ unsigned long xs = (unsigned long) s; >+ >+ if (count < 8) >+ goto rest; >+ >+ if (xs & 1) { >+ fb_writeb(0, xs++); >+ count--; >+ } >+ if (xs & 2) { >+ fb_writew(0, xs); >+ xs += 2; >+ count -= 2; >+ } >+ while (count > 3) { >+ fb_writel(0, xs); >+ xs += 4; >+ count -= 4; >+ } >+rest: >+ while (count--) >+ fb_writeb(0, xs++); >+ >+ return s; >+} >+ >+static __inline__ void *fb_memset255(void *s, size_t count) >+{ >+ unsigned long xs = (unsigned long) s; >+ >+ if (count < 8) >+ goto rest; >+ >+ if (xs & 1) { >+ fb_writeb(0xff, xs++); >+ count--; >+ } >+ if (xs & 2) { >+ fb_writew(0xffff, xs); >+ xs += 2; >+ count -= 2; >+ } >+ while (count > 3) { >+ fb_writel(0xffffffff, xs); >+ xs += 4; >+ count -= 4; >+ } >+rest: >+ while (count--) >+ fb_writeb(0xff, xs++); >+ >+ return s; >+} >+ >+#if defined(__i386__) >+ >+static __inline__ void fast_memmove(void *d, const void *s, size_t count) >+{ >+ int d0, d1, d2, d3; >+ if (d < s) { >+__asm__ __volatile__ ( >+ "cld\n\t" >+ "shrl $1,%%ecx\n\t" >+ "jnc 1f\n\t" >+ "movsb\n" >+ "1:\tshrl $1,%%ecx\n\t" >+ "jnc 2f\n\t" >+ "movsw\n" >+ "2:\trep\n\t" >+ "movsl" >+ : "=&c" (d0), "=&D" (d1), "=&S" (d2) >+ :"0"(count),"1"((long)d),"2"((long)s) >+ :"memory"); >+ } else { >+__asm__ __volatile__ ( >+ "std\n\t" >+ "shrl $1,%%ecx\n\t" >+ "jnc 1f\n\t" >+ "movb 3(%%esi),%%al\n\t" >+ "movb %%al,3(%%edi)\n\t" >+ "decl %%esi\n\t" >+ "decl %%edi\n" >+ "1:\tshrl $1,%%ecx\n\t" >+ "jnc 2f\n\t" >+ "movw 2(%%esi),%%ax\n\t" >+ "movw %%ax,2(%%edi)\n\t" >+ "decl %%esi\n\t" >+ "decl %%edi\n\t" >+ "decl %%esi\n\t" >+ "decl %%edi\n" >+ "2:\trep\n\t" >+ "movsl\n\t" >+ "cld" >+ : "=&c" (d0), "=&D" (d1), "=&S" (d2), "=&a" (d3) >+ :"0"(count),"1"(count-4+(long)d),"2"(count-4+(long)s) >+ :"memory"); >+ } >+} >+ >+static __inline__ void *fb_memmove(char *dst, const char *src, size_t size) >+{ >+ fast_memmove(dst, src, size); >+ return dst; >+} >+ >+#else /* !__i386__ */ >+ >+ /* >+ * Anyone who'd like to write asm functions for other CPUs? >+ * (Why are these functions better than those from include/asm/string.h?) >+ */ >+ >+static __inline__ void *fb_memmove(void *d, const void *s, size_t count) >+{ >+ unsigned long dst, src; >+ >+ if (d < s) { >+ dst = (unsigned long) d; >+ src = (unsigned long) s; >+ >+ if ((count < 8) || ((dst ^ src) & 3)) >+ goto restup; >+ >+ if (dst & 1) { >+ fb_writeb(fb_readb(src++), dst++); >+ count--; >+ } >+ if (dst & 2) { >+ fb_writew(fb_readw(src), dst); >+ src += 2; >+ dst += 2; >+ count -= 2; >+ } >+ while (count > 3) { >+ fb_writel(fb_readl(src), dst); >+ src += 4; >+ dst += 4; >+ count -= 4; >+ } >+ >+ restup: >+ while (count--) >+ fb_writeb(fb_readb(src++), dst++); >+ } else { >+ dst = (unsigned long) d + count; >+ src = (unsigned long) s + count; >+ >+ if ((count < 8) || ((dst ^ src) & 3)) >+ goto restdown; >+ >+ if (dst & 1) { >+ src--; >+ dst--; >+ count--; >+ fb_writeb(fb_readb(src), dst); >+ } >+ if (dst & 2) { >+ src -= 2; >+ dst -= 2; >+ count -= 2; >+ fb_writew(fb_readw(src), dst); >+ } >+ while (count > 3) { >+ src -= 4; >+ dst -= 4; >+ count -= 4; >+ fb_writel(fb_readl(src), dst); >+ } >+ >+ restdown: >+ while (count--) { >+ src--; >+ dst--; >+ fb_writeb(fb_readb(src), dst); >+ } >+ } >+ >+ return d; >+} >+ >+static __inline__ void fast_memmove(char *d, const char *s, size_t count) >+{ >+ unsigned long dst, src; >+ >+ if (d < s) { >+ dst = (unsigned long) d; >+ src = (unsigned long) s; >+ >+ if ((count < 8) || ((dst ^ src) & 3)) >+ goto restup; >+ >+ if (dst & 1) { >+ fb_writeb(fb_readb(src++), dst++); >+ count--; >+ } >+ if (dst & 2) { >+ fb_writew(fb_readw(src), dst); >+ src += 2; >+ dst += 2; >+ count -= 2; >+ } >+ while (count > 3) { >+ fb_writel(fb_readl(src), dst); >+ src += 4; >+ dst += 4; >+ count -= 4; >+ } >+ >+ restup: >+ while (count--) >+ fb_writeb(fb_readb(src++), dst++); >+ } else { >+ dst = (unsigned long) d + count; >+ src = (unsigned long) s + count; >+ >+ if ((count < 8) || ((dst ^ src) & 3)) >+ goto restdown; >+ >+ if (dst & 1) { >+ src--; >+ dst--; >+ count--; >+ fb_writeb(fb_readb(src), dst); >+ } >+ if (dst & 2) { >+ src -= 2; >+ dst -= 2; >+ count -= 2; >+ fb_writew(fb_readw(src), dst); >+ } >+ while (count > 3) { >+ src -= 4; >+ dst -= 4; >+ count -= 4; >+ fb_writel(fb_readl(src), dst); >+ } >+ >+ restdown: >+ while (count--) { >+ src--; >+ dst--; >+ fb_writeb(fb_readb(src), dst); >+ } >+ } >+} >+ >+#endif /* !__i386__ */ >+ >+#endif /* !__mc68000__ */ >+ >+#endif /* _VIDEO_FBCON_H */ >diff -urN linux-2.4.22-rc2-ac3/kernel/panic.c linux-2.4.22-rc2-ac3-new/kernel/panic.c >--- linux-2.4.22-rc2-ac3/kernel/panic.c 2003-08-21 07:31:58.000000000 -0400 >+++ linux-2.4.22-rc2-ac3-new/kernel/panic.c 2003-08-21 17:00:01.000000000 -0400 >@@ -223,6 +223,13 @@ > * We can't use the "normal" timers since we just panicked.. > */ > printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); >+ >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ { >+ extern int splash_verbose(void); >+ (void)splash_verbose(); >+ } >+#endif > mdelay(panic_timeout*1000); > /* > * Should we run the reboot notifier. For the moment Im >@@ -243,6 +250,12 @@ > disabled_wait(caller); > #endif > sti(); >+#ifdef CONFIG_FBCON_SPLASHSCREEN >+ { >+ extern int splash_verbose(void); >+ (void)splash_verbose(); >+ } >+#endif > for(;;) { > panic_blink(buf); > CHECK_EMERGENCY_SYNC
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 28625
: 17639