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

📄 hostchan.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved. *  * This software may be freely used, copied, modified, and distributed * provided that the above copyright notice is preserved in all copies of the * software. *//* -*-C-*- * * $Revision: 1.8 $ *     $Date: 1999/11/01 15:32:59 $ * * * hostchan.c - Semi Synchronous Host side channel interface for Angel. */#include <stdio.h>#ifdef HAVE_SYS_TIME_H#  include <sys/time.h>#else#  include "winsock.h"#  include "time.h"#endif#include "hsys.h"#include "host.h"#include "logging.h"#include "chandefs.h"#include "chanpriv.h"#include "devclnt.h"#include "buffers.h"#include "drivers.h"#include "adperr.h"#include "devsw.h"#include "hostchan.h"#ifndef UNUSED#define UNUSED(x) (x = x)  /* Silence compiler warnings for unused arguments */#endif#define HEARTRATE 5000000/* * list of available drivers, declared in drivers.c */extern DeviceDescr *devices[];static DeviceDescr *deviceToUse = NULL;static struct Channel {    ChannelCallback callback;    void *callback_state;} channels[CI_NUM_CHANNELS];static unsigned char HomeSeq;static unsigned char OppoSeq;/* * Handler for DC_APPL packets */static DC_Appl_Handler dc_appl_handler = NULL;/* * slots for registered asynchronous processing callback procedures */#define MAX_ASYNC_CALLBACKS 8static unsigned int             num_async_callbacks = 0;static Adp_Async_Callback       async_callbacks[MAX_ASYNC_CALLBACKS];/* * writeQueueRoot is the queue of write requests pending acknowledgement * writeQueueSend is the queue of pending write requests which will * be a subset of the list writeQueueRoot */static Packet *writeQueueRoot = NULL;static Packet *writeQueueSend = NULL;static Packet *resend_pkt = NULL;static int resending = FALSE;/* heartbeat_enabled is a flag used to indicate whether the heartbeat is * currently turned on, heartbeat_enabled will be false in situations * where even though a heartbeat is being used it is problematical or * dis-advantageous to have it turned on, for instance during the  * initial stages of boot up */unsigned int heartbeat_enabled = FALSE;/* heartbeat_configured is set up by the device driver to indicate whether * the heartbeat is being used during this debug session.  In contrast to * heartbeat_enabled it must not be changed during a session.  The logic for * deciding whether to send a heartbeat is: Is heartbeat_configured for this * session? if and only if it is then if heartbeat[is currently]_enabled and * we are due to send a pulse then send it  */unsigned int heartbeat_configured = TRUE;void Adp_initSeq( void ) {  Packet *tmp_pkt = writeQueueSend;  HomeSeq = 0;  OppoSeq = 0;  if ( writeQueueSend != NULL) {    while (writeQueueSend->pk_next !=NULL) {      tmp_pkt = writeQueueSend;      writeQueueSend = tmp_pkt->pk_next;      DevSW_FreePacket(tmp_pkt);    }  }  tmp_pkt = writeQueueRoot;  if ( writeQueueRoot == NULL)    return;  while (writeQueueRoot->pk_next !=NULL) {    tmp_pkt = writeQueueRoot;    writeQueueRoot = tmp_pkt->pk_next;    DevSW_FreePacket(tmp_pkt);  }  return;}/**********************************************************************//* *  Function: DummyCallback *   Purpose: Default callback routine to handle unexpected input *              on a channel * *    Params: *       Input: packet  The received packet * *              state   Contains nothing of significance * *   Returns: Nothing */static void DummyCallback(Packet *packet, void *state){    ChannelID chan;    const char fmt[] = "Unexpected read on channel %u, length %d\n";    char fmtbuf[sizeof(fmt) + 24];    UNUSED(state);    chan = *(packet->pk_buffer);    sprintf(fmtbuf, fmt, chan, packet->pk_length);    printf(fmtbuf);    /*     * junk this packet     */    DevSW_FreePacket(packet);}/* *  Function: BlockingCallback *   Purpose: Callback routine used to implement a blocking read call * *    Params: *       Input: packet  The received packet. * *      Output: state   Address of higher level's pointer to the received *                      packet. * *   Returns: Nothing */static void BlockingCallback(Packet *packet, void *state){    /*     * Pass the packet back to the caller which requested a packet     * from this channel.  This also flags the completion of the I/O     * request to the blocking read call.     */    *((Packet **)state) = packet;}/* *  Function: FireCallback *   Purpose: Pass received packet along to the callback routine for *              the appropriate channel * *    Params: *       Input: packet  The received packet. * *   Returns: Nothing * * Post-conditions: The Target-to-Host sequence number for the channel *                      will have been incremented. */static void FireCallback(Packet *packet){    ChannelID chan;    struct Channel *ch;    /*     * is this a sensible channel number?     */    chan = *(packet->pk_buffer);    if (invalidChannelID(chan))    {        printf("ERROR: invalid ChannelID received from target\n");        /*         * free the packet's resources, 'cause no-one else will         */        DevSW_FreePacket(packet);        return;    }    /*     * looks OK - increment sequence number, and pass packet to callback     */    ch = channels + chan;    (ch->callback)(packet, ch->callback_state);}/**********************************************************************//* * These are the externally visible functions.  They are documented * in hostchan.h */void Adp_addToQueue(Packet **head, Packet *newpkt){    /*     * this is a bit of a hack     */    Packet *pk;    /*     * make sure that the hack we are about to use will work as expected     */    ASSERT(&(((Packet *)0)->pk_next) == 0, "bad struct Packet layout");#if defined(DEBUG) && 0    printf("Adp_addToQueue(%p, %p)\n", head, newpkt);#endif    /*     * here's the hack - it relies upon the next     * pointer being at the start of Packet.     */    pk = (Packet *)(head);    /*     * skip to the end of the queue     */    while (pk->pk_next != NULL)        pk = pk->pk_next;    /*     * now add the new element     */    newpkt->pk_next = NULL;    pk->pk_next = newpkt;}Packet *Adp_removeFromQueue(Packet **head){    struct Packet *pk;    pk = *head;    if (pk != NULL)        *head = pk->pk_next;    return pk;}void Adp_SetLogEnable(int logEnableFlag){  DevSW_SetLogEnable(logEnableFlag);}void Adp_SetLogfile(const char *filename){  DevSW_SetLogfile(filename);}AdpErrs Adp_OpenDevice(const char *name, const char *arg,                       unsigned int heartbeat_on){    int i;    AdpErrs retc;    ChannelID chan;#ifdef DEBUG    printf("Adp_OpenDevice(%s, %s)\n", name, arg ? arg : "<NULL>");#endif    heartbeat_configured = heartbeat_on;    if (deviceToUse != NULL)        return adp_device_already_open;    for (i = 0; (deviceToUse = devices[i]) != NULL; ++i)        if (DevSW_Match(deviceToUse, name, arg) == adp_ok)            break;    if (deviceToUse == NULL)        return adp_device_not_found;    /*     * we seem to have found a suitable device driver, so try to open it     */    if ((retc = DevSW_Open(deviceToUse, name, arg, DC_DBUG)) != adp_ok)    {        /* we don't have a device to use */        deviceToUse = NULL;        return retc;    }    /*     * there is no explicit open on channels any more, so     * initialise state for all channels.     */    for (chan = 0; chan < CI_NUM_CHANNELS; ++chan)    {        struct Channel *ch = channels + chan;        ch->callback = DummyCallback;        ch->callback_state = NULL;        OppoSeq = 0;        HomeSeq = 0;    }    return adp_ok;}AdpErrs Adp_CloseDevice(void){    AdpErrs retc;#ifdef DEBUG    printf("Adp_CloseDevice\n");#endif    if (deviceToUse == NULL)        return adp_device_not_open;    heartbeat_enabled = FALSE;    retc = DevSW_Close(deviceToUse, DC_DBUG);    /*     * we have to clear deviceToUse, even when the lower layers     * faulted the close, otherwise the condition will never clear     */    if (retc != adp_ok)        WARN("DevSW_Close faulted the call");    deviceToUse = NULL;    return retc;}AdpErrs Adp_Ioctl(int opcode, void *args){#ifdef DEBUG    printf("Adp_Ioctl\n");#endif    if (deviceToUse == NULL)        return adp_device_not_open;    return DevSW_Ioctl(deviceToUse, opcode, args);}AdpErrs Adp_ChannelRegisterRead(const ChannelID chan,                                const ChannelCallback cbfunc,                                void *cbstate){#ifdef DEBUG    printf("Adp_ChannelRegisterRead(%d, %p, %x)\n", chan, cbfunc, cbstate);#endif    if (deviceToUse == NULL)        return adp_device_not_open;    if (invalidChannelID(chan))        return adp_bad_channel_id;    if (cbfunc == NULL)    {        channels[chan].callback = DummyCallback;        channels[chan].callback_state = NULL;    }    else    {        channels[chan].callback = cbfunc;        channels[chan].callback_state = cbstate;    }    return adp_ok;}AdpErrs Adp_ChannelRead(const ChannelID chan, Packet **packet){    struct Channel *ch;#ifdef DEBUG    printf("Adp_ChannelRead(%d, %x)\n", chan, *packet);#endif    if (deviceToUse == NULL)        return adp_device_not_open;    if (invalidChannelID(chan))        return adp_bad_channel_id;    /*     * if a callback has already been registered for this     * channel, then we do not allow this blocking read.     */    ch = channels + chan;    if (ch->callback != DummyCallback)        return adp_callback_already_registered;    /*     * OK, use our own callback to wait for a packet to arrive     * on this channel     */    ch->callback = BlockingCallback;    ch->callback_state = packet;    *packet = NULL;    /*     * keep polling until a packet appears for this channel     */    while (((volatile Packet *)(*packet)) == NULL)        /*         * this call will block until a packet is read on any channel         */        Adp_AsynchronousProcessing(async_block_on_read);    /*     * OK, the packet has arrived: clear the callback     */    ch->callback = DummyCallback;    ch->callback_state = NULL;    return adp_ok;}static AdpErrs ChannelWrite(    const ChannelID chan, Packet *packet, AsyncMode mode){    struct Channel *ch;    unsigned char *cptr;#ifdef DEBUG    printf( "Adp_ChannelWrite(%d, %x)\n", chan, packet );#endif    if (deviceToUse == NULL)        return adp_device_not_open;    if (invalidChannelID(chan))        return adp_bad_channel_id;    /*     * fill in the channels header at the start of this buffer     */    ch = channels + chan;    cptr = packet->pk_buffer;    *cptr++ = chan;    *cptr = 0;    packet->pk_length += CHAN_HEADER_SIZE;    /*     * OK, add this packet to the write queue, and try to flush it out     */    Adp_addToQueue(&writeQueueSend, packet);    Adp_AsynchronousProcessing(mode);    return adp_ok;}AdpErrs Adp_ChannelWrite(const ChannelID chan, Packet *packet) {  return ChannelWrite(chan, packet, async_block_on_write);}AdpErrs Adp_ChannelWriteAsync(const ChannelID chan, Packet *packet) {  return ChannelWrite(chan, packet, async_block_on_nothing);}static AdpErrs send_resend_msg(DeviceID devid) {  /*   * Send a resend message, usually in response to a bad packet or   * a resend request */  Packet * packet;  packet = DevSW_AllocatePacket(CF_DATA_BYTE_POS);  packet->pk_buffer[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;  packet->pk_buffer[CF_HOME_SEQ_BYTE_POS] = HomeSeq;  packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS] = OppoSeq;  packet->pk_buffer[CF_FLAGS_BYTE_POS] = CF_RELIABLE | CF_RESEND;  packet->pk_length = CF_DATA_BYTE_POS;  return DevSW_Write(deviceToUse, packet, devid);}static AdpErrs check_seq(unsigned char msg_home, unsigned char msg_oppo) {  Packet *tmp_pkt;  UNUSED(msg_oppo);  /*    * check if we have got an ack for anything and if so remove it from the   * queue   */  if (msg_home == (unsigned char)(OppoSeq+1)) {    /*     * arrived in sequence can increment our opposing seq number and remove     * the relevant packet from our queue     * check that the packet we're going to remove really is the right one     */    tmp_pkt = writeQueueRoot;    while ((tmp_pkt->pk_next != NULL) &&           (tmp_pkt->pk_next->pk_buffer[CF_HOME_SEQ_BYTE_POS]            != OppoSeq)){      tmp_pkt = tmp_pkt->pk_next;    }    OppoSeq++;    if (tmp_pkt->pk_next == NULL) {#ifdef DEBUG      printf("trying to remove a non existant packet\n");#endif      return adp_bad_packet;    }    else {      Packet *tmp = tmp_pkt->pk_next;#ifdef RET_DEBUG      printf("removing a packet from the root queue\n");#endif      tmp_pkt->pk_next = tmp_pkt->pk_next->pk_next;      /* remove the appropriate packet */      DevSW_FreePacket(tmp);    return adp_ok;

⌨️ 快捷键说明

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