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