fbcon.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:22k
- /*
- * 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 */
- };
- 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 */
- };
- /* 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__)
- #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@-nt"
- "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-nt"
- "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-nt"
- "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-nt"
- "1:"
- : "=a" (s), "=d" (count)
- : "d" (0), "0" ((char *)s+count), "1" (count)
- );
- __asm__ __volatile__(
- "subql #1,%1 ; jcs 3fnt"
- "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6nt"
- "2: moveml %2/%%d4/%%d5/%%d6,%0@-nt"
- "dbra %1,2bnt"
- "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@+nt"
- "1: lsrl #1,%1 ; jcc 1f ; clrw %0@+nt"
- "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+nt"
- "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+nt"
- "1:"
- : "=a" (s), "=d" (count)
- : "0" (s), "1" (count)
- );
- } else {
- long tmp;
- __asm__ __volatile__(
- "movel %1,%2nt"
- "lsrl #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1nt"
- "lsrl #1,%2 ; jcs 2fnt" /* %0 increased=>bit 2 switched*/
- "clrw %0@+ ; subqw #2,%1 ; jra 2fnt"
- "1: lsrl #1,%2 ; jcc 2fnt"
- "clrw %0@+ ; subqw #2,%1nt"
- "2: movew %1,%2; lsrl #2,%1 ; jeq 6fnt"
- "lsrl #1,%1 ; jcc 3f ; clrl %0@+nt"
- "3: lsrl #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+nt"
- "4: subql #1,%1 ; jcs 6fnt"
- "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+nt"
- "dbra %1,5b ; clrw %1; subql #1,%1; jcc 5bnt"
- "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+nt"
- "7: ; btst #0,%1 ; jeq 8f ; clrb %0@+nt"
- "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@-nt"
- "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-nt"
- "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-nt"
- "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-nt"
- "1:"
- : "=a" (s), "=d" (count)
- : "d" (-1), "0" ((char *)s+count), "1" (count)
- );
- __asm__ __volatile__(
- "subql #1,%1 ; jcs 3fnt"
- "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6nt"
- "2: moveml %2/%%d4/%%d5/%%d6,%0@-nt"
- "dbra %1,2bnt"
- "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@+nt"
- "1: lsrl #1,%2 ; jcc 1f ; movew %1@+,%0@+nt"
- "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+nt"
- "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+nt"
- "1:"
- : "=a" (d), "=a" (s), "=d" (count)
- : "0" (d), "1" (s), "2" (count)
- );
- } else {
- long tmp;
- __asm__ __volatile__(
- "movel %0,%3nt"
- "lsrl #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2nt"
- "lsrl #1,%3 ; jcs 2fnt" /* %0 increased=>bit 2 switched*/
- "movew %1@+,%0@+ ; subqw #2,%2 ; jra 2fnt"
- "1: lsrl #1,%3 ; jcc 2fnt"
- "movew %1@+,%0@+ ; subqw #2,%2nt"
- "2: movew %2,%-; lsrl #2,%2 ; jeq 6fnt"
- "lsrl #1,%2 ; jcc 3f ; movel %1@+,%0@+nt"
- "3: lsrl #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+nt"
- "4: subql #1,%2 ; jcs 6fnt"
- "5: movel %1@+,%0@+;movel %1@+,%0@+nt"
- "movel %1@+,%0@+;movel %1@+,%0@+nt"
- "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5bnt"
- "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+nt"
- "7: ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+nt"
- "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@-nt"
- "1: lsrl #1,%2 ; jcc 1f ; movew %1@-,%0@-nt"
- "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@-nt"
- "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-nt"
- "1:"
- : "=a" (d), "=a" (s), "=d" (count)
- : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
- );
- } else {
- long tmp;
- __asm__ __volatile__(
- "movel %0,%3nt"
- "lsrl #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2nt"
- "lsrl #1,%3 ; jcs 2fnt" /* %0 increased=>bit 2 switched*/
- "movew %1@-,%0@- ; subqw #2,%2 ; jra 2fnt"
- "1: lsrl #1,%3 ; jcc 2fnt"
- "movew %1@-,%0@- ; subqw #2,%2nt"
- "2: movew %2,%-; lsrl #2,%2 ; jeq 6fnt"
- "lsrl #1,%2 ; jcc 3f ; movel %1@-,%0@-nt"
- "3: lsrl #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-nt"
- "4: subql #1,%2 ; jcs 6fnt"
- "5: movel %1@-,%0@-;movel %1@-,%0@-nt"
- "movel %1@-,%0@-;movel %1@-,%0@-nt"
- "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5bnt"
- "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-nt"
- "7: ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-nt"
- "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/%/a1n"
- " moveml %/d0/%/d1/%/a0/%/a1,%1@n"
- " addql #8,%1; addql #8,%1n"
- " dbra %2,1bn"
- " clrw %2; subql #1,%2n"
- " 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,%0n"
- " moveml %0@,%/d0/%/d1/%/a0/%/a1n"
- " moveml %/d0/%/d1/%/a0/%/a1,%1@-n"
- " dbra %2,1bn"
- " clrw %2; subql #1,%2n"
- " 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__ (
- "cldnt"
- "shrl $1,%%ecxnt"
- "jnc 1fnt"
- "movsbn"
- "1:tshrl $1,%%ecxnt"
- "jnc 2fnt"
- "movswn"
- "2:trepnt"
- "movsl"
- : "=&c" (d0), "=&D" (d1), "=&S" (d2)
- :"0"(count),"1"((long)d),"2"((long)s)
- :"memory");
- } else {
- __asm__ __volatile__ (
- "stdnt"
- "shrl $1,%%ecxnt"
- "jnc 1fnt"
- "movb 3(%%esi),%%alnt"
- "movb %%al,3(%%edi)nt"
- "decl %%esint"
- "decl %%edin"
- "1:tshrl $1,%%ecxnt"
- "jnc 2fnt"
- "movw 2(%%esi),%%axnt"
- "movw %%ax,2(%%edi)nt"
- "decl %%esint"
- "decl %%edint"
- "decl %%esint"
- "decl %%edin"
- "2:trepnt"
- "movslnt"
- "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 */