Merge from Etherboot 5.4
authorMichael Brown <mcb30@etherboot.org>
Thu, 16 Mar 2006 17:59:51 +0000 (17:59 +0000)
committerMichael Brown <mcb30@etherboot.org>
Thu, 16 Mar 2006 17:59:51 +0000 (17:59 +0000)
src/arch/i386/Makefile
src/arch/i386/prefix/hdprefix.S [new file with mode: 0644]
src/arch/ia64/core/efi.c
src/core/elf_loader.c
src/drivers/bus/pci.c

index 0c258ae..94b85c8 100644 (file)
@@ -82,6 +82,10 @@ MEDIA                        += dsk
 OBJS_dskprefix         = dskprefix zdskprefix
 CFLAGS_zdskprefix      = $(CFLAGS_ZPREFIX)
 
+MEDIA                  += hd
+OBJS_hdprefix          = hdprefix zhdprefix
+CFLAGS_zhdprefix       = $(CFLAGS_ZPREFIX)
+
 MEDIA                  += raw
 OBJS_rawprefix         = rawprefix zrawprefix
 CFLAGS_zrawprefix      = $(CFLAGS_ZPREFIX)
diff --git a/src/arch/i386/prefix/hdprefix.S b/src/arch/i386/prefix/hdprefix.S
new file mode 100644 (file)
index 0000000..38e62bc
--- /dev/null
@@ -0,0 +1,296 @@
+/****************************************************************\
+
+hdprefix.S Copyright (C) 2005 Per Dalgas Jakobsen
+
+This code has been inspired/derived by the OSLoader by Vladislav Aleksandrov.
+http://www.programmersheaven.com/zone5/cat469/40546.htm.
+
+This software may be used and distributed according to the terms
+of the GNU Public License (GPL), incorporated herein by reference.
+
+hdprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.
+
+Actions performed by hdprefix:
+1) Load the MBR to LOADSEG:0
+2) Check which partition is active (or try first partition if none active)
+3) Check wether LBA is supported.
+3a) LBA
+3a1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
+3b) CHS (standard)
+3b1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
+4) Check loaded bootsector for BOOTMAGIC code.
+5) Jump to payload LOADSEG:ENTRYPOINT.
+
+Output with failure points (!#):
+---
+Loading (!1)partition #
+Std. BIOS(!2) | Ext. BIOS(!3)
+Booting...(!4)
+(!5)
+---
+
+!1: Failed to load MBR with Int13,ah=2.
+!2: Failed to load bootrecord+payload with Int13,ah=2.
+!3: Failed to load bootrecord+payload with Int13,ah=42.
+!4: Invalid BOOTMAGIC in loaded bootrecord.
+!5: Jumping to payload.
+
+\*****************************************************************/
+.equ   BOOTSEG,        0x07c0
+.equ   LOADSEG,        0x1000
+.equ   ENTRYPOINT,     _start
+
+.equ   BOOTMAGIC,      0x0aa55
+
+.equ   partition_table,        0x1be
+.equ   partition_rec_size,     0x10
+
+.equ   boot_ind,       0       /* 80h=active */
+.equ   start_head,     1
+.equ   start_sector,   2       /* bits 0-5 */
+.equ   start_cyl,      3       /* bits 8,9 in bits 6,7 of sector */
+.equ   os_ind,         4       /* os indicator */
+.equ   end_head,       5
+.equ   end_sector,     6       /* bits 0-5 */
+.equ   end_track,      7       /* bits 8,9 in bits 6,7 of sector */
+.equ   nsect,          8       /* sectors preceding partition */
+.equ   lenght,         0x0c    /* length of partition in sectors */
+
+/-------------------------------------------------------------
+
+       .arch i386
+       .text
+       .section ".prefix", "ax", @progbits
+       .code16
+        
+bootstart:
+       jmp     $BOOTSEG,$_go           /* reload cs:ip */
+
+
+/****************************************************************/
+/* support routines.                                           */
+/*--------------------------------------------------------------*/
+_failed:
+       movw    $BOOTSEG,%ax
+       movw    %ax,%ds
+       movw    $_failed_msg_end-_failed_msg,%cx
+       movw    $_failed_msg,%si
+       call    _print_str
+
+       /* stop execution - should probably have option to auto-reboot after delay. */
+_failed_loop:
+       jmp     _failed_loop
+
+/*--------------------------------------------------------------*/
+_print_str:
+       /* cx = count, ds:si = string. */
+       movw    $0x0007,%bx
+       movb    $0x0e,%ah
+_print_loop:
+       lodsb
+       int     $0x10
+       loop    _print_loop
+       ret
+
+/*--------------------------------------------------------------*/                     
+_print_char:
+       /* al = char. */
+       movw    $0x0007,%bx
+       movb    $0x0e,%ah
+       int     $0x10
+       ret
+
+/*--------------------------------------------------------------*/
+_print_nl:
+       /* - */
+       movb    $0x0d,%al
+       call    _print_char
+       movb    $0x0a,%al
+       call    _print_char
+       ret
+
+/*--------------------------------------------------------------*/
+_print_hex:
+       /* dx = value */
+       movb    $0x0e,%ah       /* write char, tty mode */
+       movw    $0x0007,%bx     /* page 0, attribute 7 (normal) */
+       call    _print_digit
+       call    _print_digit
+       call    _print_digit
+       /* fall through */
+_print_digit:
+       rolw    $4,%dx          /* rotate so that lowest 4 bits are used */
+       movb    $0x0f,%al       /* mask for nibble */
+       andb    %dl,%al
+       addb    $0x90,%al       /* convert al to ascii hex (four instructions) */
+       daa
+       adcb    $0x40,%al
+       daa
+       int     $0x10
+       ret
+
+/****************************************************************/
+
+
+_go:
+       cli
+       movw    $BOOTSEG,%ax
+       movw    %ax,%ds
+       movw    %ax,%ss
+       movw    $0x2000,%sp     /* good large stack. */
+       sti
+       cld
+       movw    $LOADSEG,%ax
+       movw    %ax,%es
+
+       movw    $_load_msg_end-_load_msg,%cx
+       movw    $_load_msg,%si
+       call    _print_str
+
+/*--- load MBR so we can use its partition table. ---*/
+       xorw    %bx,%bx
+       movw    $0x0001,%cx     /* chs: 0,0,1 */
+       movb    %bh,%dh         /* - */
+       movb    $0x80,%dl
+       movw    $0x0201,%ax     /* read one sector (MBR) */
+       int     $0x13
+       jc      _failed
+
+/*--- find the active partition ---*/
+       movw    $_part_msg_end-_part_msg,%cx
+       movw    $_part_msg,%si
+       call    _print_str
+
+       movw    $partition_table,%di
+       movw    $4,%cx
+_partition_loop:
+       cmpb    $0x80,%es:(%di)         /* active? */
+       je      _partition_found
+       addw    $partition_rec_size,%di
+       loop    _partition_loop
+
+       /*- no partitions marked active - use 1. partition. */
+       movw    $partition_table,%di
+       movw    $4,%cx
+
+_partition_found:
+       movb    $'5',%al                        /* convert to ascii */
+       subb    %cl,%al
+       call    _print_char
+       call    _print_nl
+
+/*--- check for lba support ---*/
+       movw    $0x55aa,%bx
+       movb    $0x80,%dl
+       movb    $0x41,%ah
+       int     $0x13
+       jc      __bios
+       cmpw    $0x0aa55,%bx
+       jnz     __bios
+       testb   $1,%cl
+       jz      __bios
+
+/*--- use lba bios calls to read sectors ---*/
+_lba:
+       movw    $_extbios_msg_end-_extbios_msg,%cx
+       movw    $_extbios_msg,%si
+       call    _print_str
+
+       movw    %es:nsect(%di),%ax
+       movw    %ax,_bios_lba_low
+       movw    %es:nsect+2(%di),%ax
+       movw    %ax,_bios_lba_high
+       movb    $0x80,%dl
+       movw    $_disk_address_packet,%si
+       movw    $0x4200,%ax     /* read */
+       int     $0x13
+       jc      _failed
+       jmp     __loaded
+
+/*--- use standard bios calls to read sectors ---*/
+__bios:
+       movw    $_stdbios_msg_end-_stdbios_msg,%cx
+       movw    $_stdbios_msg,%si
+       call    _print_str
+
+       movw    _disk_address_packet+2(,1),%ax  /* only low byte is used. */
+       xorw    %bx,%bx
+       movw    %es:start_sector(%di),%cx
+       movb    %es:start_head(%di),%dh
+       movb    $0x80,%dl
+       movb    $0x02,%ah
+       int     $0x13
+       jc      _failed
+
+__loaded:
+       movw    $_boot_msg_end-_boot_msg,%cx
+       movw    $_boot_msg,%si
+       call    _print_str
+
+       /* check if it has a valid bootrecord. */
+       cmpw    $BOOTMAGIC,%es:510(,1)
+       jne     _failed
+       call    _print_nl
+
+       /* call the payload. */
+       pushl   $0              /* No parameters to preserve for exit path */
+       pushw   $0              /* Use prefix exit path mechanism */
+       jmp     $LOADSEG,$ENTRYPOINT
+
+       .section ".text16", "ax", @progbits
+       .globl  prefix_exit
+prefix_exit:
+       int     $0x19           /* should try to boot machine */
+       .globl  prefix_exit_end
+prefix_exit_end:
+       .previous
+        
+
+/*--------------------------------------------------------------*/
+
+_load_msg:     .ascii  "Loading "
+_load_msg_end:
+_part_msg:     .ascii  "partition "
+_part_msg_end:
+_boot_msg:     .ascii  "Booting..."
+_boot_msg_end:
+_stdbios_msg:  .ascii  "Std. BIOS\r\n"
+_stdbios_msg_end:
+_extbios_msg:  .ascii  "Ext. BIOS\r\n"
+_extbios_msg_end:
+_failed_msg:   .ascii  "FAILED!!!\r\n"
+_failed_msg_end:
+
+
+/*--------------------------------------------------------------*/
+
+_disk_address_packet:
+               .byte   0x10            /* size of the packet */
+               .byte   0               /* reserved */
+               .word   _verbatim_size_sct      /* number of sectors to read */
+               .word   0x0000          /* offset */
+               .word   LOADSEG         /* segment of buffer */
+_bios_lba_low: .word   0
+_bios_lba_high:        .word   0
+               .word   0
+               .word   0
+
+       .rept 32
+               .byte   0
+       .endr
+
+
+/*--- Partition table ------------------------------------------*/
+
+       .org 446, 0
+       .rept 64
+               .byte   0
+       .endr
+
+
+/*--- Magic code -----------------------------------------------*/
+       .org 510, 0
+               .word BOOTMAGIC
+
+/*** END ********************************************************/
index 97e585f..2da7685 100644 (file)
@@ -898,7 +898,7 @@ struct Elf_Bhdr *prepare_boot_params(void *header)
        notes.nf1.n_descsz = sizeof(notes.nf1_bootp_data);
        notes.nf1.n_type   = EB_BOOTP_DATA;
        CP(notes.nf1_name,   EB_PARAM_NOTE);
-       notes.nf1_bootp_data = virt_to_phys(BOOTP_DATA_ADDR);
+       notes.nf1_bootp_data = virt_to_phys(&bootp_data);
 
        notes.nf2.n_namesz = sizeof(EB_PARAM_NOTE);
        notes.nf2.n_descsz = sizeof(notes.nf2_header);
index 88a2975..85b60e8 100644 (file)
@@ -199,7 +199,6 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
        }
        printf("(ELF");
        elf_freebsd_probe();
-       multiboot_probe(data, len);
        printf(")... ");
        phdr_size = estate.e.elf32.e_phnum * estate.e.elf32.e_phentsize;
        if (estate.e.elf32.e_phoff + phdr_size > len) {
@@ -207,7 +206,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
                return dead_download;
        }
        if (phdr_size > sizeof(estate.p.dummy)) {
-               printf("Program header to big\n");
+               printf("Program header too big\n");
                return dead_download;
        }
        memcpy(&estate.p.phdr32, data + estate.e.elf32.e_phoff, phdr_size);
@@ -251,6 +250,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
        }
 #if ELF_NOTES
        /* Load ELF notes from the image */
+       estate.check_ip_checksum = 0;
        for(estate.segment = 0; estate.segment < estate.e.elf32.e_phnum; estate.segment++) {
                if (estate.p.phdr32[estate.segment].p_type != PT_NOTE)
                        continue;
@@ -289,6 +289,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
        estate.loc = 0;
        estate.skip = 0;
        estate.toread = 0;
+       multiboot_init();
        return elf32_download;
 }
 
@@ -516,6 +517,7 @@ static inline os_download_t elf64_probe(unsigned char *data, unsigned int len)
        }
 #if ELF_NOTES
        /* Load ELF notes from the image */
+       estate.check_ip_checksum = 0;
        for(estate.segment = 0; estate.segment < estate.e.elf64.e_phnum; estate.segment++) {
                if (estate.p.phdr64[estate.segment].p_type != PT_NOTE)
                        continue;
index 95a7650..02286b7 100644 (file)
@@ -256,11 +256,12 @@ unsigned long pci_bar_start ( struct pci_device *pci, unsigned int index ) {
                        pci_read_config_dword ( pci, index + 4, &hi );
                        if ( hi ) {
 #if ULONG_MAX > 0xffffffff
-                                       bar = hi;
-                                       bar <<= 32;
+                               bar = hi;
+                               bar <<= 32;
 #else
-                                       printf ( "Unhandled 64bit BAR\n" );
-                                       return -1UL;
+                               printf ( "Unhandled 64bit BAR %08x:%08x\n",
+                                        hi, lo );
+                               return -1UL;
 #endif
                        }
                }