Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6084 serge 1
#include 
2
 
3031 serge 3
#include 
4
#include 
2338 Serge 5
#include "i915_drv.h"
6
 
2325 Serge 7
#include 
8
#include 
9
#include 
10
#include 
11
 
6088 serge 12
#include "getopt.h"
13
 
2342 Serge 14
#include "bitmap.h"
6088 serge 15
#include "i915_kos32.h"
2340 Serge 16
 
6320 serge 17
#define DRV_NAME "i915 v4.4.5"
6084 serge 18
 
5060 serge 19
#define I915_DEV_CLOSE 0
20
#define I915_DEV_INIT  1
21
#define I915_DEV_READY 2
22
 
6088 serge 23
static int my_atoi(char **cmd);
24
static char* parse_mode(char *p, videomode_t *mode);
5354 serge 25
void cpu_detect1();
26
int kmap_init();
2344 Serge 27
 
5060 serge 28
unsigned long volatile jiffies;
6088 serge 29
int oops_in_progress;
30
int x86_clflush_size;
31
unsigned int tsc_khz;
3482 Serge 32
struct workqueue_struct *system_wq;
3764 Serge 33
int driver_wq_state;
6088 serge 34
struct drm_device *main_device;
35
struct drm_file   *drm_file_handlers[256];
36
videomode_t usermode;
37
extern int __getopt_initialized;
3482 Serge 38
 
4126 Serge 39
void i915_driver_thread()
40
{
5060 serge 41
    struct drm_i915_private *dev_priv = NULL;
42
    struct workqueue_struct *cwq = NULL;
4126 Serge 43
    static int dpms = 1;
44
    static int dpms_lock = 0;
45
    oskey_t   key;
46
    unsigned long irqflags;
47
    int tmp;
48
 
49
    printf("%s\n",__FUNCTION__);
50
 
5060 serge 51
    while(driver_wq_state == I915_DEV_INIT)
52
    {
6084 serge 53
        jiffies = GetClockNs() / 10000000;
5060 serge 54
        delay(1);
55
    };
56
 
6084 serge 57
    if( driver_wq_state == I915_DEV_CLOSE)
58
    {
59
        asm volatile ("int $0x40"::"a"(-1));
60
    };
61
 
5060 serge 62
    dev_priv = main_device->dev_private;
63
 
4126 Serge 64
    asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(1),"c"(1));
65
    asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(4),"c"(0x46),"d"(0x330));
66
    asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(4),"c"(0xC6),"d"(0x330));
67
 
5060 serge 68
    while(driver_wq_state != I915_DEV_CLOSE)
4126 Serge 69
    {
6084 serge 70
        jiffies = GetClockNs() / 10000000;
5060 serge 71
 
4126 Serge 72
        key = get_key();
73
 
74
        if( (key.val != 1) && (key.state == 0x02))
75
        {
76
            if(key.code == 0x46 && dpms_lock == 0)
77
            {
78
                dpms_lock = 1;
79
                if(dpms == 1)
80
                {
81
                    i915_dpms(main_device, DRM_MODE_DPMS_OFF);
82
                    printf("dpms off\n");
83
                }
84
                else
85
                {
86
                    i915_dpms(main_device, DRM_MODE_DPMS_ON);
87
                    printf("dpms on\n");
88
                };
89
                dpms ^= 1;
90
                }
91
            else if(key.code == 0xC6)
92
                dpms_lock = 0;
93
        };
6296 serge 94
        cwq = dev_priv->wq;
4126 Serge 95
 
96
        spin_lock_irqsave(&cwq->lock, irqflags);
6296 serge 97
        while (!list_empty(&cwq->worklist))
98
        {
99
            struct work_struct *work = list_entry(cwq->worklist.next,
100
                                        struct work_struct, entry);
101
            work_func_t f = work->func;
102
            list_del_init(cwq->worklist.next);
4126 Serge 103
 
6296 serge 104
            spin_unlock_irqrestore(&cwq->lock, irqflags);
105
            f(work);
106
            spin_lock_irqsave(&cwq->lock, irqflags);
107
        }
108
        spin_unlock_irqrestore(&cwq->lock, irqflags);
109
 
110
        cwq = dev_priv->hotplug.dp_wq;
111
 
112
        spin_lock_irqsave(&cwq->lock, irqflags);
4126 Serge 113
        while (!list_empty(&cwq->worklist))
114
        {
115
            struct work_struct *work = list_entry(cwq->worklist.next,
116
                                        struct work_struct, entry);
117
            work_func_t f = work->func;
118
            list_del_init(cwq->worklist.next);
119
 
120
            spin_unlock_irqrestore(&cwq->lock, irqflags);
121
            f(work);
122
            spin_lock_irqsave(&cwq->lock, irqflags);
123
        }
124
        spin_unlock_irqrestore(&cwq->lock, irqflags);
125
 
126
        delay(1);
127
    };
