Subversion Repositories Kolibri OS

Rev

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