Subversion Repositories Kolibri OS

Rev

Rev 5128 | Rev 5367 | 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.  
  253.     return err;
  254. };
  255.  
  256.  
  257. #define CURRENT_API     0x0200      /*      2.00     */
  258. #define COMPATIBLE_API  0x0100      /*      1.00     */
  259.  
  260. #define API_VERSION     (COMPATIBLE_API << 16) | CURRENT_API
  261. #define DISPLAY_VERSION  API_VERSION
  262.  
  263.  
  264. #define SRV_GETVERSION          0
  265. #define SRV_ENUM_MODES          1
  266. #define SRV_SET_MODE            2
  267. #define SRV_GET_CAPS            3
  268.  
  269. #define SRV_CREATE_SURFACE      10
  270. #define SRV_DESTROY_SURFACE     11
  271. #define SRV_LOCK_SURFACE        12
  272. #define SRV_UNLOCK_SURFACE      13
  273. #define SRV_RESIZE_SURFACE      14
  274. #define SRV_BLIT_BITMAP         15
  275. #define SRV_BLIT_TEXTURE        16
  276. #define SRV_BLIT_VIDEO          17
  277.  
  278.  
  279. #define SRV_GET_PCI_INFO            20
  280. #define SRV_I915_GET_PARAM              21
  281. #define SRV_I915_GEM_CREATE         22
  282. #define SRV_DRM_GEM_CLOSE           23
  283. #define SRV_DRM_GEM_FLINK               24
  284. #define SRV_DRM_GEM_OPEN                25
  285. #define SRV_I915_GEM_PIN                26
  286. #define SRV_I915_GEM_UNPIN              27
  287. #define SRV_I915_GEM_SET_CACHING        28
  288. #define SRV_I915_GEM_PWRITE             29
  289. #define SRV_I915_GEM_BUSY               30
  290. #define SRV_I915_GEM_SET_DOMAIN         31
  291. #define SRV_I915_GEM_MMAP               32
  292. #define SRV_I915_GEM_SET_TILING         33
  293. #define SRV_I915_GEM_GET_TILING         34
  294. #define SRV_I915_GEM_GET_APERTURE       35
  295. #define SRV_I915_GEM_MMAP_GTT           36
  296. #define SRV_I915_GEM_THROTTLE           37
  297. #define SRV_I915_GEM_EXECBUFFER2        38
  298. #define SRV_I915_GEM_WAIT               39
  299. #define SRV_I915_GEM_CONTEXT_CREATE     40
  300. #define SRV_I915_GEM_CONTEXT_DESTROY    41
  301. #define SRV_I915_REG_READ               42
  302.  
  303. #define SRV_FBINFO                      43
  304. #define SRV_MASK_UPDATE                 44
  305. #define SRV_MASK_UPDATE_EX              45
  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_SET_CACHING:
  391.             retval = i915_gem_set_caching_ioctl(main_device, inp, file);
  392.             break;
  393.  
  394.         case SRV_I915_GEM_PWRITE:
  395.             retval = i915_gem_pwrite_ioctl(main_device, inp, file);
  396.             break;
  397.  
  398.         case SRV_I915_GEM_BUSY:
  399.             retval = i915_gem_busy_ioctl(main_device, inp, file);
  400.             break;
  401.  
  402.         case SRV_I915_GEM_SET_DOMAIN:
  403.             retval = i915_gem_set_domain_ioctl(main_device, inp, file);
  404.             break;
  405.  
  406.         case SRV_I915_GEM_MMAP:
  407.             retval = i915_gem_mmap_ioctl(main_device, inp, file);
  408.             break;
  409.  
  410.         case SRV_I915_GEM_SET_TILING:
  411.             retval = i915_gem_set_tiling(main_device, inp, file);
  412.             break;
  413.  
  414.         case SRV_I915_GEM_GET_TILING:
  415.             retval = i915_gem_get_tiling(main_device, inp, file);
  416.             break;
  417.  
  418.         case SRV_I915_GEM_GET_APERTURE:
  419. //            printf("SRV_I915_GEM_GET_APERTURE ");
  420.             retval = i915_gem_get_aperture_ioctl(main_device, inp, file);
  421. //            printf(" retval=%d\n", retval);
  422.             break;
  423.  
  424.         case SRV_I915_GEM_MMAP_GTT:
  425.             retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file);
  426.             break;
  427.  
  428.         case SRV_I915_GEM_THROTTLE:
  429.             retval = i915_gem_throttle_ioctl(main_device, inp, file);
  430.             break;
  431.  
  432.         case SRV_I915_GEM_EXECBUFFER2:
  433. //            printf("SRV_I915_GEM_EXECBUFFER2\n");
  434.             retval = i915_gem_execbuffer2(main_device, inp, file);
  435.             break;
  436.  
  437.         case SRV_I915_GEM_WAIT:
  438.             retval = i915_gem_wait_ioctl(main_device, inp, file);
  439.             break;
  440.  
  441.         case SRV_I915_GEM_CONTEXT_CREATE:
  442.             retval = i915_gem_context_create_ioctl(main_device, inp, file);
  443.             break;
  444.  
  445.         case SRV_I915_GEM_CONTEXT_DESTROY:
  446.             retval = i915_gem_context_destroy_ioctl(main_device, inp, file);
  447.             break;
  448.  
  449.         case SRV_I915_REG_READ:
  450.             retval = i915_reg_read_ioctl(main_device, inp, file);
  451.             break;
  452.  
  453.         case SRV_FBINFO:
  454.             retval = i915_fbinfo(inp);
  455.             break;
  456.  
  457.         case SRV_MASK_UPDATE:
  458.             retval = i915_mask_update(main_device, inp, file);
  459.             break;
  460.  
  461.         case SRV_MASK_UPDATE_EX:
  462.             retval = i915_mask_update_ex(main_device, inp, file);
  463.             break;
  464.     };
  465.  
  466.     return retval;
  467. }
  468.  
  469.  
  470. #define PCI_CLASS_REVISION      0x08
  471. #define PCI_CLASS_DISPLAY_VGA   0x0300
  472. #define PCI_CLASS_BRIDGE_HOST   0x0600
  473. #define PCI_CLASS_BRIDGE_ISA    0x0601
  474.  
  475. int pci_scan_filter(u32 id, u32 busnr, u32 devfn)
  476. {
  477.     u16 vendor, device;
  478.     u32 class;
  479.     int   ret = 0;
  480.  
  481.     vendor   = id & 0xffff;
  482.     device   = (id >> 16) & 0xffff;
  483.  
  484.     if(vendor == 0x8086)
  485.     {
  486.         class = PciRead32(busnr, devfn, PCI_CLASS_REVISION);
  487.         class >>= 16;
  488.  
  489.         if( (class == PCI_CLASS_DISPLAY_VGA) ||
  490.             (class == PCI_CLASS_BRIDGE_HOST) ||
  491.             (class == PCI_CLASS_BRIDGE_ISA))
  492.             ret = 1;
  493.     }
  494.     return ret;
  495. };
  496.  
  497.  
  498. struct mtrr
  499. {
  500.     u64  base;
  501.     u64  mask;
  502. };
  503.  
  504. struct cpuinfo
  505. {
  506.     u64  caps;
  507.     u64  def_mtrr;
  508.     u64  mtrr_cap;
  509.     int    var_mtrr_count;
  510.     int    fix_mtrr_count;
  511.     struct mtrr var_mtrr[9];
  512.     char   model_name[64];
  513. };
  514.  
  515. #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
  516. #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
  517.  
  518. #define MSR_MTRRdefType                 0x000002ff
  519.  
  520. #define IA32_MTRRCAP            0xFE
  521. #define IA32_CR_PAT_MSR         0x277
  522.  
  523. #define PAT_TYPE_UC             0
  524. #define PAT_TYPE_WC             1
  525. #define PAT_TYPE_WB             6
  526. #define PAT_TYPE_UCM            7
  527.  
  528.  
  529. #define MTRR_UC                 0
  530. #define MTRR_WC                 1
  531. #define MTRR_WB                 6
  532.  
  533. static inline u64 read_msr(u32 msr)
  534. {
  535.     union {
  536.         u64  val;
  537.         struct {
  538.             u32 low;
  539.             u32 high;
  540.         };
  541.     }tmp;
  542.  
  543.     asm volatile (
  544.     "rdmsr"
  545.     : "=a" (tmp.low), "=d" (tmp.high)
  546.     : "c" (msr));
  547.     return tmp.val;
  548. }
  549.  
  550. static inline void write_msr(u32 msr, u64 val)
  551. {
  552.     union {
  553.         u64  val;
  554.         struct {
  555.             u32 low;
  556.             u32 high;
  557.         };
  558.     }tmp;
  559.  
  560.     tmp.val = val;
  561.  
  562.     asm volatile (
  563.     "wrmsr"
  564.     :: "a" (tmp.low), "d" (tmp.high), "c" (msr));
  565. }
  566.  
  567. #define SIZE_OR_MASK_BITS(n)  (~((1ULL << ((n) - PAGE_SHIFT)) - 1))
  568.  
  569. static void set_mtrr(unsigned int reg, unsigned long base,
  570.                  unsigned long size, int type)
  571. {
  572.     unsigned int base_lo, base_hi, mask_lo, mask_hi;
  573.     u64 size_or_mask, size_and_mask;
  574.  
  575.     size_or_mask = SIZE_OR_MASK_BITS(36);
  576.     size_and_mask = 0x00f00000;
  577.  
  578.     if (size == 0) {
  579.         /*
  580.          * The invalid bit is kept in the mask, so we simply
  581.          * clear the relevant mask register to disable a range.
  582.          */
  583.         native_write_msr(MTRRphysMask_MSR(reg), 0, 0);
  584.     }
  585.     else {
  586.         base_lo = base << PAGE_SHIFT | type;
  587.         base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
  588.         mask_lo = -size << PAGE_SHIFT | 0x800;
  589.         mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
  590.  
  591.         native_write_msr(MTRRphysBase_MSR(reg), base_lo, base_hi);
  592.         native_write_msr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
  593.     };
  594. }
  595.  
  596.  
  597. static u32 deftype_lo, deftype_hi;
  598.  
  599. void cpu_detect1()
  600. {
  601.     struct cpuinfo cpuinfo;
  602.  
  603.     u32 junk, tfms, cap0, misc;
  604.     int i;
  605.  
  606.     cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
  607.  
  608.     if (cap0 & (1<<19))
  609.     {
  610.         x86_clflush_size = ((misc >> 8) & 0xff) * 8;
  611.     }
  612.  
  613. #if 0
  614.     cpuid(0x80000002, (unsigned int*)&cpuinfo.model_name[0], (unsigned int*)&cpuinfo.model_name[4],
  615.           (unsigned int*)&cpuinfo.model_name[8], (unsigned int*)&cpuinfo.model_name[12]);
  616.     cpuid(0x80000003, (unsigned int*)&cpuinfo.model_name[16], (unsigned int*)&cpuinfo.model_name[20],
  617.           (unsigned int*)&cpuinfo.model_name[24], (unsigned int*)&cpuinfo.model_name[28]);
  618.     cpuid(0x80000004, (unsigned int*)&cpuinfo.model_name[32], (unsigned int*)&cpuinfo.model_name[36],
  619.           (unsigned int*)&cpuinfo.model_name[40], (unsigned int*)&cpuinfo.model_name[44]);
  620.  
  621.     printf("\n%s\n\n",cpuinfo.model_name);
  622.  
  623.     cpuinfo.def_mtrr = read_msr(MSR_MTRRdefType);
  624.     cpuinfo.mtrr_cap = read_msr(IA32_MTRRCAP);
  625.  
  626.     printf("MSR_MTRRdefType %016llx\n\n", cpuinfo.def_mtrr);
  627.  
  628.     cpuinfo.var_mtrr_count = (u8_t)cpuinfo.mtrr_cap;
  629.  
  630.     for(i = 0; i < cpuinfo.var_mtrr_count; i++)
  631.     {
  632.         u64_t mtrr_base;
  633.         u64_t mtrr_mask;
  634.  
  635.         cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i));
  636.         cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i));
  637.  
  638.         printf("MTRR_%d base: %016llx mask: %016llx\n", i,
  639.                cpuinfo.var_mtrr[i].base,
  640.                cpuinfo.var_mtrr[i].mask);
  641.     };
  642.  
  643.     unsigned int cr0, cr3, cr4, eflags;
  644.  
  645.     eflags = safe_cli();
  646.  
  647.     /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
  648.     cr0 = read_cr0() | (1<<30);
  649.     write_cr0(cr0);
  650.     wbinvd();
  651.  
  652.     cr4 = read_cr4();
  653.     write_cr4(cr4 & ~(1<<7));
  654.  
  655.     cr3 = read_cr3();
  656.     write_cr3(cr3);
  657.  
  658.     /* Save MTRR state */
  659.     rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
  660.  
  661.     /* Disable MTRRs, and set the default type to uncached */
  662.     native_write_msr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
  663.     wbinvd();
  664.  
  665.     i = 0;
  666.     set_mtrr(i++,0,0x80000000>>12,MTRR_WB);
  667.     set_mtrr(i++,0x80000000>>12,0x40000000>>12,MTRR_WB);
  668.     set_mtrr(i++,0xC0000000>>12,0x20000000>>12,MTRR_WB);
  669.     set_mtrr(i++,0xdb800000>>12,0x00800000>>12,MTRR_UC);
  670.     set_mtrr(i++,0xdc000000>>12,0x04000000>>12,MTRR_UC);
  671.     set_mtrr(i++,0xE0000000>>12,0x10000000>>12,MTRR_WC);
  672.  
  673.     for(; i < cpuinfo.var_mtrr_count; i++)
  674.         set_mtrr(i,0,0,0);
  675.  
  676.     write_cr3(cr3);
  677.  
  678.     /* Intel (P6) standard MTRRs */
  679.     native_write_msr(MSR_MTRRdefType, deftype_lo, deftype_hi);
  680.  
  681.     /* Enable caches */
  682.     write_cr0(read_cr0() & ~(1<<30));
  683.  
  684.     /* Restore value of CR4 */
  685.     write_cr4(cr4);
  686.  
  687.     safe_sti(eflags);
  688.  
  689.     printf("\nnew MTRR map\n\n");
  690.  
  691.     for(i = 0; i < cpuinfo.var_mtrr_count; i++)
  692.     {
  693.         u64_t mtrr_base;
  694.         u64_t mtrr_mask;
  695.  
  696.         cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i));
  697.         cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i));
  698.  
  699.         printf("MTRR_%d base: %016llx mask: %016llx\n", i,
  700.                cpuinfo.var_mtrr[i].base,
  701.                cpuinfo.var_mtrr[i].mask);
  702.     };
  703. #endif
  704.  
  705.     tsc_khz = (unsigned int)(GetCpuFreq()/1000);
  706. }
  707.  
  708.  
  709. int get_driver_caps(hwcaps_t *caps)
  710. {
  711.     int ret = 0;
  712.  
  713.     switch(caps->idx)
  714.     {
  715.         case 0:
  716.             caps->opt[0] = 0;
  717.             caps->opt[1] = 0;
  718.             break;
  719.  
  720.         case 1:
  721.             caps->cap1.max_tex_width  = 4096;
  722.             caps->cap1.max_tex_height = 4096;
  723.             break;
  724.         default:
  725.             ret = 1;
  726.     };
  727.     caps->idx = 1;
  728.     return ret;
  729. }
  730.  
  731.  
  732. void get_pci_info(struct pci_device *dev)
  733. {
  734.     struct pci_dev *pdev = main_device->pdev;
  735.  
  736.     memset(dev, sizeof(*dev), 0);
  737.  
  738.     dev->domain     = 0;
  739.     dev->bus        = pdev->busnr;
  740.     dev->dev        = pdev->devfn >> 3;
  741.     dev->func       = pdev->devfn & 7;
  742.     dev->vendor_id  = pdev->vendor;
  743.     dev->device_id  = pdev->device;
  744.     dev->revision   = pdev->revision;
  745. };
  746.  
  747.  
  748.  
  749. char *strstr(const char *cs, const char *ct);
  750.  
  751. static int my_atoi(char **cmd)
  752. {
  753.     char* p = *cmd;
  754.     int val = 0;
  755.     int sign = 1;
  756.  
  757.     if(*p == '-')
  758.     {
  759.         sign = -1;
  760.         p++;
  761.     };
  762.  
  763.     for (;; *p++) {
  764.         switch (*p) {
  765.         case '0' ... '9':
  766.             val = 10*val+(*p-'0');
  767.             break;
  768.         default:
  769.             *cmd = p;
  770.             return val*sign;
  771.         }
  772.     }
  773. }
  774.  
  775. char* parse_mode(char *p, videomode_t *mode)
  776. {
  777.     char c;
  778.  
  779.     while( (c = *p++) == ' ');
  780.  
  781.     if( c )
  782.     {
  783.         p--;
  784.  
  785.         mode->width = my_atoi(&p);
  786.         if(*p == 'x') p++;
  787.  
  788.         mode->height = my_atoi(&p);
  789.         if(*p == 'x') p++;
  790.  
  791.         mode->bpp = 32;
  792.  
  793.         mode->freq = my_atoi(&p);
  794.  
  795.         if( mode->freq == 0 )
  796.             mode->freq = 60;
  797.     }
  798.  
  799.     return p;
  800. };
  801.  
  802.  
  803. static char* parse_path(char *p, char *log)
  804. {
  805.     char  c;
  806.  
  807.     while( (c = *p++) == ' ');
  808.         p--;
  809.     while((c = *p++) && (c != ' '))
  810.         *log++ = c;
  811.  
  812.     *log = 0;
  813.  
  814.     return p;
  815. };
  816.  
  817. void parse_cmdline(char *cmdline, struct cmdtable *table, char *log, videomode_t *mode)
  818. {
  819.     char *p = cmdline;
  820.     char *p1;
  821.     int val;
  822.     char c = *p++;
  823.  
  824.     if( table )
  825.     {
  826.         while(table->key)
  827.         {
  828.             if(p1 = strstr(cmdline, table->key))
  829.             {
  830.                 p1+= table->size;
  831.                 *table->val = my_atoi(&p1);
  832.             }
  833.             table++;
  834.         }
  835.     }
  836.  
  837.     while( c )
  838.     {
  839.         if( c == '-')
  840.         {
  841.             switch(*p++)
  842.             {
  843.                 case 'l':
  844.                     p = parse_path(p, log);
  845.                     break;
  846.  
  847.                 case 'm':
  848.                     p = parse_mode(p, mode);
  849.                     break;
  850.             };
  851.         };
  852.         c = *p++;
  853.     };
  854. };
  855.  
  856. char *strstr(const char *cs, const char *ct)
  857. {
  858. int d0, d1;
  859. register char *__res;
  860. __asm__ __volatile__(
  861.     "movl %6,%%edi\n\t"
  862.     "repne\n\t"
  863.     "scasb\n\t"
  864.     "notl %%ecx\n\t"
  865.     "decl %%ecx\n\t"    /* NOTE! This also sets Z if searchstring='' */
  866.     "movl %%ecx,%%edx\n"
  867.     "1:\tmovl %6,%%edi\n\t"
  868.     "movl %%esi,%%eax\n\t"
  869.     "movl %%edx,%%ecx\n\t"
  870.     "repe\n\t"
  871.     "cmpsb\n\t"
  872.     "je 2f\n\t"     /* also works for empty string, see above */
  873.     "xchgl %%eax,%%esi\n\t"
  874.     "incl %%esi\n\t"
  875.     "cmpb $0,-1(%%eax)\n\t"
  876.     "jne 1b\n\t"
  877.     "xorl %%eax,%%eax\n\t"
  878.     "2:"
  879.     : "=a" (__res), "=&c" (d0), "=&S" (d1)
  880.     : "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
  881.     : "dx", "di");
  882. return __res;
  883. }
  884.  
  885.