* Sync to recent trunk (r52563).
[reactos.git] / boot / freeldr / freeldr / arcemul / mm.c
1 /*
2 * PROJECT: ReactOS Boot Loader (FreeLDR)
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: boot/freeldr/freeldr/arcemul/mm.c
5 * PURPOSE: Routines for ARC Memory Management
6 * PROGRAMMERS: Hervé Poussineau <hpoussin@reactos.org>
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <freeldr.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* FUNCTIONS ******************************************************************/
16
17 typedef struct
18 {
19 MEMORY_DESCRIPTOR m;
20 ULONG Index;
21 BOOLEAN GeneratedDescriptor;
22 } MEMORY_DESCRIPTOR_INT;
23 static const MEMORY_DESCRIPTOR_INT MemoryDescriptors[] =
24 {
25 #if defined (__i386__) || defined (_M_AMD64)
26 { { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // realmode int vectors
27 { { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // freeldr stack + cmdline
28 { { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
29 { { MemorySpecialMemory, 0x78, 8 }, 3, }, // prot mode stack. BIOSCALLBUFFER
30 { { MemoryFirmwareTemporary, 0x80, 0x10 }, 4, }, // File system read buffer. FILESYSBUFFER
31 { { MemoryFirmwareTemporary, 0x90, 0x10 }, 5, }, // Disk read buffer for int 13h. DISKREADBUFFER
32 { { MemoryFirmwarePermanent, 0xA0, 0x60 }, 6, }, // ROM / Video
33 #elif __arm__ // This needs to be done per-platform specific way
34
35 #endif
36 };
37 const MEMORY_DESCRIPTOR*
38 ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current)
39 {
40 MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
41 BIOS_MEMORY_MAP BiosMemoryMap[32];
42 static ULONG BiosMemoryMapEntryCount;
43 static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
44 static BOOLEAN MemoryMapInitialized = FALSE;
45 ULONG i, j;
46
47 //
48 // Check if it is the first time we're called
49 //
50 if (!MemoryMapInitialized)
51 {
52 //
53 // Get the machine generated memory map
54 //
55 RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
56 BiosMemoryMapEntryCount = MachVtbl.GetMemoryMap(BiosMemoryMap,
57 sizeof(BiosMemoryMap) /
58 sizeof(BIOS_MEMORY_MAP));
59
60 //
61 // Copy the entries to our structure
62 //
63 for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++)
64 {
65 //
66 // Is it suitable memory?
67 //
68 if (BiosMemoryMap[i].Type != BiosMemoryUsable)
69 {
70 //
71 // No. Process next descriptor
72 //
73 continue;
74 }
75
76 //
77 // Copy this memory descriptor
78 //
79 BiosMemoryDescriptors[j].m.MemoryType = MemoryFree;
80 BiosMemoryDescriptors[j].m.BasePage = (ULONG)(BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE);
81 BiosMemoryDescriptors[j].m.PageCount = (ULONG)(BiosMemoryMap[i].Length / MM_PAGE_SIZE);
82 BiosMemoryDescriptors[j].Index = j;
83 BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE;
84 j++;
85 }
86
87 //
88 // Remember how much descriptors we found
89 //
90 BiosMemoryMapEntryCount = j;
91
92 //
93 // Mark memory map as already retrieved and initialized
94 //
95 MemoryMapInitialized = TRUE;
96 }
97
98 CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
99
100 if (Current == NULL)
101 {
102 //
103 // First descriptor requested
104 //
105 if (BiosMemoryMapEntryCount > 0)
106 {
107 //
108 // Return first generated memory descriptor
109 //
110 return &BiosMemoryDescriptors[0].m;
111 }
112 else if (sizeof(MemoryDescriptors) > 0)
113 {
114 //
115 // Return first fixed memory descriptor
116 //
117 return &MemoryDescriptors[0].m;
118 }
119 else
120 {
121 //
122 // Strange case, we have no memory descriptor
123 //
124 return NULL;
125 }
126 }
127 else if (CurrentDescriptor->GeneratedDescriptor)
128 {
129 //
130 // Current entry is a generated descriptor
131 //
132 if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount)
133 {
134 //
135 // Return next generated descriptor
136 //
137 return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m;
138 }
139 else if (sizeof(MemoryDescriptors) > 0)
140 {
141 //
142 // Return first fixed memory descriptor
143 //
144 return &MemoryDescriptors[0].m;
145 }
146 else
147 {
148 //
149 // No fixed memory descriptor; end of memory map
150 //
151 return NULL;
152 }
153 }
154 else
155 {
156 //
157 // Current entry is a fixed descriptor
158 //
159 if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0]))
160 {
161 //
162 // Return next fixed descriptor
163 //
164 return &MemoryDescriptors[CurrentDescriptor->Index + 1].m;
165 }
166 else
167 {
168 //
169 // No more fixed memory descriptor; end of memory map
170 //
171 return NULL;
172 }
173 }
174 }