#include "via_3d_reg.h"
#include "drmP.h"
+#include "drm.h"
+#include "via_drm.h"
+#include "via_verifier.h"
+#include "via_drv.h"
typedef enum{
state_command,
state_error
} verifier_state_t;
-typedef enum{
- no_sequence = 0,
- z_address,
- dest_address,
- tex_address
-}sequence_t;
-
typedef enum{
no_check = 0,
* that does not include any part of the address.
*/
-static sequence_t seqs[] = {
+static drm_via_sequence_t seqs[] = {
no_sequence,
no_sequence,
no_sequence,
-typedef struct{
- unsigned texture;
- uint32_t z_addr;
- uint32_t d_addr;
- uint32_t t_addr[2][10];
- uint32_t pitch[2][10];
- uint32_t height[2][10];
- uint32_t tex_level_lo[2];
- uint32_t tex_level_hi[2];
- uint32_t tex_palette_size[2];
- sequence_t unfinished;
- int agp_texture;
- int multitex;
- drm_device_t *dev;
- drm_map_t *map_cache;
- uint32_t vertex_count;
-} sequence_context_t;
-
-static sequence_context_t hc_sequence;
-
-
static __inline__ int
eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words)
{
*/
static __inline__ drm_map_t *
-via_drm_lookup_agp_map (sequence_context_t *seq, unsigned long offset, unsigned long size,
+via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned long size,
drm_device_t *dev)
{
struct list_head *list;
static __inline__ int
-finish_current_sequence(sequence_context_t *cur_seq)
+finish_current_sequence(drm_via_state_t *cur_seq)
{
switch(cur_seq->unfinished) {
case z_address:
}
static __inline__ int
-investigate_hazard( uint32_t cmd, hazard_t hz, sequence_context_t *cur_seq)
+investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
{
register uint32_t tmp, *tmp_addr;
static __inline__ int
via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
- sequence_context_t *cur_seq)
+ drm_via_state_t *cur_seq)
{
uint32_t a_fire, bcmd , dw_count;
int ret = 0;
* How many dwords per vertex ?
*/
- if ((bcmd & (0xF << 11)) == 0) {
+ if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) {
DRM_ERROR("Illegal B command vertex data for AGP.\n");
ret = 1;
break;
if (bcmd & (1 << 14)) dw_count++;
while(buf < buf_end) {
- if (*buf == HALCYON_HEADER2) {
- DRM_ERROR("Missing Vertex Fire command or verifier "
- "lost sync.\n");
- ret = 1;
- break;
- }
if (*buf == a_fire) {
have_fire = 1;
buf++;
buf++;
break;
}
- if ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD) {
- DRM_ERROR("Stray Vertex Fire command encountered.\n");
+ if ((*buf == HALCYON_HEADER2) ||
+ ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) {
+ DRM_ERROR("Missing Vertex Fire command, "
+ "Stray Vertex Fire command or verifier "
+ "lost sync.\n");
ret = 1;
break;
}
ret = 1;
break;
}
+ if (cur_seq->agp && ((buf - cur_seq->buf_start) & 0x01)) {
+ DRM_ERROR("AGP Primitive list end misaligned.\n");
+ ret = 1;
+ break;
+ }
}
*buffer = buf;
return ret;
static __inline__ verifier_state_t
-via_check_header2( uint32_t const **buffer, const uint32_t *buf_end )
+via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
+ drm_via_state_t *hc_state)
{
uint32_t cmd;
int hz_mode;
switch(cmd) {
case HC_ParaType_CmdVdata:
- if (via_check_prim_list(&buf, buf_end, &hc_sequence ))
+ if (via_check_prim_list(&buf, buf_end, hc_state ))
return state_error;
*buffer = buf;
return state_command;
hz_table = table1;
break;
case HC_ParaType_Tex:
- hc_sequence.texture = 0;
+ hc_state->texture = 0;
hz_table = table2;
break;
case (HC_ParaType_Tex | (HC_SubType_Tex1 << 8)):
- hc_sequence.texture = 1;
+ hc_state->texture = 1;
hz_table = table2;
break;
case (HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)):
while(buf < buf_end) {
cmd = *buf++;
if ((hz = hz_table[cmd >> 24])) {
- if ((hz_mode = investigate_hazard(cmd, hz, &hc_sequence))) {
+ if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) {
if (hz_mode == 1) {
buf--;
break;
}
return state_error;
}
- } else if (hc_sequence.unfinished &&
- finish_current_sequence(&hc_sequence)) {
+ } else if (hc_state->unfinished &&
+ finish_current_sequence(hc_state)) {
return state_error;
}
}
- if (hc_sequence.unfinished && finish_current_sequence(&hc_sequence)) {
+ if (hc_state->unfinished && finish_current_sequence(hc_state)) {
return state_error;
}
*buffer = buf;
int
-via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t *dev)
+via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t *dev,
+ int agp)
{
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ drm_via_state_t *hc_state = &dev_priv->hc_state;
+ drm_via_state_t saved_state = *hc_state;
uint32_t cmd;
const uint32_t *buf_end = buf + ( size >> 2 );
verifier_state_t state = state_command;
- hc_sequence.dev = dev;
- hc_sequence.unfinished = no_sequence;
- hc_sequence.map_cache = NULL;
+
+ hc_state->dev = dev;
+ hc_state->unfinished = no_sequence;
+ hc_state->map_cache = NULL;
+ hc_state->agp = agp;
+ hc_state->buf_start = buf;
while (buf < buf_end) {
switch (state) {
case state_header2:
- state = via_check_header2( &buf, buf_end );
+ state = via_check_header2( &buf, buf_end, hc_state );
break;
case state_header1:
state = via_check_header1( &buf, buf_end );
break;
case state_error:
default:
+ *hc_state = saved_state;
return DRM_ERR(EINVAL);
}
}
- return (state == state_error) ? DRM_ERR(EINVAL) : 0;
+ if (state == state_error) {
+ *hc_state = saved_state;
+ return DRM_ERR(EINVAL);
+ }
+ return 0;
}
static void
void
via_init_command_verifier( void )
{
- hc_sequence.texture = 0;
setup_hazard_table(init_table1, table1, sizeof(init_table1) / sizeof(hz_init_t));
setup_hazard_table(init_table2, table2, sizeof(init_table2) / sizeof(hz_init_t));
setup_hazard_table(init_table3, table3, sizeof(init_table3) / sizeof(hz_init_t));
--- /dev/null
+/*
+ * Copyright 2004 The Unichrome Project. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE UNICHROME PROJECT, 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.
+ *
+ * Author: Thomas Hellström 2004.
+ */
+
+#ifndef _VIA_VERIFIER_H_
+#define _VIA_VERIFIER_H_
+
+typedef enum{
+ no_sequence = 0,
+ z_address,
+ dest_address,
+ tex_address
+}drm_via_sequence_t;
+
+
+
+typedef struct{
+ unsigned texture;
+ uint32_t z_addr;
+ uint32_t d_addr;
+ uint32_t t_addr[2][10];
+ uint32_t pitch[2][10];
+ uint32_t height[2][10];
+ uint32_t tex_level_lo[2];
+ uint32_t tex_level_hi[2];
+ uint32_t tex_palette_size[2];
+ drm_via_sequence_t unfinished;
+ int agp_texture;
+ int multitex;
+ drm_device_t *dev;
+ drm_map_t *map_cache;
+ uint32_t vertex_count;
+ int agp;
+ const uint32_t *buf_start;
+} drm_via_state_t;
+
+extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
+ drm_device_t *dev, int agp);
+
+#endif