128
 
129
    asm volatile ("int $0x40"::"a"(-1));
130
}
131
 
5354 serge 132
u32  __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
2325 Serge 133
{
5060 serge 134
    static pci_dev_t device;
135
    const struct pci_device_id  *ent;
6088 serge 136
    char *safecmdline;
4104 Serge 137
    int err = 0;
2325 Serge 138
 
139
    if(action != 1)
3764 Serge 140
    {
5060 serge 141
        driver_wq_state = I915_DEV_CLOSE;
2325 Serge 142
        return 0;
3764 Serge 143
    };
2325 Serge 144
 
145
    if( GetService("DISPLAY") != 0 )
146
        return 0;
147
 
6283 serge 148
    printf("\n%s build %s %s\nusage: i915 [options]\n",
6084 serge 149
           DRV_NAME, __DATE__, __TIME__);
150
 
6088 serge 151
    printf("--rc6 <-1,0-7>  Enable power-saving render C-state 6.\n"
152
           "                Different stages can be selected via bitmask values\n"
153
           "                (0 = disable; 1 = enable rc6; 2 = enable deep rc6;\n"
154
           "                4 = enable deepest rc6).\n"
155
           "                For example, 3 would enable rc6 and deep rc6,\n"
156
           "                and 7 would enable everything.\n"
157
           "                default: -1 (use per-chip default)\n");
158
    printf("--fbc <-1,0,1>  Enable frame buffer compression for power savings\n"
159
           "                (default: -1 (use per-chip default))\n");
160
    printf("-l\n"
161
           "--log     path to log file\n");
162
    printf("-m\n"
163
           "--mode  set videomode\n");
164
    printf("-v\n"
165
           "--video :x[M][R][-][@][i][m][eDd]\n"
166
           "                set videomode for CONNECTOR\n");
6084 serge 167
 
2340 Serge 168
    if( cmdline && *cmdline )
6088 serge 169
    {
170
        int argc, i, c;
171
        char **argv;
2325 Serge 172
 
6088 serge 173
        safecmdline = __builtin_strdup(cmdline);
174
        printf("cmdline %s\n", safecmdline);
175
 
176
        argc = split_cmdline(safecmdline, NULL);
177
        argv = __builtin_malloc((argc+1)*sizeof(char*));
178
        split_cmdline(safecmdline, argv);
179
        argv[argc] = NULL;
180
 
181
        while(1)
182
        {
183
            static struct option long_options[] =
184
            {
185
                {"log",   required_argument, 0, 'l'},
186
                {"mode",  required_argument, 0, 'm'},
187
                {"video", required_argument, 0, 'v'},
188
                {"rc6", required_argument, 0, OPTION_RC6},
189
                {"fbc", required_argument, 0, OPTION_FBC},
190
                {0, 0, 0, 0}
191
            };
192
 
193
            int option_index = 0;
194
 
6283 serge 195
            c = getopt_long (argc, argv, "l:m:v:",
6088 serge 196
                            long_options, &option_index);
197
 
198
            if (c == -1)
199
                break;
200
 
201
            switch(c)
202
            {
203
                case OPTION_RC6:
204
                    i915.enable_rc6 = my_atoi(&optarg);
205
                    printf("i915.rc6 = %d\n",i915.enable_rc6);
206
                    break;
207
 
208
                case OPTION_FBC:
209
                    i915.enable_fbc = my_atoi(&optarg);
210
                    printf("i915.fbc = %d\n",i915.enable_fbc);
211
                    break;
212
 
213
                case 'l':
214
                    i915.log_file = optarg;
215
                    break;
216
 
217
                case 'm':
218
                    parse_mode(optarg, &usermode);
219
                    break;
220
 
221
                case 'v':
222
                    i915.cmdline_mode = optarg;
223
                    printf("i915.cmdline_mode =%s\n",i915.cmdline_mode);
224
                    break;
225
            }
226
        }
227
    };
228
 
229
    if( i915.log_file && !dbg_open(i915.log_file))
6084 serge 230
    {
6088 serge 231
        printf("Can't open %s\nExit\n", i915.log_file);
6084 serge 232
        return 0;
2325 Serge 233
    }
6084 serge 234
    else
235
    {
236
        dbgprintf("\nLOG: %s build %s %s\n",DRV_NAME,__DATE__, __TIME__);
237
    }
2325 Serge 238
 
5354 serge 239
    cpu_detect1();
2351 Serge 240
 
5060 serge 241
    err = enum_pci_devices();
242
    if( unlikely(err != 0) )
243
    {
244
        dbgprintf("Device enumeration failed\n");
245
        return 0;
246
    }
2325 Serge 247
 
5354 serge 248
    err = kmap_init();
249
    if( unlikely(err != 0) )
250
    {
251
        dbgprintf("kmap initialization failed\n");
252
        return 0;
253
    }
254
 
5097 serge 255
    dmi_scan_machine();
256
 
6320 serge 257
    err = fake_framebuffer_create();
258
    if( unlikely(err != 0))
259
        return 0;
260
 
5060 serge 261
    driver_wq_state = I915_DEV_INIT;
262
    CreateKernelThread(i915_driver_thread);
263
 
2325 Serge 264
    err = i915_init();
5060 serge 265
    if(unlikely(err!= 0))
2338 Serge 266
    {
5060 serge 267
        driver_wq_state = I915_DEV_CLOSE;
3298 Serge 268
        dbgprintf("Epic Fail :(\n");
6084 serge 269
        delay(100);
3298 Serge 270
        return 0;
2338 Serge 271
    };
2325 Serge 272
 
5060 serge 273
    driver_wq_state = I915_DEV_READY;
274
 
4280 Serge 275
    init_display_kms(main_device, &usermode);
276
 
2338 Serge 277
    err = RegService("DISPLAY", display_handler);
2325 Serge 278
 
2338 Serge 279
    if( err != 0)
280
        dbgprintf("Set DISPLAY handler\n");
281
 
2325 Serge 282
    return err;
283
};
284
 
