Subversion Repositories Kolibri OS

Rev

Rev 5078 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6296 serge 1
#include 
2
 
4075 Serge 3
#include 
4
 
5
#include 
6
#include 
6296 serge 7
#include 
8
#include 
4075 Serge 9
 
10
#include "vmwgfx_drv.h"
11
 
6296 serge 12
#include 
4075 Serge 13
 
6296 serge 14
#define VMW_DEV_CLOSE 0
15
#define VMW_DEV_INIT  1
16
#define VMW_DEV_READY 2
17
void cpu_detect1();
18
int kmap_init();
4075 Serge 19
 
6296 serge 20
unsigned long volatile jiffies;
21
int oops_in_progress;
22
int x86_clflush_size;
23
unsigned int tsc_khz;
24
struct workqueue_struct *system_wq;
25
int driver_wq_state;
4111 Serge 26
struct drm_device *main_device;
27
struct drm_file   *drm_file_handlers[256];
6296 serge 28
int kms_modeset = 1;
29
static char  log[256];
4075 Serge 30
 
31
int vmw_init(void);
4111 Serge 32
int kms_init(struct drm_device *dev);
5078 serge 33
void vmw_driver_thread();
4075 Serge 34
 
35
void parse_cmdline(char *cmdline, char *log);
36
int _stdcall display_handler(ioctl_t *io);
6296 serge 37
void kms_update();
38
void vmw_fb_update(struct vmw_private *vmw_priv);
4075 Serge 39
 
40
int gem_getparam(struct drm_device *dev, void *data);
41
 
6296 serge 42
void vmw_driver_thread()
43
{
44
	struct vmw_private *dev_priv = NULL;
45
    struct workqueue_struct *cwq = NULL;
46
    unsigned long irqflags;
4075 Serge 47
 
6296 serge 48
    printf("%s\n",__FUNCTION__);
4075 Serge 49
 
6296 serge 50
    while(driver_wq_state == VMW_DEV_INIT)
51
    {
52
        jiffies = GetClockNs() / 10000000;
53
        delay(1);
54
    };
4075 Serge 55
 
6296 serge 56
    if( driver_wq_state == VMW_DEV_CLOSE)
57
    {
58
        asm volatile ("int $0x40"::"a"(-1));
59
    };
4075 Serge 60
 
6296 serge 61
    dev_priv = main_device->dev_private;
62
    cwq = system_wq;
4075 Serge 63
 
6296 serge 64
    while(driver_wq_state != VMW_DEV_CLOSE )
65
    {
66
        jiffies = GetClockNs() / 10000000;
4075 Serge 67
 
6296 serge 68
 //       kms_update();
69
 
70
        spin_lock_irqsave(&cwq->lock, irqflags);
71
        while (!list_empty(&cwq->worklist))
72
        {
73
            struct work_struct *work = list_entry(cwq->worklist.next,
74
                                        struct work_struct, entry);
75
            work_func_t f = work->func;
76
            list_del_init(cwq->worklist.next);
77
 
78
            spin_unlock_irqrestore(&cwq->lock, irqflags);
79
            f(work);
80
            spin_lock_irqsave(&cwq->lock, irqflags);
81
        }
82
        spin_unlock_irqrestore(&cwq->lock, irqflags);
83
 
84
        vmw_fb_update(dev_priv);
85
        delay(2);
86
    };
87
 
88
    asm volatile ("int $0x40"::"a"(-1));
89
}
90
 
91
u32  __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
4075 Serge 92
{
6296 serge 93
    static pci_dev_t device;
94
    const struct pci_device_id  *ent;
95
    char *safecmdline;
4075 Serge 96
    int     err = 0;
97
 
98
    if(action != 1)
99
    {
6296 serge 100
        driver_wq_state = VMW_DEV_CLOSE;
4075 Serge 101
        return 0;
102
    };
103
 
104
    if( GetService("DISPLAY") != 0 )
105
        return 0;
106
 
107
    if( cmdline && *cmdline )
108
        parse_cmdline(cmdline, log);
109
 
4570 Serge 110
    if( *log && !dbg_open(log))
4075 Serge 111
    {
112
            printf("Can't open %s\nExit\n", log);
113
            return 0;
114
    }
115
 
6296 serge 116
    cpu_detect1();
4570 Serge 117
 
6296 serge 118
    err = enum_pci_devices();
119
    if( unlikely(err != 0) )
120
    {
121
        dbgprintf("Device enumeration failed\n");
122
        return 0;
123
    }
4075 Serge 124
 
6296 serge 125
    err = kmap_init();
126
    if( unlikely(err != 0) )
127
    {
128
        dbgprintf("kmap initialization failed\n");
129
        return 0;
130
    }
4075 Serge 131
 
6296 serge 132
    driver_wq_state = VMW_DEV_INIT;
133
    CreateKernelThread(vmw_driver_thread);
4075 Serge 134
    err = vmw_init();
6296 serge 135
    if(unlikely(err!= 0))
4075 Serge 136
    {
6296 serge 137
        driver_wq_state = VMW_DEV_CLOSE;
4075 Serge 138
        dbgprintf("Epic Fail :(\n");
6296 serge 139
        delay(100);
4075 Serge 140
        return 0;
141
    };
6296 serge 142
LINE();
4075 Serge 143
 
6296 serge 144
    driver_wq_state = VMW_DEV_READY;
145
 
146
//    kms_init(main_device);
147
 
4075 Serge 148
    err = RegService("DISPLAY", display_handler);
149
 
150
    if( err != 0)
151
        dbgprintf("Set DISPLAY handler\n");
152
 
153
 
4111 Serge 154
 
4075 Serge 155
    return err;
156
};
157
 
158
#define CURRENT_API     0x0200      /*      2.00     */
159
#define COMPATIBLE_API  0x0100      /*      1.00     */
160
 
161
#define API_VERSION     (COMPATIBLE_API << 16) | CURRENT_API
162
#define DISPLAY_VERSION  API_VERSION
163
 
164
 
165
#define SRV_GETVERSION          0
166
#define SRV_ENUM_MODES          1
167
#define SRV_SET_MODE            2
168
#define SRV_GET_CAPS            3
6296 serge 169
#define SRV_CMDLINE                 4
4075 Serge 170
 
171
#define SRV_GET_PCI_INFO            20
172
 
173
#define check_input(size) \
174
    if( unlikely((inp==NULL)||(io->inp_size != (size))) )   \
175
        break;
176
 
177
#define check_output(size) \
178
    if( unlikely((outp==NULL)||(io->out_size != (size))) )   \
179
        break;
180
 
181
int _stdcall display_handler(ioctl_t *io)
182
{
183
    struct drm_file *file;
184
 
185
    int    retval = -1;
6296 serge 186
    u32 *inp;
187
    u32 *outp;
4075 Serge 188
 
189
    inp = io->input;
190
    outp = io->output;
191
 
192
    file = drm_file_handlers[0];
193
 
194
    switch(io->io_code)
195
    {
196
        case SRV_GETVERSION:
197
            check_output(4);
198
            *outp  = DISPLAY_VERSION;
199
            retval = 0;
200
            break;
4080 Serge 201
 
4075 Serge 202
        case SRV_ENUM_MODES:
5078 serge 203
 //           dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n",
204
 //                      inp, io->inp_size, io->out_size );
205
 //           check_output(4);
4075 Serge 206
//            check_input(*outp * sizeof(videomode_t));
4080 Serge 207
            if( kms_modeset)
4075 Serge 208
                retval = get_videomodes((videomode_t*)inp, outp);
209
            break;
210
 
211
        case SRV_SET_MODE:
5078 serge 212
//            dbgprintf("SRV_SET_MODE inp %x inp_size %x\n",
213
//                       inp, io->inp_size);
214
//            check_input(sizeof(videomode_t));
4080 Serge 215
            if( kms_modeset )
4075 Serge 216
                retval = set_user_mode((videomode_t*)inp);
217
            break;
218
 
4080 Serge 219
#if 0
4075 Serge 220
        case SRV_GET_CAPS:
221
            retval = get_driver_caps((hwcaps_t*)inp);
222
            break;
223
 
224
 
225
        case SRV_GET_PCI_INFO:
226
            get_pci_info((struct pci_device *)inp);
227
            retval = 0;
228
            break;
229
 
230
        case SRV_GET_PARAM:
231
            retval = gem_getparam(main_device, inp);
232
            break;
233
 
234
        case SRV_I915_GEM_CREATE:
235
            retval = i915_gem_create_ioctl(main_device, inp, file);
236
            break;
237
 
238
        case SRV_DRM_GEM_CLOSE:
239
            retval = drm_gem_close_ioctl(main_device, inp, file);
240
            break;
241
 
242
        case SRV_I915_GEM_PIN:
243
            retval = i915_gem_pin_ioctl(main_device, inp, file);
244
            break;
245
 
246
        case SRV_I915_GEM_SET_CACHEING:
247
            retval = i915_gem_set_caching_ioctl(main_device, inp, file);
248
            break;
249
 
250
        case SRV_I915_GEM_GET_APERTURE:
251
            retval = i915_gem_get_aperture_ioctl(main_device, inp, file);
252
            break;
253
 
254
        case SRV_I915_GEM_PWRITE:
255
            retval = i915_gem_pwrite_ioctl(main_device, inp, file);
256
            break;
257
 
258
        case SRV_I915_GEM_BUSY:
259
            retval = i915_gem_busy_ioctl(main_device, inp, file);
260
            break;
261
 
262
        case SRV_I915_GEM_SET_DOMAIN:
263
            retval = i915_gem_set_domain_ioctl(main_device, inp, file);
264
            break;
265
 
266
        case SRV_I915_GEM_THROTTLE:
267
            retval = i915_gem_throttle_ioctl(main_device, inp, file);
268
            break;
269
 
270
        case SRV_I915_GEM_MMAP:
271
            retval = i915_gem_mmap_ioctl(main_device, inp, file);
272
            break;
273
 
274
        case SRV_I915_GEM_MMAP_GTT:
275
            retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file);
276
            break;
277
 
278
 
279
        case SRV_FBINFO:
280
            retval = i915_fbinfo(inp);
281
            break;
282
 
283
        case SRV_I915_GEM_EXECBUFFER2:
284
            retval = i915_gem_execbuffer2(main_device, inp, file);
285
            break;
286
 
287
        case SRV_MASK_UPDATE:
288
            retval = i915_mask_update(main_device, inp, file);
289
            break;
290
#endif
291
 
292
    };
