Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148455924
D17131.id51431.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D17131.id51431.diff
View Options
Index: stand/i386/libi386/Makefile
===================================================================
--- stand/i386/libi386/Makefile
+++ stand/i386/libi386/Makefile
@@ -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 \
Index: stand/i386/libi386/bio.c
===================================================================
--- /dev/null
+++ stand/i386/libi386/bio.c
@@ -0,0 +1,63 @@
+/*-
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "libi386.h"
+
+/*
+ * The idea is borrowed from pxe.c and zfsimpl.c. The original buffer
+ * space in pxe.c was 2x 0x2000. Allocating it from BSS will give us needed
+ * memory below 1MB and usable for real mode calls.
+ */
+
+static char bio_buffer[BIO_BUFFER_SIZE];
+static char *bio_buffer_end = bio_buffer + BIO_BUFFER_SIZE;
+static char *bio_buffer_ptr = bio_buffer;
+
+void *
+bio_alloc(size_t size)
+{
+ char *ptr;
+
+ ptr = bio_buffer_ptr;
+ if (ptr + size > bio_buffer_end)
+ return (NULL);
+ bio_buffer_ptr += size;
+
+ return (ptr);
+}
+
+void
+bio_free(void *ptr, size_t size)
+{
+
+ if (ptr == NULL)
+ return;
+
+ bio_buffer_ptr -= size;
+ if (bio_buffer_ptr != ptr)
+ panic("bio_alloc()/bio_free() mismatch\n");
+}
Index: stand/i386/libi386/biosdisk.c
===================================================================
--- stand/i386/libi386/biosdisk.c
+++ stand/i386/libi386/biosdisk.c
@@ -469,10 +469,10 @@
* 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;
@@ -861,8 +861,8 @@
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);
@@ -937,14 +937,25 @@
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:
@@ -953,8 +964,10 @@
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;
@@ -986,13 +999,16 @@
* 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;
@@ -1004,7 +1020,10 @@
if (rsize != NULL)
*rsize = size;
- return (0);
+error:
+ if (bbuf != PTOV(V86_IO_BUFFER))
+ bio_free(bbuf, bio_size);
+ return (rc);
}
static int
Index: stand/i386/libi386/libi386.h
===================================================================
--- stand/i386/libi386/libi386.h
+++ stand/i386/libi386/libi386.h
@@ -121,6 +121,11 @@
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
*/
Index: stand/i386/libi386/pxe.c
===================================================================
--- stand/i386/libi386/pxe.c
+++ stand/i386/libi386/pxe.c
@@ -48,18 +48,10 @@
#include <bootp.h>
#include <bootstrap.h>
+#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 @@
#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 @@
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 @@
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 @@
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 @@
}
void
-pxenv_call(int func)
+pxenv_call(int func, void *ptr)
{
#ifdef PXE_DEBUG
if (pxe_debug)
@@ -304,14 +308,13 @@
#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 @@
}
void
-bangpxe_call(int func)
+bangpxe_call(int func, void *ptr)
{
#ifdef PXE_DEBUG
if (pxe_debug)
@@ -327,14 +330,13 @@
#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 @@
{
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 @@
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 @@
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 @@
*/
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 @@
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 @@
}
*pkt = buf;
+ bio_free(isr, sizeof(*isr));
return (rsize);
}
@@ -515,26 +543,31 @@
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);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 19, 12:28 AM (8 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29934838
Default Alt Text
D17131.id51431.diff (15 KB)
Attached To
Mode
D17131: loader: create bio_alloc and bio_free for bios bounce buffer
Attached
Detach File
Event Timeline
Log In to Comment