Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. #define iowrite32(v, addr)      writel((v), (addr))
  3.  
  4. #include "drmP.h"
  5. #include "drm.h"
  6. #include "i915_drm.h"
  7. #include "i915_drv.h"
  8. #include "intel_drv.h"
  9.  
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/mod_devicetable.h>
  13. #include <errno-base.h>
  14. #include <linux/pci.h>
  15.  
  16. #include <syscall.h>
  17.  
  18. #include "bitmap.h"
  19.  
  20. extern struct drm_device *main_device;
  21.  
  22.  
  23. typedef struct
  24. {
  25.     kobj_t     header;
  26.  
  27.     uint32_t  *data;
  28.     uint32_t   hot_x;
  29.     uint32_t   hot_y;
  30.  
  31.     struct list_head   list;
  32.     struct drm_i915_gem_object  *cobj;
  33. }cursor_t;
  34.  
  35. #define CURSOR_WIDTH 64
  36. #define CURSOR_HEIGHT 64
  37.  
  38.  
  39. struct tag_display
  40. {
  41.     int  x;
  42.     int  y;
  43.     int  width;
  44.     int  height;
  45.     int  bpp;
  46.     int  vrefresh;
  47.     int  pitch;
  48.     int  lfb;
  49.  
  50.     int  supported_modes;
  51.     struct drm_device    *ddev;
  52.     struct drm_connector *connector;
  53.     struct drm_crtc      *crtc;
  54.  
  55.     struct list_head   cursors;
  56.  
  57.     cursor_t   *cursor;
  58.     int       (*init_cursor)(cursor_t*);
  59.     cursor_t* (__stdcall *select_cursor)(cursor_t*);
  60.     void      (*show_cursor)(int show);
  61.     void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
  62.     void      (__stdcall *restore_cursor)(int x, int y);
  63.     void      (*disable_mouse)(void);
  64.     u32  mask_seqno;
  65.     u32  check_mouse;
  66.     u32  check_m_pixel;
  67.  
  68. };
  69.  
  70.  
  71. static display_t *os_display;
  72.  
  73. u32_t cmd_buffer;
  74. u32_t cmd_offset;
  75.  
  76. void init_render();
  77. int  sna_init();
  78.  
  79. int init_cursor(cursor_t *cursor);
  80. static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
  81. static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
  82.  
  83. void __stdcall restore_cursor(int x, int y)
  84. {};
  85.  
  86. void disable_mouse(void)
  87. {};
  88.  
  89. static char *manufacturer_name(unsigned char *x)
  90. {
  91.     static char name[4];
  92.  
  93.     name[0] = ((x[0] & 0x7C) >> 2) + '@';
  94.     name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
  95.     name[2] = (x[1] & 0x1F) + '@';
  96.     name[3] = 0;
  97.  
  98.     return name;
  99. }
  100.  
  101. bool set_mode(struct drm_device *dev, struct drm_connector *connector,
  102.               videomode_t *reqmode, bool strict)
  103. {
  104.     drm_i915_private_t      *dev_priv   = dev->dev_private;
  105.     struct drm_fb_helper    *fb_helper  = &dev_priv->fbdev->helper;
  106.  
  107.     struct drm_mode_config  *config     = &dev->mode_config;
  108.     struct drm_display_mode *mode       = NULL, *tmpmode;
  109.     struct drm_framebuffer  *fb         = NULL;
  110.     struct drm_crtc         *crtc;
  111.     struct drm_encoder      *encoder;
  112.     struct drm_mode_set     set;
  113.     char *con_name;
  114.     char *enc_name;
  115.     unsigned hdisplay, vdisplay;
  116.     int ret;
  117.  
  118.     mutex_lock(&dev->mode_config.mutex);
  119.  
  120.     list_for_each_entry(tmpmode, &connector->modes, head)
  121.     {
  122.         if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
  123.             (drm_mode_height(tmpmode)   == reqmode->height) &&
  124.             (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
  125.         {
  126.             mode = tmpmode;
  127.             goto do_set;
  128.         }
  129.     };
  130.  
  131.     if( (mode == NULL) && (strict == false) )
  132.     {
  133.         list_for_each_entry(tmpmode, &connector->modes, head)
  134.         {
  135.             if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
  136.                 (drm_mode_height(tmpmode) == reqmode->height) )
  137.             {
  138.                 mode = tmpmode;
  139.                 goto do_set;
  140.             }
  141.         };
  142.     };
  143.  
  144.     printf("%s failed\n", __FUNCTION__);
  145.  
  146.     return -1;
  147.  
  148. do_set:
  149.  
  150.  
  151.     encoder = connector->encoder;
  152.     crtc = encoder->crtc;
  153.  
  154.     con_name = drm_get_connector_name(connector);
  155.     enc_name = drm_get_encoder_name(encoder);
  156.  
  157.     DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s encoder %s\n",
  158.               reqmode->width, reqmode->height, crtc->base.id,
  159.               con_name, enc_name);
  160.  
  161.     drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
  162.  
  163.     hdisplay = mode->hdisplay;
  164.     vdisplay = mode->vdisplay;
  165.  
  166.     if (crtc->invert_dimensions)
  167.         swap(hdisplay, vdisplay);
  168.  
  169.     fb = fb_helper->fb;
  170.  
  171.     fb->width  = reqmode->width;
  172.     fb->height = reqmode->height;
  173.     fb->pitches[0]  = ALIGN(reqmode->width * 4, 64);
  174.     fb->pitches[1]  = ALIGN(reqmode->width * 4, 64);
  175.     fb->pitches[2]  = ALIGN(reqmode->width * 4, 64);
  176.     fb->pitches[3]  = ALIGN(reqmode->width * 4, 64);
  177.  
  178.     fb->bits_per_pixel = 32;
  179.     fb->depth = 24;
  180.  
  181.     crtc->fb = fb;
  182.     crtc->enabled = true;
  183.     os_display->crtc = crtc;
  184.  
  185.     set.crtc = crtc;
  186.     set.x = 0;
  187.     set.y = 0;
  188.     set.mode = mode;
  189.     set.connectors = &connector;
  190.     set.num_connectors = 1;
  191.     set.fb = fb;
  192.     ret = crtc->funcs->set_config(&set);
  193.     mutex_unlock(&dev->mode_config.mutex);
  194.  
  195.     if ( !ret )
  196.     {
  197.         os_display->width    = fb->width;
  198.         os_display->height   = fb->height;
  199.         os_display->pitch    = fb->pitches[0];
  200.         os_display->vrefresh = drm_mode_vrefresh(mode);
  201.  
  202.         sysSetScreen(fb->width, fb->height, fb->pitches[0]);
  203.  
  204.         dbgprintf("new mode %d x %d pitch %d\n",
  205.                        fb->width, fb->height, fb->pitches[0]);
  206.     }
  207.     else
  208.         DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
  209.                    fb->width, fb->height, crtc);
  210.  
  211.  
  212.     return ret;
  213. }
  214.  
  215. static int count_connector_modes(struct drm_connector* connector)
  216. {
  217.     struct drm_display_mode  *mode;
  218.     int count = 0;
  219.  
  220.     list_for_each_entry(mode, &connector->modes, head)
  221.     {
  222.         count++;
  223.     };
  224.     return count;
  225. };
  226.  
  227. static struct drm_connector* get_def_connector(struct drm_device *dev)
  228. {
  229.     struct drm_connector  *connector;
  230.     struct drm_connector_helper_funcs *connector_funcs;
  231.  
  232.     struct drm_connector  *def_connector = NULL;
  233.  
  234.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  235.     {
  236.         struct drm_encoder  *encoder;
  237.         struct drm_crtc     *crtc;
  238.  
  239.         if( connector->status != connector_status_connected)
  240.             continue;
  241.  
  242.         connector_funcs = connector->helper_private;
  243.         encoder = connector_funcs->best_encoder(connector);
  244.         if( encoder == NULL)
  245.             continue;
  246.  
  247.         connector->encoder = encoder;
  248.  
  249.         crtc = encoder->crtc;
  250.  
  251.         dbgprintf("CONNECTOR %x ID:  %d status %d encoder %x\n crtc %x",
  252.                    connector, connector->base.id,
  253.                    connector->status, connector->encoder,
  254.                    crtc);
  255.  
  256. //        if (crtc == NULL)
  257. //            continue;
  258.  
  259.         def_connector = connector;
  260.  
  261.         break;
  262.     };
  263.  
  264.     return def_connector;
  265. };
  266.  
  267.  
  268. int init_display_kms(struct drm_device *dev)
  269. {
  270.     struct drm_connector    *connector;
  271.     struct drm_connector_helper_funcs *connector_funcs;
  272.     struct drm_encoder      *encoder;
  273.     struct drm_crtc         *crtc = NULL;
  274.     struct drm_framebuffer  *fb;
  275.  
  276.     cursor_t  *cursor;
  277.     u32_t      ifl;
  278.  
  279. //    ENTER();
  280.  
  281.     list_for_each_entry(connector, &dev->mode_config.connector_list, head)
  282.     {
  283.         if( connector->status != connector_status_connected)
  284.             continue;
  285.  
  286.         connector_funcs = connector->helper_private;
  287.         encoder = connector_funcs->best_encoder(connector);
  288.         if( encoder == NULL)
  289.         {
  290.             dbgprintf("CONNECTOR %x ID: %d no active encoders\n",
  291.                       connector, connector->base.id);
  292.             continue;
  293.         }
  294.         connector->encoder = encoder;
  295.         crtc = encoder->crtc;
  296.  
  297.         dbgprintf("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n",
  298.                connector, connector->base.id,
  299.                connector->status, connector->encoder,
  300.                crtc, crtc->base.id );
  301.  
  302.         break;
  303.     };
  304.  
  305.     if(connector == NULL)
  306.     {
  307.         dbgprintf("No active connectors!\n");
  308.         return -1;
  309.     };
  310.  
  311.     if(crtc == NULL)
  312.     {
  313.         struct drm_crtc *tmp_crtc;
  314.         int crtc_mask = 1;
  315.  
  316.         list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head)
  317.         {
  318.             if (encoder->possible_crtcs & crtc_mask)
  319.             {
  320.                 crtc = tmp_crtc;
  321.                 encoder->crtc = crtc;
  322.                 break;
  323.             };
  324.             crtc_mask <<= 1;
  325.         };
  326.     };
  327.  
  328.     if(crtc == NULL)
  329.     {
  330.         dbgprintf("No CRTC for encoder %d\n", encoder->base.id);
  331.         return -1;
  332.     };
  333.  
  334.  
  335.     DRM_DEBUG_KMS("[Select CRTC:%d]\n", crtc->base.id);
  336.  
  337.     os_display = GetDisplay();
  338.     os_display->ddev = dev;
  339.     os_display->connector = connector;
  340.     os_display->crtc = crtc;
  341.  
  342.     os_display->supported_modes = count_connector_modes(connector);
  343.  
  344.  
  345.     ifl = safe_cli();
  346.     {
  347.         struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  348.  
  349.         list_for_each_entry(cursor, &os_display->cursors, list)
  350.         {
  351.             init_cursor(cursor);
  352.         };
  353.  
  354.         os_display->restore_cursor(0,0);
  355.         os_display->init_cursor    = init_cursor;
  356.         os_display->select_cursor  = select_cursor_kms;
  357.         os_display->show_cursor    = NULL;
  358.         os_display->move_cursor    = move_cursor_kms;
  359.         os_display->restore_cursor = restore_cursor;
  360.         os_display->disable_mouse  = disable_mouse;
  361.  
  362.         intel_crtc->cursor_x = os_display->width/2;
  363.         intel_crtc->cursor_y = os_display->height/2;
  364.  
  365.         select_cursor_kms(os_display->cursor);
  366.     };
  367.     safe_sti(ifl);
  368.  
  369. #define XY_COLOR_BLT        ((2<<29)|(0x50<<22)|(0x4))
  370. #define BLT_WRITE_ALPHA     (1<<21)
  371. #define BLT_WRITE_RGB       (1<<20)
  372.  
  373. #if 0
  374.  
  375. #if 1
  376.     {
  377.  
  378.         drm_i915_private_t *dev_priv = dev->dev_private;
  379.         struct drm_i915_gem_object *obj;
  380.         struct intel_ring_buffer *ring;
  381.  
  382.         obj = i915_gem_alloc_object(dev, 4096);
  383.         i915_gem_object_pin(obj, 4096, true, true);
  384.  
  385.         cmd_buffer = MapIoMem((addr_t)obj->pages.page[0], 4096, PG_SW|PG_NOCACHE);
  386.         cmd_offset = obj->gtt_offset;
  387.     };
  388. #endif
  389.  
  390.     main_device = dev;
  391.  
  392.     int err;
  393.  
  394.     err = init_bitmaps();
  395.     if( !err )
  396.     {
  397.         printf("Initialize bitmap manager\n");
  398.     };
  399.  
  400.     sna_init();
  401. #endif
  402.  
  403. //    LEAVE();
  404.  
  405.     return 0;
  406. };
  407.  
  408.  
  409. int get_videomodes(videomode_t *mode, int *count)
  410. {
  411.     int err = -1;
  412.  
  413. //    ENTER();
  414.  
  415. //    dbgprintf("mode %x count %d\n", mode, *count);
  416.  
  417.     if( *count == 0 )
  418.     {
  419.         *count = os_display->supported_modes;
  420.         err = 0;
  421.     }
  422.     else if( mode != NULL )
  423.     {
  424.         struct drm_display_mode  *drmmode;
  425.         int i = 0;
  426.  
  427.         if( *count > os_display->supported_modes)
  428.             *count = os_display->supported_modes;
  429.  
  430.         list_for_each_entry(drmmode, &os_display->connector->modes, head)
  431.         {
  432.             if( i < *count)
  433.             {
  434.                 mode->width  = drm_mode_width(drmmode);
  435.                 mode->height = drm_mode_height(drmmode);
  436.                 mode->bpp    = 32;
  437.                 mode->freq   = drm_mode_vrefresh(drmmode);
  438.                 i++;
  439.                 mode++;
  440.             }
  441.             else break;
  442.         };
  443.         *count = i;
  444.         err = 0;
  445.     };
  446. //    LEAVE();
  447.     return err;
  448. };
  449.  
  450. int set_user_mode(videomode_t *mode)
  451. {
  452.     int err = -1;
  453.  
  454. //    ENTER();
  455.  
  456. //    dbgprintf("width %d height %d vrefresh %d\n",
  457. //               mode->width, mode->height, mode->freq);
  458.  
  459.     if( (mode->width  != 0)  &&
  460.         (mode->height != 0)  &&
  461.         (mode->freq   != 0 ) &&
  462.         ( (mode->width   != os_display->width)  ||
  463.           (mode->height  != os_display->height) ||
  464.           (mode->freq    != os_display->vrefresh) ) )
  465.     {
  466.         if( set_mode(os_display->ddev, os_display->connector, mode, true) )
  467.             err = 0;
  468.     };
  469.  
  470. //    LEAVE();
  471.     return err;
  472. };
  473.  
  474. void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  475. {
  476. /*  FIXME    synchronization */
  477.  
  478.     list_del(&cursor->list);
  479. //    radeon_bo_unpin(cursor->robj);
  480. //    KernelFree(cursor->data);
  481.     __DestroyObject(cursor);
  482. };
  483.  
  484. int init_cursor(cursor_t *cursor)
  485. {
  486.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  487.     struct drm_i915_gem_object *obj;
  488.     uint32_t *bits;
  489.     uint32_t *src;
  490.  
  491.     int       i,j;
  492.     int       ret;
  493.  
  494. //    ENTER();
  495.  
  496.     if (dev_priv->info->cursor_needs_physical)
  497.     {
  498.         bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
  499.         if (unlikely(bits == NULL))
  500.             return ENOMEM;
  501.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  502.     }
  503.     else
  504.     {
  505.         obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
  506.         if (unlikely(obj == NULL))
  507.             return -ENOMEM;
  508.  
  509.         ret = i915_gem_object_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true, true);
  510.         if (ret) {
  511.             drm_gem_object_unreference(&obj->base);
  512.             return ret;
  513.         }
  514.  
  515. /* You don't need to worry about fragmentation issues.
  516.  * GTT space is continuous. I guarantee it.                           */
  517.  
  518.         bits = (u32*)MapIoMem(dev_priv->mm.gtt->gma_bus_addr + obj->gtt_offset,
  519.                     CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
  520.  
  521.         if (unlikely(bits == NULL))
  522.         {
  523.             i915_gem_object_unpin(obj);
  524.             drm_gem_object_unreference(&obj->base);
  525.             return -ENOMEM;
  526.         };
  527.         cursor->cobj = obj;
  528.     };
  529.  
  530.     src = cursor->data;
  531.  
  532.     for(i = 0; i < 32; i++)
  533.     {
  534.         for(j = 0; j < 32; j++)
  535.             *bits++ = *src++;
  536.         for(j = 32; j < CURSOR_WIDTH; j++)
  537.             *bits++ = 0;
  538.     }
  539.     for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
  540.         *bits++ = 0;
  541.  
  542. // release old cursor
  543.  
  544.     KernelFree(cursor->data);
  545.  
  546.     cursor->data = bits;
  547.  
  548.     cursor->header.destroy = destroy_cursor;
  549. //    LEAVE();
  550.  
  551.     return 0;
  552. }
  553.  
  554.  
  555. static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
  556. {
  557.     struct drm_device *dev = crtc->dev;
  558.     struct drm_i915_private *dev_priv = dev->dev_private;
  559.     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  560.     int pipe = intel_crtc->pipe;
  561.     bool visible = base != 0;
  562.  
  563.     if (intel_crtc->cursor_visible != visible) {
  564.         uint32_t cntl = I915_READ(CURCNTR(pipe));
  565.         if (base) {
  566.             cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
  567.             cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
  568.             cntl |= pipe << 28; /* Connect to correct pipe */
  569.         } else {
  570.             cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
  571.             cntl |= CURSOR_MODE_DISABLE;
  572.         }
  573.         I915_WRITE(CURCNTR(pipe), cntl);
  574.  
  575.         intel_crtc->cursor_visible = visible;
  576.     }
  577.     /* and commit changes on next vblank */
  578.     I915_WRITE(CURBASE(pipe), base);
  579. }
  580.  
  581. void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  582. {
  583.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  584.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  585.     u32 base, pos;
  586.     bool visible;
  587.  
  588.     int pipe = intel_crtc->pipe;
  589.  
  590.     intel_crtc->cursor_x = x;
  591.     intel_crtc->cursor_y = y;
  592.  
  593.     x = x - cursor->hot_x;
  594.     y = y - cursor->hot_y;
  595.  
  596.  
  597.     pos = 0;
  598.  
  599.     base = intel_crtc->cursor_addr;
  600.     if (x >= os_display->width)
  601.         base = 0;
  602.  
  603.     if (y >= os_display->height)
  604.         base = 0;
  605.  
  606.     if (x < 0)
  607.     {
  608.         if (x + intel_crtc->cursor_width < 0)
  609.             base = 0;
  610.  
  611.         pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
  612.         x = -x;
  613.     }
  614.     pos |= x << CURSOR_X_SHIFT;
  615.  
  616.     if (y < 0)
  617.     {
  618.         if (y + intel_crtc->cursor_height < 0)
  619.             base = 0;
  620.  
  621.         pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
  622.         y = -y;
  623.     }
  624.     pos |= y << CURSOR_Y_SHIFT;
  625.  
  626.     visible = base != 0;
  627.     if (!visible && !intel_crtc->cursor_visible)
  628.         return;
  629.  
  630.     I915_WRITE(CURPOS(pipe), pos);
  631. //    if (IS_845G(dev) || IS_I865G(dev))
  632. //        i845_update_cursor(crtc, base);
  633. //    else
  634.         i9xx_update_cursor(os_display->crtc, base);
  635.  
  636. };
  637.  
  638.  
  639. cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  640. {
  641.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  642.     struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
  643.     cursor_t *old;
  644.  
  645.     old = os_display->cursor;
  646.     os_display->cursor = cursor;
  647.  
  648.     if (!dev_priv->info->cursor_needs_physical)
  649.        intel_crtc->cursor_addr = cursor->cobj->gtt_offset;
  650.     else
  651.         intel_crtc->cursor_addr = (addr_t)cursor->cobj;
  652.  
  653.     intel_crtc->cursor_width = 32;
  654.     intel_crtc->cursor_height = 32;
  655.  
  656.     move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y);
  657.     return old;
  658. };
  659.  
  660. #if 0
  661.  
  662. #define XY_SRC_COPY_BLT_CMD     ((2<<29)|(0x53<<22)|6)
  663.  
  664.  
  665. typedef struct
  666. {
  667.     int left;
  668.     int top;
  669.     int right;
  670.     int bottom;
  671. }rect_t;
  672.  
  673.  
  674. #include "clip.inc"
  675.  
  676. void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
  677.  
  678. #define CURRENT_TASK             (0x80003000)
  679.  
  680. static u32_t get_display_map()
  681. {
  682.     u32_t   addr;
  683.  
  684.     addr = (u32_t)os_display;
  685.     addr+= sizeof(display_t);            /*  shoot me  */
  686.     return *(u32_t*)addr;
  687. }
  688.  
  689. #define XY_SRC_COPY_CHROMA_CMD     ((2<<29)|(0x73<<22)|8)
  690. #define ROP_COPY_SRC               0xCC
  691. #define FORMAT8888                 3
  692.  
  693. typedef int v4si __attribute__ ((vector_size (16)));
  694.  
  695.  
  696. int blit_video(u32 hbitmap, int  dst_x, int dst_y,
  697.                int src_x, int src_y, u32 w, u32 h)
  698. {
  699.     drm_i915_private_t *dev_priv = main_device->dev_private;
  700.     struct intel_ring_buffer *ring;
  701.  
  702.     bitmap_t  *bitmap;
  703.     rect_t     winrc;
  704.     clip_t     dst_clip;
  705.     clip_t     src_clip;
  706.     u32_t      width;
  707.     u32_t      height;
  708.  
  709.     u32_t      br13, cmd, slot_mask, *b;
  710.     u32_t      offset;
  711.     u8         slot;
  712.     int      n=0;
  713.  
  714.     if(unlikely(hbitmap==0))
  715.         return -1;
  716.  
  717.     bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
  718.  
  719.     if(unlikely(bitmap==NULL))
  720.         return -1;
  721.  
  722.  
  723.     GetWindowRect(&winrc);
  724.  
  725.     dst_clip.xmin   = 0;
  726.     dst_clip.ymin   = 0;
  727.     dst_clip.xmax   = winrc.right-winrc.left-1;
  728.     dst_clip.ymax   = winrc.bottom -winrc.top -1;
  729.  
  730.     src_clip.xmin   = 0;
  731.     src_clip.ymin   = 0;
  732.     src_clip.xmax   = bitmap->width  - 1;
  733.     src_clip.ymax   = bitmap->height - 1;
  734.  
  735.     width  = w;
  736.     height = h;
  737.  
  738.     if( blit_clip(&dst_clip, &dst_x, &dst_y,
  739.                   &src_clip, &src_x, &src_y,
  740.                   &width, &height) )
  741.         return 0;
  742.  
  743.     dst_x+= winrc.left;
  744.     dst_y+= winrc.top;
  745.  
  746.     slot = *((u8*)CURRENT_TASK);
  747.  
  748.     slot_mask = (u32_t)slot<<24;
  749.  
  750.     {
  751. #if 0
  752.         static v4si write_mask = {0xFF000000, 0xFF000000,
  753.                                   0xFF000000, 0xFF000000};
  754.  
  755.         u8* src_offset;
  756.         u8* dst_offset;
  757.  
  758.         src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
  759.         src_offset += (u32)bitmap->uaddr;
  760.  
  761.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  762.         dst_offset+= get_display_map();
  763.  
  764.         u32_t tmp_h = height;
  765.  
  766.         __asm__ __volatile__ (
  767.         "movdqa     %[write_mask],  %%xmm7    \n"
  768.         "movd       %[slot_mask],   %%xmm6    \n"
  769.         "punpckldq  %%xmm6, %%xmm6            \n"
  770.         "punpcklqdq %%xmm6, %%xmm6            \n"
  771.         :: [write_mask] "m" (write_mask),
  772.            [slot_mask]  "g" (slot_mask)
  773.         :"xmm7", "xmm6");
  774.  
  775.         while( tmp_h--)
  776.         {
  777.             u32_t tmp_w = width;
  778.  
  779.             u8* tmp_src = src_offset;
  780.             u8* tmp_dst = dst_offset;
  781.  
  782.             src_offset+= bitmap->pitch;
  783.             dst_offset+= os_display->width;
  784.  
  785.             while( tmp_w >= 8 )
  786.             {
  787.                 __asm__ __volatile__ (
  788.                 "movq       (%0),   %%xmm0            \n"
  789.                 "punpcklbw  %%xmm0, %%xmm0            \n"
  790.                 "movdqa     %%xmm0, %%xmm1            \n"
  791.                 "punpcklwd  %%xmm0, %%xmm0            \n"
  792.                 "punpckhwd  %%xmm1, %%xmm1            \n"
  793.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  794.                 "pcmpeqb    %%xmm6, %%xmm1            \n"
  795.                 "maskmovdqu %%xmm7, %%xmm0            \n"
  796.                 "addl       $16, %%edi                \n"
  797.                 "maskmovdqu %%xmm7, %%xmm1            \n"
  798.                 :: "r" (tmp_dst), "D" (tmp_src)
  799.                 :"xmm0", "xmm1");
  800.                 __asm__ __volatile__ ("":::"edi");
  801.                 tmp_w -= 8;
  802.                 tmp_src += 32;
  803.                 tmp_dst += 8;
  804.             };
  805.  
  806.             if( tmp_w >= 4 )
  807.             {
  808.                 __asm__ __volatile__ (
  809.                 "movd       (%0),   %%xmm0            \n"
  810.                 "punpcklbw  %%xmm0, %%xmm0            \n"
  811.                 "punpcklwd  %%xmm0, %%xmm0            \n"
  812.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  813.                 "maskmovdqu %%xmm7, %%xmm0            \n"
  814.                 :: "r" (tmp_dst), "D" (tmp_src)
  815.                 :"xmm0");
  816.                 tmp_w -= 4;
  817.                 tmp_src += 16;
  818.                 tmp_dst += 4;
  819.             };
  820.  
  821.             while( tmp_w--)
  822.             {
  823.                 *(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
  824.                 tmp_src+=4;
  825.                 tmp_dst++;
  826.             };
  827.         };
  828. #else
  829.         u8* src_offset;
  830.         u8* dst_offset;
  831.         u32 ifl;
  832.  
  833.         src_offset = (u8*)(src_y*bitmap->pitch + src_x*4);
  834.         src_offset += (u32)bitmap->uaddr;
  835.  
  836.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  837.         dst_offset+= get_display_map();
  838.  
  839.         u32_t tmp_h = height;
  840.  
  841.       ifl = safe_cli();
  842.         while( tmp_h--)
  843.         {
  844.             u32_t tmp_w = width;
  845.  
  846.             u8* tmp_src = src_offset;
  847.             u8* tmp_dst = dst_offset;
  848.  
  849.             src_offset+= bitmap->pitch;
  850.             dst_offset+= os_display->width;
  851.  
  852.             while( tmp_w--)
  853.             {
  854.                 *(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00;
  855.                 tmp_src+=4;
  856.                 tmp_dst++;
  857.             };
  858.         };
  859.       safe_sti(ifl);
  860.     }
  861. #endif
  862.  
  863.     if((cmd_buffer & 0xFC0)==0xFC0)
  864.         cmd_buffer&= 0xFFFFF000;
  865.  
  866.     b = (u32_t*)ALIGN(cmd_buffer,16);
  867.  
  868.     offset = cmd_offset + ((u32_t)b & 0xFFF);
  869.  
  870.     cmd = XY_SRC_COPY_CHROMA_CMD | BLT_WRITE_RGB | BLT_WRITE_ALPHA;
  871.     cmd |= 3 << 17;
  872.  
  873.     br13 = os_display->pitch;
  874.     br13|= ROP_COPY_SRC << 16;
  875.     br13|= FORMAT8888   << 24;
  876.  
  877.     b[n++] = cmd;
  878.     b[n++] = br13;
  879.     b[n++] = (dst_y << 16) | dst_x;                   // left, top
  880.     b[n++] = ((dst_y+height-1)<< 16)|(dst_x+width-1); // bottom, right
  881.     b[n++] = 0;                          // destination
  882.     b[n++] = (src_y << 16) | src_x;      // source left & top
  883.     b[n++] = bitmap->pitch;              // source pitch
  884.     b[n++] = bitmap->gaddr;              // source
  885.  
  886.     b[n++] = 0;                          // Transparency Color Low
  887.     b[n++] = 0x00FFFFFF;                 // Transparency Color High
  888.  
  889.     b[n++] = MI_BATCH_BUFFER_END;
  890.     if( n & 1)
  891.         b[n++] = MI_NOOP;
  892.  
  893.     i915_gem_object_set_to_gtt_domain(bitmap->obj, false);
  894.  
  895.     if (HAS_BLT(main_device))
  896.     {
  897.         int ret;
  898.  
  899.         ring = &dev_priv->ring[BCS];
  900.         ring->dispatch_execbuffer(ring, cmd_offset, n*4);
  901.  
  902.         ret = intel_ring_begin(ring, 4);
  903.         if (ret)
  904.             return ret;
  905.  
  906.         intel_ring_emit(ring, MI_FLUSH_DW);
  907.         intel_ring_emit(ring, 0);
  908.         intel_ring_emit(ring, 0);
  909.         intel_ring_emit(ring, MI_NOOP);
  910.         intel_ring_advance(ring);
  911.     }
  912.     else
  913.     {
  914.         ring = &dev_priv->ring[RCS];
  915.         ring->dispatch_execbuffer(ring, cmd_offset, n*4);
  916.         ring->flush(ring, 0, I915_GEM_DOMAIN_RENDER);
  917.     };
  918.  
  919.     bitmap->obj->base.read_domains = I915_GEM_DOMAIN_CPU;
  920.     bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  921.  
  922.     return 0;
  923. fail:
  924.     return -1;
  925. };
  926.  
  927.  
  928. /* For display hotplug interrupt */
  929. static void
  930. ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
  931. {
  932.     if ((dev_priv->irq_mask & mask) != 0) {
  933.         dev_priv->irq_mask &= ~mask;
  934.         I915_WRITE(DEIMR, dev_priv->irq_mask);
  935.         POSTING_READ(DEIMR);
  936.     }
  937. }
  938.  
  939. static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
  940. {
  941.     drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
  942.     unsigned long irqflags;
  943.  
  944. //    if (!i915_pipe_enabled(dev, pipe))
  945. //        return -EINVAL;
  946.  
  947.     spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
  948.     ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
  949.                     DE_PIPEA_VBLANK : DE_PIPEB_VBLANK);
  950.     spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
  951.  
  952.     return 0;
  953. }
  954.  
  955.  
  956.  
  957. static int i915_interrupt_info(struct drm_device *dev)
  958. {
  959.     drm_i915_private_t *dev_priv = dev->dev_private;
  960.     int ret, i, pipe;
  961.  
  962.     if (!HAS_PCH_SPLIT(dev)) {
  963.         dbgprintf("Interrupt enable:    %08x\n",
  964.                I915_READ(IER));
  965.         dbgprintf("Interrupt identity:  %08x\n",
  966.                I915_READ(IIR));
  967.         dbgprintf("Interrupt mask:      %08x\n",
  968.                I915_READ(IMR));
  969.         for_each_pipe(pipe)
  970.             dbgprintf("Pipe %c stat:         %08x\n",
  971.                    pipe_name(pipe),
  972.                    I915_READ(PIPESTAT(pipe)));
  973.     } else {
  974.         dbgprintf("North Display Interrupt enable:      %08x\n",
  975.            I915_READ(DEIER));
  976.         dbgprintf("North Display Interrupt identity:    %08x\n",
  977.            I915_READ(DEIIR));
  978.         dbgprintf("North Display Interrupt mask:        %08x\n",
  979.            I915_READ(DEIMR));
  980.         dbgprintf("South Display Interrupt enable:      %08x\n",
  981.            I915_READ(SDEIER));
  982.         dbgprintf("South Display Interrupt identity:    %08x\n",
  983.            I915_READ(SDEIIR));
  984.         dbgprintf("South Display Interrupt mask:        %08x\n",
  985.            I915_READ(SDEIMR));
  986.         dbgprintf("Graphics Interrupt enable:           %08x\n",
  987.            I915_READ(GTIER));
  988.         dbgprintf("Graphics Interrupt identity:         %08x\n",
  989.            I915_READ(GTIIR));
  990.         dbgprintf("Graphics Interrupt mask:             %08x\n",
  991.                I915_READ(GTIMR));
  992.     }
  993.     dbgprintf("Interrupts received: %d\n",
  994.            atomic_read(&dev_priv->irq_received));
  995.     for (i = 0; i < I915_NUM_RINGS; i++) {
  996.         if (IS_GEN6(dev) || IS_GEN7(dev)) {
  997.             printf("Graphics Interrupt mask (%s):       %08x\n",
  998.                    dev_priv->ring[i].name,
  999.                    I915_READ_IMR(&dev_priv->ring[i]));
  1000.         }
  1001. //        i915_ring_seqno_info(m, &dev_priv->ring[i]);
  1002.     }
  1003.  
  1004.     return 0;
  1005. }
  1006.  
  1007. void execute_buffer (struct drm_i915_gem_object *buffer, uint32_t offset,
  1008.                      int size)
  1009. {
  1010.     struct intel_ring_buffer *ring;
  1011.     drm_i915_private_t *dev_priv = main_device->dev_private;
  1012.     u32 invalidate;
  1013.     u32 seqno = 2;
  1014.  
  1015.     offset += buffer->gtt_offset;
  1016. //    dbgprintf("execute %x size %d\n", offset, size);
  1017.  
  1018. //    asm volatile(
  1019. //    "mfence \n"
  1020. //    "wbinvd \n"
  1021. //    "mfence  \n"
  1022. //    :::"memory");
  1023.  
  1024.     ring = &dev_priv->ring[RCS];
  1025.     ring->dispatch_execbuffer(ring, offset, size);
  1026.  
  1027.     invalidate = I915_GEM_DOMAIN_COMMAND;
  1028.     if (INTEL_INFO(main_device)->gen >= 4)
  1029.         invalidate |= I915_GEM_DOMAIN_SAMPLER;
  1030.     if (ring->flush(ring, invalidate, 0))
  1031.         i915_gem_next_request_seqno(ring);
  1032.  
  1033.     ring->irq_get(ring);
  1034.  
  1035.     ring->add_request(ring, &seqno);
  1036.  
  1037. //    i915_interrupt_info(main_device);
  1038.  
  1039. };
  1040.  
  1041.  
  1042. int blit_textured(u32 hbitmap, int  dst_x, int dst_y,
  1043.                int src_x, int src_y, u32 w, u32 h)
  1044. {
  1045.     drm_i915_private_t *dev_priv = main_device->dev_private;
  1046.  
  1047.     bitmap_t  *src_bitmap, *dst_bitmap;
  1048.     bitmap_t   screen;
  1049.  
  1050.     rect_t     winrc;
  1051.  
  1052. //    dbgprintf("  handle: %d dx %d dy %d sx %d sy %d w %d h %d\n",
  1053. //              hbitmap, dst_x, dst_y, src_x, src_y, w, h);
  1054.  
  1055.     if(unlikely(hbitmap==0))
  1056.         return -1;
  1057.  
  1058.     src_bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
  1059. //    dbgprintf("bitmap %x\n", src_bitmap);
  1060.  
  1061.     if(unlikely(src_bitmap==NULL))
  1062.         return -1;
  1063.  
  1064.     GetWindowRect(&winrc);
  1065.  
  1066.     screen.pitch  = os_display->pitch;
  1067.     screen.gaddr  = 0;
  1068.     screen.width  = os_display->width;
  1069.     screen.height = os_display->height;
  1070.     screen.obj    = (void*)-1;
  1071.  
  1072.     dst_bitmap = &screen;
  1073.  
  1074.     dst_x+= winrc.left;
  1075.     dst_y+= winrc.top;
  1076.  
  1077.     sna_blit_copy(dst_bitmap, dst_x, dst_y, w, h, src_bitmap, src_x, src_y);
  1078.  
  1079. };
  1080.  
  1081. int sna_blit_tex(bitmap_t *dst_bitmap, int dst_x, int dst_y,
  1082.                   int w, int h, bitmap_t *src_bitmap, int src_x, int src_y,
  1083.                   bitmap_t *mask_bitmap);
  1084.  
  1085. int create_context();
  1086. struct context *get_context();
  1087.  
  1088. int blit_tex(u32 hbitmap, int  dst_x, int dst_y,
  1089.              int src_x, int src_y, u32 w, u32 h)
  1090. {
  1091.     drm_i915_private_t *dev_priv = main_device->dev_private;
  1092.     struct context *ctx;
  1093.  
  1094.     bitmap_t  *src_bitmap, *dst_bitmap;
  1095.     bitmap_t   screen;
  1096.     int        ret;
  1097.  
  1098.     bitmap_t *mask_bitmap;
  1099.     rect_t     winrc;
  1100.  
  1101. //    dbgprintf("  handle: %d dx %d dy %d sx %d sy %d w %d h %d\n",
  1102. //              hbitmap, dst_x, dst_y, src_x, src_y, w, h);
  1103.  
  1104.     if(unlikely(hbitmap==0))
  1105.         return -1;
  1106.  
  1107.     src_bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap);
  1108. //    dbgprintf("bitmap %x\n", src_bitmap);
  1109.  
  1110.     if(unlikely(src_bitmap==NULL))
  1111.         return -1;
  1112.  
  1113.     ctx = get_context();
  1114.     if(unlikely(ctx==NULL))
  1115.     {
  1116.         ret = create_context();
  1117.         if(ret!=0)
  1118.             return -1;
  1119.  
  1120.         ctx = get_context();
  1121.     };
  1122.  
  1123.     mask_bitmap = ctx->mask;
  1124.  
  1125.     GetWindowRect(&winrc);
  1126.     dst_x+= winrc.left;
  1127.     dst_y+= winrc.top;
  1128.  
  1129.  
  1130.     if(ctx->seqno != os_display->mask_seqno)
  1131.     {
  1132.         u8* src_offset;
  1133.         u8* dst_offset;
  1134.         u32 slot;
  1135.         u32 ifl;
  1136.  
  1137.         ret = gem_object_lock(mask_bitmap->obj);
  1138.         if(ret !=0 )
  1139.         {
  1140.             dbgprintf("%s fail\n", __FUNCTION__);
  1141.             return ret;
  1142.         };
  1143.  
  1144. //        printf("width %d height %d\n", winrc.right, winrc.bottom);
  1145.  
  1146.         mask_bitmap->width  = winrc.right;
  1147.         mask_bitmap->height = winrc.bottom;
  1148.         mask_bitmap->pitch =  ALIGN(w,64);
  1149.  
  1150.         slot = *((u8*)CURRENT_TASK);
  1151. //        slot = 0x01;
  1152.  
  1153.         slot|= (slot<<8)|(slot<<16)|(slot<<24);
  1154.  
  1155.  
  1156.         __asm__ __volatile__ (
  1157.         "movd       %[slot],   %%xmm6    \n"
  1158.         "punpckldq  %%xmm6, %%xmm6            \n"
  1159.         "punpcklqdq %%xmm6, %%xmm6            \n"
  1160.         :: [slot]  "m" (slot)
  1161.         :"xmm6");
  1162.  
  1163.         src_offset = mask_bitmap->uaddr;
  1164.  
  1165.         dst_offset = (u8*)(dst_y*os_display->width + dst_x);
  1166.         dst_offset+= get_display_map();
  1167.  
  1168.         u32_t tmp_h = mask_bitmap->height;
  1169.  
  1170.       ifl = safe_cli();
  1171.         while( tmp_h--)
  1172.         {
  1173.             int tmp_w = mask_bitmap->width;
  1174.  
  1175.             u8* tmp_src = src_offset;
  1176.             u8* tmp_dst = dst_offset;
  1177.  
  1178.             src_offset+= mask_bitmap->pitch;
  1179.             dst_offset+= os_display->width;
  1180.  
  1181. //            while( tmp_w--)
  1182. //            {
  1183. //                *(tmp_src) = (*tmp_dst==slot)?0x1:0x00;
  1184. //                tmp_src++;
  1185. //                tmp_dst++;
  1186. //            };
  1187.             while(tmp_w >= 64)
  1188.             {
  1189.                 __asm__ __volatile__ (
  1190.                 "movdqu     (%0),   %%xmm0            \n"
  1191.                 "movdqu   16(%0),   %%xmm1            \n"
  1192.                 "movdqu   32(%0),   %%xmm2            \n"
  1193.                 "movdqu   48(%0),   %%xmm3            \n"
  1194.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  1195.                 "pcmpeqb    %%xmm6, %%xmm1            \n"
  1196.                 "pcmpeqb    %%xmm6, %%xmm2            \n"
  1197.                 "pcmpeqb    %%xmm6, %%xmm3            \n"
  1198.                 "movdqa     %%xmm0,   (%%edi)         \n"
  1199.                 "movdqa     %%xmm1, 16(%%edi)         \n"
  1200.                 "movdqa     %%xmm2, 32(%%edi)         \n"
  1201.                 "movdqa     %%xmm3, 48(%%edi)         \n"
  1202.  
  1203.                 :: "r" (tmp_dst), "D" (tmp_src)
  1204.                 :"xmm0","xmm1","xmm2","xmm3");
  1205.                 tmp_w -= 64;
  1206.                 tmp_src += 64;
  1207.                 tmp_dst += 64;
  1208.             }
  1209.  
  1210.             if( tmp_w >= 32 )
  1211.             {
  1212.                 __asm__ __volatile__ (
  1213.                 "movdqu     (%0),   %%xmm0            \n"
  1214.                 "movdqu   16(%0),   %%xmm1            \n"
  1215.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  1216.                 "pcmpeqb    %%xmm6, %%xmm1            \n"
  1217.                 "movdqa     %%xmm0,   (%%edi)         \n"
  1218.                 "movdqa     %%xmm1, 16(%%edi)         \n"
  1219.  
  1220.                 :: "r" (tmp_dst), "D" (tmp_src)
  1221.                 :"xmm0","xmm1");
  1222.                 tmp_w -= 32;
  1223.                 tmp_src += 32;
  1224.                 tmp_dst += 32;
  1225.             }
  1226.  
  1227.             while( tmp_w > 0 )
  1228.             {
  1229.                 __asm__ __volatile__ (
  1230.                 "movdqu     (%0),   %%xmm0            \n"
  1231.                 "pcmpeqb    %%xmm6, %%xmm0            \n"
  1232.                 "movdqa     %%xmm0,   (%%edi)         \n"
  1233.                 :: "r" (tmp_dst), "D" (tmp_src)
  1234.                 :"xmm0");
  1235.                 tmp_w -= 16;
  1236.                 tmp_src += 16;
  1237.                 tmp_dst += 16;
  1238.             }
  1239.         };
  1240.       safe_sti(ifl);
  1241.       ctx->seqno = os_display->mask_seqno;
  1242.     }
  1243.  
  1244.     screen.pitch  = os_display->pitch;
  1245.     screen.gaddr  = 0;
  1246.     screen.width  = os_display->width;
  1247.     screen.height = os_display->height;
  1248.     screen.obj    = (void*)-1;
  1249.  
  1250.     dst_bitmap = &screen;
  1251.  
  1252.  
  1253.     sna_blit_tex(dst_bitmap, dst_x, dst_y, w, h, src_bitmap, src_x, src_y,
  1254.                  mask_bitmap);
  1255.  
  1256. //    asm volatile ("int3");
  1257. };
  1258.  
  1259.  
  1260. struct context *context_map[256];
  1261.  
  1262. void __attribute__((regparm(1))) destroy_context(struct context *context)
  1263. {
  1264.     printf("destroy context %x\n", context);
  1265.  
  1266.     context_map[context->slot] = NULL;
  1267.     __DestroyObject(context);
  1268. };
  1269.  
  1270.  
  1271. int create_context()
  1272. {
  1273.     struct context *context;
  1274.  
  1275.     bitmap_t  *mask;
  1276.     int        slot;
  1277.  
  1278.     struct io_call_10 io_10;
  1279.     int    ret;
  1280.  
  1281.     slot = *((u8*)CURRENT_TASK);
  1282.  
  1283.     if(context_map[slot] != NULL)
  1284.         return 0;
  1285.  
  1286.     context = CreateObject(GetPid(), sizeof(*context));
  1287. //    printf("context %x\n", coontext);
  1288.     if( context == NULL)
  1289.         goto err1;
  1290.     context->header.destroy = destroy_context;
  1291.  
  1292.     dbgprintf("Create mask surface\n");
  1293.  
  1294.     io_10.width  = os_display->width/4;     /* need bitmap format here */
  1295.     io_10.height = os_display->height+1;
  1296.     io_10.max_width  = os_display->width/4;
  1297.     io_10.max_height = os_display->height+1;
  1298.  
  1299.     ret = create_surface(&io_10);
  1300.     if(ret)
  1301.         goto err2;
  1302.  
  1303.     mask= (bitmap_t*)hman_get_data(&bm_man, io_10.handle);
  1304.     if(unlikely(mask == NULL)) /* something really terrible happend */
  1305.         goto err2;
  1306.     dbgprintf("done\n");
  1307.  
  1308.     context->mask  = mask;
  1309.     context->seqno = os_display->mask_seqno-1;
  1310.     context->slot  = slot;
  1311.  
  1312.     context_map[slot] = context;
  1313.     return 0;
  1314.  
  1315. err2:
  1316.     __DestroyObject(context);
  1317. err1:
  1318.     return -1;
  1319. };
  1320.  
  1321. struct context *get_context()
  1322. {
  1323.  
  1324.     int slot = *((u8*)CURRENT_TASK);
  1325.  
  1326.     return context_map[slot];
  1327. }
  1328.  
  1329. #endif
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.  
  1338. void __stdcall run_workqueue(struct workqueue_struct *cwq)
  1339. {
  1340.     unsigned long irqflags;
  1341.  
  1342. //    dbgprintf("wq: %x head %x, next %x\n",
  1343. //               cwq, &cwq->worklist, cwq->worklist.next);
  1344.  
  1345.     spin_lock_irqsave(&cwq->lock, irqflags);
  1346.  
  1347.     while (!list_empty(&cwq->worklist))
  1348.     {
  1349.         struct work_struct *work = list_entry(cwq->worklist.next,
  1350.                                         struct work_struct, entry);
  1351.         work_func_t f = work->func;
  1352.         list_del_init(cwq->worklist.next);
  1353. //        dbgprintf("head %x, next %x\n",
  1354. //                  &cwq->worklist, cwq->worklist.next);
  1355.  
  1356.         spin_unlock_irqrestore(&cwq->lock, irqflags);
  1357.         f(work);
  1358.         spin_lock_irqsave(&cwq->lock, irqflags);
  1359.     }
  1360.  
  1361.     spin_unlock_irqrestore(&cwq->lock, irqflags);
  1362. }
  1363.  
  1364.  
  1365. static inline
  1366. int __queue_work(struct workqueue_struct *wq,
  1367.                          struct work_struct *work)
  1368. {
  1369.     unsigned long flags;
  1370. //    ENTER();
  1371.  
  1372. //    dbgprintf("wq: %x, work: %x\n",
  1373. //               wq, work );
  1374.  
  1375.     if(!list_empty(&work->entry))
  1376.         return 0;
  1377.  
  1378.     spin_lock_irqsave(&wq->lock, flags);
  1379.  
  1380.     if(list_empty(&wq->worklist))
  1381.         TimerHs(0,0, run_workqueue, wq);
  1382.  
  1383.     list_add_tail(&work->entry, &wq->worklist);
  1384.  
  1385.     spin_unlock_irqrestore(&wq->lock, flags);
  1386. //    dbgprintf("wq: %x head %x, next %x\n",
  1387. //               wq, &wq->worklist, wq->worklist.next);
  1388.  
  1389. //    LEAVE();
  1390.     return 1;
  1391. };
  1392.  
  1393. void __stdcall delayed_work_timer_fn(unsigned long __data)
  1394. {
  1395. //    ENTER();
  1396.     struct delayed_work *dwork = (struct delayed_work *)__data;
  1397.     struct workqueue_struct *wq = dwork->work.data;
  1398.  
  1399. //    dbgprintf("wq: %x, work: %x\n",
  1400. //               wq, &dwork->work );
  1401.  
  1402.     __queue_work(wq, &dwork->work);
  1403. //    LEAVE();
  1404. }
  1405.  
  1406.  
  1407. int queue_delayed_work_on(struct workqueue_struct *wq,
  1408.                         struct delayed_work *dwork, unsigned long delay)
  1409. {
  1410.     struct work_struct *work = &dwork->work;
  1411.  
  1412.     work->data = wq;
  1413.     TimerHs(0,0, delayed_work_timer_fn, dwork);
  1414.     return 1;
  1415. }
  1416.  
  1417. int queue_delayed_work(struct workqueue_struct *wq,
  1418.                         struct delayed_work *dwork, unsigned long delay)
  1419. {
  1420.     u32  flags;
  1421. //    ENTER();
  1422.  
  1423. //    dbgprintf("wq: %x, work: %x\n",
  1424. //               wq, &dwork->work );
  1425.  
  1426.     if (delay == 0)
  1427.         return __queue_work(wq, &dwork->work);
  1428.  
  1429.     return queue_delayed_work_on(wq, dwork, delay);
  1430. }
  1431.  
  1432.  
  1433. struct workqueue_struct *alloc_workqueue(const char *fmt,
  1434.                            unsigned int flags,
  1435.                            int max_active)
  1436. {
  1437.     struct workqueue_struct *wq;
  1438.  
  1439.     wq = kzalloc(sizeof(*wq),0);
  1440.     if (!wq)
  1441.         goto err;
  1442.  
  1443.     INIT_LIST_HEAD(&wq->worklist);
  1444.  
  1445.     return wq;
  1446. err:
  1447.     return NULL;
  1448. }
  1449.  
  1450. #define NSEC_PER_SEC    1000000000L
  1451.  
  1452. void getrawmonotonic(struct timespec *ts)
  1453. {
  1454.     u32 tmp = GetTimerTicks();
  1455.  
  1456.     ts->tv_sec  = tmp/100;
  1457.     ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
  1458. }
  1459.  
  1460. void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
  1461. {
  1462.         while (nsec >= NSEC_PER_SEC) {
  1463.                 nsec -= NSEC_PER_SEC;
  1464.                 ++sec;
  1465.         }
  1466.         while (nsec < 0) {
  1467.                 nsec += NSEC_PER_SEC;
  1468.                 --sec;
  1469.         }
  1470.         ts->tv_sec = sec;
  1471.         ts->tv_nsec = nsec;
  1472. }
  1473.  
  1474.  
  1475.  
  1476.