28 |
#include <pupa/err.h> |
#include <pupa/err.h> |
29 |
#include <pupa/dl.h> |
#include <pupa/dl.h> |
30 |
#include <pupa/misc.h> |
#include <pupa/misc.h> |
31 |
|
#include <pupa/loader.h> |
32 |
|
|
33 |
|
struct mem_region |
34 |
|
{ |
35 |
|
pupa_addr_t addr; |
36 |
|
pupa_size_t size; |
37 |
|
}; |
38 |
|
|
39 |
|
#define MAX_REGIONS 32 |
40 |
|
|
41 |
|
static struct mem_region mem_regions[MAX_REGIONS]; |
42 |
|
static int num_regions; |
43 |
|
|
44 |
|
pupa_addr_t pupa_os_area_addr; |
45 |
|
pupa_size_t pupa_os_area_size; |
46 |
|
pupa_size_t pupa_lower_mem, pupa_upper_mem; |
47 |
|
|
48 |
static char * |
static char * |
49 |
make_install_device (void) |
make_install_device (void) |
67 |
return pupa_prefix; |
return pupa_prefix; |
68 |
} |
} |
69 |
|
|
70 |
|
/* Add a memory region. */ |
71 |
|
static void |
72 |
|
add_mem_region (pupa_addr_t addr, pupa_size_t size) |
73 |
|
{ |
74 |
|
if (num_regions == MAX_REGIONS) |
75 |
|
/* Ignore. */ |
76 |
|
return; |
77 |
|
|
78 |
|
mem_regions[num_regions].addr = addr; |
79 |
|
mem_regions[num_regions].size = size; |
80 |
|
num_regions++; |
81 |
|
} |
82 |
|
|
83 |
|
/* Compact memory regions. */ |
84 |
|
static void |
85 |
|
compact_mem_regions (void) |
86 |
|
{ |
87 |
|
int i, j; |
88 |
|
|
89 |
|
/* Sort them. */ |
90 |
|
for (i = 0; i < num_regions - 1; i++) |
91 |
|
for (j = i + 1; j < num_regions; j++) |
92 |
|
if (mem_regions[i].addr > mem_regions[j].addr) |
93 |
|
{ |
94 |
|
struct mem_region tmp = mem_regions[i]; |
95 |
|
mem_regions[i] = mem_regions[j]; |
96 |
|
mem_regions[j] = tmp; |
97 |
|
} |
98 |
|
|
99 |
|
/* Merge overlaps. */ |
100 |
|
for (i = 0; i < num_regions - 1; i++) |
101 |
|
if (mem_regions[i].addr + mem_regions[i].size >= mem_regions[i + 1].addr) |
102 |
|
{ |
103 |
|
j = i + 1; |
104 |
|
|
105 |
|
if (mem_regions[i].addr + mem_regions[i].size |
106 |
|
< mem_regions[j].addr + mem_regions[j].size) |
107 |
|
mem_regions[i].size = (mem_regions[j].addr + mem_regions[j].size |
108 |
|
- mem_regions[i].addr); |
109 |
|
|
110 |
|
pupa_memmove (mem_regions + j, mem_regions + j + 1, |
111 |
|
(num_regions - j - 1) * sizeof (struct mem_region)); |
112 |
|
i--; |
113 |
|
} |
114 |
|
} |
115 |
|
|
116 |
void |
void |
117 |
pupa_machine_init (void) |
pupa_machine_init (void) |
118 |
{ |
{ |
119 |
pupa_uint32_t cont; |
pupa_uint32_t cont; |
120 |
struct pupa_machine_mmap_entry *entry |
struct pupa_machine_mmap_entry *entry |
121 |
= (struct pupa_machine_mmap_entry *) PUPA_MEMORY_MACHINE_SCRATCH_ADDR; |
= (struct pupa_machine_mmap_entry *) PUPA_MEMORY_MACHINE_SCRATCH_ADDR; |
|
pupa_size_t lower_mem = (pupa_get_memsize (0) << 10); |
|
122 |
pupa_addr_t end_addr = pupa_get_end_addr (); |
pupa_addr_t end_addr = pupa_get_end_addr (); |
123 |
|
int i; |
124 |
|
|
125 |
/* Initialize the console as early as possible. */ |
/* Initialize the console as early as possible. */ |
126 |
pupa_console_init (); |
pupa_console_init (); |
127 |
|
|
128 |
|
pupa_lower_mem = pupa_get_memsize (0) << 10; |
129 |
|
|
130 |
/* Sanity check. */ |
/* Sanity check. */ |
131 |
if (lower_mem < PUPA_MEMORY_MACHINE_RESERVED_END) |
if (pupa_lower_mem < PUPA_MEMORY_MACHINE_RESERVED_END) |
132 |
pupa_fatal ("too small memory"); |
pupa_fatal ("too small memory"); |
133 |
|
|
134 |
/* Turn on Gate A20 to access >1MB. */ |
/* Turn on Gate A20 to access >1MB. */ |
135 |
pupa_gate_a20 (1); |
pupa_gate_a20 (1); |
136 |
|
|
137 |
/* Add the lower memory into free memory. */ |
/* Add the lower memory into free memory. */ |
138 |
if (lower_mem >= PUPA_MEMORY_MACHINE_RESERVED_END) |
if (pupa_lower_mem >= PUPA_MEMORY_MACHINE_RESERVED_END) |
139 |
pupa_mm_init_region ((void *) PUPA_MEMORY_MACHINE_RESERVED_END, |
add_mem_region (PUPA_MEMORY_MACHINE_RESERVED_END, |
140 |
lower_mem - PUPA_MEMORY_MACHINE_RESERVED_END); |
pupa_lower_mem - PUPA_MEMORY_MACHINE_RESERVED_END); |
141 |
|
|
142 |
pupa_mm_init_region ((void *) end_addr, |
add_mem_region (end_addr, PUPA_MEMORY_MACHINE_RESERVED_START - end_addr); |
|
PUPA_MEMORY_MACHINE_RESERVED_START - end_addr); |
|
143 |
|
|
144 |
/* Check if pupa_get_mmap_entry works. */ |
/* Check if pupa_get_mmap_entry works. */ |
145 |
cont = pupa_get_mmap_entry (entry, 0); |
cont = pupa_get_mmap_entry (entry, 0); |
167 |
len = ((addr + entry->len > 0xFFFFFFFF) |
len = ((addr + entry->len > 0xFFFFFFFF) |
168 |
? 0xFFFFFFFF - addr |
? 0xFFFFFFFF - addr |
169 |
: (pupa_size_t) entry->len); |
: (pupa_size_t) entry->len); |
170 |
pupa_mm_init_region ((void *) addr, len); |
add_mem_region (addr, len); |
171 |
} |
} |
172 |
|
|
173 |
next: |
next: |
184 |
if (eisa_mmap) |
if (eisa_mmap) |
185 |
{ |
{ |
186 |
if ((eisa_mmap & 0xFFFF) == 0x3C00) |
if ((eisa_mmap & 0xFFFF) == 0x3C00) |
187 |
pupa_mm_init_region ((void *) 0x100000, |
add_mem_region (0x100000, (eisa_mmap << 16) + 0x100000 * 15); |
|
(eisa_mmap << 16) + 0x100000 * 15); |
|
188 |
else |
else |
189 |
{ |
{ |
190 |
pupa_mm_init_region ((void *) 0x100000, |
add_mem_region (0x100000, (eisa_mmap & 0xFFFF) << 10); |
191 |
(eisa_mmap & 0xFFFF) << 10); |
add_mem_region (0x1000000, eisa_mmap << 16); |
|
pupa_mm_init_region ((void *) 0x1000000, eisa_mmap << 16); |
|
192 |
} |
} |
193 |
} |
} |
194 |
else |
else |
195 |
pupa_mm_init_region ((void *) 0x100000, |
add_mem_region (0x100000, pupa_get_memsize (1) << 10); |
|
(pupa_size_t) pupa_get_memsize (1) << 10); |
|
196 |
} |
} |
197 |
|
|
198 |
|
compact_mem_regions (); |
199 |
|
|
200 |
|
/* Add the memory regions to free memory, except for the region starting |
201 |
|
from 1MB. This region is partially used for loading OS images. |
202 |
|
For now, 1/4 of this is added to free memory. */ |
203 |
|
for (i = 0; i < num_regions; i++) |
204 |
|
if (mem_regions[i].addr == 0x100000) |
205 |
|
{ |
206 |
|
pupa_size_t quarter = mem_regions[i].size >> 2; |
207 |
|
|
208 |
|
pupa_upper_mem = mem_regions[i].size; |
209 |
|
pupa_os_area_addr = mem_regions[i].addr; |
210 |
|
pupa_os_area_size = mem_regions[i].size - quarter; |
211 |
|
pupa_mm_init_region ((void *) (pupa_os_area_addr + pupa_os_area_size), |
212 |
|
quarter); |
213 |
|
} |
214 |
|
else |
215 |
|
pupa_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size); |
216 |
|
|
217 |
|
if (! pupa_os_area_addr) |
218 |
|
pupa_fatal ("no upper memory"); |
219 |
|
|
220 |
/* The memory system was initialized, thus register built-in devices. */ |
/* The memory system was initialized, thus register built-in devices. */ |
221 |
pupa_biosdisk_init (); |
pupa_biosdisk_init (); |
222 |
|
|