6088 serge 285
int do_command_line(const char* usercmd)
286
{
287
    char *cmdline;
288
    int argc, i, c;
289
    char **argv;
6103 serge 290
    int retval = 0;
3480 Serge 291
 
6088 serge 292
    if( (usercmd == NULL) || (*usercmd == 0) )
293
        return 1;
294
 
295
    cmdline = __builtin_strdup(usercmd);
296
    printf("cmdline %s\n", cmdline);
297
 
298
    argc = split_cmdline(cmdline, NULL);
299
    argv = __builtin_malloc((argc+1)*sizeof(char*));
300
    split_cmdline(cmdline, argv);
301
    argv[argc] = NULL;
302
 
303
    __getopt_initialized = 0;
304
 
305
    while(1)
306
    {
307
        static struct option long_options[] =
308
        {
6103 serge 309
            {"list-connectors",      no_argument,       0, OPTION_CONNECTORS},
310
            {"list-connector-modes", required_argument, 0, OPTION_CONN_MODES},
311
            {"video",                required_argument, 0, 'v'},
6088 serge 312
            {0, 0, 0, 0}
313
        };
314
 
315
        int option_index = 0;
316
 
317
        c = getopt_long (argc, argv, "v:",
318
                        long_options, &option_index);
319
 
320
        if (c == -1)
321
            break;
322
 
323
        switch(c)
324
        {
325
            case 'v':
326
                printf("cmdline_mode %s\n",optarg);
6103 serge 327
                retval = set_cmdline_mode_ext(main_device, optarg);
6088 serge 328
                break;
6103 serge 329
 
330
            case OPTION_CONNECTORS:
331
                list_connectors(main_device);
332
                break;
333
 
334
            case OPTION_CONN_MODES:
335
                retval = list_connector_modes(main_device, optarg);
336
                break;
6088 serge 337
        }
338
    }
339
    __builtin_free(argv);
340
    __builtin_free(cmdline);
341
 
6103 serge 342
    return retval;
6088 serge 343
};
344
 
2344 Serge 345
#define CURRENT_API     0x0200      /*      2.00     */
346
#define COMPATIBLE_API  0x0100      /*      1.00     */
2338 Serge 347
 
2344 Serge 348
#define API_VERSION     (COMPATIBLE_API << 16) | CURRENT_API
2351 Serge 349
#define DISPLAY_VERSION  API_VERSION
2338 Serge 350
 
351
 
6084 serge 352
#define SRV_GETVERSION              0
353
#define SRV_ENUM_MODES              1
354
#define SRV_SET_MODE                2
355
#define SRV_GET_CAPS                3
6088 serge 356
#define SRV_CMDLINE                 4
2342 Serge 357
 
6084 serge 358
#define SRV_GET_PCI_INFO                20
4246 Serge 359
#define SRV_I915_GET_PARAM              21
6084 serge 360
#define SRV_I915_GEM_CREATE             22
361
#define SRV_DRM_GEM_CLOSE               23
4246 Serge 362
#define SRV_DRM_GEM_FLINK               24
363
#define SRV_DRM_GEM_OPEN                25
364
#define SRV_I915_GEM_PIN                26
365
#define SRV_I915_GEM_UNPIN              27
5367 serge 366
#define SRV_I915_GEM_GET_CACHING        28
367
#define SRV_I915_GEM_SET_CACHING        29
368
#define SRV_I915_GEM_PWRITE             30
369
#define SRV_I915_GEM_BUSY               31
370
#define SRV_I915_GEM_SET_DOMAIN         32
371
#define SRV_I915_GEM_MMAP               33
372
#define SRV_I915_GEM_SET_TILING         34
373
#define SRV_I915_GEM_GET_TILING         35
374
#define SRV_I915_GEM_GET_APERTURE       36
375
#define SRV_I915_GEM_MMAP_GTT           37
376
#define SRV_I915_GEM_THROTTLE           38
377
#define SRV_I915_GEM_EXECBUFFER2        39
378
#define SRV_I915_GEM_WAIT               40
379
#define SRV_I915_GEM_CONTEXT_CREATE     41
380
#define SRV_I915_GEM_CONTEXT_DESTROY    42
381
#define SRV_I915_REG_READ               43
3260 Serge 382
 
5367 serge 383
#define SRV_FBINFO                      44
384
#define SRV_MASK_UPDATE                 45
385
#define SRV_MASK_UPDATE_EX              46
3263 Serge 386
 
6131 serge 387
#define SRV_I915_GEM_PREAD              47
388
 
2338 Serge 389
#define check_input(size) \
390
    if( unlikely((inp==NULL)||(io->inp_size != (size))) )   \
391
        break;
392
 
393
#define check_output(size) \
394
    if( unlikely((outp==NULL)||(io->out_size != (size))) )   \
395
        break;
396
 