293
 
294
    return retval;
295
}
296
 
297
 
298
#define PCI_CLASS_REVISION      0x08
299
#define PCI_CLASS_DISPLAY_VGA   0x0300
300
#define PCI_CLASS_BRIDGE_HOST   0x0600
301
#define PCI_CLASS_BRIDGE_ISA    0x0601
302
 
6296 serge 303
int pci_scan_filter(u32 id, u32 busnr, u32 devfn)
4075 Serge 304
{
6296 serge 305
    u16 vendor, device;
306
    u32 class;
4075 Serge 307
    int   ret = 0;
308
 
309
    vendor   = id & 0xffff;
310
    device   = (id >> 16) & 0xffff;
311
 
312
    if(vendor == 0x15AD )
313
    {
314
        class = PciRead32(busnr, devfn, PCI_CLASS_REVISION);
315
        class >>= 16;
316
 
317
        if( class == PCI_CLASS_DISPLAY_VGA )
318
            ret = 1;
319
    }
320
    return ret;
321
};
322
 
323
 
324
static char* parse_path(char *p, char *log)
325
{
326
    char  c;
327
 
328
    while( (c = *p++) == ' ');
329
        p--;
330
    while( (c = *log++ = *p++) && (c != ' '));
331
    *log = 0;
332
 
333
    return p;
334
};
335
 
336
void parse_cmdline(char *cmdline, char *log)
337
{
338
    char *p = cmdline;
339
 
340
    char c = *p++;
341
 
342
    while( c )
343
    {
344
        if( c == '-')
345
        {
346
            switch(*p++)
347
            {
348
                case 'l':
349
                    p = parse_path(p, log);
350
                    break;
351
            };
352
        };
353
        c = *p++;
354
    };
355
};
356
 
6296 serge 357
struct mtrr
358
{
359
    u64  base;
360
    u64  mask;
361
};
4075 Serge 362
 
6296 serge 363
struct cpuinfo
4075 Serge 364
{
6296 serge 365
    u64  caps;
366
    u64  def_mtrr;
367
    u64  mtrr_cap;
368
    int    var_mtrr_count;
369
    int    fix_mtrr_count;
370
    struct mtrr var_mtrr[9];
371
    char   model_name[64];
372
};
4075 Serge 373
 
6296 serge 374
static u32 deftype_lo, deftype_hi;
4075 Serge 375
 
6296 serge 376
void cpu_detect1()
4075 Serge 377
{
6296 serge 378
    struct cpuinfo cpuinfo;
4075 Serge 379
 
380
    u32 junk, tfms, cap0, misc;
6296 serge 381
    int i;
4075 Serge 382
 
383
    cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
384
 
385
    if (cap0 & (1<<19))
386
    {
387
        x86_clflush_size = ((misc >> 8) & 0xff) * 8;
388
    }
389
 
390
    tsc_khz = (unsigned int)(GetCpuFreq()/1000);
391
}
392
 
393
/*
394
int get_driver_caps(hwcaps_t *caps)
395
{
396
    int ret = 0;
397
 
398
    switch(caps->idx)
399
    {
400
        case 0:
401
            caps->opt[0] = 0;
402
            caps->opt[1] = 0;
403
            break;
404
 
405
        case 1:
406
            caps->cap1.max_tex_width  = 4096;
407
            caps->cap1.max_tex_height = 4096;
408
            break;
409
        default:
410
            ret = 1;
411
    };
412
    caps->idx = 1;
413
    return ret;
414
}
415
 
416
 
417
void get_pci_info(struct pci_device *dev)
418
{
419
    struct pci_dev *pdev = main_device->pdev;
420
 
421
    memset(dev, sizeof(*dev), 0);
422
 
423
    dev->domain     = 0;
424
    dev->bus        = pdev->busnr;
425
    dev->dev        = pdev->devfn >> 3;
426
    dev->func       = pdev->devfn & 7;
427
    dev->vendor_id  = pdev->vendor;
428
    dev->device_id  = pdev->device;
429
    dev->revision   = pdev->revision;
430
};
431
 
432
*/
433
 
434
#include 
435
#include 
436
#include 
437
#include 
438
 
439
 
440
 
441
 
4080 Serge 442
#include "vmwgfx_kms.h"
443
 
444
void kms_update();
445
 
446
 
447
extern struct drm_device *main_device;
448
 
449
#define CURSOR_WIDTH 64
450
#define CURSOR_HEIGHT 64
451
 
452
 
5078 serge 453
display_t *os_display;
4111 Serge 454
 
4080 Serge 455
static int count_connector_modes(struct drm_connector* connector)
456
{
457
    struct drm_display_mode  *mode;
458
    int count = 0;
459
 
460
    list_for_each_entry(mode, &connector->modes, head)
461
    {
462
        count++;
463
    };
464
    return count;
465
};
466
 
4570 Serge 467
static void __stdcall restore_cursor(int x, int y){};
468
static void disable_mouse(void) {};
469
 
470
static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
471
{
472
    struct drm_crtc *crtc = os_display->crtc;
473
    struct vmw_private *dev_priv = vmw_priv(crtc->dev);
474
    struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
475
 
5078 serge 476
    du->cursor_x = x;
477
    du->cursor_y = y;
4570 Serge 478
    vmw_cursor_update_position(dev_priv, true, x,y);
479
};
480
 
481
static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
482
{
483
    struct vmw_private *dev_priv = vmw_priv(os_display->ddev);
5078 serge 484
    struct vmw_display_unit *du = vmw_crtc_to_du(os_display->crtc);
4570 Serge 485
    cursor_t *old;
486
 
487
    old = os_display->cursor;
488
    os_display->cursor = cursor;
489
 
490
    vmw_cursor_update_image(dev_priv, cursor->data,
491
                    64, 64, cursor->hot_x, cursor->hot_y);
5078 serge 492
    vmw_cursor_update_position(dev_priv, true,
493
                   du->cursor_x, du->cursor_y);
4570 Serge 494
    return old;
495
};
496
 
4080 Serge 497
int kms_init(struct drm_device *dev)
498
{
499
    struct drm_connector    *connector;
500
    struct drm_encoder      *encoder;
501
    struct drm_crtc         *crtc = NULL;
5078 serge 502
    struct vmw_display_unit *du;
4080 Serge 503
    cursor_t  *cursor;
504
    int        mode_count;
6296 serge 505
    u32        ifl;
4080 Serge 506
    int        err;
507
 
508
    crtc = list_entry(dev->mode_config.crtc_list.next, typeof(*crtc), head);
509
    encoder = list_entry(dev->mode_config.encoder_list.next, typeof(*encoder), head);
510
    connector = list_entry(dev->mode_config.connector_list.next, typeof(*connector), head);
511
    connector->encoder = encoder;
512
 
513
    mode_count = count_connector_modes(connector);
514
    if(mode_count == 0)
515
    {
516
        struct drm_display_mode *mode;
517
 
518
        connector->funcs->fill_modes(connector,
519
                                     dev->mode_config.max_width,
520
                                     dev->mode_config.max_height);
521
 
522
        list_for_each_entry(mode, &connector->modes, head)
523
        mode_count++;
524
    };
525
 
526
    DRM_DEBUG_KMS("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n",
527
               connector, connector->base.id,
528
               connector->status, connector->encoder,
529
               crtc, crtc->base.id );
530
 
531
    os_display = GetDisplay();
532
 
5078 serge 533
    os_display->ddev = dev;
534
    os_display->connector = connector;
535
    os_display->crtc = crtc;
536
    os_display->supported_modes = mode_count;
537
 
4080 Serge 538
    ifl = safe_cli();
539
    {
4570 Serge 540
        os_display->restore_cursor(0,0);
541
        os_display->select_cursor  = select_cursor_kms;
542
        os_display->show_cursor    = NULL;
543
        os_display->move_cursor    = move_cursor_kms;
544
        os_display->restore_cursor = restore_cursor;
545
        os_display->disable_mouse  = disable_mouse;
4080 Serge 546
    };
547
    safe_sti(ifl);
548
 
5078 serge 549
    du = vmw_crtc_to_du(os_display->crtc);
550
    du->cursor_x = os_display->width/2;
551
    du->cursor_y = os_display->height/2;
552
    select_cursor_kms(os_display->cursor);
4080 Serge 553
 
554
    return 0;
555
};
556
 
