* 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. */
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.) */
.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
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.
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
.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