fbcon.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:22k
源码类别:

嵌入式Linux

开发平台:

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__) || defined(__x86_64__)
  178. #define fb_readb __raw_readb
  179. #define fb_readw __raw_readw
  180. #define fb_readl __raw_readl
  181. #define fb_writeb __raw_writeb
  182. #define fb_writew __raw_writew
  183. #define fb_writel __raw_writel
  184. #define fb_memset memset_io
  185. #else
  186. #define fb_readb(addr) (*(volatile u8 *) (addr))
  187. #define fb_readw(addr) (*(volatile u16 *) (addr))
  188. #define fb_readl(addr) (*(volatile u32 *) (addr))
  189. #define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
  190. #define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
  191. #define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
  192. #define fb_memset memset
  193. #endif
  194. extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int);
  195. extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
  196. /* ================================================================= */
  197. /*                      Utility Assembler Functions                  */
  198. /* ================================================================= */
  199. #if defined(__mc68000__)
  200. /* ====================================================================== */
  201. /* Those of a delicate disposition might like to skip the next couple of
  202.  * pages.
  203.  *
  204.  * These functions are drop in replacements for memmove and
  205.  * memset(_, 0, _). However their five instances add at least a kilobyte
  206.  * to the object file. You have been warned.
  207.  *
  208.  * Not a great fan of assembler for the sake of it, but I think
  209.  * that these routines are at least 10 times faster than their C
  210.  * equivalents for large blits, and that's important to the lowest level of
  211.  * a graphics driver. Question is whether some scheme with the blitter
  212.  * would be faster. I suspect not for simple text system - not much
  213.  * asynchrony.
  214.  *
  215.  * Code is very simple, just gruesome expansion. Basic strategy is to
  216.  * increase data moved/cleared at each step to 16 bytes to reduce
  217.  * instruction per data move overhead. movem might be faster still
  218.  * For more than 15 bytes, we try to align the write direction on a
  219.  * longword boundary to get maximum speed. This is even more gruesome.
  220.  * Unaligned read/write used requires 68020+ - think this is a problem?
  221.  *
  222.  * Sorry!
  223.  */
  224. /* ++roman: I've optimized Robert's original versions in some minor
  225.  * aspects, e.g. moveq instead of movel, let gcc choose the registers,
  226.  * use movem in some places...
  227.  * For other modes than 1 plane, lots of more such assembler functions
  228.  * were needed (e.g. the ones using movep or expanding color values).
  229.  */
  230. /* ++andreas: more optimizations:
  231.    subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
  232.    addal is faster than addaw
  233.    movep is rather expensive compared to ordinary move's
  234.    some functions rewritten in C for clarity, no speed loss */
  235. static __inline__ void *fb_memclear_small(void *s, size_t count)
  236. {
  237.    if (!count)
  238.       return(0);
  239.    __asm__ __volatile__(
  240.          "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-nt"
  241.       "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-nt"
  242.       "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-nt"
  243.       "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-nt"
  244.       "1:"
  245.          : "=a" (s), "=d" (count)
  246.          : "d" (0), "0" ((char *)s+count), "1" (count)
  247.    );
  248.    __asm__ __volatile__(
  249.          "subql  #1,%1 ; jcs 3fnt"
  250.  "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6nt"
  251.       "2: moveml %2/%%d4/%%d5/%%d6,%0@-nt"
  252.          "dbra %1,2bnt"
  253.       "3:"
  254.          : "=a" (s), "=d" (count)
  255.          : "d" (0), "0" (s), "1" (count)
  256.  : "d4", "d5", "d6"
  257.   );
  258.    return(0);
  259. }
  260. static __inline__ void *fb_memclear(void *s, size_t count)
  261. {
  262.    if (!count)
  263.       return(0);
  264.    if (count < 16) {
  265.       __asm__ __volatile__(
  266.             "lsrl   #1,%1 ; jcc 1f ; clrb %0@+nt"
  267.          "1: lsrl   #1,%1 ; jcc 1f ; clrw %0@+nt"
  268.          "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+nt"
  269.          "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+nt"
  270.          "1:"
  271.             : "=a" (s), "=d" (count)
  272.             : "0" (s), "1" (count)
  273.      );
  274.    } else {
  275.       long tmp;
  276.       __asm__ __volatile__(
  277.             "movel %1,%2nt"
  278.             "lsrl   #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1nt"
  279.             "lsrl   #1,%2 ; jcs 2fnt"  /* %0 increased=>bit 2 switched*/
  280.             "clrw   %0@+  ; subqw  #2,%1 ; jra 2fnt"
  281.          "1: lsrl   #1,%2 ; jcc 2fnt"
  282.             "clrw   %0@+  ; subqw  #2,%1nt"
  283.          "2: movew %1,%2; lsrl #2,%1 ; jeq 6fnt"
  284.             "lsrl   #1,%1 ; jcc 3f ; clrl %0@+nt"
  285.          "3: lsrl   #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+nt"
  286.          "4: subql  #1,%1 ; jcs 6fnt"
  287.          "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+nt"
  288.             "dbra %1,5b   ; clrw %1; subql #1,%1; jcc 5bnt"
  289.          "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+nt"
  290.          "7:            ; btst #0,%1 ; jeq 8f ; clrb %0@+nt"
  291.          "8:"
  292.             : "=a" (s), "=d" (count), "=d" (tmp)
  293.             : "0" (s), "1" (count)
  294.      );
  295.    }
  296.    return(0);
  297. }
  298. static __inline__ void *fb_memset255(void *s, size_t count)
  299. {
  300.    if (!count)
  301.       return(0);
  302.    __asm__ __volatile__(
  303.          "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-nt"
  304.       "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-nt"
  305.       "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-nt"
  306.       "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-nt"
  307.       "1:"
  308.          : "=a" (s), "=d" (count)
  309.          : "d" (-1), "0" ((char *)s+count), "1" (count)
  310.    );
  311.    __asm__ __volatile__(
  312.          "subql  #1,%1 ; jcs 3fnt"
  313.  "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6nt"
  314.       "2: moveml %2/%%d4/%%d5/%%d6,%0@-nt"
  315.          "dbra %1,2bnt"
  316.       "3:"
  317.          : "=a" (s), "=d" (count)
  318.          : "d" (-1), "0" (s), "1" (count)
  319.  : "d4", "d5", "d6"
  320.   );
  321.    return(0);
  322. }
  323. static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
  324. {
  325.    if (d < s) {
  326.       if (count < 16) {
  327.          __asm__ __volatile__(
  328.                "lsrl   #1,%2 ; jcc 1f ; moveb %1@+,%0@+nt"
  329.             "1: lsrl   #1,%2 ; jcc 1f ; movew %1@+,%0@+nt"
  330.             "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+nt"
  331.             "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+nt"
  332.             "1:"
  333.                : "=a" (d), "=a" (s), "=d" (count)
  334.                : "0" (d), "1" (s), "2" (count)
  335.         );
  336.       } else {
  337.          long tmp;
  338.          __asm__ __volatile__(
  339.                "movel  %0,%3nt"
  340.                "lsrl   #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2nt"
  341.                "lsrl   #1,%3 ; jcs 2fnt"  /* %0 increased=>bit 2 switched*/
  342.                "movew  %1@+,%0@+  ; subqw  #2,%2 ; jra 2fnt"
  343.             "1: lsrl   #1,%3 ; jcc 2fnt"
  344.                "movew  %1@+,%0@+  ; subqw  #2,%2nt"
  345.             "2: movew  %2,%-; lsrl #2,%2 ; jeq 6fnt"
  346.                "lsrl   #1,%2 ; jcc 3f ; movel %1@+,%0@+nt"
  347.             "3: lsrl   #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+nt"
  348.             "4: subql  #1,%2 ; jcs 6fnt"
  349.             "5: movel  %1@+,%0@+;movel %1@+,%0@+nt"
  350.                "movel  %1@+,%0@+;movel %1@+,%0@+nt"
  351.                "dbra   %2,5b ; clrw %2; subql #1,%2; jcc 5bnt"
  352.             "6: movew  %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+nt"
  353.             "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+nt"
  354.             "8:"
  355.                : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
  356.                : "0" (d), "1" (s), "2" (count)
  357.         );
  358.       }
  359.    } else {
  360.       if (count < 16) {
  361.          __asm__ __volatile__(
  362.                "lsrl   #1,%2 ; jcc 1f ; moveb %1@-,%0@-nt"
  363.             "1: lsrl   #1,%2 ; jcc 1f ; movew %1@-,%0@-nt"
  364.             "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@-nt"
  365.             "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-nt"
  366.             "1:"
  367.                : "=a" (d), "=a" (s), "=d" (count)
  368.                : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
  369.         );
  370.       } else {
  371.          long tmp;
  372.          __asm__ __volatile__(
  373.                "movel %0,%3nt"
  374.                "lsrl   #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2nt"
  375.                "lsrl   #1,%3 ; jcs 2fnt"  /* %0 increased=>bit 2 switched*/
  376.                "movew  %1@-,%0@-  ; subqw  #2,%2 ; jra 2fnt"
  377.             "1: lsrl   #1,%3 ; jcc 2fnt"
  378.                "movew  %1@-,%0@-  ; subqw  #2,%2nt"
  379.             "2: movew %2,%-; lsrl #2,%2 ; jeq 6fnt"
  380.                "lsrl   #1,%2 ; jcc 3f ; movel %1@-,%0@-nt"
  381.             "3: lsrl   #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-nt"
  382.             "4: subql  #1,%2 ; jcs 6fnt"
  383.             "5: movel %1@-,%0@-;movel %1@-,%0@-nt"
  384.                "movel %1@-,%0@-;movel %1@-,%0@-nt"
  385.                "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5bnt"
  386.             "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-nt"
  387.             "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-nt"
  388.             "8:"
  389.                : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
  390.                : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
  391.         );
  392.       }
  393.    }
  394.    return(0);
  395. }
  396. /* ++andreas: Simple and fast version of memmove, assumes size is
  397.    divisible by 16, suitable for moving the whole screen bitplane */
  398. static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
  399. {
  400.   if (!size)
  401.     return;
  402.   if (dst < src)
  403.     __asm__ __volatile__
  404.       ("1:"
  405.        "  moveml %0@+,%/d0/%/d1/%/a0/%/a1n"
  406.        "  moveml %/d0/%/d1/%/a0/%/a1,%1@n"
  407.        "  addql #8,%1; addql #8,%1n"
  408.        "  dbra %2,1bn"
  409.        "  clrw %2; subql #1,%2n"
  410.        "  jcc 1b"
  411.        : "=a" (src), "=a" (dst), "=d" (size)
  412.        : "0" (src), "1" (dst), "2" (size / 16 - 1)
  413.        : "d0", "d1", "a0", "a1", "memory");
  414.   else
  415.     __asm__ __volatile__
  416.       ("1:"
  417.        "  subql #8,%0; subql #8,%0n"
  418.        "  moveml %0@,%/d0/%/d1/%/a0/%/a1n"
  419.        "  moveml %/d0/%/d1/%/a0/%/a1,%1@-n"
  420.        "  dbra %2,1bn"
  421.        "  clrw %2; subql #1,%2n"
  422.        "  jcc 1b"
  423.        : "=a" (src), "=a" (dst), "=d" (size)
  424.        : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
  425.        : "d0", "d1", "a0", "a1", "memory");
  426. }
  427. #elif defined(CONFIG_SUN4)
  428. /* You may think that I'm crazy and that I should use generic
  429.    routines.  No, I'm not: sun4's framebuffer crashes if we std
  430.    into it, so we cannot use memset.  */
  431. static __inline__ void *sun4_memset(void *s, char val, size_t count)
  432. {
  433.     int i;
  434.     for(i=0; i<count;i++)
  435.         ((char *) s) [i] = val;
  436.     return s;
  437. }
  438. static __inline__ void *fb_memset255(void *s, size_t count)
  439. {
  440.     return sun4_memset(s, 255, count);
  441. }
  442. static __inline__ void *fb_memclear(void *s, size_t count)
  443. {
  444.     return sun4_memset(s, 0, count);
  445. }
  446. static __inline__ void *fb_memclear_small(void *s, size_t count)
  447. {
  448.     return sun4_memset(s, 0, count);
  449. }
  450. /* To be honest, this is slow_memmove :). But sun4 is crappy, so what we can do. */
  451. static __inline__ void fast_memmove(void *d, const void *s, size_t count)
  452. {
  453.     int i;
  454.     if (d<s) {
  455. for (i=0; i<count; i++)
  456.     ((char *) d)[i] = ((char *) s)[i];
  457.     } else
  458. for (i=0; i<count; i++)
  459.     ((char *) d)[count-i-1] = ((char *) s)[count-i-1];
  460. }
  461. static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
  462. {
  463.     fast_memmove(dst, src, size);
  464.     return dst;
  465. }
  466. #else
  467. static __inline__ void *fb_memclear_small(void *s, size_t count)
  468. {
  469.     char *xs = (char *) s;
  470.     while (count--)
  471. fb_writeb(0, xs++);
  472.     return s;
  473. }
  474. static __inline__ void *fb_memclear(void *s, size_t count)
  475. {
  476.     unsigned long xs = (unsigned long) s;
  477.     if (count < 8)
  478. goto rest;
  479.     if (xs & 1) {
  480. fb_writeb(0, xs++);
  481. count--;
  482.     }
  483.     if (xs & 2) {
  484. fb_writew(0, xs);
  485. xs += 2;
  486. count -= 2;
  487.     }
  488.     while (count > 3) {
  489. fb_writel(0, xs);
  490. xs += 4;
  491. count -= 4;
  492.     }
  493. rest:
  494.     while (count--)
  495. fb_writeb(0, xs++);
  496.     return s;
  497. }
  498. static __inline__ void *fb_memset255(void *s, size_t count)
  499. {
  500.     unsigned long xs = (unsigned long) s;
  501.     if (count < 8)
  502. goto rest;
  503.     if (xs & 1) {
  504. fb_writeb(0xff, xs++);
  505. count--;
  506.     }
  507.     if (xs & 2) {
  508. fb_writew(0xffff, xs);
  509. xs += 2;
  510. count -= 2;
  511.     }
  512.     while (count > 3) {
  513. fb_writel(0xffffffff, xs);
  514. xs += 4;
  515. count -= 4;
  516.     }
  517. rest:
  518.     while (count--)
  519. fb_writeb(0xff, xs++);
  520.     return s;
  521. }
  522. #if defined(__i386__)
  523. static __inline__ void fast_memmove(void *d, const void *s, size_t count)
  524. {
  525.   int d0, d1, d2, d3;
  526.     if (d < s) {
  527. __asm__ __volatile__ (
  528. "cldnt"
  529. "shrl $1,%%ecxnt"
  530. "jnc 1fnt"
  531. "movsbn"
  532. "1:tshrl $1,%%ecxnt"
  533. "jnc 2fnt"
  534. "movswn"
  535. "2:trepnt"
  536. "movsl"
  537. : "=&c" (d0), "=&D" (d1), "=&S" (d2)
  538. :"0"(count),"1"((long)d),"2"((long)s)
  539. :"memory");
  540.     } else {
  541. __asm__ __volatile__ (
  542. "stdnt"
  543. "shrl $1,%%ecxnt"
  544. "jnc 1fnt"
  545. "movb 3(%%esi),%%alnt"
  546. "movb %%al,3(%%edi)nt"
  547. "decl %%esint"
  548. "decl %%edin"
  549. "1:tshrl $1,%%ecxnt"
  550. "jnc 2fnt"
  551. "movw 2(%%esi),%%axnt"
  552. "movw %%ax,2(%%edi)nt"
  553. "decl %%esint"
  554. "decl %%edint"
  555. "decl %%esint"
  556. "decl %%edin"
  557. "2:trepnt"
  558. "movslnt"
  559. "cld"
  560. : "=&c" (d0), "=&D" (d1), "=&S" (d2), "=&a" (d3)
  561. :"0"(count),"1"(count-4+(long)d),"2"(count-4+(long)s)
  562. :"memory");
  563.     }
  564. }
  565. static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
  566. {
  567.     fast_memmove(dst, src, size);
  568.     return dst;
  569. }
  570. #else /* !__i386__ */
  571.     /*
  572.      *  Anyone who'd like to write asm functions for other CPUs?
  573.      *   (Why are these functions better than those from include/asm/string.h?)
  574.      */
  575. static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
  576. {
  577.     unsigned long dst, src;
  578.     if (d < s) {
  579. dst = (unsigned long) d;
  580. src = (unsigned long) s;
  581. if ((count < 8) || ((dst ^ src) & 3))
  582.     goto restup;
  583. if (dst & 1) {
  584.     fb_writeb(fb_readb(src++), dst++);
  585.     count--;
  586. }
  587. if (dst & 2) {
  588.     fb_writew(fb_readw(src), dst);
  589.     src += 2;
  590.     dst += 2;
  591.     count -= 2;
  592. }
  593. while (count > 3) {
  594.     fb_writel(fb_readl(src), dst);
  595.     src += 4;
  596.     dst += 4;
  597.     count -= 4;
  598. }
  599.     restup:
  600. while (count--)
  601.     fb_writeb(fb_readb(src++), dst++);
  602.     } else {
  603. dst = (unsigned long) d + count;
  604. src = (unsigned long) s + count;
  605. if ((count < 8) || ((dst ^ src) & 3))
  606.     goto restdown;
  607. if (dst & 1) {
  608.     src--;
  609.     dst--;
  610.     count--;
  611.     fb_writeb(fb_readb(src), dst);
  612. }
  613. if (dst & 2) {
  614.     src -= 2;
  615.     dst -= 2;
  616.     count -= 2;
  617.     fb_writew(fb_readw(src), dst);
  618. }
  619. while (count > 3) {
  620.     src -= 4;
  621.     dst -= 4;
  622.     count -= 4;
  623.     fb_writel(fb_readl(src), dst);
  624. }
  625.     restdown:
  626. while (count--) {
  627.     src--;
  628.     dst--;
  629.     fb_writeb(fb_readb(src), dst);
  630. }
  631.     }
  632.     return d;
  633. }
  634. static __inline__ void fast_memmove(char *d, const char *s, size_t count)
  635. {
  636.     unsigned long dst, src;
  637.     if (d < s) {
  638. dst = (unsigned long) d;
  639. src = (unsigned long) s;
  640. if ((count < 8) || ((dst ^ src) & 3))
  641.     goto restup;
  642. if (dst & 1) {
  643.     fb_writeb(fb_readb(src++), dst++);
  644.     count--;
  645. }
  646. if (dst & 2) {
  647.     fb_writew(fb_readw(src), dst);
  648.     src += 2;
  649.     dst += 2;
  650.     count -= 2;
  651. }
  652. while (count > 3) {
  653.     fb_writel(fb_readl(src), dst);
  654.     src += 4;
  655.     dst += 4;
  656.     count -= 4;
  657. }
  658.     restup:
  659. while (count--)
  660.     fb_writeb(fb_readb(src++), dst++);
  661.     } else {
  662. dst = (unsigned long) d + count;
  663. src = (unsigned long) s + count;
  664. if ((count < 8) || ((dst ^ src) & 3))
  665.     goto restdown;
  666. if (dst & 1) {
  667.     src--;
  668.     dst--;
  669.     count--;
  670.     fb_writeb(fb_readb(src), dst);
  671. }
  672. if (dst & 2) {
  673.     src -= 2;
  674.     dst -= 2;
  675.     count -= 2;
  676.     fb_writew(fb_readw(src), dst);
  677. }
  678. while (count > 3) {
  679.     src -= 4;
  680.     dst -= 4;
  681.     count -= 4;
  682.     fb_writel(fb_readl(src), dst);
  683. }
  684.     restdown:
  685. while (count--) {
  686.     src--;
  687.     dst--;
  688.     fb_writeb(fb_readb(src), dst);
  689. }
  690.     }
  691. }
  692. #endif /* !__i386__ */
  693. #endif /* !__mc68000__ */
  694. #endif /* _VIDEO_FBCON_H */