Excuse me in advance if this is too long.
Let me explain what I'm trying to do:
I'm using the uengine interrupt to StrongARM to ask for an ARP service
performed by VxWorks.
I'm not using the OS ARP Cache directly from uengines, rather I maintain a
private hash table (SRAM and DRAM) for IP to MAC entries. This table is
written by the core and read by uengines. All locking, hash unit and
duplicates issues are just fine.
When a lookup from uengine thread fails to find an entry for IP (the MAC is
unknown!), the uengine thread will write the request in a mailbox and raise
an interrupt to core. ACK from core is waited (inter thread signal). when
ACK received, uthread will drop the packet, hopefully next packet required
MAC will be resolved since ARP Service on core will add the information to
IP2MAC table. On core there is an interrupt handler, that is a callback
function registered with the Global uengine ISR (yeah, the same one
breakpoint is using!). This handler will read the uthread request from
mailbox and send it by message queue to ARP resolver task. The interrupt
handler send an inter thread signal as an ACK back to uengines. The ARP
resolver task perform the ARP and adds the resolved MAC to IP2MAC hash
table.
some code snippets:
#macro arp_resolve_request(_output_intf, _ip)
.local mailbox
xbuf_alloc($request, 2)
move($request0, _output_intf)
move($request1, _ip)
#if (UENGINE_ID == 0)
move(mailbox, LWOFFSET0)
#else // UENGINE_ID == 1
move(mailbox, LWOFFSET2)
#endif
sram_write($request0, UTHREAD_TO_CORE_MAILBOXES, mailbox, LWCOUNT2,
sig_done)
block_on_sram#:
br_!signal[sram, block_on_sram#] ; block until mailbox written to continue
fast_wr[1, ireg] ; raise interrupt
block_on_inter_thread#:
br_!signal[inter_thread, block_on_inter_thread#] ; wait for core ACK
xbuf_free($request)
alu[--,--,b, 0] ; this will cause drop pkt
.endlocal // mailbox
#endm
note that I use only the first 2 (0, 1) uengines to Receive & Forward so
just two mailboxes.
now at the core...
I connect the interrupt handler as:
#include "ueng.h"
.........
/* statics initialization */
unsigned int & ArpServ::_ireg(*(unsigned int *)0xB00401E0);
.................
uEng_intConnect(UENG_MSG_INT, 0xFFFFFF, interrupt_handler, 0);
................
void ArpServ::interrupt_handler(int){
REQUEST_t request;
unsigned int ifname, ipaddr, request_size;
unsigned int iregShadow;
iregShadow= _ireg;
_ireg = iregShadow & 0xF8FFFFFF;
iregShadow &= 0xFFFFFF;
for(int bit=0; bit
participants (1)
-
Arthur Berkowitz