r300: initial command stream parser for packet 0.
this at least parses the DDX stream and lets me run gnome-terminal/metacitymain
parent
38835f9cd2
commit
dc3a7c023d
|
@ -3125,6 +3125,7 @@
|
||||||
# define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000
|
# define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000
|
||||||
# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12)
|
# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12)
|
||||||
# define RADEON_CP_PACKET0_REG_MASK 0x000007ff
|
# define RADEON_CP_PACKET0_REG_MASK 0x000007ff
|
||||||
|
# define R300_CP_PACKET0_REG_MASK 0x00001fff
|
||||||
# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff
|
# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff
|
||||||
# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800
|
# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800
|
||||||
|
|
||||||
|
|
|
@ -151,8 +151,6 @@ void r300_init_reg_flags(struct drm_device *dev)
|
||||||
for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
|
for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
|
||||||
r300_reg_flags[i]|=(mark);
|
r300_reg_flags[i]|=(mark);
|
||||||
|
|
||||||
#define MARK_SAFE 1
|
|
||||||
#define MARK_CHECK_OFFSET 2
|
|
||||||
|
|
||||||
#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
|
#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
|
||||||
|
|
||||||
|
@ -234,6 +232,11 @@ void r300_init_reg_flags(struct drm_device *dev)
|
||||||
ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
|
ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
|
||||||
ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
|
ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
|
||||||
|
|
||||||
|
ADD_RANGE(R500_SU_REG_DEST, 1);
|
||||||
|
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV410) {
|
||||||
|
ADD_RANGE(R300_DST_PIPE_CONFIG, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
|
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
|
||||||
ADD_RANGE(R500_VAP_INDEX_OFFSET, 1);
|
ADD_RANGE(R500_VAP_INDEX_OFFSET, 1);
|
||||||
ADD_RANGE(R500_US_CONFIG, 2);
|
ADD_RANGE(R500_US_CONFIG, 2);
|
||||||
|
@ -243,6 +246,8 @@ void r300_init_reg_flags(struct drm_device *dev)
|
||||||
ADD_RANGE(R500_RS_INST_0, 16);
|
ADD_RANGE(R500_RS_INST_0, 16);
|
||||||
ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
|
ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
|
||||||
ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2);
|
ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2);
|
||||||
|
|
||||||
|
ADD_RANGE(R500_GA_US_VECTOR_INDEX, 2);
|
||||||
} else {
|
} else {
|
||||||
ADD_RANGE(R300_PFS_CNTL_0, 3);
|
ADD_RANGE(R300_PFS_CNTL_0, 3);
|
||||||
ADD_RANGE(R300_PFS_NODE_0, 4);
|
ADD_RANGE(R300_PFS_NODE_0, 4);
|
||||||
|
@ -255,9 +260,39 @@ void r300_init_reg_flags(struct drm_device *dev)
|
||||||
ADD_RANGE(R300_RS_ROUTE_0, 8);
|
ADD_RANGE(R300_RS_ROUTE_0, 8);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add 2d blit engine registers for DDX */
|
||||||
|
ADD_RANGE(RADEON_SRC_Y_X, 3); /* 1434, 1438, 143c,
|
||||||
|
SRC_Y_X, DST_Y_X, DST_HEIGHT_WIDTH
|
||||||
|
*/
|
||||||
|
ADD_RANGE(RADEON_DP_GUI_MASTER_CNTL, 1); /* 146c */
|
||||||
|
ADD_RANGE(RADEON_DP_BRUSH_BKGD_CLR, 2); /* 1478, 147c */
|
||||||
|
ADD_RANGE(RADEON_DP_SRC_FRGD_CLR, 2); /* 15d8, 15dc */
|
||||||
|
ADD_RANGE(RADEON_DP_CNTL, 1); /* 16c0 */
|
||||||
|
ADD_RANGE(RADEON_DP_WRITE_MASK, 1); /* 16cc */
|
||||||
|
ADD_RANGE(RADEON_DEFAULT_SC_BOTTOM_RIGHT, 1); /* 16e8 */
|
||||||
|
|
||||||
|
ADD_RANGE(RADEON_DSTCACHE_CTLSTAT, 1);
|
||||||
|
ADD_RANGE(RADEON_WAIT_UNTIL, 1);
|
||||||
|
|
||||||
|
ADD_RANGE_MARK(RADEON_DST_OFFSET, 1, MARK_CHECK_OFFSET);
|
||||||
|
ADD_RANGE_MARK(RADEON_SRC_OFFSET, 1, MARK_CHECK_OFFSET);
|
||||||
|
|
||||||
|
ADD_RANGE_MARK(RADEON_DST_PITCH_OFFSET, 1, MARK_CHECK_OFFSET);
|
||||||
|
ADD_RANGE_MARK(RADEON_SRC_PITCH_OFFSET, 1, MARK_CHECK_OFFSET);
|
||||||
|
|
||||||
|
/* TODO SCISSOR */
|
||||||
|
ADD_RANGE_MARK(R300_SC_SCISSOR0, 2, MARK_CHECK_SCISSOR);
|
||||||
|
|
||||||
|
ADD_RANGE(R300_SC_CLIP_0_A, 2);
|
||||||
|
ADD_RANGE(R300_SC_CLIP_RULE, 1);
|
||||||
|
ADD_RANGE(R300_SC_SCREENDOOR, 1);
|
||||||
|
|
||||||
|
ADD_RANGE(R300_VAP_PVS_CODE_CNTL_0, 4);
|
||||||
|
ADD_RANGE(R300_VAP_PVS_VECTOR_INDX_REG, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ int r300_check_range(unsigned reg, int count)
|
int r300_check_range(unsigned reg, int count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (reg & ~0xffff)
|
if (reg & ~0xffff)
|
||||||
|
@ -268,6 +303,13 @@ static __inline__ int r300_check_range(unsigned reg, int count)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int r300_get_reg_flags(unsigned reg)
|
||||||
|
{
|
||||||
|
if (reg & ~0xffff)
|
||||||
|
return -1;
|
||||||
|
return r300_reg_flags[(reg >> 2)];
|
||||||
|
}
|
||||||
|
|
||||||
static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
|
static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
|
||||||
dev_priv,
|
dev_priv,
|
||||||
drm_radeon_kcmd_buffer_t
|
drm_radeon_kcmd_buffer_t
|
||||||
|
|
|
@ -2301,6 +2301,8 @@ int radeon_modeset_cp_init(struct drm_device *dev)
|
||||||
|
|
||||||
dev_priv->new_memmap = 1;
|
dev_priv->new_memmap = 1;
|
||||||
|
|
||||||
|
r300_init_reg_flags(dev);
|
||||||
|
|
||||||
radeon_cp_load_microcode(dev_priv);
|
radeon_cp_load_microcode(dev_priv);
|
||||||
|
|
||||||
DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset);
|
DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset);
|
||||||
|
|
|
@ -88,11 +88,84 @@ out:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int radeon_cs_packet0(struct drm_device *dev, uint32_t *packets,
|
||||||
|
uint32_t offset_dw)
|
||||||
|
{
|
||||||
|
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||||
|
int hdr = packets[offset_dw];
|
||||||
|
int num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
|
||||||
|
int need_reloc = 0;
|
||||||
|
int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
|
||||||
|
int count_dw = 1;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while (count_dw < num_dw) {
|
||||||
|
/* need to have something like the r300 validation here -
|
||||||
|
list of allowed registers */
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
ret = r300_check_range(reg, 1);
|
||||||
|
switch(ret) {
|
||||||
|
case -1:
|
||||||
|
DRM_ERROR("Illegal register %x\n", reg);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
flags = r300_get_reg_flags(reg);
|
||||||
|
if (flags == MARK_CHECK_OFFSET)
|
||||||
|
DRM_DEBUG("need to relocate %x %d\n", reg, flags);
|
||||||
|
else if (flags == MARK_CHECK_SCISSOR) {
|
||||||
|
DRM_DEBUG("need to validate scissor %x %d\n", reg, flags);
|
||||||
|
} else {
|
||||||
|
DRM_DEBUG("illegal register %x %d\n", reg, flags);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count_dw++;
|
||||||
|
reg += 4;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int radeon_cs_parse(struct drm_device *dev, void *ib,
|
int radeon_cs_parse(struct drm_device *dev, void *ib,
|
||||||
uint32_t *packets, uint32_t dwords)
|
uint32_t *packets, uint32_t dwords)
|
||||||
{
|
{
|
||||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||||
volatile int rb;
|
volatile int rb;
|
||||||
|
int size_dw = dwords;
|
||||||
|
/* scan the packet for various things */
|
||||||
|
int count_dw = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
while (count_dw < size_dw && ret == 0) {
|
||||||
|
int hdr = packets[count_dw];
|
||||||
|
int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
|
||||||
|
int reg;
|
||||||
|
|
||||||
|
switch (hdr & RADEON_CP_PACKET_MASK) {
|
||||||
|
case RADEON_CP_PACKET0:
|
||||||
|
ret = radeon_cs_packet0(dev, packets, count_dw);
|
||||||
|
break;
|
||||||
|
case RADEON_CP_PACKET1:
|
||||||
|
case RADEON_CP_PACKET2:
|
||||||
|
reg = hdr & RADEON_CP_PACKET0_REG_MASK;
|
||||||
|
DRM_DEBUG("Packet 1/2: %d %x\n", num_dw, reg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RADEON_CP_PACKET3:
|
||||||
|
reg = hdr & 0xff00;
|
||||||
|
DRM_DEBUG("Packet 3: %d %x\n", num_dw, reg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
count_dw += num_dw+2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
|
||||||
/* copy the packet into the IB */
|
/* copy the packet into the IB */
|
||||||
memcpy(ib, packets, dwords * sizeof(uint32_t));
|
memcpy(ib, packets, dwords * sizeof(uint32_t));
|
||||||
|
|
|
@ -1619,4 +1619,11 @@ extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *mas
|
||||||
extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master);
|
extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master);
|
||||||
extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
|
extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
|
||||||
extern int radeon_cs_init(struct drm_device *dev);
|
extern int radeon_cs_init(struct drm_device *dev);
|
||||||
|
|
||||||
|
#define MARK_SAFE 1
|
||||||
|
#define MARK_CHECK_OFFSET 2
|
||||||
|
#define MARK_CHECK_SCISSOR 3
|
||||||
|
|
||||||
|
extern int r300_check_range(unsigned reg, int count);
|
||||||
|
extern int r300_get_reg_flags(unsigned reg);
|
||||||
#endif /* __RADEON_DRV_H__ */
|
#endif /* __RADEON_DRV_H__ */
|
||||||
|
|
Loading…
Reference in New Issue