OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [video/] [fbcon.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.