Subversion Repositories Kolibri OS

Rev

Rev 4570 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4075 Serge 1
#include 
2
#include 
3
 
4
#include 
5
#include 
6
 
7
#include "vmwgfx_drv.h"
8
 
9
#include 
10
#include 
11
#include 
12
#include 
13
 
14
#include "bitmap.h"
15
 
16
struct pci_device {
17
    uint16_t    domain;
18
    uint8_t     bus;
19
    uint8_t     dev;
20
    uint8_t     func;
21
    uint16_t    vendor_id;
22
    uint16_t    device_id;
23
    uint16_t    subvendor_id;
24
    uint16_t    subdevice_id;
25
    uint32_t    device_class;
26
    uint8_t     revision;
27
};
28
 
4111 Serge 29
struct drm_device *main_device;
30
struct drm_file   *drm_file_handlers[256];
4075 Serge 31
 
32
int vmw_init(void);
4111 Serge 33
int kms_init(struct drm_device *dev);
5078 serge 34
void vmw_driver_thread();
4111 Serge 35
void kms_update();
4075 Serge 36
void cpu_detect();
37
 
38
void parse_cmdline(char *cmdline, char *log);
39
int _stdcall display_handler(ioctl_t *io);
40
 
41
 
42
void get_pci_info(struct pci_device *dev);
43
int gem_getparam(struct drm_device *dev, void *data);
44
 
45
int i915_mask_update(struct drm_device *dev, void *data,
46
            struct drm_file *file);
47
 
48
 
49
static char  log[256];
50
 
51
struct workqueue_struct *system_wq;
52
int driver_wq_state;
53
 
54
int x86_clflush_size;
55
unsigned int tsc_khz;
56
 
4080 Serge 57
int kms_modeset = 1;
4075 Serge 58
 
59
u32_t  __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
60
{
61
 
62
    int     err = 0;
63
 
64
    if(action != 1)
65
    {
66
        driver_wq_state = 0;
67
        return 0;
68
    };
69
 
70
    if( GetService("DISPLAY") != 0 )
71
        return 0;
72
 
73
    if( cmdline && *cmdline )
74
        parse_cmdline(cmdline, log);
75
 
4570 Serge 76
    if( *log && !dbg_open(log))
4075 Serge 77
    {
78
            printf("Can't open %s\nExit\n", log);
79
            return 0;
80
    }
81
 
4570 Serge 82
    dbgprintf(" vmw v3.14-rc1\n cmdline: %s\n", cmdline);
83
 
4075 Serge 84
    cpu_detect();
85
    dbgprintf("\ncache line size %d\n", x86_clflush_size);
86
 
87
    enum_pci_devices();
88
 
89
    err = vmw_init();
90
    if(err)
91
    {
92
        dbgprintf("Epic Fail :(\n");
93
        return 0;
94
    };
4111 Serge 95
    kms_init(main_device);
4075 Serge 96
 
97
    err = RegService("DISPLAY", display_handler);
98
 
99
    if( err != 0)
100
        dbgprintf("Set DISPLAY handler\n");
101
 
4111 Serge 102
    driver_wq_state = 1;
4075 Serge 103
 
4111 Serge 104
    CreateKernelThread(vmw_driver_thread);
105
 
4075 Serge 106
    return err;
107
};
108
 
109
 
110
#define CURRENT_API     0x0200      /*      2.00     */
111
#define COMPATIBLE_API  0x0100      /*      1.00     */
112
 
113
#define API_VERSION     (COMPATIBLE_API << 16) | CURRENT_API
114
#define DISPLAY_VERSION  API_VERSION
115
 
116
 
117
#define SRV_GETVERSION          0
118
#define SRV_ENUM_MODES          1
119
#define SRV_SET_MODE            2
120
#define SRV_GET_CAPS            3
121
 
122
#define SRV_CREATE_SURFACE      10
123
#define SRV_DESTROY_SURFACE     11
124
#define SRV_LOCK_SURFACE        12
125
#define SRV_UNLOCK_SURFACE      13
126
#define SRV_RESIZE_SURFACE      14
127
#define SRV_BLIT_BITMAP         15
128
#define SRV_BLIT_TEXTURE        16
129
#define SRV_BLIT_VIDEO          17
130
 
131
 
132
#define SRV_GET_PCI_INFO            20
133
#define SRV_GET_PARAM               21
134
#define SRV_I915_GEM_CREATE         22
135
#define SRV_DRM_GEM_CLOSE           23
136
#define SRV_I915_GEM_PIN            24
137
#define SRV_I915_GEM_SET_CACHEING   25
138
#define SRV_I915_GEM_GET_APERTURE   26
139
#define SRV_I915_GEM_PWRITE         27
140
#define SRV_I915_GEM_BUSY           28
141
#define SRV_I915_GEM_SET_DOMAIN     29
142
#define SRV_I915_GEM_MMAP           30
143
#define SRV_I915_GEM_MMAP_GTT       31
144
#define SRV_I915_GEM_THROTTLE       32
145
#define SRV_FBINFO                  33
146
#define SRV_I915_GEM_EXECBUFFER2    34
147
#define SRV_MASK_UPDATE             35
148
 
149
 
150
 
151
#define check_input(size) \
152
    if( unlikely((inp==NULL)||(io->inp_size != (size))) )   \
153
        break;
154
 
155
#define check_output(size) \
156
    if( unlikely((outp==NULL)||(io->out_size != (size))) )   \
157
        break;
158
 
159
int _stdcall display_handler(ioctl_t *io)
160
{
161
    struct drm_file *file;
162
 
163
    int    retval = -1;
164
    u32_t *inp;
165
    u32_t *outp;
166
 
167
    inp = io->input;
168
    outp = io->output;
169
 
170
    file = drm_file_handlers[0];
171
 
172
    switch(io->io_code)
173
    {
174
        case SRV_GETVERSION:
175
            check_output(4);
176
            *outp  = DISPLAY_VERSION;
177
            retval = 0;
178
            break;
4080 Serge 179
 
4075 Serge 180
        case SRV_ENUM_MODES:
5078 serge 181
 //           dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n",
182
 //                      inp, io->inp_size, io->out_size );
183
 //           check_output(4);
4075 Serge 184
//            check_input(*outp * sizeof(videomode_t));
4080 Serge 185
            if( kms_modeset)
4075 Serge 186
                retval = get_videomodes((videomode_t*)inp, outp);
187
            break;
188
 
189
        case SRV_SET_MODE:
5078 serge 190
//            dbgprintf("SRV_SET_MODE inp %x inp_size %x\n",
191
//                       inp, io->inp_size);
192
//            check_input(sizeof(videomode_t));
4080 Serge 193
            if( kms_modeset )
4075 Serge 194
                retval = set_user_mode((videomode_t*)inp);
195
            break;
196
 
4080 Serge 197
#if 0
4075 Serge 198
        case SRV_GET_CAPS:
199
            retval = get_driver_caps((hwcaps_t*)inp);
200
            break;
201
 
202
        case SRV_CREATE_SURFACE:
203
//            check_input(8);
204
//            retval = create_surface(main_device, (struct io_call_10*)inp);
205
            break;
206
 
207
        case SRV_LOCK_SURFACE:
208
//            retval = lock_surface((struct io_call_12*)inp);
209
            break;
210
 
211
        case SRV_RESIZE_SURFACE:
212
//            retval = resize_surface((struct io_call_14*)inp);
213
            break;
214
 
215
        case SRV_BLIT_BITMAP:
216
//            srv_blit_bitmap( inp[0], inp[1], inp[2],
217
//                        inp[3], inp[4], inp[5], inp[6]);
218
 
219
//            blit_tex( inp[0], inp[1], inp[2],
220
//                    inp[3], inp[4], inp[5], inp[6]);
221
 
222
            break;
223
 
224
        case SRV_GET_PCI_INFO:
225
            get_pci_info((struct pci_device *)inp);
226
            retval = 0;
227
            break;
228
 
229
        case SRV_GET_PARAM:
230
            retval = gem_getparam(main_device, inp);
231
            break;
232
 
233
        case SRV_I915_GEM_CREATE:
234
            retval = i915_gem_create_ioctl(main_device, inp, file);
235
            break;
236
 
237
        case SRV_DRM_GEM_CLOSE:
238
            retval = drm_gem_close_ioctl(main_device, inp, file);
239
            break;
240
 
241
        case SRV_I915_GEM_PIN:
242
            retval = i915_gem_pin_ioctl(main_device, inp, file);
243
            break;
244
 
245
        case SRV_I915_GEM_SET_CACHEING:
246
            retval = i915_gem_set_caching_ioctl(main_device, inp, file);
247
            break;
248
 
249
        case SRV_I915_GEM_GET_APERTURE:
250
            retval = i915_gem_get_aperture_ioctl(main_device, inp, file);
251
            break;
252
 
253
        case SRV_I915_GEM_PWRITE:
254
            retval = i915_gem_pwrite_ioctl(main_device, inp, file);
255
            break;
256
 
257
        case SRV_I915_GEM_BUSY:
258
            retval = i915_gem_busy_ioctl(main_device, inp, file);
259
            break;
260
 
261
        case SRV_I915_GEM_SET_DOMAIN:
262
            retval = i915_gem_set_domain_ioctl(main_device, inp, file);
263
            break;
264
 
265
        case SRV_I915_GEM_THROTTLE:
266
            retval = i915_gem_throttle_ioctl(main_device, inp, file);
267
            break;
268
 
269
        case SRV_I915_GEM_MMAP:
270
            retval = i915_gem_mmap_ioctl(main_device, inp, file);
271
            break;
272
 
273
        case SRV_I915_GEM_MMAP_GTT:
274
            retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file);
275
            break;
276
 
277
 
278
        case SRV_FBINFO:
279
            retval = i915_fbinfo(inp);
280
            break;
281
 
282
        case SRV_I915_GEM_EXECBUFFER2:
283
            retval = i915_gem_execbuffer2(main_device, inp, file);
284
            break;
285
 
286
        case SRV_MASK_UPDATE:
287
            retval = i915_mask_update(main_device, inp, file);
288
            break;
289
#endif
290
 
291
    };
