1/****************************************************************************** 2* 3* Author: Xilinx, Inc. 4* 5* 6* This program is free software; you can redistribute it and/or modify it 7* under the terms of the GNU General Public License as published by the 8* Free Software Foundation; either version 2 of the License, or (at your 9* option) any later version. 10* 11* 12* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A 13* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS 14* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, 15* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE 16* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING 17* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. 18* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO 19* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY 20* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM 21* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND 22* FITNESS FOR A PARTICULAR PURPOSE. 23* 24* 25* Xilinx hardware products are not intended for use in life support 26* appliances, devices, or systems. Use in such applications is 27* expressly prohibited. 28* 29* 30* (c) Copyright 2002-2004 Xilinx Inc. 31* All rights reserved. 32* 33* 34* You should have received a copy of the GNU General Public License along 35* with this program; if not, write to the Free Software Foundation, Inc., 36* 675 Mass Ave, Cambridge, MA 02139, USA. 37* 38******************************************************************************/ 39/*****************************************************************************/ 40/* 41* 42* @file xpacket_fifo_v1_00_b.c 43* 44* Contains functions for the XPacketFifoV100b component. See xpacket_fifo_v1_00_b.h 45* for more information about the component. 46* 47* <pre> 48* MODIFICATION HISTORY: 49* 50* Ver Who Date Changes 51* ----- ---- -------- ----------------------------------------------- 52* 1.00b rpm 03/26/02 First release 53* </pre> 54* 55*****************************************************************************/ 56 57/***************************** Include Files *********************************/ 58 59#include "xbasic_types.h" 60#include "xio.h" 61#include "xstatus.h" 62#include "xpacket_fifo_v1_00_b.h" 63 64/************************** Constant Definitions *****************************/ 65 66/* width of a FIFO word */ 67 68#define XPF_FIFO_WIDTH_BYTE_COUNT 4UL 69 70/**************************** Type Definitions *******************************/ 71 72/***************** Macros (Inline Functions) Definitions *********************/ 73 74/************************* Variable Definitions ******************************/ 75 76/************************** Function Prototypes ******************************/ 77 78/*****************************************************************************/ 79/* 80* 81* This function initializes a packet FIFO. Initialization resets the 82* FIFO such that it's empty and ready to use. 83* 84* @param InstancePtr contains a pointer to the FIFO to operate on. 85* @param RegBaseAddress contains the base address of the registers for 86* the packet FIFO. 87* @param DataBaseAddress contains the base address of the data for 88* the packet FIFO. 89* 90* @return 91* 92* Always returns XST_SUCCESS. 93* 94* @note 95* 96* None. 97* 98******************************************************************************/ 99XStatus 100XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr, 101 u32 RegBaseAddress, u32 DataBaseAddress) 102{ 103 /* assert to verify input argument are valid */ 104 105 XASSERT_NONVOID(InstancePtr != NULL); 106 107 /* initialize the component variables to the specified state */ 108 109 InstancePtr->RegBaseAddress = RegBaseAddress; 110 InstancePtr->DataBaseAddress = DataBaseAddress; 111 InstancePtr->IsReady = XCOMPONENT_IS_READY; 112 113 /* reset the FIFO such that it's empty and ready to use and indicate the 114 * initialization was successful, note that the is ready variable must be 115 * set prior to calling the reset function to prevent an assert 116 */ 117 XPF_V100B_RESET(InstancePtr); 118 119 return XST_SUCCESS; 120} 121 122/*****************************************************************************/ 123/* 124* 125* This function performs a self-test on the specified packet FIFO. The self 126* test resets the FIFO and reads a register to determine if it is the correct 127* reset value. This test is destructive in that any data in the FIFO will 128* be lost. 129* 130* @param InstancePtr is a pointer to the packet FIFO to be operated on. 131* 132* @param FifoType specifies the type of FIFO, read or write, for the self test. 133* The FIFO type is specified by the values XPF_READ_FIFO_TYPE or 134* XPF_WRITE_FIFO_TYPE. 135* 136* @return 137* 138* XST_SUCCESS is returned if the selftest is successful, or 139* XST_PFIFO_BAD_REG_VALUE indicating that the value readback from the 140* occupancy/vacancy count register after a reset does not match the 141* specified reset value. 142* 143* @note 144* 145* None. 146* 147******************************************************************************/ 148XStatus 149XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType) 150{ 151 u32 Register; 152 153 /* assert to verify valid input arguments */ 154 155 XASSERT_NONVOID(InstancePtr != NULL); 156 XASSERT_NONVOID((FifoType == XPF_READ_FIFO_TYPE) || 157 (FifoType == XPF_WRITE_FIFO_TYPE)); 158 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 159 160 /* reset the fifo and then check to make sure the occupancy/vacancy 161 * register contents are correct for a reset condition 162 */ 163 XPF_V100B_RESET(InstancePtr); 164 165 Register = XIo_In32(InstancePtr->RegBaseAddress + 166 XPF_COUNT_STATUS_REG_OFFSET); 167 168 /* check the value of the register to ensure that it's correct for the 169 * specified FIFO type since both FIFO types reset to empty, but a bit 170 * in the register changes definition based upon FIFO type 171 */ 172 173 if (FifoType == XPF_READ_FIFO_TYPE) { 174 /* check the regiser value for a read FIFO which should be empty */ 175 176 if (Register != XPF_EMPTY_FULL_MASK) { 177 return XST_PFIFO_BAD_REG_VALUE; 178 } 179 } else { 180 /* check the register value for a write FIFO which should not be full 181 * on reset 182 */ 183 if ((Register & XPF_EMPTY_FULL_MASK) != 0) { 184 return XST_PFIFO_BAD_REG_VALUE; 185 } 186 } 187 188 /* the test was successful */ 189 190 return XST_SUCCESS; 191} 192 193/*****************************************************************************/ 194/* 195* 196* Read data from a FIFO and puts it into a specified buffer. The packet FIFO is 197* currently 32 bits wide such that an input buffer which is a series of bytes 198* is filled from the FIFO a word at a time. If the requested byte count is not 199* a multiple of 32 bit words, it is necessary for this function to format the 200* remaining 32 bit word from the FIFO into a series of bytes in the buffer. 201* There may be up to 3 extra bytes which must be extracted from the last word 202* of the FIFO and put into the buffer. 203* 204* @param InstancePtr contains a pointer to the FIFO to operate on. 205* @param BufferPtr points to the memory buffer to write the data into. This 206* buffer must be 32 bit aligned or an alignment exception could be 207* generated. Since this buffer is a byte buffer, the data is assumed to 208* be endian independent. 209* @param ByteCount contains the number of bytes to read from the FIFO. This 210* number of bytes must be present in the FIFO or an error will be 211* returned. 212* 213* @return 214* 215* XST_SUCCESS indicates the operation was successful. If the number of 216* bytes specified by the byte count is not present in the FIFO 217* XST_PFIFO_LACK_OF_DATA is returned. 218* 219* If the function was successful, the specified buffer is modified to contain 220* the bytes which were removed from the FIFO. 221* 222* @note 223* 224* Note that the exact number of bytes which are present in the FIFO is 225* not known by this function. It can only check for a number of 32 bit 226* words such that if the byte count specified is incorrect, but is still 227* possible based on the number of words in the FIFO, up to 3 garbage bytes 228* may be present at the end of the buffer. 229* <br><br> 230* This function assumes that if the device consuming data from the FIFO is 231* a byte device, the order of the bytes to be consumed is from the most 232* significant byte to the least significant byte of a 32 bit word removed 233* from the FIFO. 234* 235******************************************************************************/ 236XStatus 237XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr, 238 u8 * BufferPtr, u32 ByteCount) 239{ 240 u32 FifoCount; 241 u32 WordCount; 242 u32 ExtraByteCount; 243 u32 *WordBuffer = (u32 *) BufferPtr; 244 245 /* assert to verify valid input arguments including 32 bit alignment of 246 * the buffer pointer 247 */ 248 XASSERT_NONVOID(InstancePtr != NULL); 249 XASSERT_NONVOID(BufferPtr != NULL); 250 XASSERT_NONVOID(((u32) BufferPtr & 251 (XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0); 252 XASSERT_NONVOID(ByteCount != 0); 253 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 254 255 /* get the count of how many 32 bit words are in the FIFO, if there aren't 256 * enought words to satisfy the request, return an error 257 */ 258 259 FifoCount = XIo_In32(InstancePtr->RegBaseAddress + 260 XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK; 261 262 if ((FifoCount * XPF_FIFO_WIDTH_BYTE_COUNT) < ByteCount) { 263 return XST_PFIFO_LACK_OF_DATA; 264 } 265 266 /* calculate the number of words to read from the FIFO before the word 267 * containing the extra bytes, and calculate the number of extra bytes 268 * the extra bytes are defined as those at the end of the buffer when 269 * the buffer does not end on a 32 bit boundary 270 */ 271 WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT; 272 ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT; 273 274 /* Read the 32 bit words from the FIFO for all the buffer except the 275 * last word which contains the extra bytes, the following code assumes 276 * that the buffer is 32 bit aligned, otherwise an alignment exception could 277 * be generated 278 */ 279 for (FifoCount = 0; FifoCount < WordCount; FifoCount++) { 280 WordBuffer[FifoCount] = XIo_In32(InstancePtr->DataBaseAddress); 281 } 282 283 /* if there are extra bytes to handle, read the last word from the FIFO 284 * and insert the extra bytes into the buffer 285 */ 286 if (ExtraByteCount > 0) { 287 u32 LastWord; 288 u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount); 289 290 /* get the last word from the FIFO for the extra bytes */ 291 292 LastWord = XIo_In32(InstancePtr->DataBaseAddress); 293 294 /* one extra byte in the last word, put the byte into the next location 295 * of the buffer, bytes in a word of the FIFO are ordered from most 296 * significant byte to least 297 */ 298 if (ExtraByteCount == 1) { 299 ExtraBytesBuffer[0] = (u8) (LastWord >> 24); 300 } 301 302 /* two extra bytes in the last word, put each byte into the next two 303 * locations of the buffer 304 */ 305 else if (ExtraByteCount == 2) { 306 ExtraBytesBuffer[0] = (u8) (LastWord >> 24); 307 ExtraBytesBuffer[1] = (u8) (LastWord >> 16); 308 } 309 /* three extra bytes in the last word, put each byte into the next three 310 * locations of the buffer 311 */ 312 else if (ExtraByteCount == 3) { 313 ExtraBytesBuffer[0] = (u8) (LastWord >> 24); 314 ExtraBytesBuffer[1] = (u8) (LastWord >> 16); 315 ExtraBytesBuffer[2] = (u8) (LastWord >> 8); 316 } 317 } 318 return XST_SUCCESS; 319} 320 321/*****************************************************************************/ 322/* 323* 324* Write data into a packet FIFO. The packet FIFO is currently 32 bits wide 325* such that an input buffer which is a series of bytes must be written into the 326* FIFO a word at a time. If the buffer is not a multiple of 32 bit words, it is 327* necessary for this function to format the remaining bytes into a single 32 328* bit word to be inserted into the FIFO. This is necessary to avoid any 329* accesses past the end of the buffer. 330* 331* @param InstancePtr contains a pointer to the FIFO to operate on. 332* @param BufferPtr points to the memory buffer that data is to be read from 333* and written into the FIFO. Since this buffer is a byte buffer, the data 334* is assumed to be endian independent. This buffer must be 32 bit aligned 335* or an alignment exception could be generated. 336* @param ByteCount contains the number of bytes to read from the buffer and to 337* write to the FIFO. 338* 339* @return 340* 341* XST_SUCCESS is returned if the operation succeeded. If there is not enough 342* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is 343* returned. 344* 345* @note 346* 347* This function assumes that if the device inserting data into the FIFO is 348* a byte device, the order of the bytes in each 32 bit word is from the most 349* significant byte to the least significant byte. 350* 351******************************************************************************/ 352XStatus 353XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr, 354 u8 * BufferPtr, u32 ByteCount) 355{ 356 u32 FifoCount; 357 u32 WordCount; 358 u32 ExtraByteCount; 359 u32 *WordBuffer = (u32 *) BufferPtr; 360 361 /* assert to verify valid input arguments including 32 bit alignment of 362 * the buffer pointer 363 */ 364 XASSERT_NONVOID(InstancePtr != NULL); 365 XASSERT_NONVOID(BufferPtr != NULL); 366 XASSERT_NONVOID(((u32) BufferPtr & 367 (XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0); 368 XASSERT_NONVOID(ByteCount != 0); 369 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 370 371 /* get the count of how many words may be inserted into the FIFO */ 372 373 FifoCount = XIo_In32(InstancePtr->RegBaseAddress + 374 XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK; 375 376 /* Calculate the number of 32 bit words required to insert the specified 377 * number of bytes in the FIFO and determine the number of extra bytes 378 * if the buffer length is not a multiple of 32 bit words 379 */ 380 381 WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT; 382 ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT; 383 384 /* take into account the extra bytes in the total word count */ 385 386 if (ExtraByteCount > 0) { 387 WordCount++; 388 } 389 390 /* if there's not enough room in the FIFO to hold the specified 391 * number of bytes, then indicate an error, 392 */ 393 if (FifoCount < WordCount) { 394 return XST_PFIFO_NO_ROOM; 395 } 396 397 /* readjust the word count to not take into account the extra bytes */ 398 399 if (ExtraByteCount > 0) { 400 WordCount--; 401 } 402 403 /* Write all the bytes of the buffer which can be written as 32 bit 404 * words into the FIFO, waiting to handle the extra bytes seperately 405 */ 406 for (FifoCount = 0; FifoCount < WordCount; FifoCount++) { 407 XIo_Out32(InstancePtr->DataBaseAddress, WordBuffer[FifoCount]); 408 } 409 410 /* if there are extra bytes to handle, extract them from the buffer 411 * and create a 32 bit word and write it to the FIFO 412 */ 413 if (ExtraByteCount > 0) { 414 u32 LastWord = 0; 415 u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount); 416 417 /* one extra byte in the buffer, put the byte into the last word 418 * to be inserted into the FIFO, perform this processing inline rather 419 * than in a loop to help performance 420 */ 421 if (ExtraByteCount == 1) { 422 LastWord = ExtraBytesBuffer[0] << 24; 423 } 424 425 /* two extra bytes in the buffer, put each byte into the last word 426 * to be inserted into the FIFO 427 */ 428 else if (ExtraByteCount == 2) { 429 LastWord = ExtraBytesBuffer[0] << 24 | 430 ExtraBytesBuffer[1] << 16; 431 } 432 433 /* three extra bytes in the buffer, put each byte into the last word 434 * to be inserted into the FIFO 435 */ 436 else if (ExtraByteCount == 3) { 437 LastWord = ExtraBytesBuffer[0] << 24 | 438 ExtraBytesBuffer[1] << 16 | 439 ExtraBytesBuffer[2] << 8; 440 } 441 442 /* write the last 32 bit word to the FIFO and return with no errors */ 443 444 XIo_Out32(InstancePtr->DataBaseAddress, LastWord); 445 } 446 447 return XST_SUCCESS; 448} 449