| 
				
			 | 
			
			
				
				@@ -41,6 +41,8 @@ struct e820_entry { 
			 | 
		
		
	
		
			
			| 
				41
			 | 
			
				41
			 | 
			
			
				
				 	uint64_t len; 
			 | 
		
		
	
		
			
			| 
				42
			 | 
			
				42
			 | 
			
			
				
				 	/** Type of region */ 
			 | 
		
		
	
		
			
			| 
				43
			 | 
			
				43
			 | 
			
			
				
				 	uint32_t type; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				
				+	/** Extended attributes (optional) */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				
				+	uint32_t attrs; 
			 | 
		
		
	
		
			
			| 
				44
			 | 
			
				46
			 | 
			
			
				
				 } __attribute__ (( packed )); 
			 | 
		
		
	
		
			
			| 
				45
			 | 
			
				47
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				46
			 | 
			
				48
			 | 
			
			
				
				 #define E820_TYPE_RAM		1 /**< Normal memory */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -48,6 +50,12 @@ struct e820_entry { 
			 | 
		
		
	
		
			
			| 
				48
			 | 
			
				50
			 | 
			
			
				
				 #define E820_TYPE_ACPI		3 /**< ACPI reclaim memory */ 
			 | 
		
		
	
		
			
			| 
				49
			 | 
			
				51
			 | 
			
			
				
				 #define E820_TYPE_NVS		4 /**< ACPI NVS memory */ 
			 | 
		
		
	
		
			
			| 
				50
			 | 
			
				52
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				
				+#define E820_ATTR_ENABLED	0x00000001UL 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				
				+#define E820_ATTR_NONVOLATILE	0x00000002UL 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				
				+#define E820_ATTR_UNKNOWN	0xfffffffcUL 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				
				+#define E820_MIN_SIZE		20 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				51
			 | 
			
				59
			 | 
			
			
				
				 /** Buffer for INT 15,e820 calls */ 
			 | 
		
		
	
		
			
			| 
				52
			 | 
			
				60
			 | 
			
			
				
				 static struct e820_entry __bss16 ( e820buf ); 
			 | 
		
		
	
		
			
			| 
				53
			 | 
			
				61
			 | 
			
			
				
				 #define e820buf __use_data16 ( e820buf ) 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -148,8 +156,15 @@ static int meme820 ( struct memory_map *memmap ) { 
			 | 
		
		
	
		
			
			| 
				148
			 | 
			
				156
			 | 
			
			
				
				 	struct memory_region *region = memmap->regions; 
			 | 
		
		
	
		
			
			| 
				149
			 | 
			
				157
			 | 
			
			
				
				 	uint32_t next = 0; 
			 | 
		
		
	
		
			
			| 
				150
			 | 
			
				158
			 | 
			
			
				
				 	uint32_t smap; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				159
			 | 
			
			
				
				+	size_t size; 
			 | 
		
		
	
		
			
			| 
				151
			 | 
			
				160
			 | 
			
			
				
				 	unsigned int flags; 
			 | 
		
		
	
		
			
			| 
				152
			 | 
			
				
			 | 
			
			
				
				-	unsigned int discard_c, discard_d, discard_D; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				161
			 | 
			
			
				
				+	unsigned int discard_d, discard_D; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				162
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				163
			 | 
			
			
				
				+	/* Clear the E820 buffer.  Do this once before starting, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				164
			 | 
			
			
				
				+	 * rather than on each call; some BIOSes rely on the contents 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				165
			 | 
			
			
				
				+	 * being preserved between calls. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				166
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				167
			 | 
			
			
				
				+	memset ( &e820buf, 0, sizeof ( e820buf ) ); 
			 | 
		
		
	
		
			
			| 
				153
			 | 
			
				168
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				154
			 | 
			
				169
			 | 
			
			
				
				 	do { 
			 | 
		
		
	
		
			
			| 
				155
			 | 
			
				170
			 | 
			
			
				
				 		__asm__ __volatile__ ( REAL_CODE ( "stc\n\t" 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -158,7 +173,7 @@ static int meme820 ( struct memory_map *memmap ) { 
			 | 
		
		
	
		
			
			| 
				158
			 | 
			
				173
			 | 
			
			
				
				 						   "popw %w0\n\t" ) 
			 | 
		
		
	
		
			
			| 
				159
			 | 
			
				174
			 | 
			
			
				
				 				       : "=r" ( flags ), "=a" ( smap ), 
			 | 
		
		
	
		
			
			| 
				160
			 | 
			
				175
			 | 
			
			
				
				 					 "=b" ( next ), "=D" ( discard_D ), 
			 | 
		
		
	
		
			
			| 
				161
			 | 
			
				
			 | 
			
			
				
				-					 "=c" ( discard_c ), "=d" ( discard_d ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				176
			 | 
			
			
				
				+					 "=c" ( size ), "=d" ( discard_d ) 
			 | 
		
		
	
		
			
			| 
				162
			 | 
			
				177
			 | 
			
			
				
				 				       : "a" ( 0xe820 ), "b" ( next ), 
			 | 
		
		
	
		
			
			| 
				163
			 | 
			
				178
			 | 
			
			
				
				 					 "D" ( __from_data16 ( &e820buf ) ), 
			 | 
		
		
	
		
			
			| 
				164
			 | 
			
				179
			 | 
			
			
				
				 					 "c" ( sizeof ( e820buf ) ), 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -170,17 +185,42 @@ static int meme820 ( struct memory_map *memmap ) { 
			 | 
		
		
	
		
			
			| 
				170
			 | 
			
				185
			 | 
			
			
				
				 			return -ENOTSUP; 
			 | 
		
		
	
		
			
			| 
				171
			 | 
			
				186
			 | 
			
			
				
				 		} 
			 | 
		
		
	
		
			
			| 
				172
			 | 
			
				187
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				188
			 | 
			
			
				
				+		if ( size < E820_MIN_SIZE ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				189
			 | 
			
			
				
				+			DBG ( "INT 15,e820 returned only %zd bytes\n", size ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				190
			 | 
			
			
				
				+			return -EINVAL; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				191
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				192
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				173
			 | 
			
				193
			 | 
			
			
				
				 		if ( flags & CF ) { 
			 | 
		
		
	
		
			
			| 
				174
			 | 
			
				194
			 | 
			
			
				
				 			DBG ( "INT 15,e820 terminated on CF set\n" ); 
			 | 
		
		
	
		
			
			| 
				175
			 | 
			
				195
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
		
			
			| 
				176
			 | 
			
				196
			 | 
			
			
				
				 		} 
			 | 
		
		
	
		
			
			| 
				177
			 | 
			
				197
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				178
			 | 
			
				
			 | 
			
			
				
				-		DBG ( "INT 15,e820 region [%llx,%llx) type %d\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				198
			 | 
			
			
				
				+		DBG ( "INT 15,e820 region [%llx,%llx) type %d", 
			 | 
		
		
	
		
			
			| 
				179
			 | 
			
				199
			 | 
			
			
				
				 		      e820buf.start, ( e820buf.start + e820buf.len ), 
			 | 
		
		
	
		
			
			| 
				180
			 | 
			
				200
			 | 
			
			
				
				 		      ( int ) e820buf.type ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				201
			 | 
			
			
				
				+		if ( size > offsetof ( typeof ( e820buf ), attrs ) ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				202
			 | 
			
			
				
				+			DBG ( " (%s", ( ( e820buf.attrs & E820_ATTR_ENABLED ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				203
			 | 
			
			
				
				+					? "enabled" : "disabled" ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				204
			 | 
			
			
				
				+			if ( e820buf.attrs & E820_ATTR_NONVOLATILE ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				205
			 | 
			
			
				
				+				DBG ( ", non-volatile" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				206
			 | 
			
			
				
				+			if ( e820buf.attrs & E820_ATTR_UNKNOWN ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				207
			 | 
			
			
				
				+				DBG ( ", other [%08lx]", e820buf.attrs ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				208
			 | 
			
			
				
				+			DBG ( ")" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				209
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				210
			 | 
			
			
				
				+		DBG ( "\n" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				211
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				212
			 | 
			
			
				
				+		/* Discard non-RAM regions */ 
			 | 
		
		
	
		
			
			| 
				181
			 | 
			
				213
			 | 
			
			
				
				 		if ( e820buf.type != E820_TYPE_RAM ) 
			 | 
		
		
	
		
			
			| 
				182
			 | 
			
				214
			 | 
			
			
				
				 			continue; 
			 | 
		
		
	
		
			
			| 
				183
			 | 
			
				215
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				216
			 | 
			
			
				
				+		/* Check extended attributes, if present */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				217
			 | 
			
			
				
				+		if ( size > offsetof ( typeof ( e820buf ), attrs ) ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				218
			 | 
			
			
				
				+			if ( ! ( e820buf.attrs & E820_ATTR_ENABLED ) ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				219
			 | 
			
			
				
				+				continue; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				220
			 | 
			
			
				
				+			if ( e820buf.attrs & E820_ATTR_NONVOLATILE ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				221
			 | 
			
			
				
				+				continue; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				222
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				223
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				184
			 | 
			
				224
			 | 
			
			
				
				 		region->start = e820buf.start; 
			 | 
		
		
	
		
			
			| 
				185
			 | 
			
				225
			 | 
			
			
				
				 		region->end = e820buf.start + e820buf.len; 
			 | 
		
		
	
		
			
			| 
				186
			 | 
			
				226
			 | 
			
			
				
				 		region++; 
			 |