397
int _stdcall display_handler(ioctl_t *io)
398
{
3255 Serge 399
    struct drm_file *file;
400
 
6084 serge 401
    int  retval = -1;
5354 serge 402
    u32 *inp;
403
    u32 *outp;
2338 Serge 404
 
405
    inp = io->input;
406
    outp = io->output;
407
 
3255 Serge 408
    file = drm_file_handlers[0];
409
 
2338 Serge 410
    switch(io->io_code)
411
    {
412
        case SRV_GETVERSION:
413
            check_output(4);
2344 Serge 414
            *outp  = DISPLAY_VERSION;
2338 Serge 415
            retval = 0;
416
            break;
417
 
418
        case SRV_ENUM_MODES:
3031 serge 419
//            dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n",
420
//                       inp, io->inp_size, io->out_size );
2340 Serge 421
            check_output(4);
2338 Serge 422
//            check_input(*outp * sizeof(videomode_t));
6088 serge 423
            retval = get_videomodes((videomode_t*)inp, outp);
2338 Serge 424
            break;
425
 
426
        case SRV_SET_MODE:
3031 serge 427
//            dbgprintf("SRV_SET_MODE inp %x inp_size %x\n",
428
//                       inp, io->inp_size);
2338 Serge 429
            check_input(sizeof(videomode_t));
6088 serge 430
            retval = set_user_mode((videomode_t*)inp);
2338 Serge 431
            break;
3033 serge 432
 
2351 Serge 433
        case SRV_GET_CAPS:
434
            retval = get_driver_caps((hwcaps_t*)inp);
435
            break;
436
 
6088 serge 437
        case SRV_CMDLINE:
438
            retval = do_command_line((char*)inp);
439
            break;
440
 
3260 Serge 441
        case SRV_GET_PCI_INFO:
3255 Serge 442
            get_pci_info((struct pci_device *)inp);
2338 Serge 443
            retval = 0;
444
            break;
3031 serge 445
 
4246 Serge 446
        case SRV_I915_GET_PARAM:
447
            retval = i915_getparam(main_device, inp, file);
3255 Serge 448
            break;
449
 
450
        case SRV_I915_GEM_CREATE:
451
            retval = i915_gem_create_ioctl(main_device, inp, file);
452
            break;
453
 
454
        case SRV_DRM_GEM_CLOSE:
455
            retval = drm_gem_close_ioctl(main_device, inp, file);
456
            break;
457
 
4246 Serge 458
        case SRV_DRM_GEM_FLINK:
459
            retval = drm_gem_flink_ioctl(main_device, inp, file);
460
            break;
461
 
462
        case SRV_DRM_GEM_OPEN:
463
            retval = drm_gem_open_ioctl(main_device, inp, file);
464
            break;
465
 
5367 serge 466
        case SRV_I915_GEM_GET_CACHING:
467
            retval = i915_gem_get_caching_ioctl(main_device, inp, file);
468
            break;
469
 
4246 Serge 470
        case SRV_I915_GEM_SET_CACHING:
471
            retval = i915_gem_set_caching_ioctl(main_device, inp, file);
3260 Serge 472
            break;
473
 
6131 serge 474
        case SRV_I915_GEM_PREAD:
475
            retval = i915_gem_pread_ioctl(main_device, inp, file);
476
            break;
477
 
3260 Serge 478
        case SRV_I915_GEM_PWRITE:
479
            retval = i915_gem_pwrite_ioctl(main_device, inp, file);
480
            break;
481
 
482
        case SRV_I915_GEM_BUSY:
483
            retval = i915_gem_busy_ioctl(main_device, inp, file);
484
            break;
485
 
486
        case SRV_I915_GEM_SET_DOMAIN:
487
            retval = i915_gem_set_domain_ioctl(main_device, inp, file);
488
            break;
489
 
3263 Serge 490
        case SRV_I915_GEM_MMAP:
491
            retval = i915_gem_mmap_ioctl(main_device, inp, file);
492
            break;
493
 
4246 Serge 494
        case SRV_I915_GEM_SET_TILING:
495
            retval = i915_gem_set_tiling(main_device, inp, file);
496
            break;
497
 
498
        case SRV_I915_GEM_GET_TILING:
499
            retval = i915_gem_get_tiling(main_device, inp, file);
500
            break;
501
 
502
        case SRV_I915_GEM_GET_APERTURE:
503
//            printf("SRV_I915_GEM_GET_APERTURE ");
504
            retval = i915_gem_get_aperture_ioctl(main_device, inp, file);
505
//            printf(" retval=%d\n", retval);
506
            break;
507
 
3480 Serge 508
        case SRV_I915_GEM_MMAP_GTT:
509
            retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file);
510
            break;
511
 
4246 Serge 512
        case SRV_I915_GEM_THROTTLE:
513
            retval = i915_gem_throttle_ioctl(main_device, inp, file);
3263 Serge 514
            break;
515
 
516
        case SRV_I915_GEM_EXECBUFFER2:
517
            retval = i915_gem_execbuffer2(main_device, inp, file);
518
            break;
519
 
4246 Serge 520
        case SRV_I915_GEM_WAIT:
521
            retval = i915_gem_wait_ioctl(main_device, inp, file);
522
            break;
523
 
524
        case SRV_I915_GEM_CONTEXT_CREATE:
525
            retval = i915_gem_context_create_ioctl(main_device, inp, file);
526
            break;
527
 
528
        case SRV_I915_GEM_CONTEXT_DESTROY:
529
            retval = i915_gem_context_destroy_ioctl(main_device, inp, file);
530
            break;
531
 
532
        case SRV_I915_REG_READ:
533
            retval = i915_reg_read_ioctl(main_device, inp, file);
534
            break;
535
 
536
        case SRV_FBINFO:
537
            retval = i915_fbinfo(inp);
538
            break;
539
 
3290 Serge 540
        case SRV_MASK_UPDATE:
541
            retval = i915_mask_update(main_device, inp, file);
542
            break;
4539 Serge 543
 
544
        case SRV_MASK_UPDATE_EX:
545
            retval = i915_mask_update_ex(main_device, inp, file);
546
            break;
2338 Serge 547
    };
