From e34b5601912ce4b611d429304d5271fcf6f9f457 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 5 Jan 2005 17:44:43 +0000 Subject: VIA update: Release video futexes when context is destroyed (This was previously done by the X server). Added New Unichrome Pro VIDEO DMA commands to the verifier. Added Quiescent heavyweight lock mode. --- shared-core/via_verifier.c | 114 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) (limited to 'shared-core/via_verifier.c') diff --git a/shared-core/via_verifier.c b/shared-core/via_verifier.c index c60c911f..7a772588 100644 --- a/shared-core/via_verifier.c +++ b/shared-core/via_verifier.c @@ -35,6 +35,8 @@ typedef enum{ state_command, state_header2, state_header1, + state_vheader5, + state_vheader6, state_error } verifier_state_t; @@ -617,6 +619,41 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end ) } +static __inline__ int +verify_mmio_address( uint32_t address) +{ + if ((address > 0x3FF) && (address < 0xC00 )) { + DRM_ERROR("Invalid HALCYON_HEADER1 command. " + "Attempt to access 3D- or command burst area.\n"); + return 1; + } else if (address > 0xCFF ) { + DRM_ERROR("Invalid HALCYON_HEADER1 command. " + "Attempt to access VGA registers.\n"); + return 1; + } + return 0; +} + +static __inline__ int +verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dwords) +{ + const uint32_t *buf = *buffer; + + if (buf_end - buf < dwords) { + DRM_ERROR("Illegal termination of video command.\n"); + return 1; + } + while (dwords--) { + if (*buf++) { + DRM_ERROR("Illegal video command tail.\n"); + return 1; + } + } + *buffer = buf; + return 0; +} + + static __inline__ verifier_state_t via_check_header1( uint32_t const **buffer, const uint32_t *buf_end ) { @@ -649,6 +686,73 @@ via_check_header1( uint32_t const **buffer, const uint32_t *buf_end ) return ret; } +static __inline__ verifier_state_t +via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end ) +{ + uint32_t data; + const uint32_t *buf = *buffer; + + if (buf_end - buf < 4) { + DRM_ERROR("Illegal termination of video header5 command\n"); + return state_error; + } + + data = *buf++ & ~VIA_VIDEOMASK; + if (verify_mmio_address(data)) + return state_error; + + data = *buf++; + if (*buf++ != 0x00F50000) { + DRM_ERROR("Illegal header5 header data\n"); + return state_error; + } + if (*buf++ != 0x00000000) { + DRM_ERROR("Illegal header5 header data\n"); + return state_error; + } + if (eat_words(&buf, buf_end, data)) + return state_error; + if (verify_video_tail(&buf, buf_end, 4 - (data & 3))) + return state_error; + *buffer = buf; + return state_command; + +} + +static __inline__ verifier_state_t +via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end ) +{ + uint32_t data; + const uint32_t *buf = *buffer; + uint32_t i; + + if (buf_end - buf < 4) { + DRM_ERROR("Illegal termination of video header6 command\n"); + return state_error; + } + + data = *buf++; + if (*buf++ != 0x00F60000) { + DRM_ERROR("Illegal header6 header data\n"); + return state_error; + } + if (*buf++ != 0x00000000) { + DRM_ERROR("Illegal header6 header data\n"); + return state_error; + } + if ((buf_end - buf) < (data << 1)) { + DRM_ERROR("Illegal termination of video header6 command\n"); + } + for (i=0; i