292
 
293
    return retval;
294
}
295
 
296
 
297
#define PCI_CLASS_REVISION      0x08
298
#define PCI_CLASS_DISPLAY_VGA   0x0300
299
#define PCI_CLASS_BRIDGE_HOST   0x0600
300
#define PCI_CLASS_BRIDGE_ISA    0x0601
301
 
302
int pci_scan_filter(u32_t id, u32_t busnr, u32_t devfn)
303
{
304
    u16_t vendor, device;
305
    u32_t class;
306
    int   ret = 0;
307
 
308
    vendor   = id & 0xffff;
309
    device   = (id >> 16) & 0xffff;
310
 
311
    if(vendor == 0x15AD )
312
    {
313
        class = PciRead32(busnr, devfn, PCI_CLASS_REVISION);
314
        class >>= 16;
315
 
316
        if( class == PCI_CLASS_DISPLAY_VGA )
317
            ret = 1;
318
    }
319
    return ret;
320
};
321
 
322
 
323
static char* parse_path(char *p, char *log)
324
{
325
    char  c;
326
 
327
    while( (c = *p++) == ' ');
328
        p--;
329
    while( (c = *log++ = *p++) && (c != ' '));
330
    *log = 0;
331
 
332
    return p;
333
};
334
 
335
void parse_cmdline(char *cmdline, char *log)
336
{
337
    char *p = cmdline;
338
 
339
    char c = *p++;
340
 
341
    while( c )
342
    {
343
        if( c == '-')
344
        {
345
            switch(*p++)
346
            {
347
                case 'l':
348
                    p = parse_path(p, log);
349
                    break;
350
            };
351
        };
352
        c = *p++;
353
    };
354
};
355
 
356
 
357
static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
358
                unsigned int *ecx, unsigned int *edx)
359
{
360
    /* ecx is often an input as well as an output. */
361
    asm volatile("cpuid"
362
        : "=a" (*eax),
363
          "=b" (*ebx),
364
          "=c" (*ecx),
365
          "=d" (*edx)
366
        : "0" (*eax), "2" (*ecx)
367
        : "memory");
368
}
369
 
370
 
371
 
372
static inline void cpuid(unsigned int op,
373
                         unsigned int *eax, unsigned int *ebx,
374
                         unsigned int *ecx, unsigned int *edx)
375
{
376
        *eax = op;
377
        *ecx = 0;
378
        __cpuid(eax, ebx, ecx, edx);
379
}
380
 
381
void cpu_detect()
382
{
383
    u32 junk, tfms, cap0, misc;
384
 
385
    cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
386
 
387
    if (cap0 & (1<<19))
388
    {
389
        x86_clflush_size = ((misc >> 8) & 0xff) * 8;
390
    }
391
 
392
    tsc_khz = (unsigned int)(GetCpuFreq()/1000);
393
}
394
 
395
/*
396
int get_driver_caps(hwcaps_t *caps)
397
{
398
    int ret = 0;
399
 
400
    switch(caps->idx)
401
    {
402
        case 0:
403
            caps->opt[0] = 0;
404
            caps->opt[1] = 0;
405
            break;
406
 
407
        case 1:
408
            caps->cap1.max_tex_width  = 4096;
409
            caps->cap1.max_tex_height = 4096;
410
            break;
411
        default:
412
            ret = 1;
413
    };
414
    caps->idx = 1;
415
    return ret;
416
}
417
 
418
 
419
void get_pci_info(struct pci_device *dev)
420
{
421
    struct pci_dev *pdev = main_device->pdev;
422
 
423
    memset(dev, sizeof(*dev), 0);
424
 
425
    dev->domain     = 0;
426
    dev->bus        = pdev->busnr;
427
    dev->dev        = pdev->devfn >> 3;
428
    dev->func       = pdev->devfn & 7;
429
    dev->vendor_id  = pdev->vendor;
430
    dev->device_id  = pdev->device;
431
    dev->revision   = pdev->revision;
432
};
433
 
434
*/
435
 
436
#include 
437
#include 
438
#include 
439
#include 
440
 
441
 
442
static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
443
{
444
        while (bytes) {
445
                if (*start != value)
446
                        return (void *)start;
447
                start++;
448
                bytes--;
449
        }
450
        return NULL;
451
}
452
 
453
/**
454
 * memchr_inv - Find an unmatching character in an area of memory.
455
 * @start: The memory area
456
 * @c: Find a character other than c
457
 * @bytes: The size of the area.
458
 *
459
 * returns the address of the first character other than @c, or %NULL
460
 * if the whole buffer contains just @c.
461
 */
462
void *memchr_inv(const void *start, int c, size_t bytes)
463
{
464
        u8 value = c;
465
        u64 value64;
466
        unsigned int words, prefix;
467
 
468
        if (bytes <= 16)
469
                return check_bytes8(start, value, bytes);
470
 
471
        value64 = value;
472
#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
473
        value64 *= 0x0101010101010101;
474
#elif defined(ARCH_HAS_FAST_MULTIPLIER)
475
        value64 *= 0x01010101;
476
        value64 |= value64 << 32;
477
#else
478
        value64 |= value64 << 8;
479
        value64 |= value64 << 16;
480
        value64 |= value64 << 32;
481
#endif
482
 
483
        prefix = (unsigned long)start % 8;
484
        if (prefix) {
485
                u8 *r;
486
 
487
                prefix = 8 - prefix;
488
                r = check_bytes8(start, value, prefix);
489
                if (r)
490
                        return r;
491
                start += prefix;
492
                bytes -= prefix;
493
        }
494
 
495
        words = bytes / 8;
496
 
497
        while (words) {
498
                if (*(u64 *)start != value64)
499
                        return check_bytes8(start, value, 8);
500
                start += 8;
501
                words--;
502
        }
503
 
504
        return check_bytes8(start, value, bytes % 8);
505
}
506
 
507
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
508
{
509
    int i;
510
 
511
    i = vsnprintf(buf, size, fmt, args);
512
 
513
    if (likely(i < size))
514
            return i;
515
    if (size != 0)
516
            return size - 1;
517
    return 0;
518
}
519
 
520
 
521
int scnprintf(char *buf, size_t size, const char *fmt, ...)
522
{
523
        va_list args;
524
        int i;
525
 
526
        va_start(args, fmt);
527
        i = vscnprintf(buf, size, fmt, args);
528
        va_end(args);
529
 
530
        return i;
531
}
532
 
533
 
534
 
535
#define _U  0x01    /* upper */
536
#define _L  0x02    /* lower */
537
#define _D  0x04    /* digit */
538
#define _C  0x08    /* cntrl */
539
#define _P  0x10    /* punct */
540
#define _S  0x20    /* white space (space/lf/tab) */
541
#define _X  0x40    /* hex digit */
542
#define _SP 0x80    /* hard space (0x20) */
543
 
544
extern const unsigned char _ctype[];
545
 
546
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
547
 
548
#define isalnum(c)  ((__ismask(c)&(_U|_L|_D)) != 0)
549
#define isalpha(c)  ((__ismask(c)&(_U|_L)) != 0)
550
#define iscntrl(c)  ((__ismask(c)&(_C)) != 0)
551
#define isdigit(c)  ((__ismask(c)&(_D)) != 0)
552
#define isgraph(c)  ((__ismask(c)&(_P|_U|_L|_D)) != 0)
553
#define islower(c)  ((__ismask(c)&(_L)) != 0)
554
#define isprint(c)  ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
555
#define ispunct(c)  ((__ismask(c)&(_P)) != 0)
556
/* Note: isspace() must return false for %NUL-terminator */
557
#define isspace(c)  ((__ismask(c)&(_S)) != 0)
558
#define isupper(c)  ((__ismask(c)&(_U)) != 0)
559
#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
560
 
561
#define isascii(c) (((unsigned char)(c))<=0x7f)
562
#define toascii(c) (((unsigned char)(c))&0x7f)
563
 
