memory.h revision 1.5 1 /* -*-C++-*- $NetBSD: memory.h,v 1.5 2004/08/06 18:33:09 uch Exp $ */
2
3 /*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #ifndef _HPCBOOT_MEMORY_H_
40 #define _HPCBOOT_MEMORY_H_
41
42 #undef MEMORY_MAP_DEBUG // super verbose.
43
44 #include <hpcboot.h>
45 class Console;
46
47 template <class T>
48 inline T
49 ROUND(const T v, const T x) {
50 return((v + x - 1) / x) * x;
51 }
52
53 template <class T>
54 inline T
55 TRUNC(const T v, const T x) {
56 return(v / x) * x;
57 }
58
59 #define MAX_MEM_BANK 16
60 class MemoryManager {
61 private:
62 struct bank {
63 paddr_t addr;
64 psize_t size;
65 };
66 // Windows CE application virtual memory size
67 enum { WCE_VMEM_MAX = 32 * 1024 * 1024 };
68 // Windows CE VirtualAlloc() boundary
69 enum { WCE_REGION_SIZE = 64 * 1024 };
70
71 protected:
72 // Console options.
73 Console *&_cons;
74 BOOL _debug;
75
76 enum { BLOCK_SIZE = WCE_REGION_SIZE * 64 }; // 4MByte
77
78 // Pagesize, D-RAM bank
79 vsize_t _page_size;
80 int _page_shift;
81 int _page_per_region;
82 struct bank _bank[MAX_MEM_BANK];
83 int _nbank;
84
85 // Allocated memory
86 vaddr_t _memory;
87
88 // Virtual <-> Physical table
89 int _naddr_table;
90 struct AddressTranslationTable {
91 vaddr_t vaddr;
92 paddr_t paddr;
93 }
94 *_addr_table;
95 int _addr_table_idx;
96
97 public:
98 vsize_t getPageSize(void) { return _page_size; }
99
100 vsize_t getTaggedPageSize(void)
101 { return _page_size - sizeof(struct PageTag); }
102 vsize_t estimateTaggedPageSize(vsize_t sz) {
103 vsize_t tsz = getTaggedPageSize();
104 return ((sz + tsz - 1) / tsz) * _page_size;
105 }
106 u_int32_t roundPage(u_int32_t v) { return ROUND(v, _page_size); }
107 u_int32_t truncPage(u_int32_t v) { return TRUNC(v, _page_size); }
108 u_int32_t roundRegion(u_int32_t v)
109 { return ROUND(v, u_int32_t(WCE_REGION_SIZE)); }
110 u_int32_t truncRegion(u_int32_t v)
111 { return TRUNC(v, u_int32_t(WCE_REGION_SIZE)); }
112
113 // Physical address ops.
114 vaddr_t mapPhysicalPage(paddr_t paddr, psize_t size, u_int32_t flags);
115 void unmapPhysicalPage(vaddr_t vaddr);
116 u_int32_t readPhysical4(paddr_t paddr);
117 // return physical address of coresspoing virtual address.
118 virtual paddr_t searchPage(vaddr_t vaddr) = 0;
119
120 MemoryManager(Console *&cons, size_t pagesize);
121 virtual ~MemoryManager(void);
122 BOOL &setDebug(void) { return _debug; }
123 virtual BOOL init(void) { return TRUE; }
124
125 // initialize page pool
126 BOOL reservePage(vsize_t size, BOOL page_commit = FALSE);
127 // register D-RAM banks
128 void loadBank(paddr_t paddr, psize_t psize);
129 // get 1 page from high address of pool.
130 BOOL getPage(vaddr_t &vaddr, paddr_t &paddr);
131 // get tagged page from low address of pool.
132 BOOL getTaggedPage(vaddr_t &vaddr, paddr_t &paddr);
133 BOOL getTaggedPage(vaddr_t &v, paddr_t &p, struct PageTag **pvec,
134 paddr_t &pvec_paddr);
135 };
136
137 //
138 // Use LockPages()
139 //
140 class MemoryManager_LockPages : public MemoryManager {
141 private:
142 BOOL(*_lock_pages)(LPVOID, DWORD, PDWORD, int);
143 BOOL(*_unlock_pages)(LPVOID, DWORD);
144 int _shift;
145
146 public:
147 MemoryManager_LockPages(BOOL(*)(LPVOID, DWORD, PDWORD, int),
148 BOOL(*)(LPVOID, DWORD), Console *&, size_t, int = 0);
149 virtual ~MemoryManager_LockPages(void);
150 paddr_t searchPage(vaddr_t vaddr);
151 };
152
153 //
154 // Use VirtualCopy()
155 //
156 class MemoryManager_VirtualCopy : public MemoryManager {
157 private:
158 // search guess
159 paddr_t _search_guess;
160
161 // Memory marker
162 u_int32_t _magic0, _magic1;
163 volatile u_int32_t *_magic_addr;
164 enum {
165 MAGIC_CHECK_DONE = 0xac1dcafe,
166 MAGIC_CHECK_DUMMY = 0xa5a5a5a5
167 };
168 void setMagic(vaddr_t v) {
169 _magic_addr =(u_int32_t *)v;
170 while ((_magic0 = Random()) == MAGIC_CHECK_DONE)
171 ;
172 while ((_magic1 = Random()) == MAGIC_CHECK_DONE)
173 ;
174 _magic_addr[0] = _magic0;
175 _magic_addr[1] = _magic1;
176 }
177 BOOL checkMagic(vaddr_t v) {
178 volatile u_int32_t *marker =(u_int32_t *)v;
179 return (marker[0] == _magic0) && (marker[1] == _magic1);
180 }
181 void clearMagic(void) {
182 _magic_addr[0] = MAGIC_CHECK_DONE;
183 _magic_addr[1] = MAGIC_CHECK_DONE;
184 }
185 vaddr_t checkMagicRegion(vaddr_t start, vsize_t size,
186 vsize_t step = 8) {
187 for (vaddr_t ref = start; ref < start + size; ref += step)
188 if (checkMagic(ref))
189 return ref - start;
190 return ~0;
191 }
192 paddr_t searchBank(int banknum);
193
194 public:
195 MemoryManager_VirtualCopy(Console *&, size_t);
196 virtual ~MemoryManager_VirtualCopy(void);
197 paddr_t searchPage(vaddr_t vaddr);
198 };
199
200 #endif // _HPCBOOT_MEMORY_H_
201