Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6103 → Rev 6104

/drivers/video/drm/radeon/evergreen_cs.c
34,6 → 34,8
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
 
#define REG_SAFE_BM_SIZE ARRAY_SIZE(evergreen_reg_safe_bm)
 
int r600_dma_cs_next_reloc(struct radeon_cs_parser *p,
struct radeon_bo_list **cs_reloc);
struct evergreen_cs_track {
83,6 → 85,8
u32 htile_offset;
u32 htile_surface;
struct radeon_bo *htile_bo;
unsigned long indirect_draw_buffer_size;
const unsigned *reg_safe_bm;
};
 
static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
443,7 → 447,7
* command stream.
*/
if (!surf.mode) {
volatile u32 *ib = p->ib.ptr;
uint32_t *ib = p->ib.ptr;
unsigned long tmp, nby, bsize, size, min = 0;
 
/* find the height the ddx wants */
1082,41 → 1086,18
}
 
/**
* evergreen_cs_check_reg() - check if register is authorized or not
* evergreen_cs_handle_reg() - process registers that need special handling.
* @parser: parser structure holding parsing context
* @reg: register we are testing
* @idx: index into the cs buffer
*
* This function will test against evergreen_reg_safe_bm and return 0
* if register is safe. If register is not flag as safe this function
* will test it against a list of register needind special handling.
*/
static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
static int evergreen_cs_handle_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
{
struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track;
struct radeon_bo_list *reloc;
u32 last_reg;
u32 m, i, tmp, *ib;
u32 tmp, *ib;
int r;
 
if (p->rdev->family >= CHIP_CAYMAN)
last_reg = ARRAY_SIZE(cayman_reg_safe_bm);
else
last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
 
i = (reg >> 7);
if (i >= last_reg) {
dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
return -EINVAL;
}
m = 1 << ((reg >> 2) & 31);
if (p->rdev->family >= CHIP_CAYMAN) {
if (!(cayman_reg_safe_bm[i] & m))
return 0;
} else {
if (!(evergreen_reg_safe_bm[i] & m))
return 0;
}
ib = p->ib.ptr;
switch (reg) {
/* force following reg to 0 in an attempt to disable out buffer
1763,29 → 1744,27
return 0;
}
 
static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
/**
* evergreen_is_safe_reg() - check if register is authorized or not
* @parser: parser structure holding parsing context
* @reg: register we are testing
*
* This function will test against reg_safe_bm and return true
* if register is safe or false otherwise.
*/
static inline bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg)
{
u32 last_reg, m, i;
struct evergreen_cs_track *track = p->track;
u32 m, i;
 
if (p->rdev->family >= CHIP_CAYMAN)
last_reg = ARRAY_SIZE(cayman_reg_safe_bm);
else
last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
 
i = (reg >> 7);
if (i >= last_reg) {
dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
if (unlikely(i >= REG_SAFE_BM_SIZE)) {
return false;
}
m = 1 << ((reg >> 2) & 31);
if (p->rdev->family >= CHIP_CAYMAN) {
if (!(cayman_reg_safe_bm[i] & m))
if (!(track->reg_safe_bm[i] & m))
return true;
} else {
if (!(evergreen_reg_safe_bm[i] & m))
return true;
}
dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
 
return false;
}
 
1794,7 → 1773,7
{
struct radeon_bo_list *reloc;
struct evergreen_cs_track *track;
volatile u32 *ib;
uint32_t *ib;
unsigned idx;
unsigned i;
unsigned start_reg, end_reg, reg;
1896,6 → 1875,14
}
break;
}
case PACKET3_INDEX_BUFFER_SIZE:
{
if (pkt->count != 0) {
DRM_ERROR("bad INDEX_BUFFER_SIZE\n");
return -EINVAL;
}
break;
}
case PACKET3_DRAW_INDEX:
{
uint64_t offset;
2006,6 → 1993,67
return r;
}
break;
case PACKET3_SET_BASE:
{
/*
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.
2 BASE_INDEX Bits [3:0] BASE_INDEX - Base Index specifies which base address is specified in the last two DWs.
0001: DX11 Draw_Index_Indirect Patch Table Base: Base address for Draw_Index_Indirect data.
3 ADDRESS_LO Bits [31:3] - Lower bits of QWORD-Aligned Address. Bits [2:0] - Reserved
4 ADDRESS_HI Bits [31:8] - Reserved. Bits [7:0] - Upper bits of Address [47:32]
*/
if (pkt->count != 2) {
DRM_ERROR("bad SET_BASE\n");
return -EINVAL;
}
 
/* currently only supporting setting indirect draw buffer base address */
if (idx_value != 1) {
DRM_ERROR("bad SET_BASE\n");
return -EINVAL;
}
 
r = radeon_cs_packet_next_reloc(p, &reloc, 0);
if (r) {
DRM_ERROR("bad SET_BASE\n");
return -EINVAL;
}
 
track->indirect_draw_buffer_size = radeon_bo_size(reloc->robj);
 
ib[idx+1] = reloc->gpu_offset;
ib[idx+2] = upper_32_bits(reloc->gpu_offset) & 0xff;
 
break;
}
case PACKET3_DRAW_INDIRECT:
case PACKET3_DRAW_INDEX_INDIRECT:
{
u64 size = pkt->opcode == PACKET3_DRAW_INDIRECT ? 16 : 20;
 
/*
DW 1 HEADER
2 DATA_OFFSET Bits [31:0] + byte aligned offset where the required data structure starts. Bits 1:0 are zero
3 DRAW_INITIATOR Draw Initiator Register. Written to the VGT_DRAW_INITIATOR register for the assigned context
*/
if (pkt->count != 1) {
DRM_ERROR("bad DRAW_INDIRECT\n");
return -EINVAL;
}
 
if (idx_value + size > track->indirect_draw_buffer_size) {
dev_warn(p->dev, "DRAW_INDIRECT buffer too small %u + %llu > %lu\n",
idx_value, size, track->indirect_draw_buffer_size);
return -EINVAL;
}
 
r = evergreen_cs_track_check(p);
if (r) {
dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
return r;
}
break;
}
case PACKET3_DISPATCH_DIRECT:
if (pkt->count != 3) {
DRM_ERROR("bad DISPATCH_DIRECT\n");
2251,9 → 2299,10
DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
return -EINVAL;
}
for (i = 0; i < pkt->count; i++) {
reg = start_reg + (4 * i);
r = evergreen_cs_check_reg(p, reg, idx+1+i);
for (reg = start_reg, idx++; reg <= end_reg; reg += 4, idx++) {
if (evergreen_is_safe_reg(p, reg))
continue;
r = evergreen_cs_handle_reg(p, reg, idx);
if (r)
return r;
}
2267,9 → 2316,10
DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
return -EINVAL;
}
for (i = 0; i < pkt->count; i++) {
reg = start_reg + (4 * i);
r = evergreen_cs_check_reg(p, reg, idx+1+i);
for (reg = start_reg, idx++; reg <= end_reg; reg += 4, idx++) {
if (evergreen_is_safe_reg(p, reg))
continue;
r = evergreen_cs_handle_reg(p, reg, idx);
if (r)
return r;
}
2524,9 → 2574,12
} else {
/* SRC is a reg. */
reg = radeon_get_ib_value(p, idx+1) << 2;
if (!evergreen_is_safe_reg(p, reg, idx+1))
if (!evergreen_is_safe_reg(p, reg)) {
dev_warn(p->dev, "forbidden register 0x%08x at %d\n",
reg, idx + 1);
return -EINVAL;
}
}
if (idx_value & 0x2) {
u64 offset;
/* DST is memory. */
2548,9 → 2601,12
} else {
/* DST is a reg. */
reg = radeon_get_ib_value(p, idx+3) << 2;
if (!evergreen_is_safe_reg(p, reg, idx+3))
if (!evergreen_is_safe_reg(p, reg)) {
dev_warn(p->dev, "forbidden register 0x%08x at %d\n",
reg, idx + 3);
return -EINVAL;
}
}
break;
case PACKET3_NOP:
break;
2574,11 → 2630,15
if (track == NULL)
return -ENOMEM;
evergreen_cs_track_init(track);
if (p->rdev->family >= CHIP_CAYMAN)
if (p->rdev->family >= CHIP_CAYMAN) {
tmp = p->rdev->config.cayman.tile_config;
else
track->reg_safe_bm = cayman_reg_safe_bm;
} else {
tmp = p->rdev->config.evergreen.tile_config;
 
track->reg_safe_bm = evergreen_reg_safe_bm;
}
BUILD_BUG_ON(ARRAY_SIZE(cayman_reg_safe_bm) != REG_SAFE_BM_SIZE);
BUILD_BUG_ON(ARRAY_SIZE(evergreen_reg_safe_bm) != REG_SAFE_BM_SIZE);
switch (tmp & 0xf) {
case 0:
track->npipes = 1;
2687,7 → 2747,7
struct radeon_cs_chunk *ib_chunk = p->chunk_ib;
struct radeon_bo_list *src_reloc, *dst_reloc, *dst2_reloc;
u32 header, cmd, count, sub_cmd;
volatile u32 *ib = p->ib.ptr;
uint32_t *ib = p->ib.ptr;
u32 idx;
u64 src_offset, dst_offset, dst2_offset;
int r;
3243,7 → 3303,13
 
switch (pkt->opcode) {
case PACKET3_NOP:
break;
case PACKET3_SET_BASE:
if (idx_value != 1) {
DRM_ERROR("bad SET_BASE");
return -EINVAL;
}
break;
case PACKET3_CLEAR_STATE:
case PACKET3_INDEX_BUFFER_SIZE:
case PACKET3_DISPATCH_DIRECT: