📄 el3.c
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <eros/target.h>#include <eros/Invoke.h>#include <eros/Device.h>#include <eros/KeyBitsKey.h>#include <domain/domdbg.h>#include <eros/NetInterfaceKey.h>#define KR_VOID 0#define KR_KEYBITS 7 /* temporary, for debugging */#define KR_EL3_SLOT 8#define KR_CONSOLEKEY_SLOT 9#define KR_NETCREATOR_SLOT 10#define KR_LOGKEY_SLOT 11#define EL3_TEST_PKT_LEN 60#define SNOCRASH_ENET 0x00, 0xA0, 0x24, 0x67, 0xae, 0x3c,#define MOOCOW_ENET 0x00, 0xA0, 0x24, 0x23, 0x7D, 0x38,#define EROS_ENET 0x00, 0x00, 0xC0, 0x81, 0xE8, 0xE7,#define COLUMBIA_ENET 0x00, 0xA0, 0x24, 0x24, 0x0e, 0x9c,#define HALIFAX_ENET 0x00, 0xA0, 0x24, 0x23, 0x7c, 0xb4,#define BCAST_ENET 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,#define SNOCRASH_IP 158, 130, 6, 65,#define EROS_IP 158, 130, 6, 119,#define HALIFAX_IP 192, 187, 131, 1,#define COLUMBIA_IP 192, 187, 131, 5,#define MOOCOW_IP 158, 130, 6, 140,struct EthernetAddr enetAddr;uint8_t pktData[EL3_TEST_PKT_LEN] ={ /* ENABLE ONE DESTINATION!!! */ /* Ethernet Dest Addr */ BCAST_ENET /* Ethernet Src Addr: snocrash's EL3BCombo */ COLUMBIA_ENET /* ARP Frame Type*/ 0x08, 0x06, /* Ethernet Hardware Type */ 0x00, 0x01, /* IP Protocol Type */ 0x08, 0x00, /* Hardware Address Size */ 0x06, /* Protocol Addr Size */ 0x04, /* ARP Req Op */ 0, 0x01, /* ARP Rep Op */ /* 0, 0x02, */ /* RARP Req Op */ /* 0, 0x03, */ /* RARP Rep Op */ /* 0, 0x04, */ /* Sender Ethernet Addr: boat-anchor's EL3BCombo */ COLUMBIA_ENET /* Sender IP Addr: boat-anchor.cis */ COLUMBIA_IP /* Target Ethernet Addr: Not-filled in in ARP req */ 0, 0, 0, 0, 0, 0, /* Target IP Addr: */ HALIFAX_IP /* Pad */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};char testInvokeMsg[] = "This is a test message to verify invocation of the driver.";voidWriteHexData(const char *s, uint32_t len){ static char hexdigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static char buffer[4096]; Message msg; char *bufnext = buffer; while (len--) { char c = *s++; *(bufnext++) = hexdigits[(c >> 4) & 0xfu]; *(bufnext++) = hexdigits[c & 0xfu]; } msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.rcv_key0 = KR_VOID; msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_VOID; msg.rcv_key3 = KR_VOID; msg.snd_data = buffer; msg.snd_len = (bufnext - buffer); msg.rcv_len = 0; /* no data returned */ msg.snd_code = 1; msg.snd_invKey = KR_LOGKEY_SLOT; (void) CALL(&msg);}voidGetELNK3Key(){ struct DevCreArg { uint32_t subclass; uint32_t ndx; }; Message msg; struct DevCreArg devCreatorReq; devCreatorReq.subclass = DEV_NET_ENET; devCreatorReq.ndx = 0; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.rcv_key0 = KR_EL3_SLOT; msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_VOID; msg.rcv_key3 = KR_VOID; msg.snd_len = sizeof(devCreatorReq); msg.snd_data = & devCreatorReq; msg.rcv_len = 0; msg.rcv_data = NULL; msg.snd_code = 2; msg.snd_invKey = KR_NETCREATOR_SLOT; (void) CALL(&msg);}voidGetEnetAddr(struct EthernetAddr * enetAddrPtr){ Message msg; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.rcv_key0 = KR_VOID; msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_VOID; msg.rcv_key3 = KR_VOID; msg.snd_len = 0; msg.snd_data = NULL; msg.rcv_len = sizeof(struct EthernetAddr); msg.rcv_data = enetAddrPtr; msg.snd_code = OC_GET_ENET_ADDR; msg.snd_invKey = KR_EL3_SLOT; (void) CALL(&msg);}voidWritePacket(void *pktbuf, uint32_t len){ Message msg; msg.snd_key0 = KR_VOID; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.rcv_key0 = KR_VOID; msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_VOID; msg.rcv_key3 = KR_VOID; msg.snd_len = len; msg.snd_data = pktbuf; msg.rcv_len = 0; msg.rcv_data = NULL; msg.snd_code = OC_WRITE_ENET; msg.snd_invKey = KR_EL3_SLOT; (void) CALL(&msg);}#define DO_ICMP_ECHO#ifdef DO_ICMP_ECHO#include <eros/endian.h>void bcopy(void *from, void *to, uint32_t len){ char *cfrom = from; char *cto = to; while (len--) *cto++ = *cfrom++;}#if !defined(MODERATELY_SLOW)/* * Checksum routine for Internet Protocol family headers. * * This routine is very heavily used in the network * code and should be modified for each CPU to be as fast as possible. * * This implementation is 386 version. */#define REDUCE {sum = (sum & 0xffff) + (sum >> 16);}#define ADDCARRY {if (sum > 0xffff) sum -= 0xffff;}#define SWAP {sum <<= 8;}#define ADVANCE(x) {w += x; mlen -= x;}/* * Thanks to gcc we don't have to guess * which registers contain sum & w. */#define Asm __asm __volatile#define ADD(n) Asm("addl " #n "(%2),%0" : "=r" (sum) : "0" (sum), "r" (w))#define ADC(n) Asm("adcl " #n "(%2),%0" : "=r" (sum) : "0" (sum), "r" (w))#define MOP Asm("adcl $0,%0" : "=r" (sum) : "0" (sum))#define UNSWAP Asm("roll $8,%0" : "=r" (sum) : "0" (sum))#define ADDBYTE {sum += *w; SWAP; byte_swapped ^= 1;}#define ADDWORD {sum += *(u_short *)w;}intin_cksum(uint16_t *buf, register int len){ register u_char *w = (u_char *) buf; register unsigned sum = 0; register int mlen = len; int byte_swapped = 0; len -= mlen; if (mlen < 16) goto short_mbuf; /* * Force to long boundary so we do longword aligned * memory operations */ if ((3 & (long)w) != 0) { REDUCE; if ((1 & (long)w) != 0) { ADDBYTE; ADVANCE(1); } if ((2 & (long)w) != 0) { ADDWORD; ADVANCE(2); } } /* * Align 4 bytes past a 16-byte cache line boundary. */ if ((4 & (long)w) == 0) { ADD(0); MOP; ADVANCE(4); } if ((8 & (long)w) != 0) { ADD(0); ADC(4); MOP; ADVANCE(8); } /* * Do as much of the checksum as possible 32 bits at at time. * In fact, this loop is unrolled to make overhead from * branches &c small. */ while ((mlen -= 32) >= 0) { /* * Add with carry 16 words and fold in the last carry * by adding a 0 with carry. * * We aligned the pointer above so that the out-of- * order operations will cause the next cache line to * be preloaded while we finish with the current one. */ ADD(12); ADC(0); ADC(4); ADC(8); ADC(28); ADC(16); ADC(20); ADC(24); MOP; w += 32; } mlen += 32; if (mlen >= 16) { ADD(12); ADC(0); ADC(4); ADC(8); MOP; ADVANCE(16); }short_mbuf: if (mlen >= 8) { ADD(0); ADC(4); MOP; ADVANCE(8); } if (mlen >= 4) { ADD(0); MOP; ADVANCE(4); } if (mlen > 0) { REDUCE; if (mlen >= 2) { ADDWORD; ADVANCE(2); } if (mlen >= 1) { ADDBYTE; } } if (len) kprintf(KR_CONSOLEKEY_SLOT, "cksum: out of data\n"); if (byte_swapped) { UNSWAP; } REDUCE; ADDCARRY; return (sum ^ 0xffff);}#elif !defined(INCREDIBLY_SLOW)/* * Checksum routine for Internet Protocol family headers (Portable Version). * * This routine is very heavily used in the network * code and should be modified for each CPU to be as fast as possible. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -