Move freeldr to reactos\boot\freeldr.
[reactos.git] / reactos / boot / freeldr / freeldr / arch / i386 / xboxmem.c
1 /* $Id$
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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 #include "debug.h"
25 #include "mm.h"
26 #include "rtl.h"
27 #include "hardware.h"
28 #include "machine.h"
29 #include "machxbox.h"
30 #include "portio.h"
31
32 static U32 InstalledMemoryMb = 0;
33 static U32 AvailableMemoryMb = 0;
34
35 #define TEST_SIZE 0x200
36 #define TEST_PATTERN1 0xaa
37 #define TEST_PATTERN2 0x55
38
39 VOID
40 XboxMemInit(VOID)
41 {
42 U8 ControlRegion[TEST_SIZE];
43 PVOID MembaseTop = (PVOID)(64 * 1024 * 1024);
44 PVOID MembaseLow = (PVOID)0;
45
46 (*(PU32)(0xfd000000 + 0x100200)) = 0x03070103 ;
47 (*(PU32)(0xfd000000 + 0x100204)) = 0x11448000 ;
48
49 WRITE_PORT_ULONG((U32*) 0xcf8, CONFIG_CMD(0, 0, 0x84));
50 WRITE_PORT_ULONG((U32*) 0xcfc, 0x7ffffff); /* Prep hardware for 128 Mb */
51
52 InstalledMemoryMb = 64;
53 memset(ControlRegion, TEST_PATTERN1, TEST_SIZE);
54 memset(MembaseTop, TEST_PATTERN1, TEST_SIZE);
55 __asm__ ("wbinvd\n");
56
57 if (0 == memcmp(MembaseTop, ControlRegion, TEST_SIZE))
58 {
59 /* Looks like there is memory .. maybe a 128MB box */
60 memset(ControlRegion, TEST_PATTERN2, TEST_SIZE);
61 memset(MembaseTop, TEST_PATTERN2, TEST_SIZE);
62 __asm__ ("wbinvd\n");
63 if (0 == memcmp(MembaseTop, ControlRegion, TEST_SIZE))
64 {
65 /* Definitely looks like there is memory */
66 if (0 == memcmp(MembaseLow, ControlRegion, TEST_SIZE))
67 {
68 /* Hell, we find the Test-string at 0x0 too ! */
69 InstalledMemoryMb = 64;
70 }
71 else
72 {
73 InstalledMemoryMb = 128;
74 }
75 }
76 }
77
78 /* Set hardware for amount of memory detected */
79 WRITE_PORT_ULONG((U32*) 0xcf8, CONFIG_CMD(0, 0, 0x84));
80 WRITE_PORT_ULONG((U32*) 0xcfc, InstalledMemoryMb * 1024 * 1024 - 1);
81
82 AvailableMemoryMb = InstalledMemoryMb;
83 }
84
85 U32
86 XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize)
87 {
88 U32 EntryCount = 0;
89
90 /* Synthesize memory map */
91 if (1 <= MaxMemoryMapSize)
92 {
93 /* Available RAM block */
94 BiosMemoryMap[0].BaseAddress = 0;
95 BiosMemoryMap[0].Length = AvailableMemoryMb * 1024 * 1024;
96 BiosMemoryMap[0].Type = MEMTYPE_USABLE;
97 EntryCount = 1;
98 }
99
100 if (2 <= MaxMemoryMapSize)
101 {
102 /* Video memory */
103 BiosMemoryMap[1].BaseAddress = AvailableMemoryMb * 1024 * 1024;
104 BiosMemoryMap[1].Length = (InstalledMemoryMb - AvailableMemoryMb) * 1024 * 1024;
105 BiosMemoryMap[1].Type = MEMTYPE_RESERVED;
106 EntryCount = 2;
107 }
108
109 return EntryCount;
110 }
111
112 PVOID
113 XboxMemReserveMemory(U32 MbToReserve)
114 {
115 if (0 == InstalledMemoryMb)
116 {
117 /* Hmm, seems we're not initialized yet */
118 XboxMemInit();
119 }
120
121 if (AvailableMemoryMb < MbToReserve)
122 {
123 /* Can't satisfy the request */
124 return NULL;
125 }
126
127 AvailableMemoryMb -= MbToReserve;
128
129 /* Top of available memory points to the space just reserved */
130 return (PVOID) (AvailableMemoryMb * 1024 * 1024);
131 }
132
133 /* EOF */