1
+ #include <asm/e820/types.h>
1
2
#include <asm/processor.h>
2
3
#include "pgtable.h"
3
4
#include "../string.h"
@@ -34,10 +35,62 @@ unsigned long *trampoline_32bit __section(.data);
34
35
extern struct boot_params * boot_params ;
35
36
int cmdline_find_option_bool (const char * option );
36
37
38
+ static unsigned long find_trampoline_placement (void )
39
+ {
40
+ unsigned long bios_start , ebda_start ;
41
+ unsigned long trampoline_start ;
42
+ struct boot_e820_entry * entry ;
43
+ int i ;
44
+
45
+ /*
46
+ * Find a suitable spot for the trampoline.
47
+ * This code is based on reserve_bios_regions().
48
+ */
49
+
50
+ ebda_start = * (unsigned short * )0x40e << 4 ;
51
+ bios_start = * (unsigned short * )0x413 << 10 ;
52
+
53
+ if (bios_start < BIOS_START_MIN || bios_start > BIOS_START_MAX )
54
+ bios_start = BIOS_START_MAX ;
55
+
56
+ if (ebda_start > BIOS_START_MIN && ebda_start < bios_start )
57
+ bios_start = ebda_start ;
58
+
59
+ bios_start = round_down (bios_start , PAGE_SIZE );
60
+
61
+ /* Find the first usable memory region under bios_start. */
62
+ for (i = boot_params -> e820_entries - 1 ; i >= 0 ; i -- ) {
63
+ entry = & boot_params -> e820_table [i ];
64
+
65
+ /* Skip all entries above bios_start. */
66
+ if (bios_start <= entry -> addr )
67
+ continue ;
68
+
69
+ /* Skip non-RAM entries. */
70
+ if (entry -> type != E820_TYPE_RAM )
71
+ continue ;
72
+
73
+ /* Adjust bios_start to the end of the entry if needed. */
74
+ if (bios_start > entry -> addr + entry -> size )
75
+ bios_start = entry -> addr + entry -> size ;
76
+
77
+ /* Keep bios_start page-aligned. */
78
+ bios_start = round_down (bios_start , PAGE_SIZE );
79
+
80
+ /* Skip the entry if it's too small. */
81
+ if (bios_start - TRAMPOLINE_32BIT_SIZE < entry -> addr )
82
+ continue ;
83
+
84
+ break ;
85
+ }
86
+
87
+ /* Place the trampoline just below the end of low memory */
88
+ return bios_start - TRAMPOLINE_32BIT_SIZE ;
89
+ }
90
+
37
91
struct paging_config paging_prepare (void * rmode )
38
92
{
39
93
struct paging_config paging_config = {};
40
- unsigned long bios_start , ebda_start ;
41
94
42
95
/* Initialize boot_params. Required for cmdline_find_option_bool(). */
43
96
boot_params = rmode ;
@@ -61,23 +114,7 @@ struct paging_config paging_prepare(void *rmode)
61
114
paging_config .l5_required = 1 ;
62
115
}
63
116
64
- /*
65
- * Find a suitable spot for the trampoline.
66
- * This code is based on reserve_bios_regions().
67
- */
68
-
69
- ebda_start = * (unsigned short * )0x40e << 4 ;
70
- bios_start = * (unsigned short * )0x413 << 10 ;
71
-
72
- if (bios_start < BIOS_START_MIN || bios_start > BIOS_START_MAX )
73
- bios_start = BIOS_START_MAX ;
74
-
75
- if (ebda_start > BIOS_START_MIN && ebda_start < bios_start )
76
- bios_start = ebda_start ;
77
-
78
- /* Place the trampoline just below the end of low memory, aligned to 4k */
79
- paging_config .trampoline_start = bios_start - TRAMPOLINE_32BIT_SIZE ;
80
- paging_config .trampoline_start = round_down (paging_config .trampoline_start , PAGE_SIZE );
117
+ paging_config .trampoline_start = find_trampoline_placement ();
81
118
82
119
trampoline_32bit = (unsigned long * )paging_config .trampoline_start ;
83
120
0 commit comments