From owner-svn-src-stable-12@freebsd.org Sun Jan 13 07:25:57 2019 Return-Path: Delivered-To: svn-src-stable-12@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2DB6D148D24F; Sun, 13 Jan 2019 07:25:57 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D2E138EF40; Sun, 13 Jan 2019 07:25:56 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id A6154181D7; Sun, 13 Jan 2019 07:25:56 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x0D7PuxS098973; Sun, 13 Jan 2019 07:25:56 GMT (envelope-from tsoome@FreeBSD.org) Received: (from tsoome@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x0D7PtmT098968; Sun, 13 Jan 2019 07:25:55 GMT (envelope-from tsoome@FreeBSD.org) Message-Id: <201901130725.x0D7PtmT098968@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tsoome set sender to tsoome@FreeBSD.org using -f From: Toomas Soome Date: Sun, 13 Jan 2019 07:25:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r342995 - stable/12/stand/i386/libi386 X-SVN-Group: stable-12 X-SVN-Commit-Author: tsoome X-SVN-Commit-Paths: stable/12/stand/i386/libi386 X-SVN-Commit-Revision: 342995 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: D2E138EF40 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.90 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.91)[-0.905,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-0.999,0] X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Jan 2019 07:25:57 -0000 Author: tsoome Date: Sun Jan 13 07:25:55 2019 New Revision: 342995 URL: https://svnweb.freebsd.org/changeset/base/342995 Log: MFC: r342619, r342626 loader: create bio_alloc and bio_free for bios bounce buffer We do have 16KB buffer space defined in pxe.c, move it to bio.c and implement bio_alloc()/bio_free() interface to make it possible to use this space for other BIOS calls (notably, from biosdisk.c). Added: stable/12/stand/i386/libi386/bio.c - copied, changed from r342619, head/stand/i386/libi386/bio.c Modified: stable/12/stand/i386/libi386/Makefile stable/12/stand/i386/libi386/biosdisk.c stable/12/stand/i386/libi386/libi386.h stable/12/stand/i386/libi386/pxe.c Directory Properties: stable/12/ (props changed) Modified: stable/12/stand/i386/libi386/Makefile ============================================================================== --- stable/12/stand/i386/libi386/Makefile Sun Jan 13 07:22:16 2019 (r342994) +++ stable/12/stand/i386/libi386/Makefile Sun Jan 13 07:25:55 2019 (r342995) @@ -4,7 +4,7 @@ LIB= i386 -SRCS= biosacpi.c biosdisk.c biosmem.c biospnp.c \ +SRCS= bio.c biosacpi.c biosdisk.c biosmem.c biospnp.c \ biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \ comconsole.c devicename.c elf32_freebsd.c \ elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \ Copied and modified: stable/12/stand/i386/libi386/bio.c (from r342619, head/stand/i386/libi386/bio.c) ============================================================================== --- head/stand/i386/libi386/bio.c Sun Dec 30 09:35:47 2018 (r342619, copy source) +++ stable/12/stand/i386/libi386/bio.c Sun Jan 13 07:25:55 2019 (r342995) @@ -1,4 +1,6 @@ /*- + * Copyright 2018 Toomas Soome + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: Modified: stable/12/stand/i386/libi386/biosdisk.c ============================================================================== --- stable/12/stand/i386/libi386/biosdisk.c Sun Jan 13 07:22:16 2019 (r342994) +++ stable/12/stand/i386/libi386/biosdisk.c Sun Jan 13 07:25:55 2019 (r342995) @@ -507,10 +507,10 @@ bd_get_diskinfo_ext(struct bdinfo *bd) * Sector size must be a multiple of 512 bytes. * An alternate test would be to check power of 2, * powerof2(params.sector_size). - * 4K is largest read buffer we can use at this time. + * 16K is largest read buffer we can use at this time. */ if (params.sector_size >= 512 && - params.sector_size <= 4096 && + params.sector_size <= 16384 && (params.sector_size % BIOSDISK_SECSIZE) == 0) bd->bd_sectorsize = params.sector_size; @@ -899,8 +899,8 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, s struct disk_devdesc *dev = (struct disk_devdesc *)devdata; bdinfo_t *bd; uint64_t disk_blocks, offset, d_offset; - size_t blks, blkoff, bsize, rest; - caddr_t bbuf; + size_t blks, blkoff, bsize, bio_size, rest; + caddr_t bbuf = NULL; int rc; bd = bd_get_bdinfo(&dev->dd); @@ -975,14 +975,25 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, s DEBUG("short I/O %d", blks); } - if (V86_IO_BUFFER_SIZE / bd->bd_sectorsize == 0) - panic("BUG: Real mode buffer is too small"); + bio_size = min(BIO_BUFFER_SIZE, size); + while (bio_size > bd->bd_sectorsize) { + bbuf = bio_alloc(bio_size); + if (bbuf != NULL) + break; + bio_size -= bd->bd_sectorsize; + } + if (bbuf == NULL) { + bio_size = V86_IO_BUFFER_SIZE; + if (bio_size / bd->bd_sectorsize == 0) + panic("BUG: Real mode buffer is too small"); - bbuf = PTOV(V86_IO_BUFFER); + /* Use alternate 4k buffer */ + bbuf = PTOV(V86_IO_BUFFER); + } rest = size; - + rc = 0; while (blks > 0) { - int x = min(blks, V86_IO_BUFFER_SIZE / bd->bd_sectorsize); + int x = min(blks, bio_size / bd->bd_sectorsize); switch (rw & F_MASK) { case F_READ: @@ -991,8 +1002,10 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, s if (rest < bsize) bsize = rest; - if ((rc = bd_io(dev, bd, dblk, x, bbuf, BD_RD)) != 0) - return (EIO); + if ((rc = bd_io(dev, bd, dblk, x, bbuf, BD_RD)) != 0) { + rc = EIO; + goto error; + } bcopy(bbuf + blkoff, buf, bsize); break; @@ -1024,13 +1037,16 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, s * Put your Data In, and shake it all about */ bcopy(buf, bbuf + blkoff, bsize); - if ((rc = bd_io(dev, bd, dblk, x, bbuf, BD_WR)) != 0) - return (EIO); + if ((rc = bd_io(dev, bd, dblk, x, bbuf, BD_WR)) != 0) { + rc = EIO; + goto error; + } break; default: /* DO NOTHING */ - return (EROFS); + rc = EROFS; + goto error; } blkoff = 0; @@ -1042,7 +1058,10 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, s if (rsize != NULL) *rsize = size; - return (0); +error: + if (bbuf != PTOV(V86_IO_BUFFER)) + bio_free(bbuf, bio_size); + return (rc); } static int Modified: stable/12/stand/i386/libi386/libi386.h ============================================================================== --- stable/12/stand/i386/libi386/libi386.h Sun Jan 13 07:22:16 2019 (r342994) +++ stable/12/stand/i386/libi386/libi386.h Sun Jan 13 07:25:55 2019 (r342995) @@ -121,6 +121,11 @@ extern vm_offset_t memtop_copyin; /* memtop less heap extern uint32_t high_heap_size; /* extended memory region available */ extern vm_offset_t high_heap_base; /* for use as the heap */ +/* 16KB buffer space for real mode data transfers. */ +#define BIO_BUFFER_SIZE 0x4000 +void *bio_alloc(size_t size); +void bio_free(void *ptr, size_t size); + /* * Values for width parameter to biospci_{read,write}_config */ Modified: stable/12/stand/i386/libi386/pxe.c ============================================================================== --- stable/12/stand/i386/libi386/pxe.c Sun Jan 13 07:22:16 2019 (r342994) +++ stable/12/stand/i386/libi386/pxe.c Sun Jan 13 07:25:55 2019 (r342995) @@ -48,18 +48,10 @@ __FBSDID("$FreeBSD$"); #include #include +#include "libi386.h" #include "btxv86.h" #include "pxe.h" -/* - * Allocate the PXE buffers statically instead of sticking grimy fingers into - * BTX's private data area. The scratch buffer is used to send information to - * the PXE BIOS, and the data buffer is used to receive data from the PXE BIOS. - */ -#define PXE_BUFFER_SIZE 0x2000 -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 */ @@ -68,9 +60,9 @@ static int pxe_debug = 0; #endif void pxe_enable(void *pxeinfo); -static void (*pxe_call)(int func); -static void pxenv_call(int func); -static void bangpxe_call(int func); +static void (*pxe_call)(int func, void *ptr); +static void pxenv_call(int func, void *ptr); +static void bangpxe_call(int func, void *ptr); static int pxe_init(void); static int pxe_print(int verbose); @@ -225,12 +217,17 @@ pxe_init(void) printf("@%04x:%04x\n", pxenv_p->RMEntry.segment, pxenv_p->RMEntry.offset); - gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer; + gci_p = bio_alloc(sizeof(*gci_p)); + if (gci_p == NULL) { + pxe_p = NULL; + return (0); + } bzero(gci_p, sizeof(*gci_p)); gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY; - pxe_call(PXENV_GET_CACHED_INFO); + pxe_call(PXENV_GET_CACHED_INFO, gci_p); if (gci_p->Status != 0) { pxe_perror(gci_p->Status); + bio_free(gci_p, sizeof(*gci_p)); pxe_p = NULL; return (0); } @@ -240,6 +237,7 @@ pxe_init(void) bcopy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset), bootp_response, bootp_response_size); } + bio_free(gci_p, sizeof(*gci_p)); return (1); } @@ -262,31 +260,37 @@ pxe_print(int verbose) static void pxe_cleanup(void) { -#ifdef PXE_DEBUG - 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; -#endif + t_PXENV_UNLOAD_STACK *unload_stack_p; + t_PXENV_UNDI_SHUTDOWN *undi_shutdown_p; if (pxe_call == NULL) return; - pxe_call(PXENV_UNDI_SHUTDOWN); + undi_shutdown_p = bio_alloc(sizeof(*undi_shutdown_p)); + if (undi_shutdown_p != NULL) { + bzero(undi_shutdown_p, sizeof(*undi_shutdown_p)); + pxe_call(PXENV_UNDI_SHUTDOWN, undi_shutdown_p); #ifdef PXE_DEBUG - if (pxe_debug && undi_shutdown_p->Status != 0) - printf("pxe_cleanup: UNDI_SHUTDOWN failed %x\n", - undi_shutdown_p->Status); + if (pxe_debug && undi_shutdown_p->Status != 0) + printf("pxe_cleanup: UNDI_SHUTDOWN failed %x\n", + undi_shutdown_p->Status); #endif + bio_free(undi_shutdown_p, sizeof(*undi_shutdown_p)); + } - pxe_call(PXENV_UNLOAD_STACK); + unload_stack_p = bio_alloc(sizeof(*unload_stack_p)); + if (unload_stack_p != NULL) { + bzero(unload_stack_p, sizeof(*unload_stack_p)); + pxe_call(PXENV_UNLOAD_STACK, unload_stack_p); #ifdef PXE_DEBUG - if (pxe_debug && unload_stack_p->Status != 0) - printf("pxe_cleanup: UNLOAD_STACK failed %x\n", - unload_stack_p->Status); + if (pxe_debug && unload_stack_p->Status != 0) + printf("pxe_cleanup: UNLOAD_STACK failed %x\n", + unload_stack_p->Status); #endif + bio_free(unload_stack_p, sizeof(*unload_stack_p)); + } } void @@ -296,7 +300,7 @@ pxe_perror(int err) } void -pxenv_call(int func) +pxenv_call(int func, void *ptr) { #ifdef PXE_DEBUG if (pxe_debug) @@ -304,14 +308,13 @@ pxenv_call(int func) #endif bzero(&v86, sizeof(v86)); - bzero(data_buffer, sizeof(data_buffer)); __pxenvseg = pxenv_p->RMEntry.segment; __pxenvoff = pxenv_p->RMEntry.offset; v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; - v86.es = VTOPSEG(scratch_buffer); - v86.edi = VTOPOFF(scratch_buffer); + v86.es = VTOPSEG(ptr); + v86.edi = VTOPOFF(ptr); v86.addr = (VTOPSEG(__pxenventry) << 16) | VTOPOFF(__pxenventry); v86.ebx = func; v86int(); @@ -319,7 +322,7 @@ pxenv_call(int func) } void -bangpxe_call(int func) +bangpxe_call(int func, void *ptr) { #ifdef PXE_DEBUG if (pxe_debug) @@ -327,14 +330,13 @@ bangpxe_call(int func) #endif 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.edx = VTOPSEG(ptr); + v86.eax = VTOPOFF(ptr); v86.addr = (VTOPSEG(__bangpxeentry) << 16) | VTOPOFF(__bangpxeentry); v86.ebx = func; v86int(); @@ -362,11 +364,14 @@ pxe_netif_end(struct netif *nif) { t_PXENV_UNDI_CLOSE *undi_close_p; - undi_close_p = (t_PXENV_UNDI_CLOSE *)scratch_buffer; - bzero(undi_close_p, sizeof(*undi_close_p)); - pxe_call(PXENV_UNDI_CLOSE); - if (undi_close_p->Status != 0) - printf("undi close failed: %x\n", undi_close_p->Status); + undi_close_p = bio_alloc(sizeof(*undi_close_p)); + if (undi_close_p != NULL) { + bzero(undi_close_p, sizeof(*undi_close_p)); + pxe_call(PXENV_UNDI_CLOSE, undi_close_p); + if (undi_close_p->Status != 0) + printf("undi close failed: %x\n", undi_close_p->Status); + bio_free(undi_close_p, sizeof(*undi_close_p)); + } } static void @@ -377,11 +382,15 @@ pxe_netif_init(struct iodesc *desc, void *machdep_hint uint8_t *mac; int i, len; - undi_info_p = (t_PXENV_UNDI_GET_INFORMATION *)scratch_buffer; + undi_info_p = bio_alloc(sizeof(*undi_info_p)); + if (undi_info_p == NULL) + return; + bzero(undi_info_p, sizeof(*undi_info_p)); - pxe_call(PXENV_UNDI_GET_INFORMATION); + pxe_call(PXENV_UNDI_GET_INFORMATION, undi_info_p); if (undi_info_p->Status != 0) { printf("undi get info failed: %x\n", undi_info_p->Status); + bio_free(undi_info_p, sizeof(*undi_info_p)); return; } @@ -410,32 +419,44 @@ pxe_netif_init(struct iodesc *desc, void *machdep_hint else desc->xid = 0; - undi_open_p = (t_PXENV_UNDI_OPEN *)scratch_buffer; + bio_free(undi_info_p, sizeof(*undi_info_p)); + undi_open_p = bio_alloc(sizeof(*undi_open_p)); + if (undi_open_p == NULL) + return; bzero(undi_open_p, sizeof(*undi_open_p)); undi_open_p->PktFilter = FLTR_DIRECTED | FLTR_BRDCST; - pxe_call(PXENV_UNDI_OPEN); + pxe_call(PXENV_UNDI_OPEN, undi_open_p); if (undi_open_p->Status != 0) printf("undi open failed: %x\n", undi_open_p->Status); + bio_free(undi_open_p, sizeof(*undi_open_p)); } static int pxe_netif_receive(void **pkt) { - t_PXENV_UNDI_ISR *isr = (t_PXENV_UNDI_ISR *)scratch_buffer; + t_PXENV_UNDI_ISR *isr; char *buf, *ptr, *frame; size_t size, rsize; + isr = bio_alloc(sizeof(*isr)); + if (isr == NULL) + return (-1); + bzero(isr, sizeof(*isr)); isr->FuncFlag = PXENV_UNDI_ISR_IN_START; - pxe_call(PXENV_UNDI_ISR); - if (isr->Status != 0) + pxe_call(PXENV_UNDI_ISR, isr); + if (isr->Status != 0) { + bio_free(isr, sizeof(*isr)); return (-1); + } bzero(isr, sizeof(*isr)); isr->FuncFlag = PXENV_UNDI_ISR_IN_PROCESS; - pxe_call(PXENV_UNDI_ISR); - if (isr->Status != 0) + pxe_call(PXENV_UNDI_ISR, isr); + if (isr->Status != 0) { + bio_free(isr, sizeof(*isr)); return (-1); + } while (isr->FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) { /* @@ -443,26 +464,31 @@ pxe_netif_receive(void **pkt) */ bzero(isr, sizeof(*isr)); isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT; - pxe_call(PXENV_UNDI_ISR); + pxe_call(PXENV_UNDI_ISR, isr); if (isr->Status != 0 || - isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE) + isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE) { + bio_free(isr, sizeof(*isr)); return (-1); + } } while (isr->FuncFlag != PXENV_UNDI_ISR_OUT_RECEIVE) { if (isr->Status != 0 || isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE) { + bio_free(isr, sizeof(*isr)); return (-1); } bzero(isr, sizeof(*isr)); isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT; - pxe_call(PXENV_UNDI_ISR); + pxe_call(PXENV_UNDI_ISR, isr); } size = isr->FrameLength; buf = malloc(size + ETHER_ALIGN); - if (buf == NULL) + if (buf == NULL) { + bio_free(isr, sizeof(*isr)); return (-1); + } ptr = buf + ETHER_ALIGN; rsize = 0; @@ -475,8 +501,9 @@ pxe_netif_receive(void **pkt) bzero(isr, sizeof(*isr)); isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT; - pxe_call(PXENV_UNDI_ISR); + pxe_call(PXENV_UNDI_ISR, isr); if (isr->Status != 0) { + bio_free(isr, sizeof(*isr)); free(buf); return (-1); } @@ -488,6 +515,7 @@ pxe_netif_receive(void **pkt) } *pkt = buf; + bio_free(isr, sizeof(*isr)); return (rsize); } @@ -515,26 +543,31 @@ pxe_netif_put(struct iodesc *desc, void *pkt, size_t l t_PXENV_UNDI_TRANSMIT *trans_p; t_PXENV_UNDI_TBD *tbd_p; char *data; + ssize_t rv = -1; - trans_p = (t_PXENV_UNDI_TRANSMIT *)scratch_buffer; - bzero(trans_p, sizeof(*trans_p)); - tbd_p = (t_PXENV_UNDI_TBD *)(scratch_buffer + sizeof(*trans_p)); - bzero(tbd_p, sizeof(*tbd_p)); + trans_p = bio_alloc(sizeof(*trans_p)); + tbd_p = bio_alloc(sizeof(*tbd_p)); + data = bio_alloc(len); - data = scratch_buffer + sizeof(*trans_p) + sizeof(*tbd_p); + if (trans_p != NULL && tbd_p != NULL && data != NULL) { + bzero(trans_p, sizeof(*trans_p)); + bzero(tbd_p, sizeof(*tbd_p)); - trans_p->TBD.segment = VTOPSEG(tbd_p); - trans_p->TBD.offset = VTOPOFF(tbd_p); + trans_p->TBD.segment = VTOPSEG(tbd_p); + trans_p->TBD.offset = VTOPOFF(tbd_p); - tbd_p->ImmedLength = len; - tbd_p->Xmit.segment = VTOPSEG(data); - tbd_p->Xmit.offset = VTOPOFF(data); - bcopy(pkt, data, len); + tbd_p->ImmedLength = len; + tbd_p->Xmit.segment = VTOPSEG(data); + tbd_p->Xmit.offset = VTOPOFF(data); + bcopy(pkt, data, len); - pxe_call(PXENV_UNDI_TRANSMIT); - if (trans_p->Status != 0) { - return (-1); + pxe_call(PXENV_UNDI_TRANSMIT, trans_p); + if (trans_p->Status == 0) + rv = len; } - return (len); + bio_free(data, len); + bio_free(tbd_p, sizeof(*tbd_p)); + bio_free(trans_p, sizeof(*trans_p)); + return (rv); }