122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie/* 222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Copyright 2004 The Unichrome Project. All Rights Reserved. 322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Copyright 2005 Thomas Hellstrom. All Rights Reserved. 422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * 522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a 622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * copy of this software and associated documentation files (the "Software"), 722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * to deal in the Software without restriction, including without limitation 822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * the rights to use, copy, modify, merge, publish, distribute, sub license, 922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * and/or sell copies of the Software, and to permit persons to whom the 1022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Software is furnished to do so, subject to the following conditions: 1122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * 1222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * The above copyright notice and this permission notice (including the 1322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * next paragraph) shall be included in all copies or substantial portions 1422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * of the Software. 1522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * 1622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 2022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * DEALINGS IN THE SOFTWARE. 2322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * 2422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Author: Thomas Hellstrom 2004, 2005. 2522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * This code was written using docs obtained under NDA from VIA Inc. 2622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * 2722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Don't run this code directly on an AGP buffer. Due to cache problems it will 2822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * be very slow. 2922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie */ 3022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 3122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie#include "via_3d_reg.h" 3222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie#include "drmP.h" 3322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie#include "drm.h" 3422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie#include "via_drm.h" 3522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie#include "via_verifier.h" 3622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie#include "via_drv.h" 3722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 38b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlietypedef enum { 3922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state_command, 4022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state_header2, 4122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state_header1, 4222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state_vheader5, 4322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state_vheader6, 4422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state_error 4522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} verifier_state_t; 4622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 47b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlietypedef enum { 4822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_check = 0, 4922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_for_header2, 5022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_for_header1, 5122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_for_header2_err, 5222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_for_header1_err, 5322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_for_fire, 5422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_z_buffer_addr0, 5522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_z_buffer_addr1, 5622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_z_buffer_addr_mode, 5722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_destination_addr0, 5822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_destination_addr1, 5922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_destination_addr_mode, 6022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_for_dummy, 6122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_for_dd, 6222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr0, 6322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr1, 6422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr2, 6522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr3, 6622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr4, 6722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr5, 6822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr6, 6922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr7, 7022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr8, 7122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_texture_addr_mode, 7222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_for_vertex_count, 7322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie check_number_texunits, 7422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie forbidden_command 75b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie} hazard_t; 7622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 7722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie/* 7822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Associates each hazard above with a possible multi-command 7922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * sequence. For example an address that is split over multiple 80b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie * commands and that needs to be checked at the first command 8122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * that does not include any part of the address. 8222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie */ 8322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 84b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airliestatic drm_via_sequence_t seqs[] = { 8522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence, 8622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence, 8722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence, 8822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence, 8922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence, 9022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence, 9122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie z_address, 9222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie z_address, 9322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie z_address, 9422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie dest_address, 9522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie dest_address, 9622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie dest_address, 9722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence, 9822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence, 9922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tex_address, 10922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie no_sequence 11022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie}; 111b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 112b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlietypedef struct { 11322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie unsigned int code; 11422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hazard_t hz; 11522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} hz_init_t; 11622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 11722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic hz_init_t init_table1[] = { 11822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xf2, check_for_header2_err}, 11922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xf0, check_for_header1_err}, 12022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xee, check_for_fire}, 12122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xcc, check_for_dummy}, 12222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xdd, check_for_dd}, 12322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x00, no_check}, 12422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x10, check_z_buffer_addr0}, 12522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x11, check_z_buffer_addr1}, 12622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x12, check_z_buffer_addr_mode}, 12722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x13, no_check}, 12822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x14, no_check}, 12922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x15, no_check}, 13022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x23, no_check}, 13122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x24, no_check}, 13222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x33, no_check}, 13322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x34, no_check}, 13422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x35, no_check}, 13522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x36, no_check}, 13622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x37, no_check}, 13722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x38, no_check}, 13822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x39, no_check}, 13922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x3A, no_check}, 14022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x3B, no_check}, 14122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x3C, no_check}, 14222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x3D, no_check}, 14322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x3E, no_check}, 14422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x40, check_destination_addr0}, 14522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x41, check_destination_addr1}, 14622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x42, check_destination_addr_mode}, 14722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x43, no_check}, 14822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x44, no_check}, 14922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x50, no_check}, 15022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x51, no_check}, 15122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x52, no_check}, 15222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x53, no_check}, 15322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x54, no_check}, 15422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x55, no_check}, 15522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x56, no_check}, 15622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x57, no_check}, 15722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x58, no_check}, 15822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x70, no_check}, 15922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x71, no_check}, 16022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x78, no_check}, 16122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x79, no_check}, 16222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7A, no_check}, 16322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7B, no_check}, 16422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7C, no_check}, 16522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7D, check_for_vertex_count} 16622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie}; 16722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 16822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic hz_init_t init_table2[] = { 16922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xf2, check_for_header2_err}, 17022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xf0, check_for_header1_err}, 17122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xee, check_for_fire}, 17222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xcc, check_for_dummy}, 17322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x00, check_texture_addr0}, 17422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x01, check_texture_addr0}, 17522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x02, check_texture_addr0}, 17622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x03, check_texture_addr0}, 17722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x04, check_texture_addr0}, 17822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x05, check_texture_addr0}, 17922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x06, check_texture_addr0}, 18022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x07, check_texture_addr0}, 18122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x08, check_texture_addr0}, 18222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x09, check_texture_addr0}, 18322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x20, check_texture_addr1}, 18422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x21, check_texture_addr1}, 18522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x22, check_texture_addr1}, 18622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x23, check_texture_addr4}, 18722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x2B, check_texture_addr3}, 18822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x2C, check_texture_addr3}, 18922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x2D, check_texture_addr3}, 19022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x2E, check_texture_addr3}, 19122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x2F, check_texture_addr3}, 19222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x30, check_texture_addr3}, 19322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x31, check_texture_addr3}, 19422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x32, check_texture_addr3}, 19522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x33, check_texture_addr3}, 19622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x34, check_texture_addr3}, 19722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x4B, check_texture_addr5}, 19822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x4C, check_texture_addr6}, 19922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x51, check_texture_addr7}, 20022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x52, check_texture_addr8}, 20122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x77, check_texture_addr2}, 20222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x78, no_check}, 20322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x79, no_check}, 20422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7A, no_check}, 20522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7B, check_texture_addr_mode}, 20622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7C, no_check}, 20722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7D, no_check}, 20822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7E, no_check}, 20922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x7F, no_check}, 21022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x80, no_check}, 21122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x81, no_check}, 21222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x82, no_check}, 21322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x83, no_check}, 21422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x85, no_check}, 21522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x86, no_check}, 21622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x87, no_check}, 21722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x88, no_check}, 21822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x89, no_check}, 21922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x8A, no_check}, 22022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x90, no_check}, 22122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x91, no_check}, 22222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x92, no_check}, 22322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x93, no_check} 22422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie}; 22522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 22622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic hz_init_t init_table3[] = { 22722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xf2, check_for_header2_err}, 22822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xf0, check_for_header1_err}, 22922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0xcc, check_for_dummy}, 23022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie {0x00, check_number_texunits} 23122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie}; 23222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 233b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airliestatic hazard_t table1[256]; 234b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airliestatic hazard_t table2[256]; 235b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airliestatic hazard_t table3[256]; 23622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 23722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ int 23858c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaisereat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words) 23922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 240925142431bd653175b80ae153bd7a8bc13628bdeDave Airlie if ((buf_end - *buf) >= num_words) { 24122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buf += num_words; 24222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 243b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } 24422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal termination of DMA command buffer\n"); 24522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 1; 24622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 24722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 24822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie/* 24922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Partially stolen from drm_memory.h 25022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie */ 25122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 252925142431bd653175b80ae153bd7a8bc13628bdeDave Airliestatic __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, 253b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie unsigned long offset, 254b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie unsigned long size, 25558c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser struct drm_device *dev) 25622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 25755910517af381eba4f978740e5e46e23eb269326Dave Airlie struct drm_map_list *r_list; 258925142431bd653175b80ae153bd7a8bc13628bdeDave Airlie drm_local_map_t *map = seq->map_cache; 25922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 260b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (map && map->offset <= offset 261b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie && (offset + size) <= (map->offset + map->size)) { 26222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return map; 26322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 264b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 265bd1b331fae2813d9f03ceee649296f02edc0b893Dave Airlie list_for_each_entry(r_list, &dev->maplist, head) { 26622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie map = r_list->map; 26722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (!map) 26822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie continue; 269b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (map->offset <= offset 270b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie && (offset + size) <= (map->offset + map->size) 271b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie && !(map->flags & _DRM_RESTRICTED) 272b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie && (map->type == _DRM_AGP)) { 27322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie seq->map_cache = map; 27422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return map; 27522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 27622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 27722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return NULL; 27822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 27922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 28022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie/* 281b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie * Require that all AGP texture levels reside in the same AGP map which should 28222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * be mappable by the client. This is not a big restriction. 283b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie * FIXME: To actually enforce this security policy strictly, drm_rmmap 284b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie * would have to wait for dma quiescent before removing an AGP map. 28522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * The via_drm_lookup_agp_map call in reality seems to take 28622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * very little CPU time. 28722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie */ 28822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 289b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airliestatic __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) 29022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 291b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie switch (cur_seq->unfinished) { 29222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case z_address: 29322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_DEBUG("Z Buffer start address is 0x%x\n", cur_seq->z_addr); 29422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 29522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case dest_address: 296b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_DEBUG("Destination start address is 0x%x\n", 297b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie cur_seq->d_addr); 29822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 29922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case tex_address: 300b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (cur_seq->agp_texture) { 301b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie unsigned start = 302b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie cur_seq->tex_level_lo[cur_seq->texture]; 30322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie unsigned end = cur_seq->tex_level_hi[cur_seq->texture]; 304b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie unsigned long lo = ~0, hi = 0, tmp; 30522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t *addr, *pitch, *height, tex; 30622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie unsigned i; 3079b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom int npot; 30822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 309b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (end > 9) 310b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie end = 9; 311b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (start > 9) 312b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie start = 9; 31322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 314b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie addr = 315b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie &(cur_seq->t_addr[tex = cur_seq->texture][start]); 31622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie pitch = &(cur_seq->pitch[tex][start]); 31722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie height = &(cur_seq->height[tex][start]); 3189b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom npot = cur_seq->tex_npot[tex]; 319b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie for (i = start; i <= end; ++i) { 32022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp = *addr++; 321b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (tmp < lo) 322b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie lo = tmp; 3239b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom if (i == 0 && npot) 3249b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom tmp += (*height++ * *pitch++); 3259b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom else 3269b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom tmp += (*height++ << *pitch++); 327b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (tmp > hi) 328b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie hi = tmp; 32922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 33022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 331b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (!via_drm_lookup_agp_map 332b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (cur_seq, lo, hi - lo, cur_seq->dev)) { 333b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR 334b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ("AGP texture is not in allowed map\n"); 33522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 2; 33622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 337b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } 33822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 33922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie default: 34022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 34122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 34222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = no_sequence; 34322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 34422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 34522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 346b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airliestatic __inline__ int 34758c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiserinvestigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq) 34822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 34922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie register uint32_t tmp, *tmp_addr; 35022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 35122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) { 35222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie int ret; 353b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((ret = finish_current_sequence(cur_seq))) 354b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return ret; 35522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 35622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 357b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie switch (hz) { 35822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_for_header2: 359b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (cmd == HALCYON_HEADER2) 360b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 1; 36122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 36222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_for_header1: 363b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 364b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 1; 36522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 36622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_for_header2_err: 367b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (cmd == HALCYON_HEADER2) 368b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 1; 36922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal DMA HALCYON_HEADER2 command\n"); 37022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 37122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_for_header1_err: 372b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 373b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 1; 37422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal DMA HALCYON_HEADER1 command\n"); 37522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 37622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_for_fire: 377b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD) 378b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 1; 37922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal DMA HALCYON_FIRECMD command\n"); 38022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 38122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_for_dummy: 382b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (HC_DUMMY == cmd) 383b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 0; 38422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal DMA HC_DUMMY command\n"); 38522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 38622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_for_dd: 387b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (0xdddddddd == cmd) 388b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 0; 38922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal DMA 0xdddddddd command\n"); 39022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 39122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_z_buffer_addr0: 39222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = z_address; 39322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->z_addr = (cur_seq->z_addr & 0xFF000000) | 394b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (cmd & 0x00FFFFFF); 39522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 39622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_z_buffer_addr1: 39722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = z_address; 39822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->z_addr = (cur_seq->z_addr & 0x00FFFFFF) | 399b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ((cmd & 0xFF) << 24); 40022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 40122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_z_buffer_addr_mode: 40222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = z_address; 403b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((cmd & 0x0000C000) == 0) 404b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 0; 40522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Attempt to place Z buffer in system memory\n"); 40622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 2; 40722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_destination_addr0: 40822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = dest_address; 40922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->d_addr = (cur_seq->d_addr & 0xFF000000) | 410b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (cmd & 0x00FFFFFF); 41122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 41222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_destination_addr1: 41322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = dest_address; 41422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->d_addr = (cur_seq->d_addr & 0x00FFFFFF) | 415b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ((cmd & 0xFF) << 24); 41622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 41722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_destination_addr_mode: 41822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = dest_address; 419b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((cmd & 0x0000C000) == 0) 420b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 0; 421b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR 422b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ("Attempt to place 3D drawing buffer in system memory\n"); 423b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 2; 42422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr0: 42522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 42622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp = (cmd >> 24); 42722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr = &cur_seq->t_addr[cur_seq->texture][tmp]; 42822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *tmp_addr = (*tmp_addr & 0xFF000000) | (cmd & 0x00FFFFFF); 42922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 43022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr1: 43122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 43222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp = ((cmd >> 24) - 0x20); 43322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp += tmp << 1; 43422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr = &cur_seq->t_addr[cur_seq->texture][tmp]; 43522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF) << 24); 43622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr++; 43722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF00) << 16); 43822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr++; 43922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF0000) << 8); 44022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 44122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr2: 44222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 44322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->tex_level_lo[tmp = cur_seq->texture] = cmd & 0x3F; 44422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->tex_level_hi[tmp] = (cmd & 0xFC0) >> 6; 44522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 44622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr3: 44722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 4489b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom tmp = ((cmd >> 24) - HC_SubA_HTXnL0Pit); 4499b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom if (tmp == 0 && 4509b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom (cmd & HC_HTXnEnPit_MASK)) { 4519b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom cur_seq->pitch[cur_seq->texture][tmp] = 4529b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom (cmd & HC_HTXnLnPit_MASK); 4539b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom cur_seq->tex_npot[cur_seq->texture] = 1; 4549b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom } else { 4559b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom cur_seq->pitch[cur_seq->texture][tmp] = 4569b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom (cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT; 4579b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom cur_seq->tex_npot[cur_seq->texture] = 0; 4589b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom if (cmd & 0x000FFFFF) { 4599b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom DRM_ERROR 4609b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom ("Unimplemented texture level 0 pitch mode.\n"); 4619b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom return 2; 4629b8d9d0e0181286c0608e6426da1eac45463ecd2Thomas Hellstrom } 46322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 46422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 46522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr4: 46622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 46722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr = &cur_seq->t_addr[cur_seq->texture][9]; 46822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF) << 24); 46922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 47022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr5: 47122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr6: 47222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 47322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie /* 47422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * Texture width. We don't care since we have the pitch. 475b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie */ 47622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 47722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr7: 47822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 47922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr = &(cur_seq->height[cur_seq->texture][0]); 48022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[5] = 1 << ((cmd & 0x00F00000) >> 20); 48122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[4] = 1 << ((cmd & 0x000F0000) >> 16); 48222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[3] = 1 << ((cmd & 0x0000F000) >> 12); 48322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[2] = 1 << ((cmd & 0x00000F00) >> 8); 48422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[1] = 1 << ((cmd & 0x000000F0) >> 4); 48522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[0] = 1 << (cmd & 0x0000000F); 48622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 48722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr8: 48822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 48922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr = &(cur_seq->height[cur_seq->texture][0]); 49022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[9] = 1 << ((cmd & 0x0000F000) >> 12); 491b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8); 49222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[7] = 1 << ((cmd & 0x000000F0) >> 4); 49322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie tmp_addr[6] = 1 << (cmd & 0x0000000F); 49422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 49522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_texture_addr_mode: 49622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->unfinished = tex_address; 497b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (2 == (tmp = cmd & 0x00000003)) { 498b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR 499b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ("Attempt to fetch texture from system memory.\n"); 50022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 2; 50122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 50222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->agp_texture = (tmp == 3); 503b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie cur_seq->tex_palette_size[cur_seq->texture] = 504b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (cmd >> 16) & 0x000000007; 50522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 50622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_for_vertex_count: 50722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cur_seq->vertex_count = cmd & 0x0000FFFF; 50822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 50922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case check_number_texunits: 510b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie cur_seq->multitex = (cmd >> 3) & 1; 51122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 51222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie default: 51322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal DMA data: 0x%x\n", cmd); 51422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 2; 51522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 51622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 2; 51722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 51822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 51922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ int 520b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlievia_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end, 52158c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser drm_via_state_t *cur_seq) 52222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 523b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie drm_via_private_t *dev_priv = 524b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (drm_via_private_t *) cur_seq->dev->dev_private; 525b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie uint32_t a_fire, bcmd, dw_count; 52622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie int ret = 0; 52722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie int have_fire; 52822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 52922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 530b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie while (buf < buf_end) { 531b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie have_fire = 0; 53222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((buf_end - buf) < 2) { 533b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR 534b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ("Unexpected termination of primitive list.\n"); 53522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = 1; 53622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 53722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 538b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB) 539b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie break; 54022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie bcmd = *buf++; 54122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdA) { 54222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Expected Vertex List A command, got 0x%x\n", 54322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buf); 54422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = 1; 54522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 54622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 547b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie a_fire = 548b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK | 549b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie HC_HE3Fire_MASK; 550b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 55122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie /* 55222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * How many dwords per vertex ? 553b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie */ 554b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 55522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) { 55622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal B command vertex data for AGP.\n"); 55722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = 1; 55822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 559b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } 56022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 56122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie dw_count = 0; 562b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (bcmd & (1 << 7)) 563b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dw_count += (cur_seq->multitex) ? 2 : 1; 564b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (bcmd & (1 << 8)) 565b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dw_count += (cur_seq->multitex) ? 2 : 1; 566b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (bcmd & (1 << 9)) 567b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dw_count++; 568b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (bcmd & (1 << 10)) 569b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dw_count++; 570b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (bcmd & (1 << 11)) 571b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dw_count++; 572b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (bcmd & (1 << 12)) 573b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dw_count++; 574b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (bcmd & (1 << 13)) 575b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dw_count++; 576b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (bcmd & (1 << 14)) 577b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dw_count++; 578b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 579b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie while (buf < buf_end) { 58022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (*buf == a_fire) { 581b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (dev_priv->num_fire_offsets >= 582b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie VIA_FIRE_BUF_SIZE) { 58322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Fire offset buffer full.\n"); 58422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = 1; 58522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 58622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 587b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie dev_priv->fire_offsets[dev_priv-> 588b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie num_fire_offsets++] = 589b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie buf; 590b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie have_fire = 1; 59122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf++; 592b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (buf < buf_end && *buf == a_fire) 59322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf++; 59422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 59522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 596b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((*buf == HALCYON_HEADER2) || 59722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) { 59822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Missing Vertex Fire command, " 59922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "Stray Vertex Fire command or verifier " 60022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "lost sync.\n"); 60122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = 1; 60222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 60322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 60422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((ret = eat_words(&buf, buf_end, dw_count))) 60522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 60622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 60722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (buf >= buf_end && !have_fire) { 60822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Missing Vertex Fire command or verifier " 60922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "lost sync.\n"); 61022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = 1; 61122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 61222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 61322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (cur_seq->agp && ((buf - cur_seq->buf_start) & 0x01)) { 61422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("AGP Primitive list end misaligned.\n"); 61522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = 1; 61622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 61722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 618b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } 61922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 62022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return ret; 62122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 62222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 62322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ verifier_state_t 62458c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiservia_check_header2(uint32_t const **buffer, const uint32_t *buf_end, 62558c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser drm_via_state_t *hc_state) 62622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 62722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t cmd; 62822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie int hz_mode; 62922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hazard_t hz; 63022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 63122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const hazard_t *hz_table; 63222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 63322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((buf_end - buf) < 2) { 634b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR 635b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ("Illegal termination of DMA HALCYON_HEADER2 sequence.\n"); 63622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 63722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 63822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf++; 63922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cmd = (*buf++ & 0xFFFF0000) >> 16; 64022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 641b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie switch (cmd) { 64222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case HC_ParaType_CmdVdata: 643b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (via_check_prim_list(&buf, buf_end, hc_state)) 64422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 64522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 64622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 64722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case HC_ParaType_NotTex: 64822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hz_table = table1; 64922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 65022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case HC_ParaType_Tex: 65122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hc_state->texture = 0; 65222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hz_table = table2; 65322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 65422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case (HC_ParaType_Tex | (HC_SubType_Tex1 << 8)): 65522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hc_state->texture = 1; 65622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hz_table = table2; 65722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 65822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case (HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)): 65922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hz_table = table3; 66022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 66122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case HC_ParaType_Auto: 66222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (eat_words(&buf, buf_end, 2)) 66322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 66422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 66522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 66622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case (HC_ParaType_Palette | (HC_SubType_Stipple << 8)): 66722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (eat_words(&buf, buf_end, 32)) 66822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 66922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 67022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 67122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case (HC_ParaType_Palette | (HC_SubType_TexPalette0 << 8)): 67222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case (HC_ParaType_Palette | (HC_SubType_TexPalette1 << 8)): 67322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Texture palettes are rejected because of " 67422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "lack of info how to determine their size.\n"); 67522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 67622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case (HC_ParaType_Palette | (HC_SubType_FogTable << 8)): 67722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Fog factor palettes are rejected because of " 67822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "lack of info how to determine their size.\n"); 67922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 68022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie default: 68122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 68222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie /* 68322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * There are some unimplemented HC_ParaTypes here, that 68422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie * need to be implemented if the Mesa driver is extended. 68522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie */ 68622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 68722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Invalid or unimplemented HALCYON_HEADER2 " 688b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie "DMA subcommand: 0x%x. Previous dword: 0x%x\n", 689b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie cmd, *(buf - 2)); 69022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 69122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 69222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 69322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 694b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie while (buf < buf_end) { 69522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cmd = *buf++; 69622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((hz = hz_table[cmd >> 24])) { 69722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) { 69822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (hz_mode == 1) { 69922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf--; 70022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 70122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 70222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 70322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 704b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } else if (hc_state->unfinished && 70522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie finish_current_sequence(hc_state)) { 70622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 70722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 70822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 70958c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser if (hc_state->unfinished && finish_current_sequence(hc_state)) 71022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 71122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 71222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 71322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 71422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 71522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ verifier_state_t 71658c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiservia_parse_header2(drm_via_private_t *dev_priv, uint32_t const **buffer, 71758c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser const uint32_t *buf_end, int *fire_count) 71822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 71922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t cmd; 72022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 721b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie const uint32_t *next_fire; 72222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie int burst = 0; 72322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 72422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie next_fire = dev_priv->fire_offsets[*fire_count]; 72522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf++; 72622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cmd = (*buf & 0xFFFF0000) >> 16; 72722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie VIA_WRITE(HC_REG_TRANS_SET + HC_REG_BASE, *buf++); 728b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie switch (cmd) { 72922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case HC_ParaType_CmdVdata: 73022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie while ((buf < buf_end) && 731b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (*fire_count < dev_priv->num_fire_offsets) && 732b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB) { 733b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie while (buf <= next_fire) { 734b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + 735b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (burst & 63), *buf++); 73622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie burst += 4; 73722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 738b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((buf < buf_end) 739b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) 74022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf++; 74122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 742b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (++(*fire_count) < dev_priv->num_fire_offsets) 74322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie next_fire = dev_priv->fire_offsets[*fire_count]; 74422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 74522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 74622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie default: 747b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie while (buf < buf_end) { 748b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 749b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (*buf == HC_HEADER2 || 750b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 || 751b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 || 752b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) 753b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie break; 754b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 755b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + 756b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (burst & 63), *buf++); 757b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie burst += 4; 75822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 75922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 76022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 76122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 76222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 76322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 764b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airliestatic __inline__ int verify_mmio_address(uint32_t address) 76522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 766b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((address > 0x3FF) && (address < 0xC00)) { 76722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Invalid VIDEO DMA command. " 76822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "Attempt to access 3D- or command burst area.\n"); 76922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 1; 77022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } else if ((address > 0xCFF) && (address < 0x1300)) { 77122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Invalid VIDEO DMA command. " 77222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "Attempt to access PCI DMA area.\n"); 773b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return 1; 774b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } else if (address > 0x13FF) { 77522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Invalid VIDEO DMA command. " 77622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "Attempt to access VGA registers.\n"); 77722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 1; 77822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 77922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 78022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 78122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 78222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ int 783b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlieverify_video_tail(uint32_t const **buffer, const uint32_t * buf_end, 784b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie uint32_t dwords) 78522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 78622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 78722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 78822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (buf_end - buf < dwords) { 78922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal termination of video command.\n"); 79022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 1; 79122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 79222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie while (dwords--) { 79322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (*buf++) { 79422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal video command tail.\n"); 79522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 1; 79622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 79722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 79822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 79922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 80022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 80122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 80222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ verifier_state_t 803b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlievia_check_header1(uint32_t const **buffer, const uint32_t * buf_end) 80422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 80522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t cmd; 80622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 80722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie verifier_state_t ret = state_command; 80822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 80922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie while (buf < buf_end) { 81022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cmd = *buf; 81122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((cmd > ((0x3FF >> 2) | HALCYON_HEADER1)) && 812b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) { 813b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) 81422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 81522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Invalid HALCYON_HEADER1 command. " 81622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "Attempt to access 3D- or command burst area.\n"); 81722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = state_error; 81822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 81922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) { 820b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) 82122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 82222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Invalid HALCYON_HEADER1 command. " 82322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie "Attempt to access VGA registers.\n"); 82422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie ret = state_error; 825b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie break; 826b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } else { 82722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf += 2; 82822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 82922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 83022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 83122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return ret; 83222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 83322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 83422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ verifier_state_t 83558c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiservia_parse_header1(drm_via_private_t *dev_priv, uint32_t const **buffer, 83658c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser const uint32_t *buf_end) 83722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 83822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie register uint32_t cmd; 83922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 84022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 84122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie while (buf < buf_end) { 84222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie cmd = *buf; 843b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) 844b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie break; 845b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie VIA_WRITE((cmd & ~HALCYON_HEADER1MASK) << 2, *++buf); 84622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf++; 84722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 84822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 84922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 85022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 85122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 85222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ verifier_state_t 85358c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiservia_check_vheader5(uint32_t const **buffer, const uint32_t *buf_end) 85422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 85522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t data; 85622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 85722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 85822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (buf_end - buf < 4) { 85922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal termination of video header5 command\n"); 86022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 86122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 86222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 86322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie data = *buf++ & ~VIA_VIDEOMASK; 86422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (verify_mmio_address(data)) 86522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 86622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 86722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie data = *buf++; 86822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (*buf++ != 0x00F50000) { 86922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal header5 header data\n"); 87022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 87122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 87222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (*buf++ != 0x00000000) { 87322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal header5 header data\n"); 87422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 87522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 876b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (eat_words(&buf, buf_end, data)) 87722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 878b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3))) 87922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 88022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 88122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 882b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 883b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie} 88422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 88522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ verifier_state_t 88658c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiservia_parse_vheader5(drm_via_private_t *dev_priv, uint32_t const **buffer, 88758c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser const uint32_t *buf_end) 88822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 889b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie uint32_t addr, count, i; 89022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 891b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 89222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie addr = *buf++ & ~VIA_VIDEOMASK; 89322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie i = count = *buf; 89422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf += 3; 89558c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser while (i--) 89622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie VIA_WRITE(addr, *buf++); 897b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (count & 3) 898b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie buf += 4 - (count & 3); 89922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 900b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie return state_command; 901b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie} 90222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 90322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ verifier_state_t 904b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlievia_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end) 90522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 90622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t data; 90722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 90822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t i; 90922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 91022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (buf_end - buf < 4) { 91122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal termination of video header6 command\n"); 91222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 91322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 91422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf++; 91522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie data = *buf++; 91622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (*buf++ != 0x00F60000) { 91722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal header6 header data\n"); 91822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 91922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 92022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (*buf++ != 0x00000000) { 92122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal header6 header data\n"); 92222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 92322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 92422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((buf_end - buf) < (data << 1)) { 92522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie DRM_ERROR("Illegal termination of video header6 command\n"); 92622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 92722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 928b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie for (i = 0; i < data; ++i) { 92922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (verify_mmio_address(*buf++)) 93022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 93122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf++; 93222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 93322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie data <<= 1; 93422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3))) 93522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_error; 93622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 93722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 938b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie} 93922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 94022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliestatic __inline__ verifier_state_t 94158c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiservia_parse_vheader6(drm_via_private_t *dev_priv, uint32_t const **buffer, 94258c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser const uint32_t *buf_end) 94322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 94422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 945b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie uint32_t addr, count, i; 94622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie const uint32_t *buf = *buffer; 94722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 94822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie i = count = *++buf; 94922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie buf += 3; 950b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie while (i--) { 95122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie addr = *buf++; 95222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie VIA_WRITE(addr, *buf++); 95322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 95422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie count <<= 1; 955b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (count & 3) 956b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie buf += 4 - (count & 3); 95722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *buffer = buf; 95822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return state_command; 959b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie} 96022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 961b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlieint 962b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlievia_verify_command_stream(const uint32_t * buf, unsigned int size, 96384b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlie struct drm_device * dev, int agp) 96422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 96522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 96622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 96722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie drm_via_state_t *hc_state = &dev_priv->hc_state; 96822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie drm_via_state_t saved_state = *hc_state; 96922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t cmd; 970b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie const uint32_t *buf_end = buf + (size >> 2); 97122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie verifier_state_t state = state_command; 972689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom int cme_video; 973689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom int supported_3d; 974689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom 975689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom cme_video = (dev_priv->chipset == VIA_PRO_GROUP_A || 976689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom dev_priv->chipset == VIA_DX9_0); 977689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom 978689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom supported_3d = dev_priv->chipset != VIA_DX9_0; 979b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 98022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hc_state->dev = dev; 98122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hc_state->unfinished = no_sequence; 98222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hc_state->map_cache = NULL; 98322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hc_state->agp = agp; 98422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie hc_state->buf_start = buf; 98522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie dev_priv->num_fire_offsets = 0; 98622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 98722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie while (buf < buf_end) { 98822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 98922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie switch (state) { 99022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_header2: 991b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie state = via_check_header2(&buf, buf_end, hc_state); 99222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 99322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_header1: 994b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie state = via_check_header1(&buf, buf_end); 99522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 99622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_vheader5: 997b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie state = via_check_vheader5(&buf, buf_end); 99822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 99922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_vheader6: 1000b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie state = via_check_vheader6(&buf, buf_end); 100122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 100222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_command: 1003689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom if ((HALCYON_HEADER2 == (cmd = *buf)) && 1004689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom supported_3d) 100522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_header2; 1006b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 100722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_header1; 1008689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom else if (cme_video 1009b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) 101022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_vheader5; 1011689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom else if (cme_video 1012b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) 101322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_vheader6; 1014689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom else if ((cmd == HALCYON_HEADER2) && !supported_3d) { 1015689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom DRM_ERROR("Accelerated 3D is not supported on this chipset yet.\n"); 1016689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom state = state_error; 1017689692e73ea4b95c9fa5d5913eade33147db2e5aThomas Hellstrom } else { 1018b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR 1019b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", 1020b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie cmd); 102122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_error; 102222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 102322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 102422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_error: 102522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie default: 102622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *hc_state = saved_state; 102720caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 102822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 1029b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } 103022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie if (state == state_error) { 103122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie *hc_state = saved_state; 103220caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 103322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 103422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 103522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 103622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 1037b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlieint 103858c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiservia_parse_command_stream(struct drm_device *dev, const uint32_t *buf, 1039b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie unsigned int size) 104022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 104122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 104222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 104322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie uint32_t cmd; 1044b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie const uint32_t *buf_end = buf + (size >> 2); 104522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie verifier_state_t state = state_command; 104622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie int fire_count = 0; 1047b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie 104822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie while (buf < buf_end) { 104922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 105022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie switch (state) { 105122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_header2: 1052b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie state = 1053b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie via_parse_header2(dev_priv, &buf, buf_end, 1054b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie &fire_count); 105522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 105622f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_header1: 1057b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie state = via_parse_header1(dev_priv, &buf, buf_end); 105822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 105922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_vheader5: 1060b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie state = via_parse_vheader5(dev_priv, &buf, buf_end); 106122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 106222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_vheader6: 1063b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie state = via_parse_vheader6(dev_priv, &buf, buf_end); 106422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 106522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_command: 1066b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie if (HALCYON_HEADER2 == (cmd = *buf)) 106722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_header2; 1068b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 106922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_header1; 107022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) 107122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_vheader5; 107222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) 107322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_vheader6; 107422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie else { 1075b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie DRM_ERROR 1076b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", 1077b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie cmd); 107822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie state = state_error; 107922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 108022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie break; 108122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie case state_error: 108222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie default: 108320caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 108422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie } 1085b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie } 108658c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser if (state == state_error) 108720caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 108822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie return 0; 108922f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 109022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 1091b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airliestatic void 109222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airliesetup_hazard_table(hz_init_t init_table[], hazard_t table[], int size) 109322f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 109422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie int i; 109522f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 109658c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser for (i = 0; i < 256; ++i) 109722f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie table[i] = forbidden_command; 109822f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 109958c1e85af3645ac8df021dbf14acd215b5687f54Nicolas Kaiser for (i = 0; i < size; ++i) 110022f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie table[init_table[i].code] = init_table[i].hz; 110122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 110222f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie 1103b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlievoid via_init_command_verifier(void) 110422f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie{ 1105b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie setup_hazard_table(init_table1, table1, 1106b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie sizeof(init_table1) / sizeof(hz_init_t)); 1107b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie setup_hazard_table(init_table2, table2, 1108b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie sizeof(init_table2) / sizeof(hz_init_t)); 1109b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie setup_hazard_table(init_table3, table3, 1110b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie sizeof(init_table3) / sizeof(hz_init_t)); 111122f579c621e2f264e6d093b07d75f99bc97d5df2Dave Airlie} 1112