564
 
565
 
566
//const char hex_asc[] = "0123456789abcdef";
567
 
568
/**
569
 * hex_to_bin - convert a hex digit to its real value
570
 * @ch: ascii character represents hex digit
571
 *
572
 * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad
573
 * input.
574
 */
575
int hex_to_bin(char ch)
576
{
577
    if ((ch >= '0') && (ch <= '9'))
578
        return ch - '0';
579
    ch = tolower(ch);
580
    if ((ch >= 'a') && (ch <= 'f'))
581
        return ch - 'a' + 10;
582
    return -1;
583
}
584
EXPORT_SYMBOL(hex_to_bin);
585
 
586
/**
587
 * hex2bin - convert an ascii hexadecimal string to its binary representation
588
 * @dst: binary result
589
 * @src: ascii hexadecimal string
590
 * @count: result length
591
 *
592
 * Return 0 on success, -1 in case of bad input.
593
 */
594
int hex2bin(u8 *dst, const char *src, size_t count)
595
{
596
    while (count--) {
597
        int hi = hex_to_bin(*src++);
598
        int lo = hex_to_bin(*src++);
599
 
600
        if ((hi < 0) || (lo < 0))
601
            return -1;
602
 
603
        *dst++ = (hi << 4) | lo;
604
    }
605
    return 0;
606
}
607
EXPORT_SYMBOL(hex2bin);
608
 
609
/**
610
 * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
611
 * @buf: data blob to dump
612
 * @len: number of bytes in the @buf
613
 * @rowsize: number of bytes to print per line; must be 16 or 32
614
 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
615
 * @linebuf: where to put the converted data
616
 * @linebuflen: total size of @linebuf, including space for terminating NUL
617
 * @ascii: include ASCII after the hex output
618
 *
619
 * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
620
 * 16 or 32 bytes of input data converted to hex + ASCII output.
621
 *
622
 * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
623
 * to a hex + ASCII dump at the supplied memory location.
624
 * The converted output is always NUL-terminated.
625
 *
626
 * E.g.:
627
 *   hex_dump_to_buffer(frame->data, frame->len, 16, 1,
628
 *          linebuf, sizeof(linebuf), true);
629
 *
630
 * example output buffer:
631
 * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
632
 */
633
void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
634
            int groupsize, char *linebuf, size_t linebuflen,
635
            bool ascii)
636
{
637
    const u8 *ptr = buf;
638
    u8 ch;
639
    int j, lx = 0;
640
    int ascii_column;
641
 
642
    if (rowsize != 16 && rowsize != 32)
643
        rowsize = 16;
644
 
645
    if (!len)
646
        goto nil;
647
    if (len > rowsize)      /* limit to one line at a time */
648
        len = rowsize;
649
    if ((len % groupsize) != 0) /* no mixed size output */
650
        groupsize = 1;
651
 
652
    switch (groupsize) {
653
    case 8: {
654
        const u64 *ptr8 = buf;
655
        int ngroups = len / groupsize;
656
 
657
        for (j = 0; j < ngroups; j++)
658
            lx += scnprintf(linebuf + lx, linebuflen - lx,
659
                    "%s%16.16llx", j ? " " : "",
660
                    (unsigned long long)*(ptr8 + j));
661
        ascii_column = 17 * ngroups + 2;
662
        break;
663
    }
664
 
665
    case 4: {
666
        const u32 *ptr4 = buf;
667
        int ngroups = len / groupsize;
668
 
669
        for (j = 0; j < ngroups; j++)
670
            lx += scnprintf(linebuf + lx, linebuflen - lx,
671
                    "%s%8.8x", j ? " " : "", *(ptr4 + j));
672
        ascii_column = 9 * ngroups + 2;
673
        break;
674
    }
675
 
676
    case 2: {
677
        const u16 *ptr2 = buf;
678
        int ngroups = len / groupsize;
679
 
680
        for (j = 0; j < ngroups; j++)
681
            lx += scnprintf(linebuf + lx, linebuflen - lx,
682
                    "%s%4.4x", j ? " " : "", *(ptr2 + j));
683
        ascii_column = 5 * ngroups + 2;
684
        break;
685
    }
686
 
687
    default:
688
        for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) {
689
            ch = ptr[j];
690
            linebuf[lx++] = hex_asc_hi(ch);
691
            linebuf[lx++] = hex_asc_lo(ch);
692
            linebuf[lx++] = ' ';
693
        }
694
        if (j)
695
            lx--;
696
 
697
        ascii_column = 3 * rowsize + 2;
698
        break;
699
    }
700
    if (!ascii)
701
        goto nil;
702
 
703
    while (lx < (linebuflen - 1) && lx < (ascii_column - 1))
704
        linebuf[lx++] = ' ';
705
    for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) {
706
        ch = ptr[j];
707
        linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
708
    }
709
nil:
710
    linebuf[lx++] = '\0';
711
}
712
 
713
/**
714
 * print_hex_dump - print a text hex dump to syslog for a binary blob of data
715
 * @level: kernel log level (e.g. KERN_DEBUG)
716
 * @prefix_str: string to prefix each line with;
717
 *  caller supplies trailing spaces for alignment if desired
718
 * @prefix_type: controls whether prefix of an offset, address, or none
719
 *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
720
 * @rowsize: number of bytes to print per line; must be 16 or 32
721
 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
722
 * @buf: data blob to dump
723
 * @len: number of bytes in the @buf
724
 * @ascii: include ASCII after the hex output
725
 *
726
 * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump
727
 * to the kernel log at the specified kernel log level, with an optional
728
 * leading prefix.
729
 *
730
 * print_hex_dump() works on one "line" of output at a time, i.e.,
731
 * 16 or 32 bytes of input data converted to hex + ASCII output.
732
 * print_hex_dump() iterates over the entire input @buf, breaking it into
733
 * "line size" chunks to format and print.
734
 *
735
 * E.g.:
736
 *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
737
 *          16, 1, frame->data, frame->len, true);
738
 *
739
 * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode:
740
 * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
741
 * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode:
742
 * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c  pqrstuvwxyz{|}~.
743
 */
744
void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
745
            int rowsize, int groupsize,
746
            const void *buf, size_t len, bool ascii)
747
{
748
    const u8 *ptr = buf;
749
    int i, linelen, remaining = len;
750
    unsigned char linebuf[32 * 3 + 2 + 32 + 1];
751
 
752
    if (rowsize != 16 && rowsize != 32)
753
        rowsize = 16;
754
 
755
    for (i = 0; i < len; i += rowsize) {
756
        linelen = min(remaining, rowsize);
757
        remaining -= rowsize;
758
 
759
        hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
760
                   linebuf, sizeof(linebuf), ascii);
761
 
762
        switch (prefix_type) {
763
        case DUMP_PREFIX_ADDRESS:
764
            printk("%s%s%p: %s\n",
765
                   level, prefix_str, ptr + i, linebuf);
766
            break;
767
        case DUMP_PREFIX_OFFSET:
768
            printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf);
769
            break;
770
        default:
771
            printk("%s%s%s\n", level, prefix_str, linebuf);
772
            break;
773
        }
774
    }
775
}
776
 
777
void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
778
                          const void *buf, size_t len)
779
{
780
    print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1,
781
                       buf, len, true);
782
}
783
 
784
 
4080 Serge 785
 
786
 
787
 
788
 
789
 
790
 
791
 
792
#include "vmwgfx_kms.h"
793
 
794
void kms_update();
795
 
796
 
797
extern struct drm_device *main_device;
798
 
799
typedef struct
800
{
801
    kobj_t     header;
802
 
803
    uint32_t  *data;
804
    uint32_t   hot_x;
805
    uint32_t   hot_y;
806
 
807
    struct list_head   list;
5078 serge 808
    void      *priv;
4080 Serge 809
}cursor_t;
810
 
811
#define CURSOR_WIDTH 64
812
#define CURSOR_HEIGHT 64
813
 
814
struct tag_display
815
{
816
    int  x;
817
    int  y;
818
    int  width;
819
    int  height;
820
    int  bpp;
821
    int  vrefresh;
822
    int  pitch;
823
    int  lfb;
824
 
825
    int  supported_modes;
826
    struct drm_device    *ddev;
827
    struct drm_connector *connector;
828
    struct drm_crtc      *crtc;
829
 
830
    struct list_head   cursors;
831
 
832
    cursor_t   *cursor;
833
    int       (*init_cursor)(cursor_t*);
834
    cursor_t* (__stdcall *select_cursor)(cursor_t*);
835
    void      (*show_cursor)(int show);
836
    void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
837
    void      (__stdcall *restore_cursor)(int x, int y);
838
    void      (*disable_mouse)(void);
839
    u32  mask_seqno;
840
    u32  check_mouse;
841
    u32  check_m_pixel;
842
};
843
 
5078 serge 844
display_t *os_display;
4111 Serge 845
 
4080 Serge 846
static int count_connector_modes(struct drm_connector* connector)
847
{
848
    struct drm_display_mode  *mode;
849
    int count = 0;
850
 
851
    list_for_each_entry(mode, &connector->modes, head)
852
    {
853
        count++;
854
    };
855
    return count;
856
};
857
 
4570 Serge 858
static void __stdcall restore_cursor(int x, int y){};
859
static void disable_mouse(void) {};
860
 
861
static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
862
{
863
    struct drm_crtc *crtc = os_display->crtc;
864
    struct vmw_private *dev_priv = vmw_priv(crtc->dev);
865
    struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
866
 
5078 serge 867
    du->cursor_x = x;
868
    du->cursor_y = y;
4570 Serge 869
    vmw_cursor_update_position(dev_priv, true, x,y);
870
};
871
 
872
static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
873
{
874
    struct vmw_private *dev_priv = vmw_priv(os_display->ddev);
5078 serge 875
    struct vmw_display_unit *du = vmw_crtc_to_du(os_display->crtc);
4570 Serge 876
    cursor_t *old;
877
 
878
    old = os_display->cursor;
879
    os_display->cursor = cursor;
880
 
881
    vmw_cursor_update_image(dev_priv, cursor->data,
882
                    64, 64, cursor->hot_x, cursor->hot_y);
5078 serge 883
    vmw_cursor_update_position(dev_priv, true,
884
                   du->cursor_x, du->cursor_y);
4570 Serge 885
    return old;
886
};
887
 
5078 serge 888
void vmw_driver_thread()
889
{
890
    DRM_DEBUG_KMS("%s\n",__FUNCTION__);
4570 Serge 891
 
5078 serge 892
    select_cursor_kms(os_display->cursor);
893
 
894
    while(driver_wq_state)
895
    {
896
        kms_update();
897
        delay(2);
898
    };
899
     __asm__ __volatile__ (
900
     "int $0x40"
901
     ::"a"(-1));
902
}
903
 
4080 Serge 904
int kms_init(struct drm_device *dev)
905
{
906
    struct drm_connector    *connector;
907
    struct drm_encoder      *encoder;
908
    struct drm_crtc         *crtc = NULL;
5078 serge 909
    struct vmw_display_unit *du;
4080 Serge 910
    cursor_t  *cursor;
911
    int        mode_count;
912
    u32_t      ifl;
913
    int        err;
914
 
915
    crtc = list_entry(dev->mode_config.crtc_list.next, typeof(*crtc), head);
916
    encoder = list_entry(dev->mode_config.encoder_list.next, typeof(*encoder), head);
917
    connector = list_entry(dev->mode_config.connector_list.next, typeof(*connector), head);
918
    connector->encoder = encoder;
919
 
920
    mode_count = count_connector_modes(connector);
921
    if(mode_count == 0)
922
    {
923
        struct drm_display_mode *mode;
924
 
925
        connector->funcs->fill_modes(connector,
926
                                     dev->mode_config.max_width,
927
                                     dev->mode_config.max_height);
928
 
929
        list_for_each_entry(mode, &connector->modes, head)
930
        mode_count++;
931
    };
932
 
933
    DRM_DEBUG_KMS("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n",
934
               connector, connector->base.id,
935
               connector->status, connector->encoder,
936
               crtc, crtc->base.id );
937
 
938
    os_display = GetDisplay();
939
 
5078 serge 940
    os_display->ddev = dev;
941
    os_display->connector = connector;
942
    os_display->crtc = crtc;
943
    os_display->supported_modes = mode_count;
944
 
4080 Serge 945
    ifl = safe_cli();
946
    {
4570 Serge 947
        os_display->restore_cursor(0,0);
948
        os_display->select_cursor  = select_cursor_kms;
949
        os_display->show_cursor    = NULL;
950
        os_display->move_cursor    = move_cursor_kms;
951
        os_display->restore_cursor = restore_cursor;
952
        os_display->disable_mouse  = disable_mouse;
4080 Serge 953
    };
954
    safe_sti(ifl);
955
 
5078 serge 956
    du = vmw_crtc_to_du(os_display->crtc);
957
    du->cursor_x = os_display->width/2;
958
    du->cursor_y = os_display->height/2;
959
    select_cursor_kms(os_display->cursor);
4080 Serge 960
 
961
    return 0;
962
};
963
 
964
 
