int pkt_test_upcall (void) { #if !defined(NO_RMODE_CALL) int i, max = RX_BUFS + 3; for (i = 0; i < max; i++) { eth_Packet eth; IREGS regs; DWORD linear = 0; memset (®s, 0, sizeof(regs)); memset (ð, 0, sizeof(eth)); eth.head.type = IP4_TYPE; memset (ð.head.destination, 0xFF, 6); memcpy (ð.head.source, _eth_addr, 6); #if (DOSX & (PHARLAP|X32VM)) rmc.eax = 0; rmc.ebx = _pkt_inf->handle; rmc.ecx = ETH_MAX; #endif regs.r_cx = ETH_MAX; regs.r_bx = _pkt_inf->handle; regs.r_ax = 0; regs.r_cs = _pkt_inf->rm_seg; regs.r_ip = PktReceiver; if (DPMI_REAL_CALL(®s)) { linear = SEG_OFS_ADDR (regs.r_es, regs.r_di); printf ("Upcall AX=0: ES:DI %04X:%04X\n", (WORD)regs.r_es, (WORD)regs.r_di); #if (DOSX & DJGPP) if (linear) dosmemput (ð, (WORD)regs.r_cx, linear); #elif (DOSX & (DOS4GW|X32VM)) if (linear) memcpy ((void*)linear, ð, (WORD)regs.r_cx); #elif (DOSX & (PHARLAP|POWERPAK)) if (linear) { RP_SET (linear, regs.r_es, regs.r_di); WriteRealMem (linear, ð, (WORD)regs.r_cx); } #else #error Help me! #endif } if (linear) { regs.r_ss = regs.r_sp = 0; regs.r_ax = 1; regs.r_cs = _pkt_inf->rm_seg; regs.r_ip = PktReceiver; regs.r_ds = regs.r_es; regs.r_si = regs.r_di; if (DPMI_REAL_CALL(®s)) printf ("Upcall AX=1\n"); } printf ("buffers used %d, dropped %lu\n", pkt_buffers_used(), pkt_rx_dropped()); } #endif pkt_dump_real_mem(); return (0); }
static int setup_rmode_receiver (void) { WORD rx_seg, rx_ofs; WORD asmpkt_size_chk; int head_size = RX_ELEMENT_HEAD_SIZE; WATT_ASSERT (rm_base); WATT_ASSERT ((head_size % 4) == 0); rx_seg = _pkt_inf->rm_seg; rx_ofs = PktReceiver; #if 0 /* test */ printf ("PktReceiver @ %04X:%04X, ", rx_seg, PktReceiver); printf ("_asmpkt_inf @ %04X:%04X\n", rx_seg, (int)sizeof(real_stub_array)); #endif *(WORD*)&real_stub_array[asmpkt_inf+0] = sizeof(real_stub_array); *(WORD*)&real_stub_array[asmpkt_inf+2] = rx_seg; asmpkt_size_chk = *(WORD*) (real_stub_array + size_chk); if (asmpkt_size_chk != sizeof(PKT_INFO)) { TCP_CONSOLE_MSG (0, ("%s (%u): Development error:\n" " sizeof(pkt_info) = %ld in pcpkt.h\n" " sizeof(pkt_info) = %u in asmpkt.nas, (diff %ld)\n", __FILE__, __LINE__, (long)sizeof(PKT_INFO), asmpkt_size_chk, (long)(sizeof(PKT_INFO) - asmpkt_size_chk))); return (-1); } if (*(WORD*)&real_stub_array[PktReceiver] != 0xA80F || /* push gs */ *(WORD*)&real_stub_array[PktReceiver+2] != 0xA00F) /* push fs */ { TCP_CONSOLE_MSG (0, ("%s (%u): Development error:\n" " PktReceiver misaligned\n", __FILE__, __LINE__)); return (-1); } if (!has_rdtsc || !use_rdtsc) { DWORD patch_it = (*(WORD*) &real_stub_array[patch_nop]) + (DWORD) &real_stub_array; TCP_CONSOLE_MSG (4, ("patch_it (%04X): %02X,%02X,%02X\n", *(WORD*)&real_stub_array[patch_nop], ((BYTE*)patch_it)[0], ((BYTE*)patch_it)[1], ((BYTE*)patch_it)[2])); ((BYTE*)patch_it) [0] = 0x90; /* NOP */ ((BYTE*)patch_it) [1] = 0x90; ((BYTE*)patch_it) [2] = 0x90; } #if (DOSX & (PHARLAP|POWERPAK|X32VM)) WriteRealMem (rm_base, &real_stub_array, sizeof(real_stub_array)); #elif (DOSX & DJGPP) dosmemput (&real_stub_array, sizeof(real_stub_array), rm_base); #elif (DOSX & DOS4GW) || (DOSX == 0) memcpy ((void*)rm_base, &real_stub_array, sizeof(real_stub_array)); #else #error Help me! #endif return (0); }
/* * Append a transmit buffer at end of receive buffer. * Must not be called before checking if there is room. */ int pkt_append_recv (const void *tx, unsigned len) { struct pkt_rx_element buf; struct pkt_ringbuf *q = &_pkt_inf->pkt_queue; DWORD addr; int idx; DISABLE(); idx = PEEKW (0, QUE_OFS(in_index)); if (idx < 0 || idx >= q->num_buf) { #if defined(USE_DEBUG) (*_printf) ("pkt_append_recv(): illegal index %d\n", idx); /* pkt_dump_real_mem(); */ #endif ENABLE(); return (0); } buf.rx_length_1 = buf.rx_length_2 = len; buf.handle = _pkt_inf->handle; buf.filler = 0; get_tstamp (buf.tstamp_put); addr = ASMPKT_INF + offsetof (PKT_INFO, rx_buf[idx]); #if (DOSX & (PHARLAP|POWERPAK|X32VM)) WriteRealMem (addr, &buf, RX_ELEMENT_HEAD_SIZE); #elif (DOSX & DOS4GW) memcpy ((void*)addr, &buf, RX_ELEMENT_HEAD_SIZE); #elif (DOSX & DJGPP) DOSMEMPUTL (&buf, RX_ELEMENT_HEAD_SIZE/4, addr); #elif (DOSX == 0) memcpy ((void*)addr, &buf, RX_ELEMENT_HEAD_SIZE); #else #error Help me! #endif addr += RX_ELEMENT_HEAD_SIZE; #if (DOSX & (PHARLAP|POWERPAK|X32VM)) WriteRealMem (addr, (void*)tx, len); #elif (DOSX & DOS4GW) memcpy ((void*)addr, tx, len); #elif (DOSX & DJGPP) DOSMEMPUTL (tx, (len+3)/4, addr); #elif (DOSX == 0) memcpy ((void*)addr, tx, len); #else #error Help me! #endif if (++idx == q->num_buf) idx = 0; POKEW (0, QUE_OFS(in_index), idx); ENABLE(); /* pkt_dump_real_mem(); */ return (len); }
static REALPTR _dx_alloc_rmode_wrapper (pmodeHook pmHook, rmodeHook rmHook, int len, int stack_size, ReturnType returnType) { #define DOFS 0x2C /* offset of data section (tiny model) */ #define DSIZE 16 /* sizeof data section at wrapper end */ #define WOFS (DOFS+DSIZE) /* offset of userWrapper code (optional) */ static unsigned char wrapper[] = { 0x16, // 00 push ss 0x06, // 01 push es 0x1E, // 02 push ds 0x0E, // 03 push cs 0x1F, // 04 pop ds ;DS = CS 0xF8, // 05 clc 0xE8,0x33,0, // 06 call userWrapper ;33 relative (3A-8) 0x72,0x1C, // 09 jc short @exit 0x66,0x60, // 0B pushad 0x66,0xFF,0x36,DOFS+12,0, // 0D push taskId ;taskId to call 0x66,0x6A,0, // 12 push 0 ;use default selectors 0xFF,0x36,DOFS+4,0, // 15 push ourCS 0x66,0xFF,0x36,DOFS,0, // 19 push protGlue ;(*protGlue)() 0xFF,0x1E,DOFS+8,0, // 1E call rm2pmAddr 0x83,0xC4,14, // 22 add sp,14 ;discard used stack 0x66,0x61, // 25 popad 0x1F, // 27 @exit:pop ds 0x07, // 28 pop es 0x17, // 29 pop ss 0xCB, // 2A retf 0x90, // 2B nop 0,0,0,0, // +0 protGlue dd ? 0,0,0,0, // +4 ourCS dw ?,? 0,0,0,0, // +8 rm2pmAddr dd ? 0,0,0,0 // +12 taskId dd ? }; // +16 userWrapper: .. FARPTR pmCbuf, fpWrapper; REALPTR rmCbuf, rm2pmAddr, dosReal; USHORT para, paras, left; ULONG cbufSize, i; UINT *stack; assert (sizeof(wrapper) == (DOFS+DSIZE)); if (!pmHook || numWrappers == MAX_WRAPPERS) return (0); _dx_rmlink_get (&rm2pmAddr,&rmCbuf,&cbufSize,&pmCbuf); len += sizeof(wrapper); paras = (len + 15) / 16; para = 0; if (_dx_real_above(paras,¶,&left)) { ULONG temp; if (_dx_cmem_usage(0,0,&temp,&temp)) return (0); if (_dx_real_above(paras,¶,&left)) para = 0; if (_dx_cmem_usage(0,1,&temp,&temp)) { if (para) _dx_real_free (para); return (0); } if (!para) return (0); } for (i = 0; i < MAX_WRAPPERS; i++) if (!_rmcb[i].dosReal) break; *(ULONG*) (wrapper+DOFS+0) = (ULONG)&PmodeGlue; /* pmode helper */ *(ULONG*) (wrapper+DOFS+4) = My_CS(); /* pmode CS */ *(ULONG*) (wrapper+DOFS+8) = (ULONG)rm2pmAddr; /* rm->pm addr */ *(ULONG*) (wrapper+DOFS+12) = i; /* task Id */ wrapper [0x2A] = returnType; /* RETF or IRET */ /* * lock pages used by callback (for 386|VMM, allthough untested) */ FP_SET (fpWrapper,para << 4, SS_DOSMEM); _dx_lock_pgs (fpWrapper, len); _dx_lock_pgsn ((void*)&PmodeGlue, (UINT)&PmGlueEnd - (UINT)&PmodeGlue); RP_SET (dosReal,0,para); FillRealMem (dosReal, 0, len); WriteRealMem (dosReal, &wrapper, sizeof(wrapper)); if (rmHook) WriteRealMem(dosReal+WOFS,(void*)rmHook,len-sizeof(wrapper)); else FillRealMem (dosReal+5,0x90,6); stack_size += sizeof(UINT) + 3; /* add a DWORD for marker */ stack_size &= ~3; /* make number of DWORDs */ stack = malloc (stack_size); if (!stack) return (0); _rmcb [i].dosReal = dosReal; _rmcb [i].callback = pmHook; _rmcb [i].stackStart = stack; _rmcb [i].stackTop = stack + stack_size/sizeof(UINT) - 2; _rmcb [i].stackTop[1] = MARKER; _rmcb [i].marker = MARKER; _dx_lock_pgsn ((void*)stack, stack_size); #if 0 printf ("dosReal %08lX, rm2pmAddr %08lX, len %d, stack %08X\n", dosReal,rm2pmAddr,len,stack); #endif numWrappers++; return (dosReal); }