root/core/highmem.inc

Revision 6b2e2742b0ef8b3fb28f008e5f2d63fba8006e68, 3.8 KB (checked in by H. Peter Anvin <hpa@…>, 3 years ago)

core: create an ersatz com32 structure as expected by libcom32

To make it easier to mix libcom32 code into the core, create a com32
structure to make the system call functions work correctly.

Signed-off-by: H. Peter Anvin <hpa@…>

  • Property mode set to 100644
Line 
1;; -----------------------------------------------------------------------
2;;
3;;   Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4;;
5;;   This program is free software; you can redistribute it and/or modify
6;;   it under the terms of the GNU General Public License as published by
7;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8;;   Boston MA 02111-1307, USA; either version 2 of the License, or
9;;   (at your option) any later version; incorporated herein by reference.
10;;
11;; -----------------------------------------------------------------------
12
13;;
14;; highmem.inc
15;;
16;; Probe for the size of high memory.  This can be overridden by a
17;; mem= command on the command line while booting a new kernel.
18;;
19
20                section .text16
21
22;
23; This is set up as a subroutine; it will set up the global variable
24; HighMemSize.  All registers are preserved.
25;
26highmemsize:
27                push es
28                pushfd
29                pushad
30
31                push cs
32                pop es
33
34;
35; First, try INT 15:E820 (get BIOS memory map)
36;
37; Note: we may have to scan this multiple times, because some (daft) BIOSes
38; report main memory as multiple contiguous ranges...
39;
40get_e820:
41                mov dword [E820Max],-(1 << 20)  ; Max amount of high memory
42                mov dword [E820Mem],(1 << 20)   ; End of detected high memory
43.start_over:
44                mov di,E820Buf
45                xor ax,ax
46                mov cx,10
47                rep stosw                       ; Clear buffer
48                xor ebx,ebx                     ; Start with first record
49                jmp short .do_e820              ; Skip "at end" check first time!
50.int_loop:      and ebx,ebx                     ; If we're back at beginning...
51                jz .e820_done                   ; ... we're done
52.do_e820:       mov eax,0000E820h
53                mov edx,534D4150h               ; "SMAP" backwards
54                xor ecx,ecx
55                mov cl,20                       ; ECX <- 20 (size of buffer)
56                mov di,E820Buf
57                int 15h
58                jnc .no_carry
59                ; If carry, ebx == 0 means error, ebx != 0 means we're done
60                and ebx,ebx
61                jnz .e820_done
62                jmp no_e820
63.no_carry:
64                cmp eax,534D4150h
65                jne no_e820
66                cmp cx,20
67                jb no_e820
68
69;
70; Look for a memory block starting at <= 1 MB and continuing upward
71;
72                cmp dword [E820Buf+4], byte 0
73                ja .int_loop                    ; Start >= 4 GB?
74                mov eax, [E820Buf]
75                cmp dword [E820Buf+16],1
76                je .is_ram                      ; Is it memory?
77                ;
78                ; Non-memory range.  Remember this as a limit; some BIOSes get the length
79                ; of primary RAM incorrect!
80                ;
81.not_ram:
82                cmp eax, (1 << 20)
83                jb .int_loop                    ; Starts in lowmem region
84                cmp eax,[E820Max]
85                jae .int_loop                   ; Already above limit
86                mov [E820Max],eax               ; Set limit
87                jmp .int_loop
88
89.is_ram:
90                cmp eax,[E820Mem]
91                ja .int_loop                    ; Not contiguous with our starting point
92                add eax,[E820Buf+8]
93                jc .overflow
94                cmp dword [E820Buf+12],0
95                je .nooverflow
96.overflow:
97                or eax,-1
98.nooverflow:
99                cmp eax,[E820Mem]
100                jbe .int_loop                   ; All is below our baseline
101                mov [E820Mem],eax
102                jmp .start_over                 ; Start over in case we find an adjacent range
103
104.e820_done:
105                mov eax,[E820Mem]
106                cmp eax,[E820Max]
107                jna .not_limited
108                mov eax,[E820Max]
109.not_limited:
110                cmp eax,(1 << 20)
111                ja got_highmem                  ; Did we actually find memory?
112                ; otherwise fall through
113
114;
115; INT 15:E820 failed.  Try INT 15:E801.
116;
117no_e820:
118                mov ax,0e801h                   ; Query high memory (semi-recent)
119                int 15h
120                jc no_e801
121                cmp ax,3c00h
122                ja no_e801                      ; > 3C00h something's wrong with this call
123                jb e801_hole                    ; If memory hole we can only use low part
124
125                mov ax,bx
126                shl eax,16                      ; 64K chunks
127                add eax,(16 << 20)              ; Add first 16M
128                jmp short got_highmem
129
130;
131; INT 15:E801 failed.  Try INT 15:88.
132;
133no_e801:
134                mov ah,88h                      ; Query high memory (oldest)
135                int 15h
136                cmp ax,14*1024                  ; Don't trust memory >15M
137                jna e801_hole
138                mov ax,14*1024
139e801_hole:
140                and eax,0ffffh
141                shl eax,10                      ; Convert from kilobytes
142                add eax,(1 << 20)               ; First megabyte
143got_highmem:
144%if HIGHMEM_SLOP != 0
145                sub eax,HIGHMEM_SLOP
146%endif
147                mov [HighMemSize],eax
148                popad
149                popfd
150                pop es
151                ret                             ; Done!
152
153                section .bss16
154                alignb 4
155E820Buf         resd 5                  ; INT 15:E820 data buffer
156E820Mem         resd 1                  ; Memory detected by E820
157E820Max         resd 1                  ; Is E820 memory capped?
158; HighMemSize is defined in com32.inc
Note: See TracBrowser for help on using the browser.