548
 
549
    return retval;
550
}
551
 
552
 
2325 Serge 553
#define PCI_CLASS_REVISION      0x08
554
#define PCI_CLASS_DISPLAY_VGA   0x0300
555
#define PCI_CLASS_BRIDGE_HOST   0x0600
2326 Serge 556
#define PCI_CLASS_BRIDGE_ISA    0x0601
2325 Serge 557
 
5354 serge 558
int pci_scan_filter(u32 id, u32 busnr, u32 devfn)
2325 Serge 559
{
5354 serge 560
    u16 vendor, device;
561
    u32 class;
2325 Serge 562
    int   ret = 0;
563
 
564
    vendor   = id & 0xffff;
565
    device   = (id >> 16) & 0xffff;
566
 
567
    if(vendor == 0x8086)
568
    {
569
        class = PciRead32(busnr, devfn, PCI_CLASS_REVISION);
570
        class >>= 16;
571
 
572
        if( (class == PCI_CLASS_DISPLAY_VGA) ||
2326 Serge 573
            (class == PCI_CLASS_BRIDGE_HOST) ||
574
            (class == PCI_CLASS_BRIDGE_ISA))
2325 Serge 575
            ret = 1;
576
    }
577
    return ret;
578
};
2340 Serge 579
 
580
 
5060 serge 581
struct mtrr
582
{
5354 serge 583
    u64  base;
584
    u64  mask;
5060 serge 585
};
586
 
587
struct cpuinfo
588
{
5354 serge 589
    u64  caps;
590
    u64  def_mtrr;
591
    u64  mtrr_cap;
5060 serge 592
    int    var_mtrr_count;
593
    int    fix_mtrr_count;
594
    struct mtrr var_mtrr[9];
595
    char   model_name[64];
596
};
597
 
598
#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
599
#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
600
 
601
#define MSR_MTRRdefType                 0x000002ff
602
 
603
#define IA32_MTRRCAP            0xFE
604
#define IA32_CR_PAT_MSR         0x277
605
 
606
#define PAT_TYPE_UC             0
607
#define PAT_TYPE_WC             1
608
#define PAT_TYPE_WB             6
609
#define PAT_TYPE_UCM            7
610
 
611
 
612
#define MTRR_UC                 0
613
#define MTRR_WC                 1
614
#define MTRR_WB                 6
615
 
5354 serge 616
static inline u64 read_msr(u32 msr)
5060 serge 617
{
618
    union {
5354 serge 619
        u64  val;
5060 serge 620
        struct {
5354 serge 621
            u32 low;
622
            u32 high;
5060 serge 623
        };
624
    }tmp;
625
 
626
    asm volatile (
627
    "rdmsr"
628
    : "=a" (tmp.low), "=d" (tmp.high)
629
    : "c" (msr));
630
    return tmp.val;
631
}
632
 
5354 serge 633
static inline void write_msr(u32 msr, u64 val)
5060 serge 634
{
635
    union {
5354 serge 636
        u64  val;
5060 serge 637
        struct {
5354 serge 638
            u32 low;
639
            u32 high;
5060 serge 640
        };
641
    }tmp;
642
 
643
    tmp.val = val;
644
 
645
    asm volatile (
646
    "wrmsr"
647
    :: "a" (tmp.low), "d" (tmp.high), "c" (msr));
648
}
649
 
