2 * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 /** Buffer for INT 15,e820 calls */
34 static struct e820_entry e820_buf
__attribute__ (( section ( ".bss16" ) ));
36 /** Continuation value for next INT 15,e820 call */
37 static uint32_t e820_ebx
;
40 * Get system memory map entry
42 * @v prev Previous system memory map entry, or NULL at start
43 * @v next Next system memory map entry, or NULL at end
45 struct e820_entry
* memmap_next ( struct e820_entry
*prev
) {
46 struct bootapp_callback_params params
;
48 /* Reset buffer and continuation value if restarting */
50 memset ( &e820_buf
, 0, sizeof ( e820_buf
) );
52 } else if ( e820_ebx
== 0 ) {
57 /* Read system memory map */
58 memset ( ¶ms
, 0, sizeof ( params
) );
61 /* Call INT 15,e820 */
62 params
.vector
.interrupt
= 0x15;
64 params
.ebx
= e820_ebx
;
65 params
.ecx
= sizeof ( e820_buf
);
66 params
.edx
= E820_SMAP
;
68 params
.edi
= ( ( ( void * ) &e820_buf
) -
69 ( ( void * ) BASE_ADDRESS
) );
70 call_interrupt ( ¶ms
);
72 /* Record continuation value */
73 e820_ebx
= params
.ebx
;
76 if ( params
.eflags
& CF
) {
77 DBG ( "INT 15,e820 failed: error %02x\n", params
.ah
);
80 if ( params
.eax
!= E820_SMAP
) {
81 DBG ( "INT 15,e820 invalid SMAP signature %08x\n",
85 DBG2 ( "INT 15,e820 region [%llx,%llx) type %d\n",
86 e820_buf
.start
, ( e820_buf
.start
+ e820_buf
.len
),
89 /* Skip non-RAM regions */
90 if ( e820_buf
.type
!= E820_TYPE_RAM
)
92 if ( params
.ecx
> offsetof ( typeof ( e820_buf
), attrs
) ) {
93 if ( ! ( e820_buf
.attrs
& E820_ATTR_ENABLED
) )
95 if ( e820_buf
.attrs
& E820_ATTR_NONVOLATILE
)
99 /* Return this region */
102 } while ( e820_ebx
!= 0 );