557
 
558
void kms_update()
559
{
560
    struct vmw_private *dev_priv = vmw_priv(main_device);
561
    size_t fifo_size;
6296 serge 562
    u32    ifl;
4080 Serge 563
    int i;
564
 
565
    struct {
566
        uint32_t header;
567
        SVGAFifoCmdUpdate body;
568
    } *cmd;
569
 
570
    fifo_size = sizeof(*cmd);
571
 
572
    cmd = vmw_fifo_reserve(dev_priv, fifo_size);
573
    if (unlikely(cmd == NULL)) {
574
        DRM_ERROR("Fifo reserve failed.\n");
575
        return;
576
    }
6296 serge 577
    os_display = GetDisplay();
4080 Serge 578
    cmd->header = cpu_to_le32(SVGA_CMD_UPDATE);
579
    cmd->body.x = 0;
580
    cmd->body.y = 0;
5078 serge 581
    cmd->body.width  = os_display->width;
582
    cmd->body.height = os_display->height;
4080 Serge 583
 
584
    vmw_fifo_commit(dev_priv, fifo_size);
585
}
586
 
587
int get_videomodes(videomode_t *mode, int *count)
588
{
5078 serge 589
    struct drm_display_mode  *drmmode;
4080 Serge 590
    int err = -1;
591
 
592
    if( *count == 0 )
593
    {
594
        *count = os_display->supported_modes;
595
        err = 0;
596
    }
597
    else if( mode != NULL )
598
    {
599
        int i = 0;
600
 
601
        if( *count > os_display->supported_modes)
602
            *count = os_display->supported_modes;
603
 
604
        list_for_each_entry(drmmode, &os_display->connector->modes, head)
605
        {
606
            if( i < *count)
607
            {
6296 serge 608
//                mode->width  = drm_mode_width(drmmode);
609
//                mode->height = drm_mode_height(drmmode);
4080 Serge 610
                mode->bpp    = 32;
5078 serge 611
                mode->freq   = drmmode->vrefresh;
4080 Serge 612
                i++;
613
                mode++;
614
            }
615
            else break;
616
        };
5078 serge 617
 
4080 Serge 618
        *count = i;
619
        err = 0;
620
    };
5078 serge 621
 
4080 Serge 622
    return err;
623
};
624
 
625
 
626
bool set_mode(struct drm_device *dev, struct drm_connector *connector,
627
              videomode_t *reqmode, bool strict);
628
 
629
 
630
int set_user_mode(videomode_t *mode)
631
{
632
    int err = -1;
633
 
634
    dbgprintf("width %d height %d vrefresh %d\n",
635
               mode->width, mode->height, mode->freq);
636
 
637
    if( (mode->width  != 0)  &&
638
        (mode->height != 0)  &&
639
        (mode->freq   != 0 ) &&
640
        ( (mode->width   != os_display->width)  ||
641
          (mode->height  != os_display->height) ||
642
          (mode->freq    != os_display->vrefresh) ) )
643
    {
6296 serge 644
//        if( set_mode(os_display->ddev, os_display->connector, mode, true) )
645
//            err = 0;
4080 Serge 646
    };
647
 
648
    return err;
649
};
650
 
4111 Serge 651
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
652
{
653
    struct file *filep;
654
    int count;
655
 
6296 serge 656
    filep = __builtin_malloc(sizeof(*filep));
4111 Serge 657
 
658
    if(unlikely(filep == NULL))
659
        return ERR_PTR(-ENOMEM);
660
 
661
    count = size / PAGE_SIZE;
662
 
663
    filep->pages = kzalloc(sizeof(struct page *) * count, 0);
664
    if(unlikely(filep->pages == NULL))
665
    {
666
        kfree(filep);
667
        return ERR_PTR(-ENOMEM);
668
    };
669
 
670
    filep->count     = count;
671
    filep->allocated = 0;
672
    filep->vma       = NULL;
673
 
674
//    printf("%s file %p pages %p count %d\n",
675
//              __FUNCTION__,filep, filep->pages, count);
676
 
677
    return filep;
678
}
679
 
680
struct page *shmem_read_mapping_page_gfp(struct file *filep,
681
                                         pgoff_t index, gfp_t gfp)
682
{
683
    struct page *page;
684
 
685
//    dbgprintf("%s, file %p index %d\n", __FUNCTION__, filep, index);
686
 
687
    if(unlikely(index >= filep->count))
688
        return ERR_PTR(-EINVAL);
689
 
690
    page = filep->pages[index];
691
 
692
    if(unlikely(page == NULL))
693
    {
694
        page = (struct page *)AllocPage();
695
 
696
        if(unlikely(page == NULL))
697
            return ERR_PTR(-ENOMEM);
698
 
699
        filep->pages[index] = page;
700
    };
701
 
702
    return page;
703
};
704
 
6296 serge 705
ktime_t ktime_get(void)
706
{
707
    ktime_t t;
708
 
709
    t.tv64 = GetClockNs();
710
 
711
    return t;
712
}
713
 
714
bool reservation_object_test_signaled_rcu(struct reservation_object *obj,
715
                                           bool test_all)
716
{
717
    return true;
718
}
719
 
720
int reservation_object_reserve_shared(struct reservation_object *obj)
721
{
722
    return 0;
723
}
724
 
725
void reservation_object_add_shared_fence(struct reservation_object *obj,
726
                                          struct fence *fence)
727
{};
728
 
729
void reservation_object_add_excl_fence(struct reservation_object *obj,
730
                                       struct fence *fence)
731
{};
732
 
733
#define KMAP_MAX    256
734
 
735
static struct mutex kmap_mutex;
736
static struct page* kmap_table[KMAP_MAX];
737
static int kmap_av;
738
static int kmap_first;
739
static void* kmap_base;
740
 
741
 
742
int kmap_init()
743
{
744
    kmap_base = AllocKernelSpace(KMAP_MAX*4096);
745
    if(kmap_base == NULL)
746
        return -1;
747
 
748
    kmap_av = KMAP_MAX;
749
    MutexInit(&kmap_mutex);
750
    return 0;
751
};
752
 
753
void *kmap(struct page *page)
754
{
755
    void *vaddr = NULL;
756
    int i;
757
 
758
    do
759
    {
760
        MutexLock(&kmap_mutex);
761
        if(kmap_av != 0)
762
        {
763
            for(i = kmap_first; i < KMAP_MAX; i++)
764
            {
765
                if(kmap_table[i] == NULL)
766
                {
767
                    kmap_av--;
768
                    kmap_first = i;
769
                    kmap_table[i] = page;
770
                    vaddr = kmap_base + (i<<12);
771
                    MapPage(vaddr,(addr_t)page,3);
772
                    break;
773
                };
774
            };
775
        };
776
        MutexUnlock(&kmap_mutex);
777
    }while(vaddr == NULL);
778
 
779
    return vaddr;
780
};
781
 
782
void *kmap_atomic(struct page *page) __attribute__ ((alias ("kmap")));
783
 
784
void kunmap(struct page *page)
785
{
786
    void *vaddr;
787
    int   i;
788
 
789
    MutexLock(&kmap_mutex);
790
 
791
    for(i = 0; i < KMAP_MAX; i++)
792
    {
793
        if(kmap_table[i] == page)
794
        {
795
            kmap_av++;
796
            if(i < kmap_first)
797
                kmap_first = i;
798
            kmap_table[i] = NULL;
799
            vaddr = kmap_base + (i<<12);
800
            MapPage(vaddr,0,0);
801
            break;
802
        };
803
    };
804
 
805
    MutexUnlock(&kmap_mutex);
806
};
807
 
808
void kunmap_atomic(void *vaddr)
809
{
810
    int i;
811
 
812
    MapPage(vaddr,0,0);
813
 
814
    i = (vaddr - kmap_base) >> 12;
815
 
816
    MutexLock(&kmap_mutex);
817
 
818
    kmap_av++;
819
    if(i < kmap_first)
820
        kmap_first = i;
821
    kmap_table[i] = NULL;
822
 
823
    MutexUnlock(&kmap_mutex);
824
}
825
 
826
 
827
#include 
828
 
829
struct rcu_ctrlblk {
830
        struct rcu_head *rcucblist;     /* List of pending callbacks (CBs). */
831
        struct rcu_head **donetail;     /* ->next pointer of last "done" CB. */
832
        struct rcu_head **curtail;      /* ->next pointer of last CB. */
833
//        RCU_TRACE(long qlen);           /* Number of pending CBs. */
834
//        RCU_TRACE(unsigned long gp_start); /* Start time for stalls. */
835
//        RCU_TRACE(unsigned long ticks_this_gp); /* Statistic for stalls. */
836
//        RCU_TRACE(unsigned long jiffies_stall); /* Jiffies at next stall. */
837
//        RCU_TRACE(const char *name);    /* Name of RCU type. */
838
};
839
 
840
/* Definition for rcupdate control block. */
841
static struct rcu_ctrlblk rcu_sched_ctrlblk = {
842
        .donetail       = &rcu_sched_ctrlblk.rcucblist,
843
        .curtail        = &rcu_sched_ctrlblk.rcucblist,
844
//        RCU_TRACE(.name = "rcu_sched")
845
};
846
 
847
static void __call_rcu(struct rcu_head *head,
848
                       void (*func)(struct rcu_head *rcu),
849
                       struct rcu_ctrlblk *rcp)
850
{
851
        unsigned long flags;
852
 
853
//        debug_rcu_head_queue(head);
854
        head->func = func;
855
        head->next = NULL;
856
 
857
        local_irq_save(flags);
858
        *rcp->curtail = head;
859
        rcp->curtail = &head->next;
860
//        RCU_TRACE(rcp->qlen++);
861
        local_irq_restore(flags);
862
}
863
 
864
/*
865
 * Post an RCU callback to be invoked after the end of an RCU-sched grace
866
 * period.  But since we have but one CPU, that would be after any
867
 * quiescent state.
868
 */
869
void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
870
{
871
        __call_rcu(head, func, &rcu_sched_ctrlblk);
872
}
873
 
874
 
875
fb_get_options(const char *name, char **option)
876
{
877
    return 1;
878
}
879
 
880
static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
881
{
882
        while (bytes) {
883
                if (*start != value)
884
                        return (void *)start;
885
                start++;
886
                bytes--;
887
        }
888
        return NULL;
889
}
890
 
891
/**
892
 * memchr_inv - Find an unmatching character in an area of memory.
893
 * @start: The memory area
894
 * @c: Find a character other than c
895
 * @bytes: The size of the area.
896
 *
897
 * returns the address of the first character other than @c, or %NULL
898
 * if the whole buffer contains just @c.
899
 */
900
void *memchr_inv(const void *start, int c, size_t bytes)
901
{
902
        u8 value = c;
903
        u64 value64;
904
        unsigned int words, prefix;
905
 
906
        if (bytes <= 16)
907
                return check_bytes8(start, value, bytes);
908
 
909
        value64 = value;
910
#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
911
        value64 *= 0x0101010101010101;
912
#elif defined(ARCH_HAS_FAST_MULTIPLIER)
913
        value64 *= 0x01010101;
914
        value64 |= value64 << 32;
915
#else
916
        value64 |= value64 << 8;
917
        value64 |= value64 << 16;
918
        value64 |= value64 << 32;
919
#endif
920
 
921
        prefix = (unsigned long)start % 8;
922
        if (prefix) {
923
                u8 *r;
924
 
925
                prefix = 8 - prefix;
926
                r = check_bytes8(start, value, prefix);
927
                if (r)
928
                        return r;
929
                start += prefix;
930
                bytes -= prefix;
931
        }
932
 
933
        words = bytes / 8;
934
 
935
        while (words) {
936
                if (*(u64 *)start != value64)
937
                        return check_bytes8(start, value, 8);
938
                start += 8;
939
                words--;
940
        }
941
 
942
        return check_bytes8(start, value, bytes % 8);
943
}
944
 
945
 
946
void drm_master_put(struct drm_master **master)
947
{};
948
 
949
 
950
bool ttm_ref_object_exists(struct ttm_object_file *tfile,
951
                           struct ttm_base_object *base)
952
{
953
    return true;
954
};
955
 
956
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
957
{
958
    list_del_init(&wait->task_list);
959
    return 1;
960
}
961
 
962
 
963
struct file *fd_array[32];
964
 
965
struct file *fget(unsigned int fd)
966
{
967
    struct file *file;
968
 
969
    file = fd_array[fd];
970
    get_file_rcu(file);
971
    return file;
972
}
973
 
974
void fput(struct file *file)
975
{
976
    if (atomic_long_dec_and_test(&file->f_count))
977
    {
978
 
979
    }
980
}
981
 
