summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-23 19:16:34 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-23 19:16:34 -0800
commit3f9303340d5e27328c0938e3f9b116154efd2efd (patch)
tree051f37e02dd3a8e59c63192a70b58ac0ad8fcad5
parent3842a4e73f1a6fa2248c0d3939ca804be7e44895 (diff)
downloadsyslinux-3f9303340d5e27328c0938e3f9b116154efd2efd.tar.gz
fs/pxe: drop the use of PKTBUF_SEG
Drop the use of a magic PKTBUF_SEG, and instead just have a high memory buffer for each file, and a single lowmem buffer that we reuse at will. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/fs/pxe/pxe.c44
-rw-r--r--core/fs/pxe/pxe.h12
-rw-r--r--core/pxelinux.asm6
3 files changed, 28 insertions, 34 deletions
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index e58901d9..2f29343e 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -29,6 +29,9 @@ static uint32_t gpxe_funcs;
static uint8_t uuid_dashes[] = {4, 2, 2, 2, 6, 0};
int have_uuid = 0;
+/* Common receive buffer */
+static __lowmem char packet_buf[PKTBUF_SIZE] __aligned(16);
+
const uint8_t TimeoutTable[] = {
2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 15, 18, 21, 26, 31, 37, 44, 53, 64, 77,
92, 110, 132, 159, 191, 229, 255, 255, 255, 255, 0
@@ -65,13 +68,10 @@ static void files_init(void)
{
int i;
struct open_file_t *socket = Files;
- uint16_t pktbuf = 0;
uint16_t nextport = 49152;
for (i = 0; i < MAX_OPEN; i++) {
- socket->tftp_pktbuf = pktbuf;
socket->tftp_nextport = nextport;
- pktbuf += PKTBUF_SIZE;
nextport++;
socket++;
}
@@ -421,8 +421,7 @@ static void get_packet_gpxe(struct open_file_t *file)
while (1) {
file_read.FileHandle = file->tftp_remoteport;
- file_read.Buffer.offs = file->tftp_pktbuf;
- file_read.Buffer.seg = PKTBUF_SEG;
+ file_read.Buffer = FAR_PTR(packet_buf);
file_read.BufferSize = PKTBUF_SIZE;
err = pxe_call(PXENV_FILE_READ, &file_read);
if (!err) /* successed */
@@ -432,6 +431,8 @@ static void get_packet_gpxe(struct open_file_t *file)
kaboom();
}
+ memcpy(file->tftp_pktbuf, packet_buf, file_read.BufferSize);
+
file->tftp_dataptr = file->tftp_pktbuf;
file->tftp_bytesleft = file_read.BufferSize;
file->tftp_filepos += file_read.BufferSize;
@@ -501,8 +502,7 @@ static void fill_buffer(struct open_file_t *file)
timeout = *timeout_ptr++;
oldtime = jiffies();
while (timeout) {
- udp_read.buffer.offs = file->tftp_pktbuf;
- udp_read.buffer.seg = PKTBUF_SEG;
+ udp_read.buffer = FAR_PTR(packet_buf);
udp_read.buffer_size = PKTBUF_SIZE;
udp_read.src_ip = file->tftp_remoteip;
udp_read.dest_ip = MyIP;
@@ -524,7 +524,7 @@ static void fill_buffer(struct open_file_t *file)
if (udp_read.buffer_size < 4) /* Bad size for a DATA packet */
continue;
- data = MK_PTR(PKTBUF_SEG, file->tftp_pktbuf);
+ data = packet_buf;
if (*(uint16_t *)data != TFTP_DATA) /* Not a data packet */
continue;
@@ -556,7 +556,8 @@ static void fill_buffer(struct open_file_t *file)
/* It's the packet we want. We're also EOF if the size < blocksize */
file->tftp_lastpkt = last_pkt; /* Update last packet number */
buffersize = udp_read.buffer_size - 4; /* Skip TFTP header */
- file->tftp_dataptr = file->tftp_pktbuf + 4;
+ memcpy(file->tftp_pktbuf, packet_buf + 4, buffersize);
+ file->tftp_dataptr = file->tftp_pktbuf;
file->tftp_filepos += buffersize;
file->tftp_bytesleft = buffersize;
if (buffersize < file->tftp_blksize) {
@@ -600,7 +601,7 @@ static uint32_t pxe_getfssec(struct file *gfile, char *buf,
if (chunk > file->tftp_bytesleft)
chunk = file->tftp_bytesleft;
file->tftp_bytesleft -= chunk;
- memcpy(buf, MK_PTR(PKTBUF_SEG, file->tftp_dataptr), chunk);
+ memcpy(buf, file->tftp_dataptr, chunk);
file->tftp_dataptr += chunk;
buf += chunk;
bytes_read += chunk;
@@ -711,8 +712,7 @@ static void pxe_searchdir(const char *filename, struct file *file)
if (path_type == PXE_URL) {
if (has_gpxe) {
file_open.Status = PXENV_STATUS_BAD_FUNC;
- file_open.FileName.offs = OFFS(rrq_packet_buf + 2);
- file_open.FileName.seg = SEG(rrq_packet_buf + 2);
+ file_open.FileName = FAR_PTR(rrq_packet_buf + 2);
err = pxe_call(PXENV_FILE_OPEN, &file_open);
if (err)
goto done;
@@ -734,8 +734,7 @@ static void pxe_searchdir(const char *filename, struct file *file)
open_file->tftp_remoteip = ip;
tid = open_file->tftp_localport; /* TID(local port No) */
- udp_write.buffer.offs = OFFS(rrq_packet_buf);
- udp_write.buffer.seg = SEG(rrq_packet_buf);
+ udp_write.buffer = FAR_PTR(rrq_packet_buf);
udp_write.ip = ip;
udp_write.gw = ((udp_write.ip ^ MyIP) & net_mask) ? gate_way : 0;
udp_write.src_port = tid;
@@ -761,12 +760,11 @@ static void pxe_searchdir(const char *filename, struct file *file)
timeout = *timeout_ptr++;
oldtime = jiffies();
for (;;) {
- buf = packet_buf;
- udp_read.buffer.offs = OFFS_WRT(buf, 0);
- udp_read.buffer.seg = 0;
- udp_read.buffer_size = 2048;
- udp_read.dest_ip = MyIP;
- udp_read.d_port = tid;
+ buf = packet_buf;
+ udp_read.buffer = FAR_PTR(buf);
+ udp_read.buffer_size = PKTBUF_SIZE;
+ udp_read.dest_ip = MyIP;
+ udp_read.d_port = tid;
err = pxe_call(PXENV_UDP_READ, &udp_read);
if (err) {
uint32_t now = jiffies();
@@ -836,7 +834,7 @@ static void pxe_searchdir(const char *filename, struct file *file)
open_file->tftp_bytesleft = buffersize;
open_file->tftp_dataptr = open_file->tftp_pktbuf;
- memcpy(MK_PTR(PKTBUF_SEG, open_file->tftp_pktbuf), data, buffersize);
+ memcpy(open_file->tftp_pktbuf, data, buffersize);
break;
case TFTP_OACK:
@@ -1478,6 +1476,10 @@ static int pxe_fs_init(struct fs_info *fs)
fs->sector_shift = fs->block_shift = TFTP_BLOCKSIZE_LG2;
fs->sector_size = fs->block_size = 1 << TFTP_BLOCKSIZE_LG2;
+ /* This block size is actually arbitrary... */
+ fs->sector_shift = fs->block_shift = TFTP_BLOCKSIZE_LG2;
+ fs->sector_size = fs->block_size = 1 << TFTP_BLOCKSIZE_LG2;
+
/* Initialize the Files structure */
files_init();
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index f62fa7a7..a4d7d83b 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -1,6 +1,7 @@
/* -----------------------------------------------------------------------
*
* Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
*
* 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
@@ -28,8 +29,7 @@
#define TFTP_PORT htons(69) /* Default TFTP port */
#define TFTP_BLOCKSIZE_LG2 9
#define TFTP_BLOCKSIZE (1 << TFTP_BLOCKSIZE_LG2)
-#define PKTBUF_SEG 0x4000
-#define PKTBUF_SIZE (65536 / MAX_OPEN)
+#define PKTBUF_SIZE 2048 /* */
#define is_digit(c) (((c) >= '0') && ((c) <= '9'))
#define major_ver(v) (((v) >> 8) && 0xff)
@@ -149,12 +149,12 @@ struct open_file_t {
uint32_t tftp_blksize; /* Block size for this connection(*) */
uint16_t tftp_bytesleft; /* Unclaimed data bytes */
uint16_t tftp_lastpkt; /* Sequence number of last packet (NBO) */
- uint16_t tftp_dataptr; /* Pointer to available data */
+ char *tftp_dataptr; /* Pointer to available data */
uint8_t tftp_goteof; /* 1 if the EOF packet received */
- uint8_t tftp_unused; /* Currently unused */
+ uint8_t tftp_unused[3]; /* Currently unused */
/* These values are preinitialized and not zeroed on close */
uint16_t tftp_nextport; /* Next port number for this slot (HBO) */
- uint16_t tftp_pktbuf; /* Packet buffer offset */
+ char tftp_pktbuf[PKTBUF_SIZE];
} __attribute__ ((packed));
/*
@@ -179,8 +179,6 @@ extern char boot_file[];
extern char path_prefix[];
extern char LocalDomain[];
-extern char packet_buf[];
-
extern char IPOption[];
extern char dot_quad_buf[];
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index a966a393..a53fead1 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -94,12 +94,6 @@ DHCPMagic resb 1 ; PXELINUX magic flags
global BOOTIFStr
BOOTIFStr resb 7 ; Space for "BOOTIF="
- section .bss16
- global packet_buf
- alignb 16
-packet_buf resb 2048 ; Transfer packet
-packet_buf_size equ $-packet_buf
-
section .text16
StackBuf equ STACK_TOP-44 ; Base of stack if we use our own
StackHome equ StackBuf