Subversion Repositories Kolibri OS

Rev

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