982
struct dma_buf *dma_buf_get(int fd)
983
{
984
        struct file *file;
985
 
986
        file = fget(fd);
987
 
988
        if (!file)
989
                return ERR_PTR(-EBADF);
990
 
991
//        if (!is_dma_buf_file(file)) {
992
//                fput(file);
993
//                return ERR_PTR(-EINVAL);
994
//        }
995
 
996
        return file->private_data;
997
}
998
 
999
int get_unused_fd_flags(unsigned flags)
1000
{
1001
    return 1;
1002
}
1003
 
1004
void fd_install(unsigned int fd, struct file *file)
1005
{
1006
    fd_array[fd] = file;
1007
}
1008
 
1009
int dma_buf_fd(struct dma_buf *dmabuf, int flags)
1010
{
1011
        int fd;
1012
 
1013
        if (!dmabuf || !dmabuf->file)
1014
                return -EINVAL;
1015
 
1016
        fd = get_unused_fd_flags(flags);
1017
        if (fd < 0)
1018
                return fd;
1019
 
1020
        fd_install(fd, dmabuf->file);
1021
 
1022
        return fd;
1023
}
1024
 
1025
void dma_buf_put(struct dma_buf *dmabuf)
1026
{
1027
        if (WARN_ON(!dmabuf || !dmabuf->file))
1028
                return;
1029
 
1030
        fput(dmabuf->file);
1031
}
1032
 
1033
 
1034
struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
1035
{
1036
        struct dma_buf *dmabuf;
1037
        struct reservation_object *resv = exp_info->resv;
1038
        struct file *file;
1039
        size_t alloc_size = sizeof(struct dma_buf);
1040
 
1041
        if (!exp_info->resv)
1042
                alloc_size += sizeof(struct reservation_object);
1043
        else
1044
                /* prevent &dma_buf[1] == dma_buf->resv */
1045
                alloc_size += 1;
1046
 
1047
        if (WARN_ON(!exp_info->priv
1048
                          || !exp_info->ops
1049
                          || !exp_info->ops->map_dma_buf
1050
                          || !exp_info->ops->unmap_dma_buf
1051
                          || !exp_info->ops->release
1052
                          || !exp_info->ops->kmap_atomic
1053
                          || !exp_info->ops->kmap
1054
                          || !exp_info->ops->mmap)) {
1055
                return ERR_PTR(-EINVAL);
1056
        }
1057
 
1058
        dmabuf = kzalloc(alloc_size, GFP_KERNEL);
1059
        if (!dmabuf) {
1060
                return ERR_PTR(-ENOMEM);
1061
        }
1062
 
1063
        dmabuf->priv = exp_info->priv;
1064
        dmabuf->ops = exp_info->ops;
1065
        dmabuf->size = exp_info->size;
1066
        dmabuf->exp_name = exp_info->exp_name;
1067
 
1068
        if (!resv) {
1069
                resv = (struct reservation_object *)&dmabuf[1];
1070
                reservation_object_init(resv);
1071
        }
1072
//        dmabuf->resv = resv;
1073
 
1074
//        file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf,
1075
//                                        exp_info->flags);
1076
//        if (IS_ERR(file)) {
1077
//                kfree(dmabuf);
1078
//                return ERR_CAST(file);
1079
//        }
1080
 
1081
//        file->f_mode |= FMODE_LSEEK;
1082
//        dmabuf->file = file;
1083
 
1084
        mutex_init(&dmabuf->lock);
1085
        INIT_LIST_HEAD(&dmabuf->attachments);
1086
 
1087
//        mutex_lock(&db_list.lock);
1088
//        list_add(&dmabuf->list_node, &db_list.head);
1089
//        mutex_unlock(&db_list.lock);
1090
 
1091
        return dmabuf;
1092
}
1093
 
1094
int dma_map_sg(struct device *dev, struct scatterlist *sglist,
1095
                           int nelems, int dir)
1096
{
1097
    struct scatterlist *s;
1098
    int i;
1099
 
1100
    for_each_sg(sglist, s, nelems, i) {
1101
        s->dma_address = (dma_addr_t)sg_phys(s);
1102
#ifdef CONFIG_NEED_SG_DMA_LENGTH
1103
        s->dma_length  = s->length;
1104
#endif
1105
    }
1106
 
1107
    return nelems;
1108
}
1109
 
1110
void *vmalloc(unsigned long size)
1111
{
1112
    return KernelAlloc(size);
1113
}
1114
 
1115
void vfree(const void *addr)
1116
{
1117
    KernelFree(addr);
1118
}