965
void kms_update()
966
{
967
    struct vmw_private *dev_priv = vmw_priv(main_device);
968
    size_t fifo_size;
5078 serge 969
    u32_t  ifl;
4080 Serge 970
    int i;
971
 
972
    struct {
973
        uint32_t header;
974
        SVGAFifoCmdUpdate body;
975
    } *cmd;
976
 
977
    fifo_size = sizeof(*cmd);
978
 
979
    cmd = vmw_fifo_reserve(dev_priv, fifo_size);
980
    if (unlikely(cmd == NULL)) {
981
        DRM_ERROR("Fifo reserve failed.\n");
982
        return;
983
    }
984
 
985
    cmd->header = cpu_to_le32(SVGA_CMD_UPDATE);
986
    cmd->body.x = 0;
987
    cmd->body.y = 0;
5078 serge 988
    cmd->body.width  = os_display->width;
989
    cmd->body.height = os_display->height;
4080 Serge 990
 
991
    vmw_fifo_commit(dev_priv, fifo_size);
992
}
993
 
994
int get_videomodes(videomode_t *mode, int *count)
995
{
5078 serge 996
    struct drm_display_mode  *drmmode;
4080 Serge 997
    int err = -1;
998
 
999
    if( *count == 0 )
1000
    {
1001
        *count = os_display->supported_modes;
1002
        err = 0;
1003
    }
1004
    else if( mode != NULL )
1005
    {
1006
        int i = 0;
1007
 
1008
        if( *count > os_display->supported_modes)
1009
            *count = os_display->supported_modes;
1010
 
1011
        list_for_each_entry(drmmode, &os_display->connector->modes, head)
1012
        {
1013
            if( i < *count)
1014
            {
1015
                mode->width  = drm_mode_width(drmmode);
1016
                mode->height = drm_mode_height(drmmode);
1017
                mode->bpp    = 32;
5078 serge 1018
                mode->freq   = drmmode->vrefresh;
4080 Serge 1019
                i++;
1020
                mode++;
1021
            }
1022
            else break;
1023
        };
5078 serge 1024
 
4080 Serge 1025
        *count = i;
1026
        err = 0;
1027
    };
5078 serge 1028
 
4080 Serge 1029
    return err;
1030
};
1031
 
1032
 
1033
bool set_mode(struct drm_device *dev, struct drm_connector *connector,
1034
              videomode_t *reqmode, bool strict);
1035
 
1036
 
1037
int set_user_mode(videomode_t *mode)
1038
{
1039
    int err = -1;
1040
 
1041
    dbgprintf("width %d height %d vrefresh %d\n",
1042
               mode->width, mode->height, mode->freq);
1043
 
1044
    if( (mode->width  != 0)  &&
1045
        (mode->height != 0)  &&
1046
        (mode->freq   != 0 ) &&
1047
        ( (mode->width   != os_display->width)  ||
1048
          (mode->height  != os_display->height) ||
1049
          (mode->freq    != os_display->vrefresh) ) )
1050
    {
1051
        if( set_mode(os_display->ddev, os_display->connector, mode, true) )
1052
            err = 0;
1053
    };
1054
 
1055
    return err;
1056
};
1057
 
4111 Serge 1058
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
1059
{
1060
    struct file *filep;
1061
    int count;
1062
 
1063
    filep = malloc(sizeof(*filep));
1064
 
1065
    if(unlikely(filep == NULL))
1066
        return ERR_PTR(-ENOMEM);
1067
 
1068
    count = size / PAGE_SIZE;
1069
 
1070
    filep->pages = kzalloc(sizeof(struct page *) * count, 0);
1071
    if(unlikely(filep->pages == NULL))
1072
    {
1073
        kfree(filep);
1074
        return ERR_PTR(-ENOMEM);
1075
    };
1076
 
1077
    filep->count     = count;
1078
    filep->allocated = 0;
1079
    filep->vma       = NULL;
1080
 
1081
//    printf("%s file %p pages %p count %d\n",
1082
//              __FUNCTION__,filep, filep->pages, count);
1083
 
1084
    return filep;
1085
}
1086
 
1087
struct page *shmem_read_mapping_page_gfp(struct file *filep,
1088
                                         pgoff_t index, gfp_t gfp)
1089
{
1090
    struct page *page;
1091
 
1092
//    dbgprintf("%s, file %p index %d\n", __FUNCTION__, filep, index);
1093
 
1094
    if(unlikely(index >= filep->count))
1095
        return ERR_PTR(-EINVAL);
1096
 
1097
    page = filep->pages[index];
1098
 
1099
    if(unlikely(page == NULL))
1100
    {
1101
        page = (struct page *)AllocPage();
1102
 
1103
        if(unlikely(page == NULL))
1104
            return ERR_PTR(-ENOMEM);
1105
 
1106
        filep->pages[index] = page;
1107
    };
1108
 
1109
    return page;
1110
};
1111