~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/video/fbcon.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.