diff options
| -rw-r--r-- | linux-core/Makefile.kernel | 3 | ||||
| l--------- | linux-core/amd.h | 1 | ||||
| l--------- | linux-core/amd_cbuffer.h | 1 | ||||
| l--------- | linux-core/amd_legacy.h | 1 | ||||
| l--------- | linux-core/amd_legacy_cbuffer.c | 1 | ||||
| -rw-r--r-- | linux-core/radeon_ms_fb.c | 53 | ||||
| -rw-r--r-- | shared-core/amd.h (renamed from shared-core/amd_cbuffer.h) | 32 | ||||
| -rw-r--r-- | shared-core/amd_legacy.h | 33 | ||||
| -rw-r--r-- | shared-core/amd_legacy_cbuffer.c | 306 | ||||
| -rw-r--r-- | shared-core/radeon_ms.h | 7 | ||||
| -rw-r--r-- | shared-core/radeon_ms_crtc.c | 102 | ||||
| -rw-r--r-- | shared-core/radeon_ms_drm.c | 10 | ||||
| -rw-r--r-- | shared-core/radeon_ms_exec.c | 222 | 
13 files changed, 521 insertions, 251 deletions
diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index ad62eff4..91decfc8 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -40,7 +40,8 @@ radeon_ms-objs := radeon_ms_drv.o radeon_ms_drm.o radeon_ms_family.o \  		radeon_ms_cp.o radeon_ms_cp_mc.o radeon_ms_i2c.o \  		radeon_ms_output.o radeon_ms_crtc.o radeon_ms_fb.o \  		radeon_ms_exec.o radeon_ms_gpu.o radeon_ms_dac.o \ -		radeon_ms_properties.o radeon_ms_rom.o radeon_ms_combios.o +		radeon_ms_properties.o radeon_ms_rom.o radeon_ms_combios.o \ +		amd_legacy_cbuffer.o  sis-objs    := sis_drv.o sis_mm.o  ffb-objs    := ffb_drv.o ffb_context.o  savage-objs := savage_drv.o savage_bci.o savage_state.o diff --git a/linux-core/amd.h b/linux-core/amd.h new file mode 120000 index 00000000..b4882447 --- /dev/null +++ b/linux-core/amd.h @@ -0,0 +1 @@ +../shared-core/amd.h
\ No newline at end of file diff --git a/linux-core/amd_cbuffer.h b/linux-core/amd_cbuffer.h deleted file mode 120000 index 780b9d8f..00000000 --- a/linux-core/amd_cbuffer.h +++ /dev/null @@ -1 +0,0 @@ -../shared-core/amd_cbuffer.h
\ No newline at end of file diff --git a/linux-core/amd_legacy.h b/linux-core/amd_legacy.h new file mode 120000 index 00000000..1a7786fc --- /dev/null +++ b/linux-core/amd_legacy.h @@ -0,0 +1 @@ +../shared-core/amd_legacy.h
\ No newline at end of file diff --git a/linux-core/amd_legacy_cbuffer.c b/linux-core/amd_legacy_cbuffer.c new file mode 120000 index 00000000..eab329b5 --- /dev/null +++ b/linux-core/amd_legacy_cbuffer.c @@ -0,0 +1 @@ +../shared-core/amd_legacy_cbuffer.c
\ No newline at end of file diff --git a/linux-core/radeon_ms_fb.c b/linux-core/radeon_ms_fb.c index a8fba712..dbbddaf4 100644 --- a/linux-core/radeon_ms_fb.c +++ b/linux-core/radeon_ms_fb.c @@ -40,19 +40,15 @@  #include "drm.h"  #include "drm_crtc.h"  #include "radeon_ms.h" +#include "amd.h" -struct radeonfb_par { -	struct drm_device       *dev; -	struct drm_crtc         *crtc; -	struct drm_display_mode *fb_mode; -};  static int radeonfb_setcolreg(unsigned regno, unsigned red,  			       unsigned green, unsigned blue,  			       unsigned transp, struct fb_info *info)  { -	struct radeonfb_par *par = info->par; -	struct drm_framebuffer *fb = par->crtc->fb; +	struct amd_fb *par = info->par; +	struct drm_framebuffer *fb = par->fb;  	struct drm_crtc *crtc = par->crtc;  	if (regno > 255) { @@ -87,8 +83,8 @@ static int radeonfb_setcolreg(unsigned regno, unsigned red,  static int radeonfb_check_var(struct fb_var_screeninfo *var,  			       struct fb_info *info)  { -        struct radeonfb_par *par = info->par; -	struct drm_framebuffer *fb = par->crtc->fb; +        struct amd_fb *par = info->par; +	struct drm_framebuffer *fb = par->fb;          if (!var->pixclock)                  return -EINVAL; @@ -176,8 +172,8 @@ static bool radeonfb_mode_equal(struct drm_display_mode *mode1,  static int radeonfb_set_par(struct fb_info *info)  { -	struct radeonfb_par *par = info->par; -	struct drm_framebuffer *fb = par->crtc->fb; +	struct amd_fb *par = info->par; +	struct drm_framebuffer *fb = par->fb;  	struct drm_device *dev = par->dev;          struct drm_display_mode *drm_mode, *search_mode;          struct drm_output *output; @@ -247,7 +243,9 @@ static int radeonfb_set_par(struct fb_info *info)  	}  	if (par->crtc->enabled) { -		if (!drm_mode_equal(&par->crtc->mode, drm_mode)) { +		if (!drm_mode_equal(&par->crtc->mode, drm_mode) || +		    par->crtc->fb != par->fb) { +			par->crtc->fb = par->fb;  			if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0)) {  				return -EINVAL;  			} @@ -274,14 +272,15 @@ static struct fb_ops radeonfb_ops = {  int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc)  { +	struct drm_radeon_private *dev_priv = dev->dev_private;  	struct fb_info *info; -	struct radeonfb_par *par; +	struct amd_fb *par;  	struct device *device = &dev->pdev->dev;   	struct drm_framebuffer *fb;  	struct drm_display_mode *mode = crtc->desired_mode;  	int ret; -	info = framebuffer_alloc(sizeof(struct radeonfb_par), device); +	info = framebuffer_alloc(sizeof(struct amd_fb), device);  	if (!info){  		DRM_INFO("[radeon_ms] framebuffer_alloc failed\n");  		return -EINVAL; @@ -324,8 +323,10 @@ int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc)  	fb->fbdev = info;  	par = info->par; +	dev_priv->fb = par;  	par->dev = dev;  	par->crtc = crtc; +	par->fb = fb;  	info->fbops = &radeonfb_ops;  	strcpy(info->fix.id, "radeonfb");  	info->fix.type = FB_TYPE_PACKED_PIXELS; @@ -439,16 +440,22 @@ EXPORT_SYMBOL(radeonfb_probe);  int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc)  { -	struct drm_framebuffer *fb = crtc->fb; -	struct fb_info *info = fb->fbdev; -	 -	if (info) { -		unregister_framebuffer(info); -		drm_bo_kunmap(&fb->kmap); -		drm_bo_usage_deref_unlocked(&fb->bo); -		drm_framebuffer_destroy(fb); -		framebuffer_release(info); +	struct drm_radeon_private *dev_priv = dev->dev_private; +	struct amd_fb *fb = dev_priv->fb; +	struct fb_info *info; + +	if (fb == NULL || fb->fb == NULL || fb->fb->fbdev == NULL) { +		DRM_INFO("[radeon_ms] %s: no crtc, or fb or fbdev\n", +			 __func__); +		return 0;  	} +	info = fb->fb->fbdev; +	unregister_framebuffer(info); +	drm_bo_kunmap(&fb->fb->kmap); +	drm_bo_usage_deref_unlocked(&fb->fb->bo); +	drm_framebuffer_destroy(fb->fb); +	framebuffer_release(info); +	dev_priv->fb = NULL;  	return 0;  }  EXPORT_SYMBOL(radeonfb_remove); diff --git a/shared-core/amd_cbuffer.h b/shared-core/amd.h index bca05751..31cf3eff 100644 --- a/shared-core/amd_cbuffer.h +++ b/shared-core/amd.h @@ -24,14 +24,13 @@   * Authors:   *    Jerome Glisse <glisse@freedesktop.org>   */ -#ifndef __AMD_CBUFFER_H__ -#define __AMD_CBUFFER_H__ +#ifndef __AMD_H__ +#define __AMD_H__  /* struct amd_cbuffer are for command buffer, this is the structure passed   * around during command validation (ie check that user have the right to   * execute the given command).   */ -  struct amd_cbuffer_arg  {  	struct list_head         list; @@ -46,6 +45,33 @@ struct amd_cbuffer  	struct amd_cbuffer_arg   arg_unused;  	struct amd_cbuffer_arg   arg_used;  	struct amd_cbuffer_arg   *args; +	void			 *driver; +}; + +struct amd_cbuffer_checker +{ +	uint32_t numof_p0_checkers; +	uint32_t numof_p3_checkers; +	int (*check)(struct drm_device *dev, struct amd_cbuffer *cbuffer); +	int (**check_p0)(struct drm_device *dev, struct amd_cbuffer *cbuffer, +			 int dw_id, int reg); +	int (**check_p3)(struct drm_device *dev, struct amd_cbuffer *cbuffer, +			 int dw_id, int op, int count); +}; + +struct amd_cbuffer_arg * +amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id); +int amd_cbuffer_check(struct drm_device *dev, struct amd_cbuffer *cbuffer); + + +/* struct amd_fb amd is for storing amd framebuffer informations + */ +struct amd_fb +{ +	struct drm_device       *dev; +	struct drm_crtc         *crtc; +	struct drm_display_mode *fb_mode; +	struct drm_framebuffer  *fb;  };  #endif diff --git a/shared-core/amd_legacy.h b/shared-core/amd_legacy.h new file mode 100644 index 00000000..92997dcd --- /dev/null +++ b/shared-core/amd_legacy.h @@ -0,0 +1,33 @@ +/* + * Copyright 2007 Jérôme Glisse + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + *    Jerome Glisse <glisse@freedesktop.org> + */ +#ifndef __AMD_LEGACY_H__ +#define __AMD_LEGACY_H__ + +int amd_legacy_cbuffer_destroy(struct drm_device *dev); +int amd_legacy_cbuffer_initialize(struct drm_device *dev); + +#endif diff --git a/shared-core/amd_legacy_cbuffer.c b/shared-core/amd_legacy_cbuffer.c new file mode 100644 index 00000000..f1b7a44b --- /dev/null +++ b/shared-core/amd_legacy_cbuffer.c @@ -0,0 +1,306 @@ +/* + * Copyright 2008 Jérôme Glisse + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + *    Jerome Glisse <glisse@freedesktop.org> + */ +#include "radeon_ms.h" +#include "amd.h" + +#define RADEON_DST_Y_X                      0x1438 +#define RADEON_SRC_Y_X                      0x1434 +#define RADEON_DP_CNTL                      0x16c0 +#define RADEON_DP_GUI_MASTER_CNTL           0x146c +#define RADEON_DP_BRUSH_BKGD_CLR            0x1478 +#define RADEON_DP_BRUSH_FRGD_CLR            0x147c +#define RADEON_DP_WRITE_MASK                0x16cc +#define RADEON_DST_PITCH_OFFSET             0x142c +#define RADEON_SRC_PITCH_OFFSET             0x1428 +#define RADEON_DST_HEIGHT_WIDTH             0x143c + +struct legacy_check +{ +	/* for 2D operations */ +	uint32_t                dp_gui_master_cntl; +	uint32_t                dst_offset; +	uint32_t                dst_pitch; +	struct amd_cbuffer_arg  *dst; +	uint32_t                dst_x; +	uint32_t                dst_y; +	uint32_t                dst_h; +	uint32_t                dst_w; +	struct amd_cbuffer_arg  *src; +	uint32_t                src_pitch; +	uint32_t                src_x; +	uint32_t                src_y; +}; + +static int check_blit(struct drm_device *dev, struct amd_cbuffer *cbuffer) +{ +	struct legacy_check *legacy_check; +	long bpp, start, end; +	 +	legacy_check = (struct legacy_check *)cbuffer->driver; +	/* check that gui master cntl have been set */ +	if (legacy_check->dp_gui_master_cntl == 0xffffffff) { +		return -EINVAL; +	} +	switch ((legacy_check->dp_gui_master_cntl >> 8) & 0xf) { +	case 2: +		bpp = 1; +		break; +	case 3: +	case 4: +		bpp = 2; +		break; +	case 6: +		bpp = 4; +		break; +	default: +		return -EINVAL; +	} +	/* check that a destination have been set */ +	if (legacy_check->dst == (void *)-1) { +		return -EINVAL; +	} +	if (legacy_check->dst_pitch == 0xffffffff) { +		return -EINVAL; +	} +	if (legacy_check->dst_x == 0xffffffff) { +		return -EINVAL; +	} +	if (legacy_check->dst_y == 0xffffffff) { +		return -EINVAL; +	} +	if (legacy_check->dst_w == 0xffffffff) { +		return -EINVAL; +	} +	if (legacy_check->dst_h == 0xffffffff) { +		return -EINVAL; +	} +	/* compute start offset of blit */ +	start = legacy_check->dst_pitch * legacy_check->dst_y + +		legacy_check->dst_x * bpp; +	/* compute end offset of blit */ +	end = legacy_check->dst_pitch * legacy_check->dst_h + +	      legacy_check->dst_w * bpp; +	/* FIXME: check that end offset is inside dst bo */ + +	/* check that a destination have been set */ +	if (legacy_check->dp_gui_master_cntl & 1) { +		if (legacy_check->src == (void *)-1) { +			return -EINVAL; +		} +		if (legacy_check->src_pitch == 0xffffffff) { +			return -EINVAL; +		} +		if (legacy_check->src_x == 0xffffffff) { +			return -EINVAL; +		} +		if (legacy_check->src_y == 0xffffffff) { +			return -EINVAL; +		} +		/* compute start offset of blit */ +		start = legacy_check->src_pitch * legacy_check->src_y + +			legacy_check->src_x * bpp; +		/* compute end offset of blit */ +		end = legacy_check->src_pitch * legacy_check->dst_h + +		      legacy_check->dst_w * bpp + start; +		/* FIXME: check that end offset is inside src bo */ +	} +	return 0; +} + +static int p0_dp_gui_master_cntl(struct drm_device *dev, +				 struct amd_cbuffer *cbuffer, +				 int dw_id, int reg) +{ +	struct legacy_check *legacy_check; +	 +	legacy_check = (struct legacy_check *)cbuffer->driver; +	legacy_check->dp_gui_master_cntl = cbuffer->cbuffer[dw_id]; +	/* we only accept src data type to be same as dst */ +	if (((legacy_check->dp_gui_master_cntl >> 12) & 0x3) != 3) { +		return -EINVAL; +	} +	return 0; +} + +static int p0_dst_pitch_offset(struct drm_device *dev, +			       struct amd_cbuffer *cbuffer, +			       int dw_id, int reg) +{ +	struct legacy_check *legacy_check; +	uint32_t gpu_addr; +	int ret; +	 +	legacy_check = (struct legacy_check *)cbuffer->driver; +	legacy_check->dst_pitch = ((cbuffer->cbuffer[dw_id] >> 22) & 0xff) << 6; +	legacy_check->dst = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, +						       dw_id); +	if (legacy_check->dst == NULL) { +		return -EINVAL; +	} +	ret = radeon_ms_bo_get_gpu_addr(dev, &legacy_check->dst->buffer->mem, +					&gpu_addr); +	if (ret) { +		return -EINVAL; +	} +	cbuffer->cbuffer[dw_id] &= 0xffc00000; +	cbuffer->cbuffer[dw_id] |= (gpu_addr >> 10); +	return 0; +} + +static int p0_src_pitch_offset(struct drm_device *dev, +			       struct amd_cbuffer *cbuffer, +			       int dw_id, int reg) +{ +	struct legacy_check *legacy_check; +	uint32_t gpu_addr; +	int ret; +	 +	legacy_check = (struct legacy_check *)cbuffer->driver; +	legacy_check->src_pitch = ((cbuffer->cbuffer[dw_id] >> 22) & 0xff) << 6; +	legacy_check->src = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, +						       dw_id); +	if (legacy_check->dst == NULL) { +		return -EINVAL; +	} +	ret = radeon_ms_bo_get_gpu_addr(dev, &legacy_check->src->buffer->mem, +					&gpu_addr); +	if (ret) { +		return -EINVAL; +	} +	cbuffer->cbuffer[dw_id] &= 0xffc00000; +	cbuffer->cbuffer[dw_id] |= (gpu_addr >> 10); +	return 0; +} + +static int p0_dst_y_x(struct drm_device *dev, +		      struct amd_cbuffer *cbuffer, +		      int dw_id, int reg) +{ +	struct legacy_check *legacy_check; +	 +	legacy_check = (struct legacy_check *)cbuffer->driver; +	legacy_check->dst_x = cbuffer->cbuffer[dw_id] & 0xffff; +	legacy_check->dst_y = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; +	return 0; +} + +static int p0_src_y_x(struct drm_device *dev, +		      struct amd_cbuffer *cbuffer, +		      int dw_id, int reg) +{ +	struct legacy_check *legacy_check; +	 +	legacy_check = (struct legacy_check *)cbuffer->driver; +	legacy_check->src_x = cbuffer->cbuffer[dw_id] & 0xffff; +	legacy_check->src_y = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; +	return 0; +} + +static int p0_dst_h_w(struct drm_device *dev, +		      struct amd_cbuffer *cbuffer, +		      int dw_id, int reg) +{ +	struct legacy_check *legacy_check; +	 +	legacy_check = (struct legacy_check *)cbuffer->driver; +	legacy_check->dst_w = cbuffer->cbuffer[dw_id] & 0xffff; +	legacy_check->dst_h = (cbuffer->cbuffer[dw_id] >> 16) & 0xffff; +	return check_blit(dev, cbuffer); +} + +static int legacy_cbuffer_check(struct drm_device *dev, +				struct amd_cbuffer *cbuffer) +{ +	struct legacy_check legacy_check; + +	memset(&legacy_check, 0xff, sizeof(struct legacy_check)); +	cbuffer->driver = &legacy_check; +	return amd_cbuffer_check(dev, cbuffer); +} + +int amd_legacy_cbuffer_destroy(struct drm_device *dev) +{ +	struct drm_radeon_private *dev_priv = dev->dev_private; + +	dev_priv->cbuffer_checker.check = NULL; +	if (dev_priv->cbuffer_checker.numof_p0_checkers) { +		drm_free(dev_priv->cbuffer_checker.check_p0, +			 dev_priv->cbuffer_checker.numof_p0_checkers * +			 sizeof(void*), DRM_MEM_DRIVER); +		dev_priv->cbuffer_checker.numof_p0_checkers = 0; +	} +	if (dev_priv->cbuffer_checker.numof_p3_checkers) { +		drm_free(dev_priv->cbuffer_checker.check_p3, +			 dev_priv->cbuffer_checker.numof_p3_checkers * +			 sizeof(void*), DRM_MEM_DRIVER); +		dev_priv->cbuffer_checker.numof_p3_checkers = 0; +	} +	return 0; +} + +int amd_legacy_cbuffer_initialize(struct drm_device *dev) +{ +	struct drm_radeon_private *dev_priv = dev->dev_private; +	struct amd_cbuffer_checker *checker = &dev_priv->cbuffer_checker; +	long size; + +	/* packet 0 */ +	checker->numof_p0_checkers = 0x5000 >> 2; +	size = checker->numof_p0_checkers * sizeof(void*); +	checker->check_p0 = drm_alloc(size, DRM_MEM_DRIVER); +	if (checker->check_p0 == NULL) { +		amd_legacy_cbuffer_destroy(dev); +		return -ENOMEM; +	} +	/* initialize to -1 */ +	memset(checker->check_p0, 0xff, size); + +	/* packet 3 */ +	checker->numof_p3_checkers = 20; +	size = checker->numof_p3_checkers * sizeof(void*); +	checker->check_p3 = drm_alloc(size, DRM_MEM_DRIVER); +	if (checker->check_p3 == NULL) { +		amd_legacy_cbuffer_destroy(dev); +		return -ENOMEM; +	} +	/* initialize to -1 */ +	memset(checker->check_p3, 0xff, size); + +	/* initialize packet0 checker */ +	checker->check_p0[RADEON_DST_Y_X >> 2] = p0_dst_y_x; +	checker->check_p0[RADEON_SRC_Y_X >> 2] = p0_src_y_x; +	checker->check_p0[RADEON_DST_HEIGHT_WIDTH >> 2] = p0_dst_h_w; +	checker->check_p0[RADEON_DST_PITCH_OFFSET >> 2] = p0_dst_pitch_offset; +	checker->check_p0[RADEON_SRC_PITCH_OFFSET >> 2] = p0_src_pitch_offset; +	checker->check_p0[RADEON_DP_GUI_MASTER_CNTL>>2] = p0_dp_gui_master_cntl; +	checker->check_p0[RADEON_DP_BRUSH_FRGD_CLR >> 2] = NULL; +	checker->check_p0[RADEON_DP_WRITE_MASK >> 2] = NULL; +	checker->check_p0[RADEON_DP_CNTL >> 2] = NULL; + +	checker->check = legacy_cbuffer_check; +	return 0; +} diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index e4010d84..ec264207 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -35,7 +35,8 @@  #include "radeon_ms_drm.h"  #include "radeon_ms_rom.h"  #include "radeon_ms_properties.h" -#include "amd_cbuffer.h" +#include "amd.h" +#include "amd_legacy.h"  #define DRIVER_AUTHOR      "Jerome Glisse, Dave Airlie,  Gareth Hughes, "\  			   "Keith Whitwell, others." @@ -292,6 +293,8 @@ struct drm_radeon_private {  	uint32_t                    *ring_buffer;  	uint32_t                    *write_back_area;  	const uint32_t              *microcode; +	/* framebuffer */ +	struct amd_fb               *fb;  	/* card family */  	uint32_t                    usec_timeout;  	uint32_t                    family; @@ -326,6 +329,8 @@ struct drm_radeon_private {  	uint8_t                     cp_ready;  	uint8_t                     bus_ready;  	uint8_t                     write_back; +	/* command buffer informations */ +	struct amd_cbuffer_checker  cbuffer_checker;  	/* abstract asic specific structures */  	struct radeon_ms_rom        rom;  	struct radeon_ms_properties properties; diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index b2383859..83dd0777 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -537,6 +537,10 @@ static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc,  		  adjusted_mode->hsync_end, adjusted_mode->htotal,  		  adjusted_mode->vdisplay, adjusted_mode->vsync_start,  		  adjusted_mode->vsync_end, adjusted_mode->vtotal, adjusted_mode->type); +	if (crtc->fb == NULL) { +		DRM_INFO("[radeon_ms] no FB bound\n"); +		return; +	}  	/* only support RGB555,RGB565,ARGB8888 should satisfy all users */  	switch (crtc->fb->bits_per_pixel) { @@ -551,7 +555,7 @@ static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc,  		format = 6;  		break;  	default: -		DRM_ERROR("Unknown color depth\n"); +		DRM_ERROR("Unknown color depth %d\n", crtc->fb->bits_per_pixel);  		return;  	}  	radeon_pll1_compute(crtc, adjusted_mode); @@ -638,6 +642,17 @@ static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc,  	radeon_ms_crtc1_restore(dev, state);  } +static void radeon_ms_crtc1_mode_set_base(struct drm_crtc *crtc, int x, int y) +{ +	struct drm_device *dev = crtc->dev; +	struct drm_radeon_private *dev_priv = dev->dev_private; +	struct radeon_state *state = &dev_priv->driver_state; + +	DRM_INFO("[radeon_ms] mode_set_base\n"); +	state->crtc_offset = REG_S(CRTC_OFFSET, CRTC_OFFSET, crtc->fb->bo->offset); +	radeon_ms_crtc1_restore(dev, state); +} +  static void radeon_ms_crtc_mode_commit(struct drm_crtc *crtc)  {  	crtc->funcs->dpms(crtc, DPMSModeOn); @@ -651,6 +666,10 @@ static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r,  	struct radeon_state *state = &dev_priv->driver_state;  	uint32_t color; +	if (regno >= 256) { +		return; +	} +	DRM_INFO("[radeon_ms] gamma[%d]=(%d, %d, %d)\n", regno, r, g, b);  	switch(radeon_ms_crtc->crtc) {  	case 1:  		state->dac_cntl2 &= ~DAC_CNTL2__PALETTE_ACCESS_CNTL; @@ -660,70 +679,22 @@ static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r,  		break;  	}  	MMIO_W(DAC_CNTL2, state->dac_cntl2); -	if (crtc->fb->bits_per_pixel == 16 && crtc->fb->depth == 16) { -		if (regno >= 64) { -			return; -		} -		MMIO_W(PALETTE_INDEX, -				REG_S(PALETTE_INDEX, PALETTE_W_INDEX, -					regno * 4)); -		color = 0; -		color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) | -			REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) | -			REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8); -		MMIO_W(PALETTE_DATA, color); -		MMIO_W(PALETTE_INDEX, -		       REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno * 4)); -		color = 0; -		color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R, r >> 6) | -			REG_S(PALETTE_30_DATA, PALETTE_DATA_G, g >> 6) | -			REG_S(PALETTE_30_DATA, PALETTE_DATA_B, b >> 6); -		MMIO_W(PALETTE_30_DATA, color); -		radeon_ms_crtc->lut_r[regno * 4] = r; -		radeon_ms_crtc->lut_g[regno * 4] = g; -		radeon_ms_crtc->lut_b[regno * 4] = b; -		if (regno < 32) { -			MMIO_W(PALETTE_INDEX, -			       REG_S(PALETTE_INDEX, PALETTE_W_INDEX, -				       regno * 8)); -			color = 0; -			color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) | -				REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) | -				REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8); -			MMIO_W(PALETTE_DATA, color); -			MMIO_W(PALETTE_INDEX, -			       REG_S(PALETTE_INDEX, PALETTE_W_INDEX, -				      regno * 8)); -			color = 0; -			color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R,r >> 6) | -				REG_S(PALETTE_30_DATA, PALETTE_DATA_G,g >> 6) | -				REG_S(PALETTE_30_DATA, PALETTE_DATA_B,b >> 6); -			MMIO_W(PALETTE_30_DATA, color); -			radeon_ms_crtc->lut_r[regno * 8] = r; -			radeon_ms_crtc->lut_g[regno * 8] = g; -			radeon_ms_crtc->lut_b[regno * 8] = b; -		} -	} else { -		if (regno >= 256) { -			return; -		} -		radeon_ms_crtc->lut_r[regno] = r; -		radeon_ms_crtc->lut_g[regno] = g; -		radeon_ms_crtc->lut_b[regno] = b; -		MMIO_W(PALETTE_INDEX, -		       REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno)); -		color = 0; -		color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) | -			REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) | -			REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8); -		MMIO_W(PALETTE_DATA, color); -		MMIO_W(PALETTE_INDEX, -				REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno)); -		color = 0; -		color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R, r >> 6) | -			REG_S(PALETTE_30_DATA, PALETTE_DATA_G, g >> 6) | -			REG_S(PALETTE_30_DATA, PALETTE_DATA_B, b >> 6); -	} +	radeon_ms_crtc->lut_r[regno] = r; +	radeon_ms_crtc->lut_g[regno] = g; +	radeon_ms_crtc->lut_b[regno] = b; +	MMIO_W(PALETTE_INDEX, REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno)); +	color = 0; +	color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) | +		REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) | +		REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8); +	MMIO_W(PALETTE_DATA, color); +	MMIO_W(PALETTE_INDEX, +			REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno)); +	color = 0; +	color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R, r >> 6) | +		REG_S(PALETTE_30_DATA, PALETTE_DATA_G, g >> 6) | +		REG_S(PALETTE_30_DATA, PALETTE_DATA_B, b >> 6); +	MMIO_W(PALETTE_30_DATA, color);  }  static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc) @@ -762,6 +733,7 @@ static const struct drm_crtc_funcs radeon_ms_crtc1_funcs= {  	.commit = radeon_ms_crtc_mode_commit,  	.mode_fixup = radeon_ms_crtc_mode_fixup,  	.mode_set = radeon_ms_crtc1_mode_set, +	.mode_set_base = radeon_ms_crtc1_mode_set_base,  	.gamma_set = radeon_ms_crtc_gamma_set,  	.cleanup = NULL, /* XXX */  }; diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index 869ccac4..0d327925 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -246,6 +246,13 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags)  		return ret;  	} +	/* initialze driver specific */ +	ret = amd_legacy_cbuffer_initialize(dev); +	if (ret != 0) { +		radeon_ms_driver_unload(dev); +		return ret; +	} +  	if (dev->primary && dev->control) {  		DRM_INFO("[radeon_ms] control 0x%lx, render 0x%lx\n",  		          (long)dev->primary->device, (long)dev->control->device); @@ -277,6 +284,9 @@ int radeon_ms_driver_unload(struct drm_device *dev)  	radeon_ms_outputs_restore(dev, &dev_priv->load_state);  	radeon_ms_connectors_destroy(dev);  	radeon_ms_outputs_destroy(dev); + +	/* shutdown specific driver */ +	amd_legacy_cbuffer_destroy(dev);  	/* shutdown cp engine */  	radeon_ms_cp_finish(dev); diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index 574e5a06..28fcc180 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -25,7 +25,7 @@   *    Jerome Glisse <glisse@freedesktop.org>   */  #include "radeon_ms.h" -#include "amd_cbuffer.h" +#include "amd.h"  static void radeon_ms_execbuffer_args_clean(struct drm_device *dev,  					    struct amd_cbuffer *cbuffer, @@ -118,175 +118,78 @@ out_err:  	return ret;  } -enum { -	REGISTER_FORBIDDEN = 0, -	REGISTER_SAFE, -	REGISTER_SET_OFFSET, -}; -static uint8_t _r3xx_register_right[0x5000 >> 2]; - -static int amd_cbuffer_packet0_set_offset(struct drm_device *dev, -					  struct amd_cbuffer *cbuffer, -					  uint32_t reg, int dw_id, -					  struct amd_cbuffer_arg *arg) -{ -	uint32_t gpu_addr; -	int ret; - -	ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, &gpu_addr); -	if (ret) { -		return ret; -	} -	switch (reg) { -	default: -		return -EINVAL; -	} -	return 0; -} - -static struct amd_cbuffer_arg * -amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id) +static int cbuffer_packet0_check(struct drm_device *dev, +				 struct amd_cbuffer *cbuffer, +				 int dw_id)  { -	struct amd_cbuffer_arg *arg; - -	list_for_each_entry(arg, &head->list, list) { -		if (arg->dw_id == dw_id) { -			return arg; -		} -	} -	/* no buffer at this dw index */ -	return NULL; -} - -static int amd_cbuffer_packet0_check(struct drm_device *dev, -				     struct drm_file *file_priv, -				     struct amd_cbuffer *cbuffer, -				     int dw_id, -				     uint8_t *register_right) -{ -	struct amd_cbuffer_arg *arg; +	struct drm_radeon_private *dev_priv = dev->dev_private;  	uint32_t reg, count, r, i;  	int ret;  	reg = cbuffer->cbuffer[dw_id] & PACKET0_REG_MASK;  	count = (cbuffer->cbuffer[dw_id] & PACKET0_COUNT_MASK) >>  		PACKET0_COUNT_SHIFT; +	if (reg + count > dev_priv->cbuffer_checker.numof_p0_checkers) { +		return -EINVAL; +	}  	for (r = reg, i = 0; i <= count; i++, r++) { -		switch (register_right[i]) { -		case REGISTER_FORBIDDEN: +		if (dev_priv->cbuffer_checker.check_p0[r] == NULL) { +			continue; +		} +		if (dev_priv->cbuffer_checker.check_p0[r] == (void *)-1) { +			DRM_INFO("[radeon_ms] check_f: %d %d -1 checker\n", +			         r, r << 2); +			return -EINVAL; +		} +		ret = dev_priv->cbuffer_checker.check_p0[r](dev, cbuffer, +							    dw_id + i + 1, reg); +		if (ret) { +			DRM_INFO("[radeon_ms] check_f: %d %d checker ret=%d\n", +			         r, r << 2, ret);  			return -EINVAL; -		case REGISTER_SAFE: -			break; -		case REGISTER_SET_OFFSET: -			arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, -							 dw_id + i +1); -			if (arg == NULL) { -				return -EINVAL; -			} -			/* remove from unparsed list */ -			list_del(&arg->list); -			list_add_tail(&arg->list, &cbuffer->arg_used.list); -			/* set the offset */ -			ret =  amd_cbuffer_packet0_set_offset(dev, cbuffer, -					  		      r, dw_id + i + 1, -							      arg); -			if (ret) { -				return ret; -			} -			break;  		}  	}  	/* header + N + 1 dword passed test */  	return count + 2;  } -static int amd_cbuffer_packet3_check(struct drm_device *dev, -				     struct drm_file *file_priv, -				     struct amd_cbuffer *cbuffer, -				     int dw_id) +static int cbuffer_packet3_check(struct drm_device *dev, +				 struct amd_cbuffer *cbuffer, +				 int dw_id)  { -	struct amd_cbuffer_arg *arg; +	struct drm_radeon_private *dev_priv = dev->dev_private;  	uint32_t opcode, count; -	uint32_t s_auth, s_mask; -	uint32_t gpu_addr;  	int ret;  	opcode = (cbuffer->cbuffer[dw_id] & PACKET3_OPCODE_MASK) >>  		 PACKET3_OPCODE_SHIFT; +	if (opcode > dev_priv->cbuffer_checker.numof_p3_checkers) { +		return -EINVAL; +	}  	count = (cbuffer->cbuffer[dw_id] & PACKET3_COUNT_MASK) >>  		PACKET3_COUNT_SHIFT; -	switch (opcode) { -	case PACKET3_OPCODE_NOP: -		break; -	case PACKET3_OPCODE_BITBLT: -	case PACKET3_OPCODE_BITBLT_MULTI: -	DRM_INFO("[radeon_ms] exec step - [05][P3]00.00\n"); -		/* we only alow simple blit */ -		if (count != 5) { -			return -EINVAL; -		} -	DRM_INFO("[radeon_ms] exec step - [05][P3]01.00\n"); -		s_mask = 0xf; -		s_auth = 0x3; -		if ((cbuffer->cbuffer[dw_id + 1] & s_mask) != s_auth) { -			return -EINVAL; -		} -	DRM_INFO("[radeon_ms] exec step - [05][P3]02.00\n"); -		arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+2); -		if (arg == NULL) { -			return -EINVAL; -		} -	DRM_INFO("[radeon_ms] exec step - [05][P3]03.00\n"); -		ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, -						&gpu_addr); -		if (ret) { -			return ret; -		} -	DRM_INFO("[radeon_ms] exec step - [05][P3]04.00\n"); -		gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; -		cbuffer->cbuffer[dw_id + 2] &= 0xFFC00000; -		cbuffer->cbuffer[dw_id + 2] |= gpu_addr; -		arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+3); -		if (arg == NULL) { -			return -EINVAL; -		} -	DRM_INFO("[radeon_ms] exec step - [05][P3]05.00\n"); -		ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, -						&gpu_addr); -		if (ret) { -			return ret; -		} -	DRM_INFO("[radeon_ms] exec step - [05][P3]06.00\n"); -		gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; -		cbuffer->cbuffer[dw_id + 3] &= 0xFFC00000; -		cbuffer->cbuffer[dw_id + 3] |= gpu_addr; -	DRM_INFO("[radeon_ms] exec step - [05][P3]07.00\n"); -		/* FIXME: check that source & destination are big enough -		 * for requested blit */ -		break; -	default: +	if (dev_priv->cbuffer_checker.check_p3[opcode] == NULL) { +		return -EINVAL; +	} +	ret = dev_priv->cbuffer_checker.check_p3[opcode](dev, cbuffer, +							 dw_id + 1, opcode, +							 count); +	if (ret) {  		return -EINVAL;  	} -	/* header + N + 1 dword passed test */  	return count + 2;  } -static int amd_cbuffer_check(struct drm_device *dev, -			     struct drm_file *file_priv, -			     struct amd_cbuffer *cbuffer) +int amd_cbuffer_check(struct drm_device *dev, struct amd_cbuffer *cbuffer)  {  	uint32_t i;  	int ret;  	for (i = 0; i < cbuffer->cbuffer_dw_count;) { -	DRM_INFO("[radeon_ms] exec step - [05]00.00 %d 0x%08X\n", -		 i, cbuffer->cbuffer[i]);  		switch (PACKET_HEADER_GET(cbuffer->cbuffer[i])) {  		case 0: -			ret = amd_cbuffer_packet0_check(dev, file_priv, -							cbuffer, i, -							_r3xx_register_right); -			if (ret) { +			ret = cbuffer_packet0_check(dev, cbuffer, i); +			if (ret <= 0) {  				return ret;  			}  			/* advance to next packet */ @@ -296,13 +199,11 @@ static int amd_cbuffer_check(struct drm_device *dev,  			/* we don't accept packet 1 */  			return -EINVAL;  		case 2: -			/* packet 2 */ -			i += 1; -			break; +			/* FIXME: accept packet 2 */ +			return -EINVAL;  		case 3: -			ret = amd_cbuffer_packet3_check(dev, file_priv, -							cbuffer, i); -			if (ret) { +			ret = cbuffer_packet3_check(dev, cbuffer, i); +			if (ret <= 0) {  				return ret;  			}  			/* advance to next packet */ @@ -313,9 +214,25 @@ static int amd_cbuffer_check(struct drm_device *dev,  	return 0;  } +struct amd_cbuffer_arg * +amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id) +{ +	struct amd_cbuffer_arg *arg; + +	list_for_each_entry(arg, &head->list, list) { +		if (arg->dw_id == dw_id) { +			return arg; +		} +	} +	/* no buffer at this dw index */ +	return NULL; +} + +  int radeon_ms_execbuffer(struct drm_device *dev, void *data,  			 struct drm_file *file_priv)  { +	struct drm_radeon_private *dev_priv = dev->dev_private;  	struct drm_radeon_execbuffer *execbuffer = data;  	struct drm_fence_arg *fence_arg = &execbuffer->fence_arg;  	struct drm_bo_kmap_obj cmd_kmap; @@ -331,13 +248,11 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data,  	/* FIXME: Lock buffer manager, is this really needed ?  	 */ -	DRM_INFO("[radeon_ms] exec step - 00.00\n");  	ret = drm_bo_read_lock(&dev->bm.bm_lock);  	if (ret) {  		return ret;  	} -	DRM_INFO("[radeon_ms] exec step - 01.00\n");  	cbuffer.args = drm_calloc(execbuffer->args_count,  				  sizeof(struct amd_cbuffer_arg),  				  DRM_MEM_DRIVER); @@ -350,7 +265,6 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data,  	INIT_LIST_HEAD(&cbuffer.arg_used.list);  	/* process arguments */ -	DRM_INFO("[radeon_ms] exec step - 02.00\n");  	ret = radeon_ms_execbuffer_args(dev, file_priv, execbuffer, &cbuffer);  	if (ret) {  		DRM_ERROR("[radeon_ms] execbuffer wrong arguments\n"); @@ -358,14 +272,12 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data,  	}  	/* map command buffer */ -	DRM_INFO("[radeon_ms] exec step - 03.00\n");  	cbuffer.cbuffer_dw_count = (cbuffer.args[0].buffer->mem.num_pages *  				    PAGE_SIZE) >> 2;  	if (execbuffer->cmd_size > cbuffer.cbuffer_dw_count) {  		ret = -EINVAL;  		goto out_free_release;  	} -	DRM_INFO("[radeon_ms] exec step - 04.00\n");  	cbuffer.cbuffer_dw_count = execbuffer->cmd_size;  	memset(&cmd_kmap, 0, sizeof(struct drm_bo_kmap_obj));  	ret = drm_bo_kmap(cbuffer.args[0].buffer, 0, @@ -374,21 +286,21 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data,  		DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret);  		goto out_free_release;  	} -	DRM_INFO("[radeon_ms] exec step - 05.00\n");  	cbuffer.cbuffer = drm_bmo_virtual(&cmd_kmap, &cmd_is_iomem); -	DRM_INFO("[radeon_ms] exec step - 05.01\n");  	list_del(&cbuffer.args[0].list); -	DRM_INFO("[radeon_ms] exec step - 05.02\n");  	list_add_tail(&cbuffer.args[0].list , &cbuffer.arg_used.list); -	DRM_INFO("[radeon_ms] exec step - 05.03\n");  	/* do cmd checking & relocations */ -	ret = amd_cbuffer_check(dev, file_priv, &cbuffer); -	if (ret) { +	if (dev_priv->cbuffer_checker.check) { +		ret = dev_priv->cbuffer_checker.check(dev, &cbuffer); +		if (ret) { +			drm_putback_buffer_objects(dev); +			goto out_free_release; +		} +	} else {  		drm_putback_buffer_objects(dev);  		goto out_free_release;  	} -	DRM_INFO("[radeon_ms] exec step - 06.00\n");  	ret = radeon_ms_ring_emit(dev, cbuffer.cbuffer,  				  cbuffer.cbuffer_dw_count); @@ -396,7 +308,6 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data,  		drm_putback_buffer_objects(dev);  		goto out_free_release;  	} -	DRM_INFO("[radeon_ms] exec step - 07.00\n");  	/* fence */  	ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence); @@ -418,16 +329,13 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data,  		}  	}  	drm_fence_usage_deref_unlocked(&fence); -	DRM_INFO("[radeon_ms] exec step - 08.00\n");  out_free_release:  	drm_bo_kunmap(&cmd_kmap);  	radeon_ms_execbuffer_args_clean(dev, &cbuffer, execbuffer->args_count); -	DRM_INFO("[radeon_ms] exec step - 09.00\n");  out_free:  	drm_free(cbuffer.args,  		 (execbuffer->args_count * sizeof(struct amd_cbuffer_arg)),  		 DRM_MEM_DRIVER);  	drm_bo_read_unlock(&dev->bm.bm_lock); -	DRM_INFO("[radeon_ms] exec step - 10.00\n");  	return ret;  }  | 