650
#define SIZE_OR_MASK_BITS(n)  (~((1ULL << ((n) - PAGE_SHIFT)) - 1))
651
 
652
static void set_mtrr(unsigned int reg, unsigned long base,
653
                 unsigned long size, int type)
654
{
655
    unsigned int base_lo, base_hi, mask_lo, mask_hi;
656
    u64 size_or_mask, size_and_mask;
657
 
658
    size_or_mask = SIZE_OR_MASK_BITS(36);
659
    size_and_mask = 0x00f00000;
660
 
661
    if (size == 0) {
662
        /*
663
         * The invalid bit is kept in the mask, so we simply
664
         * clear the relevant mask register to disable a range.
665
         */
666
        native_write_msr(MTRRphysMask_MSR(reg), 0, 0);
667
    }
668
    else {
669
        base_lo = base << PAGE_SHIFT | type;
670
        base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
671
        mask_lo = -size << PAGE_SHIFT | 0x800;
672
        mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
673
 
674
        native_write_msr(MTRRphysBase_MSR(reg), base_lo, base_hi);
675
        native_write_msr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
676
    };
677
}
678
 
679
 
680
static u32 deftype_lo, deftype_hi;
681
 
5354 serge 682
void cpu_detect1()
2344 Serge 683
{
5060 serge 684
    struct cpuinfo cpuinfo;
685
 
2344 Serge 686
    u32 junk, tfms, cap0, misc;
5060 serge 687
    int i;
5354 serge 688
 
2344 Serge 689
    cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
690
 
691
    if (cap0 & (1<<19))
692
    {
693
        x86_clflush_size = ((misc >> 8) & 0xff) * 8;
694
    }
3482 Serge 695
 
5354 serge 696
#if 0
5060 serge 697
    cpuid(0x80000002, (unsigned int*)&cpuinfo.model_name[0], (unsigned int*)&cpuinfo.model_name[4],
698
          (unsigned int*)&cpuinfo.model_name[8], (unsigned int*)&cpuinfo.model_name[12]);
699
    cpuid(0x80000003, (unsigned int*)&cpuinfo.model_name[16], (unsigned int*)&cpuinfo.model_name[20],
700
          (unsigned int*)&cpuinfo.model_name[24], (unsigned int*)&cpuinfo.model_name[28]);
701
    cpuid(0x80000004, (unsigned int*)&cpuinfo.model_name[32], (unsigned int*)&cpuinfo.model_name[36],
702
          (unsigned int*)&cpuinfo.model_name[40], (unsigned int*)&cpuinfo.model_name[44]);
703
 
704
    printf("\n%s\n\n",cpuinfo.model_name);
705
 
706
    cpuinfo.def_mtrr = read_msr(MSR_MTRRdefType);
707
    cpuinfo.mtrr_cap = read_msr(IA32_MTRRCAP);
708
 
709
    printf("MSR_MTRRdefType %016llx\n\n", cpuinfo.def_mtrr);
710
 
711
    cpuinfo.var_mtrr_count = (u8_t)cpuinfo.mtrr_cap;
712
 
713
    for(i = 0; i < cpuinfo.var_mtrr_count; i++)
714
    {
715
        u64_t mtrr_base;
716
        u64_t mtrr_mask;
717
 
718
        cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i));
719
        cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i));
720
 
721
        printf("MTRR_%d base: %016llx mask: %016llx\n", i,
722
               cpuinfo.var_mtrr[i].base,
723
               cpuinfo.var_mtrr[i].mask);
724
    };
725
 
726
    unsigned int cr0, cr3, cr4, eflags;
727
 
728
    eflags = safe_cli();
729
 
730
    /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
731
    cr0 = read_cr0() | (1<<30);
732
    write_cr0(cr0);
733
    wbinvd();
734
 
735
    cr4 = read_cr4();
736
    write_cr4(cr4 & ~(1<<7));
737
 
738
    cr3 = read_cr3();
739
    write_cr3(cr3);
740
 
741
    /* Save MTRR state */
742
    rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
743
 
744
    /* Disable MTRRs, and set the default type to uncached */
745
    native_write_msr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
746
    wbinvd();
747
 
748
    i = 0;
749
    set_mtrr(i++,0,0x80000000>>12,MTRR_WB);
750
    set_mtrr(i++,0x80000000>>12,0x40000000>>12,MTRR_WB);
751
    set_mtrr(i++,0xC0000000>>12,0x20000000>>12,MTRR_WB);
752
    set_mtrr(i++,0xdb800000>>12,0x00800000>>12,MTRR_UC);
753
    set_mtrr(i++,0xdc000000>>12,0x04000000>>12,MTRR_UC);
754
    set_mtrr(i++,0xE0000000>>12,0x10000000>>12,MTRR_WC);
755
 
756
    for(; i < cpuinfo.var_mtrr_count; i++)
757
        set_mtrr(i,0,0,0);
758
 
759
    write_cr3(cr3);
760
 
761
    /* Intel (P6) standard MTRRs */
762
    native_write_msr(MSR_MTRRdefType, deftype_lo, deftype_hi);
763
 
764
    /* Enable caches */
765
    write_cr0(read_cr0() & ~(1<<30));
766
 
767
    /* Restore value of CR4 */
768
    write_cr4(cr4);
769
 
770
    safe_sti(eflags);
771
 
772
    printf("\nnew MTRR map\n\n");
773
 
774
    for(i = 0; i < cpuinfo.var_mtrr_count; i++)
775
    {
776
        u64_t mtrr_base;
777
        u64_t mtrr_mask;
778
 
779
        cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i));
780
        cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i));
781
 
782
        printf("MTRR_%d base: %016llx mask: %016llx\n", i,
783
               cpuinfo.var_mtrr[i].base,
784
               cpuinfo.var_mtrr[i].mask);
785
    };
786
#endif
787
 
3482 Serge 788
    tsc_khz = (unsigned int)(GetCpuFreq()/1000);
2344 Serge 789
}
790
 
3243 Serge 791
 
792
int get_driver_caps(hwcaps_t *caps)
793
{
794
    int ret = 0;
795
 
796
    switch(caps->idx)
797
    {
798
        case 0:
799
            caps->opt[0] = 0;
800
            caps->opt[1] = 0;
801
            break;
802
 
803
        case 1:
804
            caps->cap1.max_tex_width  = 4096;
805
            caps->cap1.max_tex_height = 4096;
806
            break;
807
        default:
808
            ret = 1;
809
    };
810
    caps->idx = 1;
811
    return ret;
812
}
813
 
3255 Serge 814
 
815
void get_pci_info(struct pci_device *dev)
816
{
817
    struct pci_dev *pdev = main_device->pdev;
818
 
819
    memset(dev, sizeof(*dev), 0);
820
 
821
    dev->domain     = 0;
822
    dev->bus        = pdev->busnr;
823
    dev->dev        = pdev->devfn >> 3;
824
    dev->func       = pdev->devfn & 7;
825
    dev->vendor_id  = pdev->vendor;
826
    dev->device_id  = pdev->device;
827
    dev->revision   = pdev->revision;
828
};
4246 Serge 829
 
830
 
831
 
4280 Serge 832
char *strstr(const char *cs, const char *ct);
833
 
834
static int my_atoi(char **cmd)
835
{
836
    char* p = *cmd;
837
    int val = 0;
838
    int sign = 1;
839
 
840
    if(*p == '-')
841
    {
842
        sign = -1;
843
        p++;
844
    };
845
 
846
    for (;; *p++) {
847
        switch (*p) {
848
        case '0' ... '9':
849
            val = 10*val+(*p-'0');
850
            break;
851
        default:
852
            *cmd = p;
853
            return val*sign;
854
        }
855
    }
856
}
857
 
6088 serge 858
static char* parse_mode(char *p, videomode_t *mode)
4280 Serge 859
{
860
    char c;
861
 
862
    while( (c = *p++) == ' ');
863
 
864
    if( c )
865
    {
866
        p--;
867
 
868
        mode->width = my_atoi(&p);
869
        if(*p == 'x') p++;
870
 
871
        mode->height = my_atoi(&p);
872
        if(*p == 'x') p++;
873
 
874
        mode->bpp = 32;
875
 
876
        mode->freq = my_atoi(&p);
877
 
878
        if( mode->freq == 0 )
879
            mode->freq = 60;
880
    }
881
 
882
    return p;
883
};
884