From owner-p4-projects@FreeBSD.ORG Fri Apr 27 12:46:51 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7935116A408; Fri, 27 Apr 2007 12:46:51 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 5096016A403 for ; Fri, 27 Apr 2007 12:46:51 +0000 (UTC) (envelope-from taleks@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 378EE13C45D for ; Fri, 27 Apr 2007 12:46:51 +0000 (UTC) (envelope-from taleks@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l3RCkpSr051655 for ; Fri, 27 Apr 2007 12:46:51 GMT (envelope-from taleks@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l3RCkoMJ051651 for perforce@freebsd.org; Fri, 27 Apr 2007 12:46:50 GMT (envelope-from taleks@FreeBSD.org) Date: Fri, 27 Apr 2007 12:46:50 GMT Message-Id: <200704271246.l3RCkoMJ051651@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to taleks@FreeBSD.org using -f From: Alexey Tarasov To: Perforce Change Reviews Cc: Subject: PERFORCE change 118874 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Apr 2007 12:46:51 -0000 http://perforce.freebsd.org/chv.cgi?CH=118874 Change 118874 by taleks@taleks_th on 2007/04/27 12:46:48 added code from pxe.c. Now need to find way to install NIC irq handler. Affected files ... .. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#3 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#3 edit Differences ... ==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#3 (text+ko) ==== @@ -1,8 +1,38 @@ +#include +#include #include "pxe_core.h" #include "pxe_mem.h" #include "pxe_ip.h" #include "pxe_mutex.h" +#include "btxv86.h" +#include "pxe.h" + + +/* PXE API calls here will be made in same way as in pxeboot. + the only difference - installation of isr, that was not needed in pxe.c. + main problem is that, v86 monitors reflects interrupts, + we need to change IDT, for correct irq and call pxe_core_isr() from it. +*/ + +/* NOTE: to think about using of this buffers */ +#define PXE_BUFFER_SIZE 0x2000 +#define PXE_TFTP_BUFFER_SIZE 512 +static char scratch_buffer[PXE_BUFFER_SIZE]; +static char data_buffer[PXE_BUFFER_SIZE]; +static pxenv_t *pxenv_p = NULL; /* PXENV+ */ +static pxe_t *pxe_p = NULL; /* !PXE */ +static BOOTPLAYER bootplayer; /* PXE Cached information. */ + +/* defined in pxetramp.s */ +extern u_int16_t __bangpxeseg; +extern u_int16_t __bangpxeoff; +extern void __bangpxeentry(void); +extern u_int16_t __pxenvseg; +extern u_int16_t __pxenvoff; +extern void __pxenventry(void); + +/**/ pxe_packet core_packets[PXE_MAX_PACKETS]; pxe_protocol_call core_protocol[256]; pxe_mutex core_mutex={0,0}; @@ -17,20 +47,135 @@ int pxe_core_init() { /* int i=1; /* packet index during initialization loop */ + int counter=0; + uint8_t checksum=0; + uint8_t *checkptr=NULL; + t_PXENV_GET_CACHED_INFO *gci_p=NULL; pxe_memset(core_packets, 0, sizeof(core_packets)); pxe_memset(core_protocol, 0, sizeof(core_protocol)); nic_ip.ip=0; + /* creating 2-linked list of packets */ /* for (; iPXEPtr.segment * 16 + + pxenv_p->PXEPtr.offset); + pxe_call = NULL; + } + in my case, I must decide how to get this. May be it's best way + to use same mechanism. or, if I'll not use BTX code, it'll be + provided other way. So a plenty of things to think. + + */ + if(pxenv_p == NULL) + return (0); + + /* look for "PXENV+" */ + if (bcmp((void *)pxenv_p->Signature, S_SIZE("PXENV+"))) { + pxenv_p = NULL; + return (0); + } + + /* make sure the size is something we can handle */ + if (pxenv_p->Length > sizeof(*pxenv_p)) { + printf("PXENV+ structure too large, ignoring\n"); + pxenv_p = NULL; + return (0); + } + + /* + * do byte checksum: + * add up each byte in the structure, the total should be 0 + */ + checksum = 0; + checkptr = (uint8_t *) pxenv_p; + for (counter = 0; counter < pxenv_p->Length; counter++) + checksum += *checkptr++; + if (checksum != 0) { + printf("PXENV+ structure failed checksum, ignoring\n"); + pxenv_p = NULL; + return (0); + } + + + /* + * PXENV+ passed, so use that if !PXE is not available or + * the checksum fails. + */ + pxe_call = pxenv_call; + if (pxenv_p->Version >= 0x0200) { + for (;;) { + if (bcmp((void *)pxe_p->Signature, S_SIZE("!PXE"))) { + pxe_p = NULL; + break; + } + checksum = 0; + checkptr = (uint8_t *)pxe_p; + for (counter = 0; counter < pxe_p->StructLength; + counter++) + checksum += *checkptr++; + if (checksum != 0) { + pxe_p = NULL; + break; + } + pxe_call = bangpxe_call; + break; + } + } + + printf("\nPXE version %d.%d, real mode entry point ", + (uint8_t) (pxenv_p->Version >> 8), + (uint8_t) (pxenv_p->Version & 0xFF)); + +/* if (pxe_call == bangpxe_call) */ + printf("@%04x:%04x\n", + pxe_p->EntryPointSP.segment, + pxe_p->EntryPointSP.offset); +/* else + printf("@%04x:%04x\n", + pxenv_p->RMEntry.segment, pxenv_p->RMEntry.offset); +*/ + gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer; + bzero(gci_p, sizeof(*gci_p)); + gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY; + + pxe_core_call(PXENV_GET_CACHED_INFO); + + if (gci_p->Status != 0) { +/* pxe_perror(gci_p->Status);*/ + pxe_p = NULL; + return (0); + } + + bcopy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset), + &bootplayer, gci_p->BufferSize); + + /* 2. install isr */ + pxe_core_install_isr(); + + /* 3. additional start UNDI */ + return 1; } +void pxe_core_install_isr() { +} + +void pxe_core_remove_isr() { +} + int pxe_core_shutdown() { int i=1; @@ -41,9 +186,45 @@ pxe_free(core_packets[i].data); } + /* 1. uninstall isr */ + pxe_core_remove_isr(); + + /* 2. shutdown PXE */ + + t_PXENV_UNLOAD_STACK *unload_stack_p = + (t_PXENV_UNLOAD_STACK *)scratch_buffer; + t_PXENV_UNDI_SHUTDOWN *undi_shutdown_p = + (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer; + + pxe_core_call(PXENV_UNDI_SHUTDOWN); + pxe_core_call(PXENV_UNLOAD_STACK); + return 1; } +/* + function code is taken from bangpxe_call(), /sys/boot/libi386/pxe.c + needs pxetramp.s wrapper and vm86int() support. + I'll see later , may be it's simplier to do own v86 monitor, + than using provided with BTX. +*/ +void pxe_core_call(int func) { + + bzero(&v86, sizeof(v86)); + bzero(data_buffer, sizeof(data_buffer)); + + __bangpxeseg = pxe_p->EntryPointSP.segment; + __bangpxeoff = pxe_p->EntryPointSP.offset; + + v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; + v86.edx = VTOPSEG(scratch_buffer); + v86.eax = VTOPOFF(scratch_buffer); + v86.addr = (VTOPSEG(__bangpxeentry) << 16) | VTOPOFF(__bangpxeentry); + v86.ebx = func; + v86int(); + v86.ctl = V86_FLAGS; +} + int pxe_core_transmit(pxe_packet* pack) { /* UNDI transmit ip packet call*/ ==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#3 (text+ko) ==== @@ -64,6 +64,11 @@ /* interrupt handler function, that used to get new packets */ void pxe_core_isr(); +/* calls PXE/UNDI API, registers of processor must be filled in with + appropriate values. + */ +void pxe_core_call(int func); + /* installs irq handler*/ void pxe_core_install_isr();