]> Zhao Yanbai Git Server - minix.git/commitdiff
BIOS function 0xE820 for memory map detection
authorTomas Hruby <tom@minix3.org>
Thu, 29 Jul 2010 07:21:11 +0000 (07:21 +0000)
committerTomas Hruby <tom@minix3.org>
Thu, 29 Jul 2010 07:21:11 +0000 (07:21 +0000)
- this function returns a ritcher description of available memory

- is ACPI compliant, ACPI data structures are excluded from free
  memory list

- available memory exported to Minix in a backwards compatible manner

- fallback to the old method if this function not available (old
  hardware)

boot/boot.c
boot/boot.h
boot/boothead.s

index e8f4fb0c472f1d8a84d6497ae2507b5d56c6a46f..2d919e04ebb873a5bfad8bbfd24f5f7fa81aefbd 100644 (file)
@@ -538,11 +538,30 @@ static void initialize(void)
         * done to get out of the way of Minix, and to put the data area
         * cleanly inside a 64K chunk if using BIOS I/O (no DMA problems).
         */
-       u32_t oldaddr= caddr;
-       u32_t memend= mem[0].base + mem[0].size;
-       u32_t newaddr= (memend - runsize) & ~0x0000FL;
+       u32_t oldaddr;
+       u32_t memend;
+       u32_t newaddr;
 #if !DOS
-       u32_t dma64k= (memend - 1) & ~0x0FFFFL;
+       u32_t dma64k;
+#endif
+
+       if (mem_entries) {
+               int i, j;
+               j = 0;
+               for(i = 0; i < mem_entries ; i++) {
+                       if (j < 3 && emem[i].type == 1) {
+                               mem[j].base = emem[i].base_lo;
+                               mem[j].size = emem[i].size_lo;
+                               j++;
+                       }
+               }
+       }
+
+       oldaddr= caddr;
+       memend= mem[0].base + mem[0].size;
+       newaddr= (memend - runsize) & ~0x0000FL;
+#if !DOS
+       dma64k= (memend - 1) & ~0x0FFFFL;
 
 
        /* Check if data segment crosses a 64K boundary. */
index bdda5e2427354d8f0466a36ebc6b282ea11df8d0..662835a12079d31324b0f919cf9634855c016b75 100644 (file)
@@ -67,7 +67,18 @@ typedef struct {             /* One chunk of free memory. */
        u32_t   size;           /* Number of bytes. */
 } memory;
 
+typedef struct {               /* One chunk of free memory. */
+       u32_t   base_lo;        /* Start byte. */
+       u32_t   base_hi;
+       u32_t   size_lo;        /* Number of bytes. */
+       u32_t   size_hi;        /* Number of bytes. */
+       u32_t   type;
+       u32_t   acpi_attrs;
+} e820_memory;
+
 EXTERN memory mem[3];          /* List of available memory. */
+EXTERN e820_memory emem[16];           /* List of available memory. */
+EXTERN int mem_entries;
 EXTERN int mon_return;         /* Monitor stays in memory? */
 EXTERN int cdbooted;           /* Did we boot from CD? (Set by boothead.s.) */
 
index 7fefb1ec396039a5c01826222528a08b738cd5d5..0c7a348f55b58e938d273c3a22363cf31f6ba810 100644 (file)
@@ -41,6 +41,8 @@
 .extern _rem_part                              ! To pass partition info
 .extern _k_flags                               ! Special kernel flags
 .extern _mem                                   ! Free memory list
+.extern _emem                          ! Free memory list for E820
+.extern _mem_entries                           ! Free memory E820 list entries
 .extern _cdbooted                              ! Whether we booted from CD
 .extern _cddevice                              ! Whether we booted from CD
 
@@ -143,6 +145,64 @@ sepID:
        mov     _runsize+0, ax
        mov     _runsize+2, dx  ! 32 bit size of this process
 
+!Determine memory using the 0xE820 BIOS function if available
+       mov     di, #_emem
+       mov     20(di), #1      ! force a valid ACPI 3.X entry
+
+       .data1 o32
+       xor     bx, bx          ! zero EBX
+       xor     bp, bp          !zero bp
+       .data1 o32
+       mov     dx, e820_magic
+       .data1 o32
+       mov     cx, const_24            ! request 24 bytes
+       
+       .data1 o32
+       mov     ax, const_0xe820
+       int     0x15
+       jc      e820_failed
+
+       .data1 o32
+       mov     dx, e820_magic
+       .data1 o32
+       cmp     dx, ax
+       jne     e820_failed
+
+       .data1 o32
+       test    bx, bx
+       je      e820_failed
+       jmp     e820_gotit
+
+e820_next:
+       .data1 o32
+       mov     ax, const_0xe820
+       mov     20(di), #1      ! force a valid ACPI 3.X entry
+       
+       .data1 o32
+       mov     cx, const_24    ! request 24 bytes
+       int     0x15
+       jc      e820_done
+       .data1 o32
+       mov     dx, e820_magic
+
+
+e820_gotit:
+       jcxz    e820_skip
+       cmp     bp, #16
+       je      e820_done       ! we have only space for 16 entries
+       inc     bp
+       add     di, #24
+e820_skip:
+       .data1 o32
+       test    bx, bx
+       jne     e820_next
+
+e820_done:
+       mov     _mem_entries, bp
+       jmp     memory_detected
+
+e820_failed:
+
 ! Determine available memory as a list of (base,size) pairs as follows:
 ! mem[0] = low memory, mem[1] = memory between 1M and 16M, mem[2] = memory
 ! above 16M.  Last two coalesced into mem[1] if adjacent.
@@ -185,6 +245,8 @@ adj_ext:
        add     14(di), bx      ! Add ext mem above 16M to mem below 16M
 no_ext:
 
+memory_detected:
+
 
 ! Time to switch to a higher level language (not much higher)
        call    _boot
@@ -1534,6 +1596,15 @@ p_mcs_desc:
        .data2  0xFFFF, UNSET
        .data1  UNSET, 0x9A, 0x00, 0x00
 
+e820_magic:
+!      .data1 0x53, 0x4D, 0x41, 0x50
+       .data1 0x50, 0x41, 0x4D, 0x53
+const_24:
+       .data1 0x18, 0x0, 0x0, 0x0
+const_0xe820:
+       .data2 0xe820
+
+
 .bss
        .comm   old_vid_mode, 2 ! Video mode at startup
        .comm   cur_vid_mode, 2 ! Current video mode