⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpcclient.c

📁 PNX系列设备驱动 PNX系列设备驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  +-------------------------------------------------------------------+
 *  | Copyright (c) 1995,1996,1997 by Philips Semiconductors.           |
 *  |                                                                   |
 *  | This software  is furnished under a license  and may only be used |
 *  | and copied in accordance with the terms  and conditions of such a |
 *  | license  and with  the inclusion of this  copyright notice.  This |
 *  | software or any other copies of this software may not be provided |
 *  | or otherwise  made available  to any other person.  The ownership |
 *  | and title of this software is not transferred.                    |
 *  |                                                                   |
 *  | The information  in this software  is subject  to change  without |
 *  | any  prior notice  and should not be construed as a commitment by |
 *  | Philips Semiconductors.                                           |
 *  |                                                                   |
 *  | This  code  and  information  is  provided  "as is"  without  any |
 *  | warranty of any kind,  either expressed or implied, including but |
 *  | not limited  to the implied warranties  of merchantability and/or |
 *  | fitness for any particular purpose.                               |
 *  +-------------------------------------------------------------------+
 *
 *  Module name              : RPCClient.c    1.42
 *
 *  Title                    : Implementation of HostCall interface
 *
 *  Last update              : 12:23:28 - 99/12/10
 *
 *  Description              :
 *
 *           This module is part of an implementation of the HostCall interface.
 *           HostCall is the software component which is required by
 *           the TCS toolset to adapt the programs generated by this toolset
 *           to a specific host (see file HostCall.h in the TCS include dir).
 *
 *           RPCClient is one of two modules which form an implementation of
 *           the HostCall interface (the other one is HostIF); RPCClient is
 *           still entirely host independent, and solves nasty datacache related
 *           issues, and selects efficient ways of transferring data over the
 *           PCI bus. More specific, the problems addressed in this module are
 *           as follows:
 *
 *           1) In reading and writing large amounts of data (e.g. by
 *              file IO functions 'read' and 'write'), data copying by
 *              the TM-1 CPU side should be avoided as much as possible.
 *
 *           2) In reading and writing large amounts of data, occupying the
 *              memory buses should be avoided as much as possible.
 *
 *           3) This interface provides- and gets data to the host via
 *              shared memory, by sending and receiving pointers to data
 *              via HostIF.
 *              The HostCall interface does not have any control over the
 *              alignment of the provided command buffers and provided
 *              data- or return buffers. Since reading/writing by the host
 *              into TM-1 visible memory is not synchronised with the TM-1
 *              data cache, the TM-1 has to do a cache copyback of data provided
 *              to the host, and cache invalidates on memory buffers filled
 *              by the host. Especially in multitasking environments, these
 *              operations are extremely dangerous when applied to memory
 *              which occupies cache pages which are not completely owned
 *              by the calling thread.
 *
 *           RPCClient solves problem 3 by copying all relevant data
 *           (like the command buffer) into cache aligned memory, and
 *           using these copies in the actual communication. RPCClient
 *           solves problem 1 by providing write buffers for direct reading
 *           to the host, and by providing the large bodies of read buffers
 *           to the host in order to give the host direct access to these buffers.
 *           This is referred to in the sequel as 'dma' (lower case).
 *           RPCClient does not yet solve problem 2; but a modification using
 *           hardware DMA will soon be provided.
 *
 *           The implementation of HostCall is partitioned between RPCClient
 *           and HostIF as follows:
 *
 *           - _HostCall_notify is provided in HostIF
 *           - _HostCall_host_send is provided in RPCClient.
 *           - _HostCall_init and -terminate are provided in RPCClient.
 *           - Module RPCClient provides the general implementation strategy
 *             and solves all cache problems.
 *           - HostIF provides a simple communication interface for sending
 *             pointers hence and forth.
 *           - RPCClient communicates with a RPCServer on the host.
 */

/*---------------------------- Includes --------------------------------------*/

#define NDEBUG

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "Lib_Local.h"
#include <ops/custom_defs.h>
#include <tmtypes.h>
#include <HostCall.h>
#include "HostIF.h"
#include "RPC_Common.h"
#include <tmlib/tmlibc.h>

/*---------------------------- Module State ----------------------------------*/

/*
#include <tmlib/tmtypes.h>
#include <tmlib/HostCall.h>
*/


/*
 * Threshold after which the read command will
 * try to avoid unnecessary copying at the
 * target site by letting the host do dma
 * in the user- provided buffer.
 */
#define READ_DMA_THRESHOLD  320  /* bytes */

/*
 * DCache page size and alignment:
 */
#define TM1_DCACHE_PAGE_SIZE        64

#define TM1_DCACHE_PAGE_TRUNC(address) \
      ((Address) LROUND_DOWN ((UInt32) (address), (UInt32) TM1_DCACHE_PAGE_SIZE))

#define TM1_DCACHE_PAGE_ALIGN(address) \
      ((Address) LROUND_UP ((UInt32) (address), (UInt32) TM1_DCACHE_PAGE_SIZE))

/* forward declaration */
static void termination_handler( HostCall_command *command );



/*----------------------------- Data Block To Host ---------------------------*/

/*
 * Declaration of the data which is to be allocated
 * for one host call. It will be allocated in one unit,
 * and contains a cache aligned copy of the command,
 * a cache aligned copy of the result buffer and tempotary
 * working space:
 */

typedef struct ShadowBlockHeader {
    HostCall_command  command;
    Int32             result_buf_offset;
    Int32             result_buf_len;
} ShadowBlockHeader;


typedef struct ShadowBlock {
    ShadowBlockHeader  header;

    /* copy of result buffer to be filled */
    /* by host follows after this header. */
} ShadowBlock;



/*--------------------------------- Cache Issues -----------------------------*/


/*
 * Make a copy of a command buffer, which is to be fully
 * within 'private' cache pages; that is, prevent the
 * possibility that parts of the cache pages which are
 * occupied by the result are used by other processes
 * during the host service request. Optionally, the
 * address of a field in a command buffer which contains
 * the address of a result buffer can be specified,
 * with the length of this buffer. When present,
 * a copy of the buffer will be allocated with (that is,
 * after) the copy of the command, together with some
 * administration.
 * The result is linked into the user- provided command
 * buffer, and will be sent to the host instead of the
 * user- provided command- and result buffer; the termination
 * handler (see below) will contain some termination
 * handling after the service request has completed;
 * this termination handling mainly consists of copying back
 * the results from the host into the user- provided space,
 * and of deallocation of the shadow command.
 * The result is properly cache- flushed such that the
 * host can expect it in memory, and cache- invalidated
 * such that the host- written results are visible
 * upon return of the host request.
 * Parameter 'preserve' causes the contents of the user
 * provided command buffer in which no results are returned
 * to be preserved (simply by copying the contents into the
 * command buffer copy before the transaction).
 */

static HostCall_command*
          make_shadow(
              HostCall_command *command,
              Int32             result_buf_len,
              Address           result_buf,
              Bool              preserve
          )
{
    Int32              shadow_block_size;
    ShadowBlock       *shadow_block;

    shadow_block_size = sizeof(ShadowBlock) + result_buf_len;
    shadow_block      = (Pointer)_cache_malloc(shadow_block_size, -1);

    if (shadow_block == Null) {
        return Null;
    }

    memcpy((Pointer)&shadow_block->header.command, (Pointer)command, sizeof(*command));
    shadow_block->header.result_buf_len      =  result_buf_len;
    shadow_block->header.command.target_link =  command;

    command->target_link             =  (HostCall_command *)shadow_block;
    command->termination_handler     =  (HostCall_Termination_Handler)termination_handler;


    if (result_buf_len == 0) {
       _cache_copyback  ( shadow_block, sizeof(ShadowBlockHeader) );

    } else {
        Int32     result_buf_offset    = result_buf - (Address)command;
        Address  *pp_shadow_result_buf = (Pointer)(((Address)&shadow_block->header.command)+result_buf_offset);
        Address   p_shadow_result_buf  = (Address)(shadow_block+1);

       *pp_shadow_result_buf                    = p_shadow_result_buf;
        shadow_block->header.result_buf_offset  = result_buf_offset;

        if (preserve) {
            memcpy ( (Pointer)p_shadow_result_buf, *(Pointer*)result_buf, result_buf_len );
        }
        _cache_copyback ( shadow_block,  sizeof(ShadowBlockHeader) );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -