Subversion Repositories Kolibri OS

Rev

Rev 5354 | Rev 6084 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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