Subversion Repositories Kolibri OS

Rev

Rev 5271 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5271 Rev 6104
Line 32... Line 32...
32
#include "cayman_reg_safe.h"
32
#include "cayman_reg_safe.h"
Line 33... Line 33...
33
 
33
 
34
#define MAX(a,b)                   (((a)>(b))?(a):(b))
34
#define MAX(a,b)                   (((a)>(b))?(a):(b))
Line -... Line 35...
-
 
35
#define MIN(a,b)                   (((a)<(b))?(a):(b))
-
 
36
 
35
#define MIN(a,b)                   (((a)<(b))?(a):(b))
37
#define REG_SAFE_BM_SIZE ARRAY_SIZE(evergreen_reg_safe_bm)
36
 
38
 
37
int r600_dma_cs_next_reloc(struct radeon_cs_parser *p,
39
int r600_dma_cs_next_reloc(struct radeon_cs_parser *p,
38
			   struct radeon_bo_list **cs_reloc);
40
			   struct radeon_bo_list **cs_reloc);
39
struct evergreen_cs_track {
41
struct evergreen_cs_track {
Line 81... Line 83...
81
	bool			db_dirty;
83
	bool			db_dirty;
82
	bool			streamout_dirty;
84
	bool			streamout_dirty;
83
	u32			htile_offset;
85
	u32			htile_offset;
84
	u32			htile_surface;
86
	u32			htile_surface;
85
	struct radeon_bo	*htile_bo;
87
	struct radeon_bo	*htile_bo;
-
 
88
	unsigned long		indirect_draw_buffer_size;
-
 
89
	const unsigned		*reg_safe_bm;
86
};
90
};
Line 87... Line 91...
87
 
91
 
