[FREELDR] Xbox memory management improvements (#1961)
[reactos.git] / boot / freeldr / freeldr / arch / i386 / xboxmem.c
1 /*
2 * FreeLoader
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Note: much of this code was based on knowledge and/or code developed
19 * by the Xbox Linux group: http://www.xbox-linux.org
20 */
21
22 #include <freeldr.h>
23 #include <debug.h>
24
25 DBG_DEFAULT_CHANNEL(MEMORY);
26
27 static ULONG InstalledMemoryMb = 0;
28 static ULONG AvailableMemoryMb = 0;
29 extern PVOID FrameBuffer;
30 extern ULONG FrameBufferSize;
31
32 #define TEST_SIZE 0x200
33 #define TEST_PATTERN1 0xAA
34 #define TEST_PATTERN2 0x55
35
36 extern VOID
37 SetMemory(
38 PFREELDR_MEMORY_DESCRIPTOR MemoryMap,
39 ULONG_PTR BaseAddress,
40 SIZE_T Size,
41 TYPE_OF_MEMORY MemoryType);
42
43 extern VOID
44 ReserveMemory(
45 PFREELDR_MEMORY_DESCRIPTOR MemoryMap,
46 ULONG_PTR BaseAddress,
47 SIZE_T Size,
48 TYPE_OF_MEMORY MemoryType,
49 PCHAR Usage);
50
51 extern ULONG
52 PcMemFinalizeMemoryMap(
53 PFREELDR_MEMORY_DESCRIPTOR MemoryMap);
54
55 VOID
56 XboxMemInit(VOID)
57 {
58 UCHAR ControlRegion[TEST_SIZE];
59 PVOID MembaseTop = (PVOID)(64 * 1024 * 1024);
60 PVOID MembaseLow = (PVOID)0;
61
62 (*(PULONG)(0xfd000000 + 0x100200)) = 0x03070103;
63 (*(PULONG)(0xfd000000 + 0x100204)) = 0x11448000;
64
65 WRITE_PORT_ULONG((ULONG*) 0xcf8, CONFIG_CMD(0, 0, 0x84));
66 WRITE_PORT_ULONG((ULONG*) 0xcfc, 0x7ffffff); /* Prep hardware for 128 Mb */
67
68 InstalledMemoryMb = 64;
69 memset(ControlRegion, TEST_PATTERN1, TEST_SIZE);
70 memset(MembaseTop, TEST_PATTERN1, TEST_SIZE);
71 __wbinvd();
72
73 if (memcmp(MembaseTop, ControlRegion, TEST_SIZE) == 0)
74 {
75 /* Looks like there is memory .. maybe a 128MB box */
76 memset(ControlRegion, TEST_PATTERN2, TEST_SIZE);
77 memset(MembaseTop, TEST_PATTERN2, TEST_SIZE);
78 __wbinvd();
79 if (memcmp(MembaseTop, ControlRegion, TEST_SIZE) == 0)
80 {
81 /* Definitely looks like there is memory */
82 if (memcmp(MembaseLow, ControlRegion, TEST_SIZE) == 0)
83 {
84 /* Hell, we find the Test-string at 0x0 too! */
85 InstalledMemoryMb = 64;
86 }
87 else
88 {
89 InstalledMemoryMb = 128;
90 }
91 }
92 }
93
94 /* Set hardware for amount of memory detected */
95 WRITE_PORT_ULONG((ULONG*) 0xcf8, CONFIG_CMD(0, 0, 0x84));
96 WRITE_PORT_ULONG((ULONG*) 0xcfc, InstalledMemoryMb * 1024 * 1024 - 1);
97
98 AvailableMemoryMb = InstalledMemoryMb;
99 }
100
101 FREELDR_MEMORY_DESCRIPTOR XboxMemoryMap[MAX_BIOS_DESCRIPTORS + 1];
102
103 PFREELDR_MEMORY_DESCRIPTOR
104 XboxMemGetMemoryMap(ULONG *MemoryMapSize)
105 {
106 TRACE("XboxMemGetMemoryMap()\n");
107 /* FIXME: Obtain memory map via multiboot spec */
108
109 /* Synthesize memory map */
110
111 /* Available RAM block */
112 SetMemory(XboxMemoryMap,
113 0,
114 AvailableMemoryMb * 1024 * 1024,
115 LoaderFree);
116
117 if (FrameBufferSize != 0)
118 {
119 /* Video memory */
120 ReserveMemory(XboxMemoryMap,
121 (ULONG_PTR)FrameBuffer,
122 FrameBufferSize,
123 LoaderFirmwarePermanent,
124 "Video memory");
125 }
126
127 *MemoryMapSize = PcMemFinalizeMemoryMap(XboxMemoryMap);
128 return XboxMemoryMap;
129 }
130
131 /* EOF */