03ddbaf71e2576365d9a58e9ad02e8fc2802ea64
[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 { { MemorySpecialMemory, 0xFFF, 1 }, 7, }, // unusable memory
34 #elif __arm__ // This needs to be done per-platform specific way
35 { { MemoryLoadedProgram, 0x80000, 32 }, 0, }, // X-Loader + OmapLdr
36 { { MemoryLoadedProgram, 0x81000, 128 }, 1, }, // FreeLDR
37 { { MemoryFirmwareTemporary, 0x80500, 4096 }, 2, }, // Video Buffer
38 #endif
39 };
40 MEMORY_DESCRIPTOR*
41 ArcGetMemoryDescriptor(MEMORY_DESCRIPTOR* Current)
42 {
43 MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
44 BIOS_MEMORY_MAP BiosMemoryMap[32];
45 static ULONG BiosMemoryMapEntryCount;
46 static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
47 static BOOLEAN MemoryMapInitialized = FALSE;
48 ULONG i, j;
49
50 //
51 // Check if it is the first time we're called
52 //
53 if (!MemoryMapInitialized)
54 {
55 //
56 // Get the machine generated memory map
57 //
58 RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
59 BiosMemoryMapEntryCount = MachVtbl.GetMemoryMap(BiosMemoryMap,
60 sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
61
62 //
63 // Copy the entries to our structure
64 //
65 for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++)
66 {
67 //
68 // Is it suitable memory?
69 //
70 if (BiosMemoryMap[i].Type != BiosMemoryUsable)
71 {
72 //
73 // No. Process next descriptor
74 //
75 continue;
76 }
77
78 //
79 // Copy this memory descriptor
80 //
81 BiosMemoryDescriptors[j].m.MemoryType = MemoryFree;
82 BiosMemoryDescriptors[j].m.BasePage = BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE;
83 BiosMemoryDescriptors[j].m.PageCount = BiosMemoryMap[i].Length / MM_PAGE_SIZE;
84 BiosMemoryDescriptors[j].Index = j;
85 BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE;
86 j++;
87 }
88
89 //
90 // Remember how much descriptors we found
91 //
92 BiosMemoryMapEntryCount = j;
93
94 //
95 // Mark memory map as already retrieved and initialized
96 //
97 MemoryMapInitialized = TRUE;
98 }
99
100 CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
101
102 if (Current == NULL)
103 {
104 //
105 // First descriptor requested
106 //
107 if (BiosMemoryMapEntryCount > 0)
108 {
109 //
110 // Return first generated memory descriptor
111 //
112 return &BiosMemoryDescriptors[0].m;
113 }
114 else if (sizeof(MemoryDescriptors) > 0)
115 {
116 //
117 // Return first fixed memory descriptor
118 //
119 return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[0].m;
120 }
121 else
122 {
123 //
124 // Strange case, we have no memory descriptor
125 //
126 return NULL;
127 }
128 }
129 else if (CurrentDescriptor->GeneratedDescriptor)
130 {
131 //
132 // Current entry is a generated descriptor
133 //
134 if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount)
135 {
136 //
137 // Return next generated descriptor
138 //
139 return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m;
140 }
141 else if (sizeof(MemoryDescriptors) > 0)
142 {
143 //
144 // Return first fixed memory descriptor
145 //
146 return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[0].m;
147 }
148 else
149 {
150 //
151 // No fixed memory descriptor; end of memory map
152 //
153 return NULL;
154 }
155 }
156 else
157 {
158 //
159 // Current entry is a fixed descriptor
160 //
161 if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0]))
162 {
163 //
164 // Return next fixed descriptor
165 //
166 return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[CurrentDescriptor->Index + 1].m;
167 }
168 else
169 {
170 //
171 // No more fixed memory descriptor; end of memory map
172 //
173 return NULL;
174 }
175 }
176 }