fbcon.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:23k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/video/fbcon.h -- Low level frame buffer based console driver
  3.  *
  4.  * Copyright (C) 1997 Geert Uytterhoeven
  5.  *
  6.  *  This file is subject to the terms and conditions of the GNU General Public
  7.  *  License.  See the file COPYING in the main directory of this archive
  8.  *  for more details.
  9.  */
  10. #ifndef _VIDEO_FBCON_H
  11. #define _VIDEO_FBCON_H
  12. #include <linux/config.h>
  13. #include <linux/types.h>
  14. #include <linux/console_struct.h>
  15. #include <linux/vt_buffer.h>
  16. #include <asm/io.h>
  17.     /*                                  
  18.      *  `switch' for the Low Level Operations
  19.      */
  20.  
  21. struct display_switch {                                                
  22.     void (*setup)(struct display *p);
  23.     void (*bmove)(struct display *p, int sy, int sx, int dy, int dx,
  24.   int height, int width);
  25.     /* for clear, conp may be NULL, which means use a blanking (black) color */
  26.     void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
  27.   int height, int width);
  28.     void (*putc)(struct vc_data *conp, struct display *p, int c, int yy,
  29.       int xx);
  30.     void (*putcs)(struct vc_data *conp, struct display *p, const unsigned short *s,
  31.   int count, int yy, int xx);     
  32.     void (*revc)(struct display *p, int xx, int yy);
  33.     void (*cursor)(struct display *p, int mode, int xx, int yy);
  34.     int  (*set_font)(struct display *p, int width, int height);
  35.     void (*clear_margins)(struct vc_data *conp, struct display *p,
  36.   int bottom_only);
  37.     unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
  38. }; 
  39. extern struct display_switch fbcon_dummy;
  40.    /*
  41.     *    This is the interface between the low-level console driver and the
  42.     *    low-level frame buffer device
  43.     */
  44. struct display {
  45.     /* Filled in by the frame buffer device */
  46.     struct fb_var_screeninfo var;   /* variable infos. yoffset and vmode */
  47.                                     /* are updated by fbcon.c */
  48.     struct fb_cmap cmap;            /* colormap */
  49.     char *screen_base;              /* pointer to top of virtual screen */    
  50.                                     /* (virtual address) */
  51.     int visual;
  52.     int type;                       /* see FB_TYPE_* */
  53.     int type_aux;                   /* Interleave for interleaved Planes */
  54.     u_short ypanstep;               /* zero if no hardware ypan */
  55.     u_short ywrapstep;              /* zero if no hardware ywrap */
  56.     u_long line_length;             /* length of a line in bytes */
  57.     u_short can_soft_blank;         /* zero if no hardware blanking */
  58.     u_short inverse;                /* != 0 text black on white as default */
  59.     struct display_switch *dispsw;  /* low level operations */
  60.     void *dispsw_data;              /* optional dispsw helper data */
  61. #if 0
  62.     struct fb_fix_cursorinfo fcrsr;
  63.     struct fb_var_cursorinfo *vcrsr;
  64.     struct fb_cursorstate crsrstate;
  65. #endif
  66.     /* Filled in by the low-level console driver */
  67.     struct vc_data *conp;           /* pointer to console data */
  68.     struct fb_info *fb_info;        /* frame buffer for this console */
  69.     int vrows;                      /* number of virtual rows */
  70.     unsigned short cursor_x;        /* current cursor position */
  71.     unsigned short cursor_y;
  72.     int fgcol;                      /* text colors */
  73.     int bgcol;
  74.     u_long next_line;               /* offset to one line below */
  75.     u_long next_plane;              /* offset to next plane */
  76.     u_char *fontdata;               /* Font associated to this display */
  77.     unsigned short _fontheightlog;
  78.     unsigned short _fontwidthlog;
  79.     unsigned short _fontheight;
  80.     unsigned short _fontwidth;
  81.     int userfont;                   /* != 0 if fontdata kmalloc()ed */
  82.     u_short scrollmode;             /* Scroll Method */
  83.     short yscroll;                  /* Hardware scrolling */
  84.     unsigned char fgshift, bgshift;
  85.     unsigned short charmask;        /* 0xff or 0x1ff */
  86. };
  87. /* drivers/video/fbcon.c */
  88. extern struct display fb_display[MAX_NR_CONSOLES];
  89. extern char con2fb_map[MAX_NR_CONSOLES];
  90. extern int PROC_CONSOLE(const struct fb_info *info);
  91. extern void set_con2fb_map(int unit, int newidx);
  92. extern int set_all_vcs(int fbidx, struct fb_ops *fb,
  93.        struct fb_var_screeninfo *var, struct fb_info *info);
  94. #define fontheight(p) ((p)->_fontheight)
  95. #define fontheightlog(p) ((p)->_fontheightlog)
  96. #ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
  97. /* fontwidth w is supported by dispsw */
  98. #define FONTWIDTH(w) (1 << ((8) - 1))
  99. /* fontwidths w1-w2 inclusive are supported by dispsw */
  100. #define FONTWIDTHRANGE(w1,w2) FONTWIDTH(8)
  101. #define fontwidth(p) (8)
  102. #define fontwidthlog(p) (0)
  103. #else
  104. /* fontwidth w is supported by dispsw */
  105. #define FONTWIDTH(w) (1 << ((w) - 1))
  106. /* fontwidths w1-w2 inclusive are supported by dispsw */
  107. #define FONTWIDTHRANGE(w1,w2) (FONTWIDTH(w2+1) - FONTWIDTH(w1))
  108. #define fontwidth(p) ((p)->_fontwidth)
  109. #define fontwidthlog(p) ((p)->_fontwidthlog)
  110. #endif
  111.     /*
  112.      *  Attribute Decoding
  113.      */
  114. /* Color */
  115. #define attr_fgcol(p,s)    
  116. (((s) >> ((p)->fgshift)) & 0x0f)
  117. #define attr_bgcol(p,s)    
  118. (((s) >> ((p)->bgshift)) & 0x0f)
  119. #define attr_bgcol_ec(p,conp) 
  120. ((conp) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0)
  121. /* Monochrome */
  122. #define attr_bold(p,s) 
  123. ((s) & 0x200)
  124. #define attr_reverse(p,s) 
  125. (((s) & 0x800) ^ ((p)->inverse ? 0x800 : 0))
  126. #define attr_underline(p,s) 
  127. ((s) & 0x400)
  128. #define attr_blink(p,s) 
  129. ((s) & 0x8000)
  130.     /*
  131.      *  Scroll Method
  132.      */
  133.      
  134. /* Internal flags */
  135. #define __SCROLL_YPAN 0x001
  136. #define __SCROLL_YWRAP 0x002
  137. #define __SCROLL_YMOVE 0x003
  138. #define __SCROLL_YREDRAW 0x004
  139. #define __SCROLL_YMASK 0x00f
  140. #define __SCROLL_YFIXED 0x010
  141. #define __SCROLL_YNOMOVE 0x020
  142. #define __SCROLL_YPANREDRAW 0x040
  143. #define __SCROLL_YNOPARTIAL 0x080
  144. /* Only these should be used by the drivers */
  145. /* Which one should you use? If you have a fast card and slow bus,
  146.    then probably just 0 to indicate fbcon should choose between
  147.    YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
  148.    and even better if your card can do fonting (1->8/32bit painting),
  149.    you should consider either SCROLL_YREDRAW (if your card is
  150.    able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
  151.    The best is to test it with some real life scrolling (usually, not
  152.    all lines on the screen are filled completely with non-space characters,
  153.    and REDRAW performs much better on such lines, so don't cat a file
  154.    with every line covering all screen columns, it would not be the right
  155.    benchmark).
  156.  */
  157. #define SCROLL_YREDRAW (__SCROLL_YFIXED|__SCROLL_YREDRAW)
  158. #define SCROLL_YNOMOVE (__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
  159. /* SCROLL_YNOPARTIAL, used in combination with the above, is for video
  160.    cards which can not handle using panning to scroll a portion of the
  161.    screen without excessive flicker.  Panning will only be used for
  162.    whole screens.
  163.  */
  164. /* Namespace consistency */
  165. #define SCROLL_YNOPARTIAL __SCROLL_YNOPARTIAL
  166. #if defined(__sparc__)
  167. /* We map all of our framebuffers such that big-endian accesses
  168.  * are what we want, so the following is sufficient.
  169.  */
  170. #define fb_readb sbus_readb
  171. #define fb_readw sbus_readw
  172. #define fb_readl sbus_readl
  173. #define fb_writeb sbus_writeb
  174. #define fb_writew sbus_writew
  175. #define fb_writel sbus_writel
  176. #define fb_memset sbus_memset_io
  177. #elif defined(__i386__) || defined(__alpha__) || 
  178.       defined(__x86_64__) || defined(__hppa__)
  179. #define fb_readb __raw_readb
  180. #define fb_readw __raw_readw
  181. #define fb_readl __raw_readl
  182. #define fb_writeb __raw_writeb
  183. #define fb_writew __raw_writew
  184. #define fb_writel __raw_writel
  185. #define fb_memset memset_io
  186. #else
  187. #define fb_readb(addr) (*(volatile u8 *) (addr))
  188. #define fb_readw(addr) (*(volatile u16 *) (addr))
  189. #define fb_readl(addr) (*(volatile u32 *) (addr))
  190. #define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
  191. #define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
  192. #define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
  193. #define fb_memset memset
  194. #endif
  195. extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int);
  196. extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
  197. /* ================================================================= */
  198. /*                      Utility Assembler Functions                  */
  199. /* ================================================================= */
  200. #if defined(__mc68000__)
  201. /* ====================================================================== */
  202. /* Those of a delicate disposition might like to skip the next couple of
  203.  * pages.
  204.  *
  205.  * These functions are drop in replacements for memmove and
  206.  * memset(_, 0, _). However their five instances add at least a kilobyte
  207.  * to the object file. You have been warned.
  208.  *
  209.  * Not a great fan of assembler for the sake of it, but I think
  210.  * that these routines are at least 10 times faster than their C
  211.  * equivalents for large blits, and that's important to the lowest level of
  212.  * a graphics driver. Question is whether some scheme with the blitter
  213.  * would be faster. I suspect not for simple text system - not much
  214.  * asynchrony.
  215.  *
  216.  * Code is very simple, just gruesome expansion. Basic strategy is to
  217.  * increase data moved/cleared at each step to 16 bytes to reduce
  218.  * instruction per data move overhead. movem might be faster still
  219.  * For more than 15 bytes, we try to align the write direction on a
  220.  * longword boundary to get maximum speed. This is even more gruesome.
  221.  * Unaligned read/write used requires 68020+ - think this is a problem?
  222.  *
  223.  * Sorry!
  224.  */
  225. /* ++roman: I've optimized Robert's original versions in some minor
  226.  * aspects, e.g. moveq instead of movel, let gcc choose the registers,
  227.  * use movem in some places...
  228.  * For other modes than 1 plane, lots of more such assembler functions
  229.  * were needed (e.g. the ones using movep or expanding color values).
  230.  */
  231. /* ++andreas: more optimizations:
  232.    subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
  233.    addal is faster than addaw
  234.    movep is rather expensive compared to ordinary move's
  235.    some functions rewritten in C for clarity, no speed loss */
  236. static __inline__ void *fb_memclear_small(void *s, size_t count)
  237. {
  238.    if (!count)
  239.       return(0);
  240.    __asm__ __volatile__(
  241.          "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-nt"
  242.       "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-nt"
  243.       "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-nt"
  244.       "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-nt"
  245.       "1:"
  246.          : "=a" (s), "=d" (count)
  247.          : "d" (0), "0" ((char *)s+count), "1" (count)
  248.    );
  249.    __asm__ __volatile__(
  250.          "subql  #1,%1 ; jcs 3fnt"
  251.  "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6nt"
  252.       "2: moveml %2/%%d4/%%d5/%%d6,%0@-nt"
  253.          "dbra %1,2bnt"
  254.       "3:"
  255.          : "=a" (s), "=d" (count)
  256.          : "d" (0), "0" (s), "1" (count)
  257.  : "d4", "d5", "d6"
  258.   );
  259.    return(0);
  260. }
  261. static __inline__ void *fb_memclear(void *s, size_t count)
  262. {
  263.    if (!count)
  264.       return(0);
  265.    if (count < 16) {
  266.       __asm__ __volatile__(
  267.             "lsrl   #1,%1 ; jcc 1f ; clrb %0@+nt"
  268.          "1: lsrl   #1,%1 ; jcc 1f ; clrw %0@+nt"
  269.          "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+nt"
  270.          "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+nt"
  271.          "1:"
  272.             : "=a" (s), "=d" (count)
  273.             : "0" (s), "1" (count)
  274.      );
  275.    } else {
  276.       long tmp;
  277.       __asm__ __volatile__(
  278.             "movel %1,%2nt"
  279.             "lsrl   #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1nt"
  280.             "lsrl   #1,%2 ; jcs 2fnt"  /* %0 increased=>bit 2 switched*/
  281.             "clrw   %0@+  ; subqw  #2,%1 ; jra 2fnt"
  282.          "1: lsrl   #1,%2 ; jcc 2fnt"
  283.             "clrw   %0@+  ; subqw  #2,%1nt"
  284.          "2: movew %1,%2; lsrl #2,%1 ; jeq 6fnt"
  285.             "lsrl   #1,%1 ; jcc 3f ; clrl %0@+nt"
  286.          "3: lsrl   #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+nt"
  287.          "4: subql  #1,%1 ; jcs 6fnt"
  288.          "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+nt"
  289.             "dbra %1,5b   ; clrw %1; subql #1,%1; jcc 5bnt"
  290.          "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+nt"
  291.          "7:            ; btst #0,%1 ; jeq 8f ; clrb %0@+nt"
  292.          "8:"
  293.             : "=a" (s), "=d" (count), "=d" (tmp)
  294.             : "0" (s), "1" (count)
  295.      );
  296.    }
  297.    return(0);
  298. }
  299. static __inline__ void *fb_memset255(void *s, size_t count)
  300. {
  301.    if (!count)
  302.       return(0);
  303.    __asm__ __volatile__(
  304.          "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-nt"
  305.       "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-nt"
  306.       "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-nt"
  307.       "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-nt"
  308.       "1:"
  309.          : "=a" (s), "=d" (count)
  310.          : "d" (-1), "0" ((char *)s+count), "1" (count)
  311.    );
  312.    __asm__ __volatile__(
  313.          "subql  #1,%1 ; jcs 3fnt"
  314.  "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6nt"
  315.       "2: moveml %2/%%d4/%%d5/%%d6,%0@-nt"
  316.          "dbra %1,2bnt"
  317.       "3:"
  318.          : "=a" (s), "=d" (count)
  319.          : "d" (-1), "0" (s), "1" (count)
  320.  : "d4", "d5", "d6"
  321.   );
  322.    return(0);
  323. }
  324. static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
  325. {
  326.    if (d < s) {
  327.       if (count < 16) {
  328.          __asm__ __volatile__(
  329.                "lsrl   #1,%2 ; jcc 1f ; moveb %1@+,%0@+nt"
  330.             "1: lsrl   #1,%2 ; jcc 1f ; movew %1@+,%0@+nt"
  331.             "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+nt"
  332.             "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+nt"
  333.             "1:"
  334.                : "=a" (d), "=a" (s), "=d" (count)
  335.                : "0" (d), "1" (s), "2" (count)
  336.         );
  337.       } else {
  338.          long tmp;
  339.          __asm__ __volatile__(
  340.                "movel  %0,%3nt"
  341.                "lsrl   #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2nt"
  342.                "lsrl   #1,%3 ; jcs 2fnt"  /* %0 increased=>bit 2 switched*/
  343.                "movew  %1@+,%0@+  ; subqw  #2,%2 ; jra 2fnt"
  344.             "1: lsrl   #1,%3 ; jcc 2fnt"
  345.                "movew  %1@+,%0@+  ; subqw  #2,%2nt"
  346.             "2: movew  %2,%-; lsrl #2,%2 ; jeq 6fnt"
  347.                "lsrl   #1,%2 ; jcc 3f ; movel %1@+,%0@+nt"
  348.             "3: lsrl   #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+nt"
  349.             "4: subql  #1,%2 ; jcs 6fnt"
  350.             "5: movel  %1@+,%0@+;movel %1@+,%0@+nt"
  351.                "movel  %1@+,%0@+;movel %1@+,%0@+nt"
  352.                "dbra   %2,5b ; clrw %2; subql #1,%2; jcc 5bnt"
  353.             "6: movew  %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+nt"
  354.             "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+nt"
  355.             "8:"
  356.                : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
  357.                : "0" (d), "1" (s), "2" (count)
  358.         );
  359.       }
  360.    } else {
  361.       if (count < 16) {
  362.          __asm__ __volatile__(
  363.                "lsrl   #1,%2 ; jcc 1f ; moveb %1@-,%0@-nt"
  364.             "1: lsrl   #1,%2 ; jcc 1f ; movew %1@-,%0@-nt"
  365.             "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@-nt"
  366.             "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-nt"
  367.             "1:"
  368.                : "=a" (d), "=a" (s), "=d" (count)
  369.                : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
  370.         );
  371.       } else {
  372.          long tmp;
  373.          __asm__ __volatile__(
  374.                "movel %0,%3nt"
  375.                "lsrl   #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2nt"
  376.                "lsrl   #1,%3 ; jcs 2fnt"  /* %0 increased=>bit 2 switched*/
  377.                "movew  %1@-,%0@-  ; subqw  #2,%2 ; jra 2fnt"
  378.             "1: lsrl   #1,%3 ; jcc 2fnt"
  379.                "movew  %1@-,%0@-  ; subqw  #2,%2nt"
  380.             "2: movew %2,%-; lsrl #2,%2 ; jeq 6fnt"
  381.                "lsrl   #1,%2 ; jcc 3f ; movel %1@-,%0@-nt"
  382.             "3: lsrl   #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-nt"
  383.             "4: subql  #1,%2 ; jcs 6fnt"
  384.             "5: movel %1@-,%0@-;movel %1@-,%0@-nt"
  385.                "movel %1@-,%0@-;movel %1@-,%0@-nt"
  386.                "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5bnt"
  387.             "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-nt"
  388.             "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-nt"
  389.             "8:"
  390.                : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
  391.                : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
  392.         );
  393.       }
  394.    }
  395.    return(0);
  396. }
  397. /* ++andreas: Simple and fast version of memmove, assumes size is
  398.    divisible by 16, suitable for moving the whole screen bitplane */
  399. static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
  400. {
  401.   if (!size)
  402.     return;
  403.   if (dst < src)
  404.     __asm__ __volatile__
  405.       ("1:"
  406.        "  moveml %0@+,%/d0/%/d1/%/a0/%/a1n"
  407.        "  moveml %/d0/%/d1/%/a0/%/a1,%1@n"
  408.        "  addql #8,%1; addql #8,%1n"
  409.        "  dbra %2,1bn"
  410.        "  clrw %2; subql #1,%2n"
  411.        "  jcc 1b"
  412.        : "=a" (src), "=a" (dst), "=d" (size)
  413.        : "0" (src), "1" (dst), "2" (size / 16 - 1)
  414.        : "d0", "d1", "a0", "a1", "memory");
  415.   else
  416.     __asm__ __volatile__
  417.       ("1:"
  418.        "  subql #8,%0; subql #8,%0n"
  419.        "  moveml %0@,%/d0/%/d1/%/a0/%/a1n"
  420.        "  moveml %/d0/%/d1/%/a0/%/a1,%1@-n"
  421.        "  dbra %2,1bn"
  422.        "  clrw %2; subql #1,%2n"
  423.        "  jcc 1b"
  424.        : "=a" (src), "=a" (dst), "=d" (size)
  425.        : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
  426.        : "d0", "d1", "a0", "a1", "memory");
  427. }
  428. #elif defined(CONFIG_SUN4)
  429. /* You may think that I'm crazy and that I should use generic
  430.    routines.  No, I'm not: sun4's framebuffer crashes if we std
  431.    into it, so we cannot use memset.  */
  432. static __inline__ void *sun4_memset(void *s, char val, size_t count)
  433. {
  434.     int i;
  435.     for(i=0; i<count;i++)
  436.         ((char *) s) [i] = val;
  437.     return s;
  438. }
  439. static __inline__ void *fb_memset255(void *s, size_t count)
  440. {
  441.     return sun4_memset(s, 255, count);
  442. }
  443. static __inline__ void *fb_memclear(void *s, size_t count)
  444. {
  445.     return sun4_memset(s, 0, count);
  446. }
  447. static __inline__ void *fb_memclear_small(void *s, size_t count)
  448. {
  449.     return sun4_memset(s, 0, count);
  450. }
  451. /* To be honest, this is slow_memmove :). But sun4 is crappy, so what we can do. */
  452. static __inline__ void fast_memmove(void *d, const void *s, size_t count)
  453. {
  454.     int i;
  455.     if (d<s) {
  456. for (i=0; i<count; i++)
  457.     ((char *) d)[i] = ((char *) s)[i];
  458.     } else
  459. for (i=0; i<count; i++)
  460.     ((char *) d)[count-i-1] = ((char *) s)[count-i-1];
  461. }
  462. static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
  463. {
  464.     fast_memmove(dst, src, size);
  465.     return dst;
  466. }
  467. #else
  468. static __inline__ void *fb_memclear_small(void *s, size_t count)
  469. {
  470.     char *xs = (char *) s;
  471.     while (count--)
  472. fb_writeb(0, xs++);
  473.     return s;
  474. }
  475. static __inline__ void *fb_memclear(void *s, size_t count)
  476. {
  477.     unsigned long xs = (unsigned long) s;
  478.     if (count < 8)
  479. goto rest;
  480.     if (xs & 1) {
  481. fb_writeb(0, xs++);
  482. count--;
  483.     }
  484.     if (xs & 2) {
  485. fb_writew(0, xs);
  486. xs += 2;
  487. count -= 2;
  488.     }
  489.     while (count > 3) {
  490. fb_writel(0, xs);
  491. xs += 4;
  492. count -= 4;
  493.     }
  494. rest:
  495.     while (count--)
  496. fb_writeb(0, xs++);
  497.     return s;
  498. }
  499. static __inline__ void *fb_memset255(void *s, size_t count)
  500. {
  501.     unsigned long xs = (unsigned long) s;
  502.     if (count < 8)
  503. goto rest;
  504.     if (xs & 1) {
  505. fb_writeb(0xff, xs++);
  506. count--;
  507.     }
  508.     if (xs & 2) {
  509. fb_writew(0xffff, xs);
  510. xs += 2;
  511. count -= 2;
  512.     }
  513.     while (count > 3) {
  514. fb_writel(0xffffffff, xs);
  515. xs += 4;
  516. count -= 4;
  517.     }
  518. rest:
  519.     while (count--)
  520. fb_writeb(0xff, xs++);
  521.     return s;
  522. }
  523. #if defined(__i386__)
  524. static __inline__ void fast_memmove(void *d, const void *s, size_t count)
  525. {
  526.   int d0, d1, d2, d3;
  527.     if (d < s) {
  528. __asm__ __volatile__ (
  529. "cldnt"
  530. "shrl $1,%%ecxnt"
  531. "jnc 1fnt"
  532. "movsbn"
  533. "1:tshrl $1,%%ecxnt"
  534. "jnc 2fnt"
  535. "movswn"
  536. "2:trepnt"
  537. "movsl"
  538. : "=&c" (d0), "=&D" (d1), "=&S" (d2)
  539. :"0"(count),"1"((long)d),"2"((long)s)
  540. :"memory");
  541.     } else {
  542. __asm__ __volatile__ (
  543. "stdnt"
  544. "shrl $1,%%ecxnt"
  545. "jnc 1fnt"
  546. "movb 3(%%esi),%%alnt"
  547. "movb %%al,3(%%edi)nt"
  548. "decl %%esint"
  549. "decl %%edin"
  550. "1:tshrl $1,%%ecxnt"
  551. "jnc 2fnt"
  552. "movw 2(%%esi),%%axnt"
  553. "movw %%ax,2(%%edi)nt"
  554. "decl %%esint"
  555. "decl %%edint"
  556. "decl %%esint"
  557. "decl %%edin"
  558. "2:trepnt"
  559. "movslnt"
  560. "cld"
  561. : "=&c" (d0), "=&D" (d1), "=&S" (d2), "=&a" (d3)
  562. :"0"(count),"1"(count-4+(long)d),"2"(count-4+(long)s)
  563. :"memory");
  564.     }
  565. }
  566. static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
  567. {
  568.     fast_memmove(dst, src, size);
  569.     return dst;
  570. }
  571. #else /* !__i386__ */
  572.     /*
  573.      *  Anyone who'd like to write asm functions for other CPUs?
  574.      *   (Why are these functions better than those from include/asm/string.h?)
  575.      */
  576. static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
  577. {
  578.     unsigned long dst, src;
  579.     if (d < s) {
  580. dst = (unsigned long) d;
  581. src = (unsigned long) s;
  582. if ((count < 8) || ((dst ^ src) & 3))
  583.     goto restup;
  584. if (dst & 1) {
  585.     fb_writeb(fb_readb(src++), dst++);
  586.     count--;
  587. }
  588. if (dst & 2) {
  589.     fb_writew(fb_readw(src), dst);
  590.     src += 2;
  591.     dst += 2;
  592.     count -= 2;
  593. }
  594. while (count > 3) {
  595.     fb_writel(fb_readl(src), dst);
  596.     src += 4;
  597.     dst += 4;
  598.     count -= 4;
  599. }
  600.     restup:
  601. while (count--)
  602.     fb_writeb(fb_readb(src++), dst++);
  603.     } else {
  604. dst = (unsigned long) d + count;
  605. src = (unsigned long) s + count;
  606. if ((count < 8) || ((dst ^ src) & 3))
  607.     goto restdown;
  608. if (dst & 1) {
  609.     src--;
  610.     dst--;
  611.     count--;
  612.     fb_writeb(fb_readb(src), dst);
  613. }
  614. if (dst & 2) {
  615.     src -= 2;
  616.     dst -= 2;
  617.     count -= 2;
  618.     fb_writew(fb_readw(src), dst);
  619. }
  620. while (count > 3) {
  621.     src -= 4;
  622.     dst -= 4;
  623.     count -= 4;
  624.     fb_writel(fb_readl(src), dst);
  625. }
  626.     restdown:
  627. while (count--) {
  628.     src--;
  629.     dst--;
  630.     fb_writeb(fb_readb(src), dst);
  631. }
  632.     }
  633.     return d;
  634. }
  635. static __inline__ void fast_memmove(char *d, const char *s, size_t count)
  636. {
  637.     unsigned long dst, src;
  638.     if (d < s) {
  639. dst = (unsigned long) d;
  640. src = (unsigned long) s;
  641. if ((count < 8) || ((dst ^ src) & 3))
  642.     goto restup;
  643. if (dst & 1) {
  644.     fb_writeb(fb_readb(src++), dst++);
  645.     count--;
  646. }
  647. if (dst & 2) {
  648.     fb_writew(fb_readw(src), dst);
  649.     src += 2;
  650.     dst += 2;
  651.     count -= 2;
  652. }
  653. while (count > 3) {
  654.     fb_writel(fb_readl(src), dst);
  655.     src += 4;
  656.     dst += 4;
  657.     count -= 4;
  658. }
  659.     restup:
  660. while (count--)
  661.     fb_writeb(fb_readb(src++), dst++);
  662.     } else {
  663. dst = (unsigned long) d + count;
  664. src = (unsigned long) s + count;
  665. if ((count < 8) || ((dst ^ src) & 3))
  666.     goto restdown;
  667. if (dst & 1) {
  668.     src--;
  669.     dst--;
  670.     count--;
  671.     fb_writeb(fb_readb(src), dst);
  672. }
  673. if (dst & 2) {
  674.     src -= 2;
  675.     dst -= 2;
  676.     count -= 2;
  677.     fb_writew(fb_readw(src), dst);
  678. }
  679. while (count > 3) {
  680.     src -= 4;
  681.     dst -= 4;
  682.     count -= 4;
  683.     fb_writel(fb_readl(src), dst);
  684. }
  685.     restdown:
  686. while (count--) {
  687.     src--;
  688.     dst--;
  689.     fb_writeb(fb_readb(src), dst);
  690. }
  691.     }
  692. }
  693. #endif /* !__i386__ */
  694. #endif /* !__mc68000__ */
  695. #endif /* _VIDEO_FBCON_H */