From: H. Peter Anvin Date: Wed, 24 Feb 2010 02:14:12 +0000 (-0800) Subject: core: add a direct 32-bit API X-Git-Tag: syslinux-4.00-pre25~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3cda063b8e079ee6518d3425650d800db4227585;p=profile%2Fivi%2Fsyslinux.git core: add a direct 32-bit API Add a direct 32-bit API to some functions; initially read file only. Signed-off-by: H. Peter Anvin --- diff --git a/com32/include/com32.h b/com32/include/com32.h index aa7fb4b..9334efb 100644 --- a/com32/include/com32.h +++ b/com32/include/com32.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- * * * Copyright 2002-2009 H. Peter Anvin - All Rights Reserved - * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -92,6 +92,8 @@ typedef struct { #define EFLAGS_VIP 0x00100000 #define EFLAGS_ID 0x00200000 +struct com32_pmapi; + extern struct com32_sys_args { uint32_t cs_sysargs; char *cs_cmdline; @@ -101,6 +103,7 @@ extern struct com32_sys_args { void __cdecl(*cs_farcall) (uint32_t, const com32sys_t *, com32sys_t *); int __cdecl(*cs_cfarcall) (uint32_t, const void *, uint32_t); uint32_t cs_memsize; + const struct com32_pmapi *cs_pm; } __com32; /* diff --git a/com32/include/syslinux/pmapi.h b/com32/include/syslinux/pmapi.h new file mode 100644 index 0000000..848a554 --- /dev/null +++ b/com32/include/syslinux/pmapi.h @@ -0,0 +1,45 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2002-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * pmapi.h + * + * Definitions for the Syslinux 4 protected-mode ABI + */ + +#ifndef _SYSLINUX_PMAPI_H +#define _SYSLINUX_PMAPI_H + +#include +#include + +struct com32_pmapi { + size_t (*read_file)(uint16_t *, void *, size_t); +}; + +#endif /* _SYSLINUX_PMAPI_H */ diff --git a/com32/lib/sys/entry.S b/com32/lib/sys/entry.S index a3a1eaa..629f336 100644 --- a/com32/lib/sys/entry.S +++ b/com32/lib/sys/entry.S @@ -30,7 +30,7 @@ */ /* Number of arguments in our version of the entry structure */ -#define COM32_ARGS 7 +#define COM32_ARGS 8 .section ".init","ax" .globl _start diff --git a/com32/lib/sys/fileread.c b/com32/lib/sys/fileread.c index 54ff711..cfd4955 100644 --- a/com32/lib/sys/fileread.c +++ b/com32/lib/sys/fileread.c @@ -34,32 +34,23 @@ #include #include #include +#include #include #include "file.h" int __file_get_block(struct file_info *fp) { - com32sys_t ireg, oreg; + ssize_t bytes_read; - memset(&ireg, 0, sizeof ireg); - ireg.eax.w[0] = 0x0007; /* Read file */ - ireg.ebx.w[0] = OFFS(__com32.cs_bounce); - ireg.es = SEG(__com32.cs_bounce); - ireg.esi.w[0] = fp->i.filedes; - ireg.ecx.w[0] = MAXBLOCK >> fp->i.blocklg2; - - __intcall(0x22, &ireg, &oreg); - - if (oreg.eflags.l & EFLAGS_CF) { + bytes_read = __com32.cs_pm->read_file(&fp->i.filedes, fp->i.buf, + MAXBLOCK >> fp->i.blocklg2); + if (!bytes_read) { errno = EIO; return -1; } - - fp->i.filedes = oreg.esi.w[0]; - fp->i.nbytes = oreg.ecx.l; - fp->i.datap = fp->i.buf; - memcpy(fp->i.buf, __com32.cs_bounce, fp->i.nbytes); - + + fp->i.nbytes = bytes_read; + fp->i.datap = fp->i.buf; return 0; } @@ -74,19 +65,33 @@ ssize_t __file_read(struct file_info * fp, void *buf, size_t count) if (fp->i.offset >= fp->i.length || !fp->i.filedes) return n; /* As good as it gets... */ - if (__file_get_block(fp)) - return n ? n : -1; + if (count > MAXBLOCK) { + /* Large transfer: copy directly, without buffering */ + ncopy = __com32.cs_pm->read_file(&fp->i.filedes, bufp, + count >> fp->i.blocklg2); + if (!ncopy) { + errno = EIO; + return n ? n : -1; + } + + goto got_data; + } else { + if (__file_get_block(fp)) + return n ? n : -1; + } } ncopy = min(count, fp->i.nbytes); memcpy(bufp, fp->i.datap, ncopy); - n += ncopy; - bufp += ncopy; - count -= ncopy; fp->i.datap += ncopy; fp->i.offset += ncopy; fp->i.nbytes -= ncopy; + + got_data: + n += ncopy; + bufp += ncopy; + count -= ncopy; } return n; diff --git a/core/com32.inc b/core/com32.inc index cb17279..810ee03 100644 --- a/core/com32.inc +++ b/core/com32.inc @@ -1,7 +1,7 @@ ;; ----------------------------------------------------------------------- ;; ;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved -;; Copyright 2009 Intel Corporation; author: H. Peter Anvin +;; 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 @@ -17,6 +17,8 @@ ;; Common code for running a COM32 image ;; + extern pm_api_vector + ; ; Load a COM32 image. A COM32 image is the 32-bit analogue to a DOS ; .com file. A COM32 image is loaded at address 0x101000, with %esp @@ -82,6 +84,7 @@ com32_start: .pm: ; Set up the calling stack frame + push dword pm_api_vector push dword [HighMemSize] ; Memory managed by Syslinux push dword core_cfarcall ; Cfarcall entry point push dword core_farcall ; Farcall entry point @@ -89,7 +92,7 @@ com32_start: push dword core_real_mode ; Bounce buffer address push dword core_intcall ; Intcall entry point push dword command_line ; Command line pointer - push dword 7 ; Argument count + push dword 8 ; Argument count sti ; Interrupts OK now call com32_entry ; Run the program... ; ... on return, fall through to com32_exit ... @@ -123,7 +126,7 @@ not_com32r_msg db ': not a COM32R image', CR, LF, 0 global __com32 alignz 4 __com32: - dd 7 ; Argument count + dd 8 ; Argument count dd 0 ; No command line dd core_intcall ; Intcall entry point dd core_xfer_buf ; Bounce buffer address @@ -131,3 +134,4 @@ __com32: dd core_farcall ; Farcall entry point dd core_cfarcall ; Cfarcall entry point HighMemSize dd 0 ; End of memory pointer (bytes) + dd pm_api_vector ; Protected mode functions diff --git a/core/fs/fs.c b/core/fs/fs.c index d67a87c..e0f469b 100644 --- a/core/fs/fs.c +++ b/core/fs/fs.c @@ -137,6 +137,27 @@ void getfssec(com32sys_t *regs) regs->ecx.l = bytes_read; } +size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors) +{ + bool have_more; + size_t bytes_read; + struct file *file; + + file = handle_to_file(*handle); + bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more); + + /* + * If we reach EOF, the filesystem driver will have already closed + * the underlying file... this really should be cleaner. + */ + if (!have_more) { + _close_file(file); + *handle = 0; + } + + return bytes_read; +} + void pm_searchdir(com32sys_t *regs) { char *name = MK_PTR(regs->ds, regs->edi.w[0]); diff --git a/core/include/core.h b/core/include/core.h index c955e73..e6364f8 100644 --- a/core/include/core.h +++ b/core/include/core.h @@ -3,6 +3,7 @@ #include #include +#include extern char core_xfer_buf[65536]; extern char core_cache_buf[65536]; diff --git a/core/include/fs.h b/core/include/fs.h index 8a173d9..1f4ad28 100644 --- a/core/include/fs.h +++ b/core/include/fs.h @@ -187,6 +187,7 @@ void mangle_name(char *, const char *); char *unmangle_name(char *, const char *); int searchdir(const char *name); void _close_file(struct file *); +size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors); /* chdir.c */ void pm_realpath(com32sys_t *regs); diff --git a/core/include/pmapi.h b/core/include/pmapi.h new file mode 100644 index 0000000..57d2e6f --- /dev/null +++ b/core/include/pmapi.h @@ -0,0 +1,8 @@ +#ifndef PMAPI_H +#define PMAPI_H + +#include + +size_t pmapi_read_file(uint16_t *, void *, size_t); + +#endif /* PMAPI_H */ diff --git a/core/pmapi.c b/core/pmapi.c new file mode 100644 index 0000000..f45a7fc --- /dev/null +++ b/core/pmapi.c @@ -0,0 +1,23 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 1994-2009 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 + * the Free Software Foundation, Inc., 53 Temple Place Ste 330, + * Boston MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include +#include +#include +#include "core.h" +#include "fs.h" + +const struct com32_pmapi pm_api_vector = +{ + .read_file = pmapi_read_file, +}; diff --git a/doc/comboot.txt b/doc/comboot.txt index 6d026aa..7950688 100644 --- a/doc/comboot.txt +++ b/doc/comboot.txt @@ -90,19 +90,22 @@ The following arguments are passed to the program on the stack: [ESP+24] dword Pointer to FAR call helper function (new in 2.05) [ESP+28] dword Pointer to CDECL helper function (new in 3.54) [ESP+32] dword Amount of memory controlled by the Syslinux core (new in 3.74) - -This corresponds to the following C prototype, available in the file -com32/include/com32.h: - -/* The standard prototype for _start() */ -int _start(unsigned int __nargs, - char *__cmdline, - void (*__intcall)(uint8_t, com32sys_t *, com32sys_t *), - void *__bounce_ptr, - unsigned int __bounce_len, - void (*__farcall)(uint32_t, com32sys_t *, com32sys_t *), - int (*__cfarcall)(uint32_t, void *, size_t) - ); + [ESP+36] dword Pointer to protected-mode functions (new in 4.00) + +The libcom32 startup code loads this into a structure named __com32, +defined in : + +extern struct com32_sys_args { + uint32_t cs_sysargs; + char *cs_cmdline; + void __cdecl(*cs_intcall)(uint8_t, const com32sys_t *, com32sys_t *); + void *cs_bounce; + uint32_t cs_bounce_size; + void __cdecl(*cs_farcall)(uint32_t, const com32sys_t *, com32sys_t *); + int __cdecl(*cs_cfarcall)(uint32_t, const void *, uint32_t); + uint32_t cs_memsize; + struct com32_pmapi *cs_pm; +} __com32; The intcall helper function can be used to issue BIOS or Syslinux API calls, and takes the interrupt number as first argument. The second @@ -149,6 +152,12 @@ The cfarcall helper function takes (CS << 16)+IP, a pointer to a stack frame, a size of that stack frame, and returns the return value of EAX (which may need to be appropriate truncated by the user.) +Starting in version 4.00, some of these API calls are available as +protected-mode function calls, using the regparm(3) calling convention +(the first three argumetns in EAX, EDX, ECX; the rest on the stack.) +Those functions are defined in struct com32_pmapi, defined in +. + ++++ SYSLINUX API CALLS +++ @@ -342,6 +351,16 @@ AX=0007h [2.08] Read file WARNING: Calling this function with an invalid file handle will probably crash the system. + 32-BIT VERSION: + + size_t cs_pm->read_file(uint16_t *handle, void *buf, size_t blocks) + + handle - file handle (input and output, set to zero on end of file) + buf - buffer to write to + blocks - number of blocks to read + + Returns number of bytes read, or 0 on failure. + AX=0008h [2.08] Close file