📄 dptarget.c
字号:
/*** File: dptarget.c** Version: 1.0.1**** Description: Target-side driver functions for NR5xx**** Copyright (c) 1996 Applied Microsystems Corporation** All Rights Reserved**** Modification History:** 10/04/96, MPH...Created from nrdrive.c** 01/20/97, MPH...Fixed nr_ReadBuf and nr_ProcessMsgs for PPC603** 02/04/97, MS....fixed numerous compiler warnings*/#include "wdb/amc500/dpconfig.h"#include "wdb/amc500/dptarget.h"#include "wdb/amc500/dualport.h"/* Local definitions */#define DEBUG_ON False /* Optional: Include nr_TestComm() if True */#ifndef NULL#define NULL 0#endif/* Private routines */STATIC void nr_WriteInt ( uInt16, uInt32, uInt16 );STATIC uInt16 nr_ReadInt ( uInt16, uInt32 );STATIC void nr_WriteBuf ( uInt16, uChar*, uInt32, uInt16 );STATIC void nr_ReadBuf ( uInt16, uInt32, volatile uChar*, Int16 );STATIC Int16 nr_ProcessMsgs ( uInt16 );STATIC Int16 nr_PutOOBMsg ( uInt16, uInt16, char*, uInt16 );STATIC void nr_Wait ( DpChannel* );STATIC void nr_WaitEnd ( void ); /* Global data */STATIC DpChannel channels[DP_MAXCHANNELS];STATIC volatile uChar RR_dummy; /* See dptarget.h for explanation */STATIC volatile uChar dummy; STATIC uChar wait_ftn_buf[MAX_WAIT_FTN_SIZE]; /* For RAM-based wait ftn */STATIC Int16 emoffonwrite_set;/*** Function: nr_ReadByte** Description: Reads a byte from DP RAM** Note: With caching, we need to use a function** Without caching, we can use a (faster) macro** Warning: Assumes 'cp' is valid**** Parameters:** cp pointer-to-channel to read from** addr address for read**** Returns:** uChar from DP RAM*/#if( nr_HasCache == True )uChar nr_ReadByte(DpChannel *cp, uInt32 addr){ register uChar ch; nr_DataCacheOff(); ch = NR_READ_BYTE( (cp), (addr) ); nr_DataCacheOn(); return ch;}#else /* nr_HasCache == True */#define nr_ReadByte(cp,addr) NR_READ_BYTE( (cp), (addr) )#endif /* nr_HasCache == True *//*** Function: nr_WriteByte** Description: Writes a byte to DP RAM** Note: With caching, we need to use a function** Without caching, we can use a (faster) macro** Warning: Assumes 'cp' is valid**** Parameters:** cp pointer-to-channel to write to** addr address for write**** Returns:** note*/#if( nr_HasCache == True )voidnr_WriteByte(DpChannel *cp, uInt32 addr, uInt16 val){ nr_DataCacheOff(); NR_WRITE_BYTE( (cp), (addr), (val) ); nr_DataCacheOn();}#else /* nr_HasCache == True */#define nr_WriteByte\(cp, addr, val) { NR_WRITE_BYTE((cp), (uInt32)(addr), (uInt16)(val)); }#endif /* nr_HasCache == True *//*** Macro: nr_InROM** Description: Determines if an address is w/in NR emulation RAM** Note: ROMSTART and ROMEND are defined in dpconfig.h** Evaluates to TRUE if address is within NetROM overlay, otherwise FALSE*/#define nr_InROM(adr) ((adr) >= (uInt32)ROMSTART && (adr) < (uInt32)ROMEND)/*** Function: nr_ConfigDP** Description: Configure dualport RAM communication structures**** Parameters:** base First address of dualport RAM ** width Width of ROM(s) emulated: 1-8 bits 2-16 bits 4-32 bits** index Location of pod0 within podgroup**** Returns:** Err_BadLength If MAX_WAIT_FTN_SIZE is too small to hold nr_Wait()** Err_NoError Otherwise*/Int16nr_ConfigDP( uInt32 base, Int16 width, Int16 index ){ DpChannel *cp; Int16 chan; uInt32 tmp, pWait, wait_ftn_size; /* Calc size of nr_Wait for copy to RAM...will it fit? */ /* 'wait_ftn_size+3' because of 32bit align code, below */ wait_ftn_size = (uInt32)((uInt32)nr_WaitEnd - (uInt32)nr_Wait); if( wait_ftn_size+3 > MAX_WAIT_FTN_SIZE ) return Err_BadLength; if( wait_ftn_size < 10 ) /* Sanity check */ return Err_BadLength; /* Copy nr_Wait routine to RAM */ pWait = (uInt32)wait_ftn_buf; tmp = (uInt32) wait_ftn_buf & 0x03; /* force 32bit align */ if(tmp != 0) pWait += (4 - tmp); memcpy( (uChar*)pWait, (uChar*)nr_Wait, wait_ftn_size ); /* Load channel structs */ for( chan = 0; chan < DP_MAXCHANNELS; chan++ ) { /* get a pointer to the channel */ cp = &channels[chan]; /* set the addresses for dualport ram */ cp->dpbase = base + chan * DP_CHAN_SIZE * width; cp->dpbase_plus_index = cp->dpbase + index; /* Time saver const */ cp->width = width; cp->index = index; /* rr_data_offset includes "index" to speed up RR_xxx macros */ /* For writes to Pods0-2, rr_data_offset will cause us to read */ /* from the next Pod. For pod3, we'll read from pod0 area */ /* This is to avoid reading addresses that the hardware is */ /* latching for the RR protocol. */ if( 3 == chan ) { cp->rr_enable = base + index + RR_ENABLE_ADR * width; cp->rr_disable = base + index + RR_DISABLE_ADR * width; } else { cp->rr_enable = cp->dpbase + index + RR_ENABLE_ADR * width; cp->rr_disable = cp->dpbase + DP_CHAN_SIZE * width + index + RR_DISABLE_ADR * width; } /* initialize the buffer system */ cp->txbuf.bufsize = 0; cp->txbuf.index = 0; cp->rxbuf.bufsize = 0; cp->rxbuf.index = (-1); /* cp->numaccess = numaccesses; */ /* initialize the ack counter */ cp->rxackval = 0; /* we can both read and write dualport */ cp->chanflags = CF_TXVALID | CF_RXVALID | CF_NOWAITIO; /* start the receive area after the status/control area */ cp->rxbase = cp->rxlim = DP_MSGBASE; cp->rx = (-1); /* start the transmit area after the receive area */ cp->txbase = cp->tx = (DP_REC_MSGS + 1) * DPM_MSGSIZE; cp->oobthresh = 0; /* xxx */ /* Points to RAM-based wait ftn; used w/ nr_SetMem() */ cp->wait_nr_done_ptr = (void (*)()) pWait; } emoffonwrite_set = True; /* Set emulate off on write */ /* This function will hang on the following line until the ** communication channel is up. If you find that the code ** is hanging here, either 1) NetROM is not configured correctly for ** this debug channel; 2) config_dpram() was called with the wrong ** parameters; or 3) the telnet session is not connecting to the ** NetROM debug port. */ while( !nr_ChanReady(chan) ) {} /* Request that NetROM synchronize comm buffers with the target */ nr_Resync(0); return Err_NoError;}/*** Function: nr_SetBlockIO** Description: This ftn affects nr_Getch(), nr_Putch() and nr_GetMsg()** val == 0 --> non-blocking I/O** val != 0 --> blocking I/O**** Parameters:** chan channel to configure, 0-3** val 0 for non-blocking, non-zero for blocking**** Returns:** Err_BadChan if the chan is invalid (0,1,2,3 are valid on NR5xx)** Err_NoError otherwise*/Int16nr_SetBlockIO( uInt16 chan, uInt16 val ){ register DpChannel *cp; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; /* get a pointer to the channel */ cp = &channels[chan]; if(val == 0) { cp->chanflags |= CF_NOWAITIO; } else { cp->chanflags &= ~CF_NOWAITIO; } return Err_NoError;}/*** Function: nr_ChanReady** Description: Test to see if a chan is ready to transmit & receive**** Parameters:** chan channel to test, 0-3**** Returns:** Err_BadChan if chan is invalid (0,1,2,3 are valid on NR5xx)** True if the channel is ready** False if the channel is not ready*/Int16nr_ChanReady( uInt16 chan ){ uChar val; register DpChannel *cp; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; /* get a pointer to the channel */ cp = &channels[chan]; /* check that the RX channel is active */ val = nr_ReadByte(cp, DP_RX); if(val != nr_ReadByte(cp, DP_RX)) { return False; } else if(val != 1) { return False; } /* check that the TX channel is active */ val = nr_ReadByte(cp, DP_TX); if(val != nr_ReadByte(cp, DP_TX)){ return False; } else if(val != 1) { return False; } /* Channel is ready */ return True;}/*** Function: nr_Poll** Description: check if a character is waiting at the channel**** Parameters:** chan channel to poll, 0-3**** Returns:** True if there is a character waiting** False if there is NOT a character waiting** Err_BadChan if the chan is invalid (0,1,2,3 are valid on NR5xx)*/Int16nr_Poll( uInt16 chan ){ DpChannel *cp; BufIo *bp; Int16 retval; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; /* get a pointer to the channel */ cp = &channels[chan]; bp = &cp->rxbuf; /* see if there is a character in this buffer */ if(bp->index < 0) { /* poll for new buffers */ nr_ProcessMsgs(chan); /* no, check for a new buffer arriving */ if(cp->rx != (-1) ) { retval = True; } else { retval = False; } } else { retval = True; } return(retval);}/*** Function: nr_Getch** Description: Gets one char from channel**** Parameters:** chan channel to read from, 0-3**** Returns:** Err_WouldBlock if channel is non-blocking and there is no char** Err_BadChan if the chan is invalid** char otherwise*/Int16nr_Getch( uInt16 chan ){ DpChannel *cp; BufIo *bp; Int16 ch; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; /* get a pointer to the channel */ cp = &channels[chan]; bp = &cp->rxbuf; /* see if there is a character in this buffer */ if(bp->index < 0) { /* wait for the buffer to become valid */ while(cp->rx == (-1) ) { /* poll for new buffers */ nr_ProcessMsgs(chan); /* did we get a message? */ if(cp->rx == (-1) ) { if(cp->chanflags & CF_NOWAITIO) return Err_WouldBlock; nr_YieldCPU(); } } /* make sure that the message is ready by reading the flags byte * of the next receive msg. */ bp->flags = nr_ReadInt(chan, cp->rx + DPM_FLAGS); /* Re-read the flags because the NetROM may have been modifying * them while we read them. */ if(bp->flags != nr_ReadInt(chan, cp->rx + DPM_FLAGS)) { /* read failed on the verify, NetROM must be writing */ bp->flags = nr_ReadInt(chan, cp->rx + DPM_FLAGS); } if((bp->flags & DPMSG_READY) == 0) { return(Err_WouldBlock); } /* set up the i/o buffer for the message */ bp->bufsize = nr_ReadInt(chan, cp->rx + DPM_SIZE); if(bp->bufsize > DP_DATA_SIZE) { bp->bufsize = DP_DATA_SIZE; } nr_ReadBuf( chan, cp->rx + DPM_DATA, bp->buf, (Int16)(bp->bufsize) ); bp->index = 0; /* return the buffer */ nr_WriteInt(chan,cp->rx+DPM_FLAGS,(uInt16)bp->flags & ~DPMSG_READY); /* advance the read pointer */ if(bp->flags & DPMSG_WRAP) { cp->rx = cp->rxbase; } else { cp->rx += DPM_MSGSIZE; } /* see if there are more messages waiting */ if(cp->rx == cp->rxlim) { cp->rx = (-1); } } /* extract the character */ ch = (Int16)bp->buf[bp->index++]; /* check whether we finished the buffer */ if(bp->index == bp->bufsize) { /* invalidate the buffer */ bp->index = (-1); } return(ch);}/*** Function: nr_Putch** Description: send one character via dp protocol**** Parameters:** chan channel to write to, 0-3**** Returns:** Err_NoError if the char was sent successfully** Err_WouldBlock if we can't send the char** Err_BadChan if the chan is invalid*/Int16nr_Putch( uInt16 chan, char ch ){ DpChannel *cp; BufIo *bp; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; /* get a pointer to the channel */ cp = &channels[chan]; bp = &cp->txbuf; /* if the current tx channel is owned by the target, wait for it */ bp->flags = nr_ReadInt(chan, cp->tx + DPM_FLAGS); if(bp->flags & DPMSG_READY) { /* wait for the buffer */ while(1) { bp->flags = nr_ReadInt(chan, cp->tx + DPM_FLAGS); if(bp->flags != nr_ReadInt(chan, cp->tx + DPM_FLAGS)) { /* read failed on the verify, NetROM must be writing */ continue; } if((bp->flags & DPMSG_READY) == 0) break; if(cp->chanflags & CF_NOWAITIO) return( Err_WouldBlock ); nr_YieldCPU(); } /* initialize the buffer structure */ bp->index = 0; bp->bufsize = 0; } /* write the character into the buffer */ bp->buf[bp->index++] = ch; bp->bufsize++; /* if the buffer is full, send it */ if(bp->index == DP_DATA_SIZE) { nr_FlushTX(chan); } return Err_NoError;}/*** Function: nr_FlushTX** Description: Transmits any chars pending in this channel**** Parameters:** chan channel to flush, 0-3**** Returns:** Err_NoError if successful** Err_BadChan if the chan is invalid*/Int16nr_FlushTX( uInt16 chan ){ DpChannel *cp; BufIo *bp; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; /* get a pointer to the channel */ cp = &channels[chan]; bp = &cp->txbuf; /* if we don't own the message or there's nothing in it, just return */ bp->flags = nr_ReadInt(chan, cp->tx + DPM_FLAGS); if((bp->flags & DPMSG_READY) != 0 || bp->index == 0) { return Err_NoError;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -