Subversion Repositories Kolibri OS

Rev

Rev 5060 | Rev 5097 | 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 <errno-base.h>
  9. #include <linux/pci.h>
  10. #include <syscall.h>
  11.  
  12. #include "bitmap.h"
  13.  
  14. #define I915_DEV_CLOSE 0
  15. #define I915_DEV_INIT  1
  16. #define I915_DEV_READY 2
  17.  
  18.  
  19. struct pci_device {
  20.     uint16_t    domain;
  21.     uint8_t     bus;
  22.     uint8_t     dev;
  23.     uint8_t     func;
  24.     uint16_t    vendor_id;
  25.     uint16_t    device_id;
  26.     uint16_t    subvendor_id;
  27.     uint16_t    subdevice_id;
  28.     uint32_t    device_class;
  29.     uint8_t     revision;
  30. };
  31.  
  32. struct drm_device *main_device;
  33. struct drm_file   *drm_file_handlers[256];
  34. videomode_t usermode;
  35.  
  36. void cpu_detect();
  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_t  __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.17-rc3 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_detect();
  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.     driver_wq_state = I915_DEV_INIT;
  224.     CreateKernelThread(i915_driver_thread);
  225.  
  226.     err = i915_init();
  227.     if(unlikely(err!= 0))
  228.     {
  229.         driver_wq_state = I915_DEV_CLOSE;
  230.         dbgprintf("Epic Fail :(\n");
  231.         return 0;
  232.     };
  233.  
  234.     driver_wq_state = I915_DEV_READY;
  235.  
  236.     init_display_kms(main_device, &usermode);
  237.  
  238.     err = RegService("DISPLAY", display_handler);
  239.  
  240.     if( err != 0)
  241.         dbgprintf("Set DISPLAY handler\n");
  242.  
  243.  
  244.     return err;
  245. };
  246.  
  247.  
  248. #define CURRENT_API     0x0200      /*      2.00     */
  249. #define COMPATIBLE_API  0x0100      /*      1.00     */
  250.  
  251. #define API_VERSION     (COMPATIBLE_API << 16) | CURRENT_API
  252. #define DISPLAY_VERSION  API_VERSION
  253.  
  254.  
  255. #define SRV_GETVERSION          0
  256. #define SRV_ENUM_MODES          1
  257. #define SRV_SET_MODE            2
  258. #define SRV_GET_CAPS            3
  259.  
  260. #define SRV_CREATE_SURFACE      10
  261. #define SRV_DESTROY_SURFACE     11
  262. #define SRV_LOCK_SURFACE        12
  263. #define SRV_UNLOCK_SURFACE      13
  264. #define SRV_RESIZE_SURFACE      14
  265. #define SRV_BLIT_BITMAP         15
  266. #define SRV_BLIT_TEXTURE        16
  267. #define SRV_BLIT_VIDEO          17
  268.  
  269.  
  270. #define SRV_GET_PCI_INFO            20
  271. #define SRV_I915_GET_PARAM              21
  272. #define SRV_I915_GEM_CREATE         22
  273. #define SRV_DRM_GEM_CLOSE           23
  274. #define SRV_DRM_GEM_FLINK               24
  275. #define SRV_DRM_GEM_OPEN                25
  276. #define SRV_I915_GEM_PIN                26
  277. #define SRV_I915_GEM_UNPIN              27
  278. #define SRV_I915_GEM_SET_CACHING        28
  279. #define SRV_I915_GEM_PWRITE             29
  280. #define SRV_I915_GEM_BUSY               30
  281. #define SRV_I915_GEM_SET_DOMAIN         31
  282. #define SRV_I915_GEM_MMAP               32
  283. #define SRV_I915_GEM_SET_TILING         33
  284. #define SRV_I915_GEM_GET_TILING         34
  285. #define SRV_I915_GEM_GET_APERTURE       35
  286. #define SRV_I915_GEM_MMAP_GTT           36
  287. #define SRV_I915_GEM_THROTTLE           37
  288. #define SRV_I915_GEM_EXECBUFFER2        38
  289. #define SRV_I915_GEM_WAIT               39
  290. #define SRV_I915_GEM_CONTEXT_CREATE     40
  291. #define SRV_I915_GEM_CONTEXT_DESTROY    41
  292. #define SRV_I915_REG_READ               42
  293.  
  294. #define SRV_FBINFO                      43
  295. #define SRV_MASK_UPDATE                 44
  296. #define SRV_MASK_UPDATE_EX              45
  297.  
  298. #define check_input(size) \
  299.     if( unlikely((inp==NULL)||(io->inp_size != (size))) )   \
  300.         break;
  301.  
  302. #define check_output(size) \
  303.     if( unlikely((outp==NULL)||(io->out_size != (size))) )   \
  304.         break;
  305.  
  306. int _stdcall display_handler(ioctl_t *io)
  307. {
  308.     struct drm_file *file;
  309.  
  310.     int    retval = -1;
  311.     u32_t *inp;
  312.     u32_t *outp;
  313.  
  314.     inp = io->input;
  315.     outp = io->output;
  316.  
  317.     file = drm_file_handlers[0];
  318.  
  319.     switch(io->io_code)
  320.     {
  321.         case SRV_GETVERSION:
  322.             check_output(4);
  323.             *outp  = DISPLAY_VERSION;
  324.             retval = 0;
  325.             break;
  326.  
  327.         case SRV_ENUM_MODES:
  328. //            dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n",
  329. //                       inp, io->inp_size, io->out_size );
  330.             check_output(4);
  331. //            check_input(*outp * sizeof(videomode_t));
  332.             if( i915_modeset)
  333.                 retval = get_videomodes((videomode_t*)inp, outp);
  334.             break;
  335.  
  336.         case SRV_SET_MODE:
  337. //            dbgprintf("SRV_SET_MODE inp %x inp_size %x\n",
  338. //                       inp, io->inp_size);
  339.             check_input(sizeof(videomode_t));
  340.             if( i915_modeset )
  341.                 retval = set_user_mode((videomode_t*)inp);
  342.             break;
  343.  
  344.         case SRV_GET_CAPS:
  345.             retval = get_driver_caps((hwcaps_t*)inp);
  346.             break;
  347.  
  348.         case SRV_GET_PCI_INFO:
  349.             get_pci_info((struct pci_device *)inp);
  350.             retval = 0;
  351.             break;
  352.  
  353.         case SRV_I915_GET_PARAM:
  354.             retval = i915_getparam(main_device, inp, file);
  355.             break;
  356.  
  357.         case SRV_I915_GEM_CREATE:
  358.             retval = i915_gem_create_ioctl(main_device, inp, file);
  359.             break;
  360.  
  361.         case SRV_DRM_GEM_CLOSE:
  362.             retval = drm_gem_close_ioctl(main_device, inp, file);
  363.             break;
  364.  
  365.         case SRV_DRM_GEM_FLINK:
  366.             retval = drm_gem_flink_ioctl(main_device, inp, file);
  367.             break;
  368.  
  369.         case SRV_DRM_GEM_OPEN:
  370.             retval = drm_gem_open_ioctl(main_device, inp, file);
  371.             break;
  372.  
  373.         case SRV_I915_GEM_PIN:
  374.             retval = i915_gem_pin_ioctl(main_device, inp, file);
  375.             break;
  376.  
  377.         case SRV_I915_GEM_UNPIN:
  378.             retval = i915_gem_unpin_ioctl(main_device, inp, file);
  379.             break;
  380.  
  381.         case SRV_I915_GEM_SET_CACHING:
  382.             retval = i915_gem_set_caching_ioctl(main_device, inp, file);
  383.             break;
  384.  
  385.         case SRV_I915_GEM_PWRITE:
  386.             retval = i915_gem_pwrite_ioctl(main_device, inp, file);
  387.             break;
  388.  
  389.         case SRV_I915_GEM_BUSY:
  390.             retval = i915_gem_busy_ioctl(main_device, inp, file);
  391.             break;
  392.  
  393.         case SRV_I915_GEM_SET_DOMAIN:
  394.             retval = i915_gem_set_domain_ioctl(main_device, inp, file);
  395.             break;
  396.  
  397.         case SRV_I915_GEM_MMAP:
  398.             retval = i915_gem_mmap_ioctl(main_device, inp, file);
  399.             break;
  400.  
  401.         case SRV_I915_GEM_SET_TILING:
  402.             retval = i915_gem_set_tiling(main_device, inp, file);
  403.             break;
  404.  
  405.         case SRV_I915_GEM_GET_TILING:
  406.             retval = i915_gem_get_tiling(main_device, inp, file);
  407.             break;
  408.  
  409.         case SRV_I915_GEM_GET_APERTURE:
  410. //            printf("SRV_I915_GEM_GET_APERTURE ");
  411.             retval = i915_gem_get_aperture_ioctl(main_device, inp, file);
  412. //            printf(" retval=%d\n", retval);
  413.             break;
  414.  
  415.         case SRV_I915_GEM_MMAP_GTT:
  416.             retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file);
  417.             break;
  418.  
  419.         case SRV_I915_GEM_THROTTLE:
  420.             retval = i915_gem_throttle_ioctl(main_device, inp, file);
  421.             break;
  422.  
  423.         case SRV_I915_GEM_EXECBUFFER2:
  424. //            printf("SRV_I915_GEM_EXECBUFFER2\n");
  425.             retval = i915_gem_execbuffer2(main_device, inp, file);
  426.             break;
  427.  
  428.         case SRV_I915_GEM_WAIT:
  429.             retval = i915_gem_wait_ioctl(main_device, inp, file);
  430.             break;
  431.  
  432.         case SRV_I915_GEM_CONTEXT_CREATE:
  433.             retval = i915_gem_context_create_ioctl(main_device, inp, file);
  434.             break;
  435.  
  436.         case SRV_I915_GEM_CONTEXT_DESTROY:
  437.             retval = i915_gem_context_destroy_ioctl(main_device, inp, file);
  438.             break;
  439.  
  440.         case SRV_I915_REG_READ:
  441.             retval = i915_reg_read_ioctl(main_device, inp, file);
  442.             break;
  443.  
  444.         case SRV_FBINFO:
  445.             retval = i915_fbinfo(inp);
  446.             break;
  447.  
  448.         case SRV_MASK_UPDATE:
  449.             retval = i915_mask_update(main_device, inp, file);
  450.             break;
  451.  
  452.         case SRV_MASK_UPDATE_EX:
  453.             retval = i915_mask_update_ex(main_device, inp, file);
  454.             break;
  455.     };
  456.  
  457.     return retval;
  458. }
  459.  
  460.  
  461. #define PCI_CLASS_REVISION      0x08
  462. #define PCI_CLASS_DISPLAY_VGA   0x0300
  463. #define PCI_CLASS_BRIDGE_HOST   0x0600
  464. #define PCI_CLASS_BRIDGE_ISA    0x0601
  465.  
  466. int pci_scan_filter(u32_t id, u32_t busnr, u32_t devfn)
  467. {
  468.     u16_t vendor, device;
  469.     u32_t class;
  470.     int   ret = 0;
  471.  
  472.     vendor   = id & 0xffff;
  473.     device   = (id >> 16) & 0xffff;
  474.  
  475.     if(vendor == 0x8086)
  476.     {
  477.         class = PciRead32(busnr, devfn, PCI_CLASS_REVISION);
  478.         class >>= 16;
  479.  
  480.         if( (class == PCI_CLASS_DISPLAY_VGA) ||
  481.             (class == PCI_CLASS_BRIDGE_HOST) ||
  482.             (class == PCI_CLASS_BRIDGE_ISA))
  483.             ret = 1;
  484.     }
  485.     return ret;
  486. };
  487.  
  488.  
  489.  
  490.  
  491. static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
  492.                 unsigned int *ecx, unsigned int *edx)
  493. {
  494.     /* ecx is often an input as well as an output. */
  495.     asm volatile("cpuid"
  496.         : "=a" (*eax),
  497.           "=b" (*ebx),
  498.           "=c" (*ecx),
  499.           "=d" (*edx)
  500.         : "0" (*eax), "2" (*ecx)
  501.         : "memory");
  502. }
  503.  
  504.  
  505.  
  506. static inline void cpuid(unsigned int op,
  507.                          unsigned int *eax, unsigned int *ebx,
  508.                          unsigned int *ecx, unsigned int *edx)
  509. {
  510.         *eax = op;
  511.         *ecx = 0;
  512.         __cpuid(eax, ebx, ecx, edx);
  513. }
  514.  
  515. struct mtrr
  516. {
  517.     u64_t  base;
  518.     u64_t  mask;
  519. };
  520.  
  521. struct cpuinfo
  522. {
  523.     u64_t  caps;
  524.     u64_t  def_mtrr;
  525.     u64_t  mtrr_cap;
  526.     int    var_mtrr_count;
  527.     int    fix_mtrr_count;
  528.     struct mtrr var_mtrr[9];
  529.     char   model_name[64];
  530. };
  531.  
  532. #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
  533. #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
  534.  
  535. #define MSR_MTRRdefType                 0x000002ff
  536.  
  537. #define IA32_MTRRCAP            0xFE
  538. #define IA32_CR_PAT_MSR         0x277
  539.  
  540. #define PAT_TYPE_UC             0
  541. #define PAT_TYPE_WC             1
  542. #define PAT_TYPE_WB             6
  543. #define PAT_TYPE_UCM            7
  544.  
  545.  
  546. #define MTRR_UC                 0
  547. #define MTRR_WC                 1
  548. #define MTRR_WB                 6
  549.  
  550. static inline u64_t read_msr(u32_t msr)
  551. {
  552.     union {
  553.         u64_t  val;
  554.         struct {
  555.             u32_t low;
  556.             u32_t high;
  557.         };
  558.     }tmp;
  559.  
  560.     asm volatile (
  561.     "rdmsr"
  562.     : "=a" (tmp.low), "=d" (tmp.high)
  563.     : "c" (msr));
  564.     return tmp.val;
  565. }
  566.  
  567. static inline void write_msr(u32_t msr, u64_t val)
  568. {
  569.     union {
  570.         u64_t  val;
  571.         struct {
  572.             u32_t low;
  573.             u32_t high;
  574.         };
  575.     }tmp;
  576.  
  577.     tmp.val = val;
  578.  
  579.     asm volatile (
  580.     "wrmsr"
  581.     :: "a" (tmp.low), "d" (tmp.high), "c" (msr));
  582. }
  583.  
  584. #define rdmsr(msr, low, high)                                   \
  585. do {                                                            \
  586.        u64 __val = read_msr((msr));                     \
  587.        (void)((low) = (u32)__val);                             \
  588.        (void)((high) = (u32)(__val >> 32));                    \
  589. } while (0)
  590.  
  591. static inline void native_write_msr(unsigned int msr,
  592.                                     unsigned low, unsigned high)
  593. {
  594.     asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
  595. }
  596.  
  597. static inline void wbinvd(void)
  598. {
  599.     asm volatile("wbinvd": : :"memory");
  600. }
  601.  
  602. #define SIZE_OR_MASK_BITS(n)  (~((1ULL << ((n) - PAGE_SHIFT)) - 1))
  603.  
  604. static void set_mtrr(unsigned int reg, unsigned long base,
  605.                  unsigned long size, int type)
  606. {
  607.     unsigned int base_lo, base_hi, mask_lo, mask_hi;
  608.     u64 size_or_mask, size_and_mask;
  609.  
  610.     size_or_mask = SIZE_OR_MASK_BITS(36);
  611.     size_and_mask = 0x00f00000;
  612.  
  613.     if (size == 0) {
  614.         /*
  615.          * The invalid bit is kept in the mask, so we simply
  616.          * clear the relevant mask register to disable a range.
  617.          */
  618.         native_write_msr(MTRRphysMask_MSR(reg), 0, 0);
  619.     }
  620.     else {
  621.         base_lo = base << PAGE_SHIFT | type;
  622.         base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
  623.         mask_lo = -size << PAGE_SHIFT | 0x800;
  624.         mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
  625.  
  626.         native_write_msr(MTRRphysBase_MSR(reg), base_lo, base_hi);
  627.         native_write_msr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
  628.     };
  629. }
  630.  
  631. static unsigned long __force_order;
  632.  
  633. static inline unsigned long read_cr0(void)
  634. {
  635.     unsigned long val;
  636.     asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
  637.     return val;
  638. }
  639.  
  640. static inline void write_cr0(unsigned long val)
  641. {
  642.     asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order));
  643. }
  644.  
  645. static inline unsigned long read_cr4(void)
  646. {
  647.     unsigned long val;
  648.     asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
  649.     return val;
  650. }
  651.  
  652. static inline void write_cr4(unsigned long val)
  653. {
  654.     asm volatile("mov %0,%%cr4": : "r" (val), "m" (__force_order));
  655. }
  656.  
  657. static inline unsigned long read_cr3(void)
  658. {
  659.     unsigned long val;
  660.     asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));
  661.     return val;
  662. }
  663.  
  664. static inline void write_cr3(unsigned long val)
  665. {
  666.     asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order));
  667. }
  668.  
  669. static u32 deftype_lo, deftype_hi;
  670.  
  671. void cpu_detect()
  672. {
  673.     struct cpuinfo cpuinfo;
  674.  
  675.     u32 junk, tfms, cap0, misc;
  676.     int i;
  677. #if 0
  678.     cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
  679.  
  680.     if (cap0 & (1<<19))
  681.     {
  682.         x86_clflush_size = ((misc >> 8) & 0xff) * 8;
  683.     }
  684.  
  685.     cpuid(0x80000002, (unsigned int*)&cpuinfo.model_name[0], (unsigned int*)&cpuinfo.model_name[4],
  686.           (unsigned int*)&cpuinfo.model_name[8], (unsigned int*)&cpuinfo.model_name[12]);
  687.     cpuid(0x80000003, (unsigned int*)&cpuinfo.model_name[16], (unsigned int*)&cpuinfo.model_name[20],
  688.           (unsigned int*)&cpuinfo.model_name[24], (unsigned int*)&cpuinfo.model_name[28]);
  689.     cpuid(0x80000004, (unsigned int*)&cpuinfo.model_name[32], (unsigned int*)&cpuinfo.model_name[36],
  690.           (unsigned int*)&cpuinfo.model_name[40], (unsigned int*)&cpuinfo.model_name[44]);
  691.  
  692.     printf("\n%s\n\n",cpuinfo.model_name);
  693.  
  694.     cpuinfo.def_mtrr = read_msr(MSR_MTRRdefType);
  695.     cpuinfo.mtrr_cap = read_msr(IA32_MTRRCAP);
  696.  
  697.     printf("MSR_MTRRdefType %016llx\n\n", cpuinfo.def_mtrr);
  698.  
  699.     cpuinfo.var_mtrr_count = (u8_t)cpuinfo.mtrr_cap;
  700.  
  701.     for(i = 0; i < cpuinfo.var_mtrr_count; i++)
  702.     {
  703.         u64_t mtrr_base;
  704.         u64_t mtrr_mask;
  705.  
  706.         cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i));
  707.         cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i));
  708.  
  709.         printf("MTRR_%d base: %016llx mask: %016llx\n", i,
  710.                cpuinfo.var_mtrr[i].base,
  711.                cpuinfo.var_mtrr[i].mask);
  712.     };
  713.  
  714.     unsigned int cr0, cr3, cr4, eflags;
  715.  
  716.     eflags = safe_cli();
  717.  
  718.     /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
  719.     cr0 = read_cr0() | (1<<30);
  720.     write_cr0(cr0);
  721.     wbinvd();
  722.  
  723.     cr4 = read_cr4();
  724.     write_cr4(cr4 & ~(1<<7));
  725.  
  726.     cr3 = read_cr3();
  727.     write_cr3(cr3);
  728.  
  729.     /* Save MTRR state */
  730.     rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
  731.  
  732.     /* Disable MTRRs, and set the default type to uncached */
  733.     native_write_msr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
  734.     wbinvd();
  735.  
  736.     i = 0;
  737.     set_mtrr(i++,0,0x80000000>>12,MTRR_WB);
  738.     set_mtrr(i++,0x80000000>>12,0x40000000>>12,MTRR_WB);
  739.     set_mtrr(i++,0xC0000000>>12,0x20000000>>12,MTRR_WB);
  740.     set_mtrr(i++,0xdb800000>>12,0x00800000>>12,MTRR_UC);
  741.     set_mtrr(i++,0xdc000000>>12,0x04000000>>12,MTRR_UC);
  742.     set_mtrr(i++,0xE0000000>>12,0x10000000>>12,MTRR_WC);
  743.  
  744.     for(; i < cpuinfo.var_mtrr_count; i++)
  745.         set_mtrr(i,0,0,0);
  746.  
  747.     write_cr3(cr3);
  748.  
  749.     /* Intel (P6) standard MTRRs */
  750.     native_write_msr(MSR_MTRRdefType, deftype_lo, deftype_hi);
  751.  
  752.     /* Enable caches */
  753.     write_cr0(read_cr0() & ~(1<<30));
  754.  
  755.     /* Restore value of CR4 */
  756.     write_cr4(cr4);
  757.  
  758.     safe_sti(eflags);
  759.  
  760.     printf("\nnew MTRR map\n\n");
  761.  
  762.     for(i = 0; i < cpuinfo.var_mtrr_count; i++)
  763.     {
  764.         u64_t mtrr_base;
  765.         u64_t mtrr_mask;
  766.  
  767.         cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i));
  768.         cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i));
  769.  
  770.         printf("MTRR_%d base: %016llx mask: %016llx\n", i,
  771.                cpuinfo.var_mtrr[i].base,
  772.                cpuinfo.var_mtrr[i].mask);
  773.     };
  774. #endif
  775.  
  776.     tsc_khz = (unsigned int)(GetCpuFreq()/1000);
  777. }
  778.  
  779.  
  780. int get_driver_caps(hwcaps_t *caps)
  781. {
  782.     int ret = 0;
  783.  
  784.     switch(caps->idx)
  785.     {
  786.         case 0:
  787.             caps->opt[0] = 0;
  788.             caps->opt[1] = 0;
  789.             break;
  790.  
  791.         case 1:
  792.             caps->cap1.max_tex_width  = 4096;
  793.             caps->cap1.max_tex_height = 4096;
  794.             break;
  795.         default:
  796.             ret = 1;
  797.     };
  798.     caps->idx = 1;
  799.     return ret;
  800. }
  801.  
  802.  
  803. void get_pci_info(struct pci_device *dev)
  804. {
  805.     struct pci_dev *pdev = main_device->pdev;
  806.  
  807.     memset(dev, sizeof(*dev), 0);
  808.  
  809.     dev->domain     = 0;
  810.     dev->bus        = pdev->busnr;
  811.     dev->dev        = pdev->devfn >> 3;
  812.     dev->func       = pdev->devfn & 7;
  813.     dev->vendor_id  = pdev->vendor;
  814.     dev->device_id  = pdev->device;
  815.     dev->revision   = pdev->revision;
  816. };
  817.  
  818.  
  819.  
  820. char *strstr(const char *cs, const char *ct);
  821.  
  822. static int my_atoi(char **cmd)
  823. {
  824.     char* p = *cmd;
  825.     int val = 0;
  826.     int sign = 1;
  827.  
  828.     if(*p == '-')
  829.     {
  830.         sign = -1;
  831.         p++;
  832.     };
  833.  
  834.     for (;; *p++) {
  835.         switch (*p) {
  836.         case '0' ... '9':
  837.             val = 10*val+(*p-'0');
  838.             break;
  839.         default:
  840.             *cmd = p;
  841.             return val*sign;
  842.         }
  843.     }
  844. }
  845.  
  846. char* parse_mode(char *p, videomode_t *mode)
  847. {
  848.     char c;
  849.  
  850.     while( (c = *p++) == ' ');
  851.  
  852.     if( c )
  853.     {
  854.         p--;
  855.  
  856.         mode->width = my_atoi(&p);
  857.         if(*p == 'x') p++;
  858.  
  859.         mode->height = my_atoi(&p);
  860.         if(*p == 'x') p++;
  861.  
  862.         mode->bpp = 32;
  863.  
  864.         mode->freq = my_atoi(&p);
  865.  
  866.         if( mode->freq == 0 )
  867.             mode->freq = 60;
  868.     }
  869.  
  870.     return p;
  871. };
  872.  
  873.  
  874. static char* parse_path(char *p, char *log)
  875. {
  876.     char  c;
  877.  
  878.     while( (c = *p++) == ' ');
  879.         p--;
  880.     while((c = *p++) && (c != ' '))
  881.         *log++ = c;
  882.  
  883.     *log = 0;
  884.  
  885.     return p;
  886. };
  887.  
  888. void parse_cmdline(char *cmdline, struct cmdtable *table, char *log, videomode_t *mode)
  889. {
  890.     char *p = cmdline;
  891.     char *p1;
  892.     int val;
  893.     char c = *p++;
  894.  
  895.     if( table )
  896.     {
  897.         while(table->key)
  898.         {
  899.             if(p1 = strstr(cmdline, table->key))
  900.             {
  901.                 p1+= table->size;
  902.                 *table->val = my_atoi(&p1);
  903.             }
  904.             table++;
  905.         }
  906.     }
  907.  
  908.     while( c )
  909.     {
  910.         if( c == '-')
  911.         {
  912.             switch(*p++)
  913.             {
  914.                 case 'l':
  915.                     p = parse_path(p, log);
  916.                     break;
  917.  
  918.                 case 'm':
  919.                     p = parse_mode(p, mode);
  920.                     break;
  921.             };
  922.         };
  923.         c = *p++;
  924.     };
  925. };
  926.  
  927. char *strstr(const char *cs, const char *ct)
  928. {
  929. int d0, d1;
  930. register char *__res;
  931. __asm__ __volatile__(
  932.     "movl %6,%%edi\n\t"
  933.     "repne\n\t"
  934.     "scasb\n\t"
  935.     "notl %%ecx\n\t"
  936.     "decl %%ecx\n\t"    /* NOTE! This also sets Z if searchstring='' */
  937.     "movl %%ecx,%%edx\n"
  938.     "1:\tmovl %6,%%edi\n\t"
  939.     "movl %%esi,%%eax\n\t"
  940.     "movl %%edx,%%ecx\n\t"
  941.     "repe\n\t"
  942.     "cmpsb\n\t"
  943.     "je 2f\n\t"     /* also works for empty string, see above */
  944.     "xchgl %%eax,%%esi\n\t"
  945.     "incl %%esi\n\t"
  946.     "cmpb $0,-1(%%eax)\n\t"
  947.     "jne 1b\n\t"
  948.     "xorl %%eax,%%eax\n\t"
  949.     "2:"
  950.     : "=a" (__res), "=&c" (d0), "=&S" (d1)
  951.     : "0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
  952.     : "dx", "di");
  953. return __res;
  954. }
  955.  
  956.  
  957.