]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
intwrap grub_pxe_scan
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 4 Apr 2010 13:49:06 +0000 (15:49 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 4 Apr 2010 13:49:06 +0000 (15:49 +0200)
fs/i386/pc/pxe.c
include/grub/i386/pc/pxe.h
kern/i386/pc/startup.S

index 82d8ee583db2f406e8c29520bd687d9e3a7c4e89..0a279df45b56b73dec61c3435304bd78aff019f7 100644 (file)
@@ -27,6 +27,7 @@
 #include <grub/env.h>
 
 #include <grub/machine/pxe.h>
+#include <grub/machine/int.h>
 #include <grub/machine/memory.h>
 
 #define SEGMENT(x)     ((x) >> 4)
@@ -55,6 +56,45 @@ struct grub_pxe_data
   char filename[0];
 };
 
+static grub_uint32_t pxe_rm_entry = 0;
+
+static struct grub_pxenv *
+grub_pxe_scan (void)
+{
+  struct grub_bios_int_registers regs;
+  struct grub_pxenv *ret;
+  void *pxe;
+
+  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
+
+  regs.ebx = 0;
+  regs.ecx = 0;
+  regs.eax = 0x5650;
+
+  grub_bios_interrupt (0x1a, &regs);
+
+  if ((regs.eax & 0xffff) != 0x564e)
+    return NULL;
+  ret = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff));
+  if (grub_memcmp (ret->signature, GRUB_PXE_SIGNATURE, sizeof (ret->signature))
+      != 0)
+    return NULL;
+  if (ret->version < 0x201)
+    return NULL;
+
+  pxe = (void *) ((((ret->pxe_ptr & 0xffff0000) >> 16) << 4)
+                 + (ret->pxe_ptr & 0xffff));
+  if (!pxe)
+    return NULL;
+
+  /* !PXE  */
+  if (*(grub_uint32_t *) pxe !=        0x45585021)
+    return NULL;
+
+  pxe_rm_entry = ret->rm_entry;
+  return ret;
+}
+
 static int
 grub_pxe_iterate (int (*hook) (const char *name))
 {
@@ -202,14 +242,14 @@ grub_pxefs_open (struct grub_file *file, const char *name)
 
   if (curr_file != 0)
     {
-      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2);
+      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2, pxe_rm_entry);
       curr_file = 0;
     }
 
   c.c1.server_ip = disk_data->server_ip;
   c.c1.gateway_ip = disk_data->gateway_ip;
   grub_strcpy ((char *)&c.c1.filename[0], name);
-  grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
+  grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1, pxe_rm_entry);
   if (c.c1.status)
     return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
 
@@ -217,7 +257,7 @@ grub_pxefs_open (struct grub_file *file, const char *name)
 
   c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
   c.c2.packet_size = grub_pxe_blksize;
-  grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
+  grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2, pxe_rm_entry);
   if (c.c2.status)
     return grub_error (GRUB_ERR_BAD_FS, "open fails");
 
@@ -275,14 +315,14 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
       struct grub_pxenv_tftp_open o;
 
       if (curr_file != 0)
-        grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
+        grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o, pxe_rm_entry);
 
       o.server_ip = disk_data->server_ip;
       o.gateway_ip = disk_data->gateway_ip;
       grub_strcpy ((char *)&o.filename[0], data->filename);
       o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
       o.packet_size = grub_pxe_blksize;
-      grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
+      grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o, pxe_rm_entry);
       if (o.status)
        {
          grub_error (GRUB_ERR_BAD_FS, "open fails");
@@ -297,7 +337,7 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
   while (pn >= data->packet_number)
     {
       c.buffer_size = data->block_size;
-      grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
+      grub_pxe_call (GRUB_PXENV_TFTP_READ, &c, pxe_rm_entry);
       if (c.status)
         {
           grub_error (GRUB_ERR_BAD_FS, "read fails");
@@ -318,7 +358,7 @@ grub_pxefs_close (grub_file_t file)
 
   if (curr_file == file)
     {
-      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
+      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c, pxe_rm_entry);
       curr_file = 0;
     }
 
@@ -454,7 +494,7 @@ grub_pxe_detect (void)
   ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
   ci.buffer = 0;
   ci.buffer_size = 0;
-  grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
+  grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry);
   if (ci.status)
     return;
 
index 39f356c83e1c69586bde971a821b336c51942cf2..049dd19507ea8ba679bcc58787d20db8e9369a2b 100644 (file)
 
 #ifndef ASM_FILE
 
+#define GRUB_PXE_SIGNATURE "PXENV+"
+
 struct grub_pxenv
 {
   grub_uint8_t signature[6];   /* 'PXENV+'.  */
@@ -302,8 +304,7 @@ struct grub_pxenv_unload_stack
   grub_uint8_t reserved[10];
 } __attribute__ ((packed));
 
-struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void);
-int EXPORT_FUNC(grub_pxe_call) (int func, void * data);
+int EXPORT_FUNC(grub_pxe_call) (int func, void * data, grub_uint32_t pxe_rm_entry);
 
 extern struct grub_pxenv *grub_pxe_pxenv;
 
index 8e4bd13bd0780b921880bd8c9b2e118470cd40a1..ef58c738c6868ff495be0d2d2ad1889235785acc 100644 (file)
@@ -1434,65 +1434,8 @@ FUNCTION(grub_get_rtc)
        popl    %ebp
        ret
 
-pxe_rm_entry:
-       .long   0
-
-/*
- * struct grub_pxenv *grub_pxe_scan (void);
- */
-FUNCTION(grub_pxe_scan)
-       pushl   %ebp
-       pushl   %ebx
-
-       xorl    %ebx, %ebx
-       xorl    %ecx, %ecx
-
-       call    prot_to_real
-       .code16
-
-       pushw   %es
-
-       movw    $0x5650, %ax
-       int     $0x1A
-       cmpw    $0x564E, %ax
-       jnz     1f
-       cmpl    $0x4E455850, %es:(%bx)          /* PXEN(V+)  */
-       jnz     1f
-       cmpw    $0x201, %es:6(%bx)              /* API version  */
-       jb      1f
-       lesw    %es:0x28(%bx), %bx              /* !PXE structure  */
-       cmpl    $0x45585021, %es:(%bx)          /* !PXE  */
-       jnz     1f
-       movw    %es, %cx
-       jmp     2f
-1:
-       xorw    %bx, %bx
-       xorw    %cx, %cx
-2:
-
-       popw    %es
-
-       DATA32 call     real_to_prot
-       .code32
-
-       xorl    %eax, %eax
-       leal    (%eax, %ecx, 4), %ecx
-       leal    (%ebx, %ecx, 4), %eax           /* eax = ecx * 16 + ebx  */
-
-       orl     %eax, %eax
-       jz      1f
-
-       movl    0x10(%eax), %ecx
-       movl    %ecx, pxe_rm_entry
-
-1:
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
 /*
- * int grub_pxe_call (int func, void* data);
+ * int grub_pxe_call (int func, void* data, grub_uint32_t pxe_rm_entry);
  */
 FUNCTION(grub_pxe_call)
        pushl   %ebp
@@ -1501,13 +1444,13 @@ FUNCTION(grub_pxe_call)
        pushl   %edi
        pushl   %ebx
 
+       movl    %ecx, %ebx
        movl    %eax, %ecx
        movl    %edx, %eax
        andl    $0xF, %eax
        shrl    $4, %edx
        shll    $16, %edx
        addl    %eax, %edx
-       movl    pxe_rm_entry, %ebx
 
        call    prot_to_real
        .code16