88
static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
92
static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
89
{
93
{
Line 441... Line 445...
441
		/* old ddx are broken they allocate bo with w*h*bpp but
445
		/* old ddx are broken they allocate bo with w*h*bpp but
442
		 * program slice with ALIGN(h, 8), catch this and patch
446
		 * program slice with ALIGN(h, 8), catch this and patch
443
		 * command stream.
447
		 * command stream.
444
		 */
448
		 */
445
		if (!surf.mode) {
449
		if (!surf.mode) {
446
			volatile u32 *ib = p->ib.ptr;
450
			uint32_t *ib = p->ib.ptr;
447
			unsigned long tmp, nby, bsize, size, min = 0;
451
			unsigned long tmp, nby, bsize, size, min = 0;
Line 448... Line 452...
448
 
452
 
449
			/* find the height the ddx wants */
453
			/* find the height the ddx wants */
450
			if (surf.nby > 8) {
454
			if (surf.nby > 8) {
Line 1080... Line 1084...
1080
	}
1084
	}
1081
	return 0;
1085
	return 0;
1082
}
1086
}
Line 1083... Line 1087...
1083
 
1087
 
1084
/**
1088
/**
1085
 * evergreen_cs_check_reg() - check if register is authorized or not
1089
 * evergreen_cs_handle_reg() - process registers that need special handling.
1086
 * @parser: parser structure holding parsing context
1090
 * @parser: parser structure holding parsing context
1087
 * @reg: register we are testing
1091
 * @reg: register we are testing
1088
 * @idx: index into the cs buffer
-
 
1089
 *
-
 
1090
 * This function will test against evergreen_reg_safe_bm and return 0
-
 
1091
 * if register is safe. If register is not flag as safe this function
-
 
1092
 * will test it against a list of register needind special handling.
1092
 * @idx: index into the cs buffer
1093
 */
1093
 */
1094
static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1094
static int evergreen_cs_handle_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1095
{
1095
{
1096
	struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track;
1096
	struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track;
1097
	struct radeon_bo_list *reloc;
-
 
1098
	u32 last_reg;
1097
	struct radeon_bo_list *reloc;
1099
	u32 m, i, tmp, *ib;
1098
	u32 tmp, *ib;
Line 1100... Line -...
1100
	int r;
-
 
1101
 
-
 
1102
	if (p->rdev->family >= CHIP_CAYMAN)
-
 
1103
		last_reg = ARRAY_SIZE(cayman_reg_safe_bm);
-
 
1104
	else
-
 
1105
		last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
-
 
1106
 
-
 
1107
	i = (reg >> 7);
-
 
1108
	if (i >= last_reg) {
-
 
1109
		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
-
 
1110
		return -EINVAL;
-
 
1111
	}
-
 
1112
	m = 1 << ((reg >> 2) & 31);
-
 
1113
	if (p->rdev->family >= CHIP_CAYMAN) {
-
 
1114
		if (!(cayman_reg_safe_bm[i] & m))
-
 
1115
			return 0;
-
 
1116
	} else {
-
 
1117
		if (!(evergreen_reg_safe_bm[i] & m))
-
 
1118
			return 0;
1099
	int r;
1119
	}
1100
 
1120
	ib = p->ib.ptr;
1101
	ib = p->ib.ptr;
1121
	switch (reg) {
1102
	switch (reg) {
1122
	/* force following reg to 0 in an attempt to disable out buffer
1103
	/* force following reg to 0 in an attempt to disable out buffer
Line 1761... Line 1742...
1761
		return -EINVAL;
1742
		return -EINVAL;
1762
	}
1743
	}
1763
	return 0;
1744
	return 0;
1764
}
1745
}
Line -... Line 1746...
-
 
1746
 
-
 
1747
/**
-
 
1748
 * evergreen_is_safe_reg() - check if register is authorized or not
-
 
1749
 * @parser: parser structure holding parsing context
-
 
1750
 * @reg: register we are testing
-
 
1751
 *
-
 
1752
 * This function will test against reg_safe_bm and return true
-
 
1753
 * if register is safe or false otherwise.
1765
 
1754
 */
1766
static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1755
static inline bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg)
1767
{
-
 
1768
	u32 last_reg, m, i;
-
 
1769
 
-
 
1770
	if (p->rdev->family >= CHIP_CAYMAN)
1756
{
1771
		last_reg = ARRAY_SIZE(cayman_reg_safe_bm);
1757
	struct evergreen_cs_track *track = p->track;
1772
	else
-
 
Line 1773... Line 1758...
1773
		last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
1758
	u32 m, i;
1774
 
1759
 
1775
	i = (reg >> 7);
-
 
1776
	if (i >= last_reg) {
1760
	i = (reg >> 7);
1777
		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
1761
	if (unlikely(i >= REG_SAFE_BM_SIZE)) {
1778
		return false;
1762
		return false;
1779
	}
-
 
1780
	m = 1 << ((reg >> 2) & 31);
1763
	}
1781
	if (p->rdev->family >= CHIP_CAYMAN) {
-
 
1782
		if (!(cayman_reg_safe_bm[i] & m))
-
 
1783
			return true;
-
 
1784
	} else {
1764
	m = 1 << ((reg >> 2) & 31);
1785
		if (!(evergreen_reg_safe_bm[i] & m))
1765
	if (!(track->reg_safe_bm[i] & m))
1786
			return true;
-
 
1787
	}
1766
		return true;
1788
	dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
1767
 
Line 1789... Line 1768...
1789
	return false;
1768
	return false;
1790
}
1769
}
1791
 
1770
 
1792
static int evergreen_packet3_check(struct radeon_cs_parser *p,
1771
static int evergreen_packet3_check(struct radeon_cs_parser *p,
1793
				   struct radeon_cs_packet *pkt)
1772
				   struct radeon_cs_packet *pkt)
1794
{
1773
{
1795
	struct radeon_bo_list *reloc;
1774
	struct radeon_bo_list *reloc;
1796
	struct evergreen_cs_track *track;
1775
	struct evergreen_cs_track *track;
1797
	volatile u32 *ib;
1776
	uint32_t *ib;
1798
	unsigned idx;
1777
	unsigned idx;
1799
	unsigned i;
1778
	unsigned i;
Line 1894... Line 1873...
1894
			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1873
			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1895
			return r;
1874
			return r;
1896
		}
1875
		}
1897
		break;
1876
		break;
1898
	}
1877
	}
-
 
1878
	case PACKET3_INDEX_BUFFER_SIZE:
-
 
1879
	{
-
 
1880
		if (pkt->count != 0) {
-
 
1881
			DRM_ERROR("bad INDEX_BUFFER_SIZE\n");
-
 
1882
			return -EINVAL;
-
 
1883
		}
-
 
1884
		break;
-
 
1885
	}
1899
	case PACKET3_DRAW_INDEX:
1886
	case PACKET3_DRAW_INDEX:
1900
	{
1887
	{
1901
		uint64_t offset;
1888
		uint64_t offset;
1902
		if (pkt->count != 3) {
1889
		if (pkt->count != 3) {
1903
			DRM_ERROR("bad DRAW_INDEX\n");
1890
			DRM_ERROR("bad DRAW_INDEX\n");
Line 2004... Line 1991...
2004
		if (r) {
1991
		if (r) {
2005
			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1992
			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
2006
			return r;
1993
			return r;
2007
		}
1994
		}
2008
		break;
1995
		break;
-
 
1996
	case PACKET3_SET_BASE:
-
 
1997
	{
-
 
1998
		/*
-
 
1999
		DW 1 HEADER Header of the packet. Shader_Type in bit 1 of the Header will correspond to the shader type of the Load, see Type-3 Packet.
-
 
2000
		   2 BASE_INDEX Bits [3:0] BASE_INDEX - Base Index specifies which base address is specified in the last two DWs.
-
 
2001
		     0001: DX11 Draw_Index_Indirect Patch Table Base: Base address for Draw_Index_Indirect data.
-
 
2002
		   3 ADDRESS_LO Bits [31:3] - Lower bits of QWORD-Aligned Address. Bits [2:0] - Reserved
-
 
2003
		   4 ADDRESS_HI Bits [31:8] - Reserved. Bits [7:0] - Upper bits of Address [47:32]
-
 
2004
		*/
-
 
2005
		if (pkt->count != 2) {
-
 
2006
			DRM_ERROR("bad SET_BASE\n");
-
 
2007
			return -EINVAL;
-
 
2008
		}
-
 
2009
 
-
 
2010
		/* currently only supporting setting indirect draw buffer base address */
-
 
2011
		if (idx_value != 1) {
-
 
2012
			DRM_ERROR("bad SET_BASE\n");
-
 
2013
			return -EINVAL;
-
 
2014
		}
-
 
2015
 
-
 
2016
		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
-
 
2017
		if (r) {
-
 
2018
			DRM_ERROR("bad SET_BASE\n");
-
 
2019
			return -EINVAL;
-
 
2020
		}
-
 
2021
 
-
 
2022
		track->indirect_draw_buffer_size = radeon_bo_size(reloc->robj);
-
 
2023
 
-
 
2024
		ib[idx+1] = reloc->gpu_offset;
-
 
2025
		ib[idx+2] = upper_32_bits(reloc->gpu_offset) & 0xff;
-
 
2026
 
-
 
2027
		break;
-
 
2028
	}
-
 
2029
	case PACKET3_DRAW_INDIRECT:
-
 
2030
	case PACKET3_DRAW_INDEX_INDIRECT:
-
 
2031
	{
-
 
2032
		u64 size = pkt->opcode == PACKET3_DRAW_INDIRECT ? 16 : 20;
-
 
2033
 
-
 
2034
		/*
-
 
2035
		DW 1 HEADER
-
 
2036
		   2 DATA_OFFSET Bits [31:0] + byte aligned offset where the required data structure starts. Bits 1:0 are zero
-
 
2037
		   3 DRAW_INITIATOR Draw Initiator Register. Written to the VGT_DRAW_INITIATOR register for the assigned context
-
 
2038
		*/
-
 
2039
		if (pkt->count != 1) {
-
 
2040
			DRM_ERROR("bad DRAW_INDIRECT\n");
-
 
2041
			return -EINVAL;
-
 
2042
		}
-
 
2043
 
-
 
2044
		if (idx_value + size > track->indirect_draw_buffer_size) {
-
 
2045
			dev_warn(p->dev, "DRAW_INDIRECT buffer too small %u + %llu > %lu\n",
-
 
2046
				idx_value, size, track->indirect_draw_buffer_size);
-
 
2047
			return -EINVAL;
-
 
2048
		}
-
 
2049
 
-
 
2050
		r = evergreen_cs_track_check(p);
-
 
2051
		if (r) {
-
 
2052
			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
-
 
2053
			return r;
-
 
2054
		}
-
 
2055
		break;
-
 
2056
	}
2009
	case PACKET3_DISPATCH_DIRECT:
2057
	case PACKET3_DISPATCH_DIRECT:
2010
		if (pkt->count != 3) {
2058
		if (pkt->count != 3) {
2011
			DRM_ERROR("bad DISPATCH_DIRECT\n");
2059
			DRM_ERROR("bad DISPATCH_DIRECT\n");
2012
			return -EINVAL;
2060
			return -EINVAL;
2013
		}
2061
		}
Line 2249... Line 2297...
2249
		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
2297
		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
2250
		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
2298
		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
2251
			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
2299
			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
2252
			return -EINVAL;
2300
			return -EINVAL;
2253
		}
2301
		}
2254
		for (i = 0; i < pkt->count; i++) {
2302
		for (reg = start_reg, idx++; reg <= end_reg; reg += 4, idx++) {
2255
			reg = start_reg + (4 * i);
2303
			if (evergreen_is_safe_reg(p, reg))
-
 
2304
				continue;
2256
			r = evergreen_cs_check_reg(p, reg, idx+1+i);
2305
			r = evergreen_cs_handle_reg(p, reg, idx);
2257
			if (r)
2306
			if (r)
2258
				return r;
2307
				return r;
2259
		}
2308
		}
2260
		break;
2309
		break;
2261
	case PACKET3_SET_CONTEXT_REG:
2310
	case PACKET3_SET_CONTEXT_REG:
Line 2265... Line 2314...
2265
		    (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
2314
		    (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
2266
		    (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
2315
		    (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
2267
			DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
2316
			DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
2268
			return -EINVAL;
2317
			return -EINVAL;
2269
		}
2318
		}
2270
		for (i = 0; i < pkt->count; i++) {
2319
		for (reg = start_reg, idx++; reg <= end_reg; reg += 4, idx++) {
2271
			reg = start_reg + (4 * i);
2320
			if (evergreen_is_safe_reg(p, reg))
-
 
2321
				continue;
2272
			r = evergreen_cs_check_reg(p, reg, idx+1+i);
2322
			r = evergreen_cs_handle_reg(p, reg, idx);
2273
			if (r)
2323
			if (r)
2274
				return r;
2324
				return r;
2275
		}
2325
		}
2276
		break;
2326
		break;
2277
	case PACKET3_SET_RESOURCE:
2327
	case PACKET3_SET_RESOURCE:
Line 2522... Line 2572...
2522
			ib[idx+1] = offset;
2572
			ib[idx+1] = offset;
2523
			ib[idx+2] = upper_32_bits(offset) & 0xff;
2573
			ib[idx+2] = upper_32_bits(offset) & 0xff;
2524
		} else {
2574
		} else {
2525
			/* SRC is a reg. */
2575
			/* SRC is a reg. */
2526
			reg = radeon_get_ib_value(p, idx+1) << 2;
2576
			reg = radeon_get_ib_value(p, idx+1) << 2;
2527
			if (!evergreen_is_safe_reg(p, reg, idx+1))
2577
			if (!evergreen_is_safe_reg(p, reg)) {
-
 
2578
				dev_warn(p->dev, "forbidden register 0x%08x at %d\n",
-
 
2579
					 reg, idx + 1);
2528
				return -EINVAL;
2580
				return -EINVAL;
2529
		}
2581
			}
-
 
2582
		}
2530
		if (idx_value & 0x2) {
2583
		if (idx_value & 0x2) {
2531
			u64 offset;
2584
			u64 offset;
2532
			/* DST is memory. */
2585
			/* DST is memory. */
2533
			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
2586
			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
2534
			if (r) {
2587
			if (r) {
Line 2546... Line 2599...
2546
			ib[idx+3] = offset;
2599
			ib[idx+3] = offset;
2547
			ib[idx+4] = upper_32_bits(offset) & 0xff;
2600
			ib[idx+4] = upper_32_bits(offset) & 0xff;
2548
		} else {
2601
		} else {
2549
			/* DST is a reg. */
2602
			/* DST is a reg. */
2550
			reg = radeon_get_ib_value(p, idx+3) << 2;
2603
			reg = radeon_get_ib_value(p, idx+3) << 2;
2551
			if (!evergreen_is_safe_reg(p, reg, idx+3))
2604
			if (!evergreen_is_safe_reg(p, reg)) {
-
 
2605
				dev_warn(p->dev, "forbidden register 0x%08x at %d\n",
-
 
2606
					 reg, idx + 3);
2552
				return -EINVAL;
2607
				return -EINVAL;
2553
		}
2608
			}
-
 
2609
		}
2554
		break;
2610
		break;
2555
	case PACKET3_NOP:
2611
	case PACKET3_NOP:
2556
		break;
2612
		break;
2557
	default:
2613
	default:
2558
		DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
2614
		DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
Line 2572... Line 2628...
2572
		/* initialize tracker, we are in kms */
2628
		/* initialize tracker, we are in kms */
2573
		track = kzalloc(sizeof(*track), GFP_KERNEL);
2629
		track = kzalloc(sizeof(*track), GFP_KERNEL);
2574
		if (track == NULL)
2630
		if (track == NULL)
2575
			return -ENOMEM;
2631
			return -ENOMEM;
2576
		evergreen_cs_track_init(track);
2632
		evergreen_cs_track_init(track);
2577
		if (p->rdev->family >= CHIP_CAYMAN)
2633
		if (p->rdev->family >= CHIP_CAYMAN) {
2578
			tmp = p->rdev->config.cayman.tile_config;
2634
			tmp = p->rdev->config.cayman.tile_config;
-
 
2635
			track->reg_safe_bm = cayman_reg_safe_bm;
2579
		else
2636
		} else {
2580
			tmp = p->rdev->config.evergreen.tile_config;
2637
			tmp = p->rdev->config.evergreen.tile_config;
-
 
2638
			track->reg_safe_bm = evergreen_reg_safe_bm;
2581
 
2639
		}
-
 
2640
		BUILD_BUG_ON(ARRAY_SIZE(cayman_reg_safe_bm) != REG_SAFE_BM_SIZE);
-
 
2641
		BUILD_BUG_ON(ARRAY_SIZE(evergreen_reg_safe_bm) != REG_SAFE_BM_SIZE);
2582
		switch (tmp & 0xf) {
2642
		switch (tmp & 0xf) {
2583
		case 0:
2643
		case 0:
2584
			track->npipes = 1;
2644
			track->npipes = 1;
2585
			break;
2645
			break;
2586
		case 1:
2646
		case 1:
Line 2685... Line 2745...
2685
int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
2745
int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
2686
{
2746
{
2687
	struct radeon_cs_chunk *ib_chunk = p->chunk_ib;
2747
	struct radeon_cs_chunk *ib_chunk = p->chunk_ib;
2688
	struct radeon_bo_list *src_reloc, *dst_reloc, *dst2_reloc;
2748
	struct radeon_bo_list *src_reloc, *dst_reloc, *dst2_reloc;
2689
	u32 header, cmd, count, sub_cmd;
2749
	u32 header, cmd, count, sub_cmd;
2690
	volatile u32 *ib = p->ib.ptr;
2750
	uint32_t *ib = p->ib.ptr;
2691
	u32 idx;
2751
	u32 idx;
2692
	u64 src_offset, dst_offset, dst2_offset;
2752
	u64 src_offset, dst_offset, dst2_offset;
2693
	int r;
2753
	int r;
Line 2694... Line 2754...
2694
 
2754
 
Line 3241... Line 3301...
3241
	u32 start_reg, end_reg, reg, i;
3301
	u32 start_reg, end_reg, reg, i;
3242
	u32 command, info;
3302
	u32 command, info;
Line 3243... Line 3303...
3243
 
3303
 
3244
	switch (pkt->opcode) {
3304
	switch (pkt->opcode) {
-
 
3305
	case PACKET3_NOP:
3245
	case PACKET3_NOP:
3306
		break;
-
 
3307
	case PACKET3_SET_BASE:
-
 
3308
		if (idx_value != 1) {
-
 
3309
			DRM_ERROR("bad SET_BASE");
-
 
3310
			return -EINVAL;
-
 
3311
		}
3246
	case PACKET3_SET_BASE:
3312
		break;
3247
	case PACKET3_CLEAR_STATE:
3313
	case PACKET3_CLEAR_STATE:
3248
	case PACKET3_INDEX_BUFFER_SIZE:
3314
	case PACKET3_INDEX_BUFFER_SIZE:
3249
	case PACKET3_DISPATCH_DIRECT:
3315
	case PACKET3_DISPATCH_DIRECT:
3250
	case PACKET3_DISPATCH_INDIRECT:
3316
	case PACKET3_DISPATCH_INDIRECT: