Home | History | Annotate | Line # | Download | only in hpcboot
      1 /* -*-C++-*-	$NetBSD: memory.h,v 1.8 2008/04/28 20:23:20 martin 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  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifndef _HPCBOOT_MEMORY_H_
     33 #define	_HPCBOOT_MEMORY_H_
     34 
     35 #undef MEMORY_MAP_DEBUG		// super verbose.
     36 
     37 #include <hpcboot.h>
     38 class Console;
     39 
     40 template <class T>
     41 inline T
     42 ROUND(const T v, const T x) {
     43 	return((v + x - 1) / x) * x;
     44 }
     45 
     46 template <class T>
     47 inline T
     48 TRUNC(const T v, const T x) {
     49 	return(v / x) * x;
     50 }
     51 
     52 #define	MAX_MEM_BANK	16
     53 class MemoryManager {
     54 private:
     55 	struct bank {
     56 		paddr_t addr;
     57 		psize_t size;
     58 	};
     59 	// Windows CE application virtual memory size
     60 	enum { WCE_VMEM_MAX = 32 * 1024 * 1024 };
     61 	// Windows CE VirtualAlloc() boundary
     62 	enum { WCE_REGION_SIZE = 64 * 1024 };
     63 
     64 protected:
     65 	// Console options.
     66 	Console *&_cons;
     67 	BOOL _debug;
     68 
     69 	enum { BLOCK_SIZE = WCE_REGION_SIZE * 64 }; // 4MByte
     70 
     71 	// Pagesize, D-RAM bank
     72 	vsize_t _page_size;
     73 	int _page_shift;
     74 	int _page_per_region;
     75 	struct bank _bank[MAX_MEM_BANK];
     76 	int _nbank;
     77 
     78 	// Allocated memory
     79 	vaddr_t _memory;
     80 
     81 	// Virtual <-> Physical table
     82 	int _naddr_table;
     83 	struct AddressTranslationTable {
     84 		vaddr_t vaddr;
     85 		paddr_t paddr;
     86 	}
     87 	*_addr_table;
     88 	int _addr_table_idx;
     89 
     90 public:
     91 	vsize_t getPageSize(void) { return _page_size; }
     92 
     93 	vsize_t getTaggedPageSize(void)
     94 		{ return _page_size - sizeof(struct PageTag); }
     95 	vsize_t estimateTaggedPageSize(vsize_t sz) {
     96 		vsize_t tsz = getTaggedPageSize();
     97 		return ((sz + tsz - 1) / tsz) * _page_size;
     98 	}
     99 	uint32_t roundPage(uint32_t v) { return ROUND(v, _page_size); }
    100 	uint32_t truncPage(uint32_t v) { return TRUNC(v, _page_size); }
    101 	uint32_t roundRegion(uint32_t v)
    102 		{ return ROUND(v, uint32_t(WCE_REGION_SIZE)); }
    103 	uint32_t truncRegion(uint32_t v)
    104 		{ return TRUNC(v, uint32_t(WCE_REGION_SIZE)); }
    105 
    106 	// Physical address ops.
    107 	vaddr_t mapPhysicalPage(paddr_t paddr, psize_t size, uint32_t flags);
    108 	void unmapPhysicalPage(vaddr_t vaddr);
    109 	uint32_t readPhysical4(paddr_t paddr);
    110 	// return physical address of coresspoing virtual address.
    111 	virtual paddr_t searchPage(vaddr_t vaddr) = 0;
    112 
    113 	MemoryManager(Console *&cons, size_t pagesize);
    114 	virtual ~MemoryManager(void);
    115 	BOOL &setDebug(void) { return _debug; }
    116 	virtual BOOL init(void) { return TRUE; }
    117 
    118 	// initialize page pool
    119 	BOOL reservePage(vsize_t size, BOOL page_commit = FALSE);
    120 	// register D-RAM banks
    121 	void loadBank(paddr_t paddr, psize_t psize);
    122 	// get 1 page from high address of pool.
    123 	BOOL getPage(vaddr_t &vaddr, paddr_t &paddr);
    124 	// get tagged page from low address of pool.
    125 	BOOL getTaggedPage(vaddr_t &vaddr, paddr_t &paddr);
    126 	BOOL getTaggedPage(vaddr_t &v, paddr_t &p, struct PageTag **pvec,
    127 	    paddr_t &pvec_paddr);
    128 };
    129 
    130 //
    131 //	Use LockPages()
    132 //
    133 class MemoryManager_LockPages : public MemoryManager {
    134 private:
    135 	BOOL(*_lock_pages)(LPVOID, DWORD, PDWORD, int);
    136 	BOOL(*_unlock_pages)(LPVOID, DWORD);
    137 	int _shift;
    138 
    139 public:
    140 	MemoryManager_LockPages(BOOL(*)(LPVOID, DWORD, PDWORD, int),
    141 	    BOOL(*)(LPVOID, DWORD), Console *&, size_t, int = 0);
    142 	virtual ~MemoryManager_LockPages(void);
    143 	paddr_t searchPage(vaddr_t vaddr);
    144 };
    145 
    146 //
    147 //	Use VirtualCopy()
    148 //
    149 class MemoryManager_VirtualCopy : public MemoryManager {
    150 private:
    151 	// search guess
    152 	paddr_t _search_guess;
    153 
    154 	// Memory marker
    155 	uint32_t _magic0, _magic1;
    156 	volatile uint32_t *_magic_addr;
    157 	enum {
    158 		MAGIC_CHECK_DONE	= 0xac1dcafe,
    159 		MAGIC_CHECK_DUMMY	= 0xa5a5a5a5
    160 	};
    161 	void setMagic(vaddr_t v) {
    162 		_magic_addr =(uint32_t *)v;
    163 		while ((_magic0 = Random()) == MAGIC_CHECK_DONE)
    164 			;
    165 		while ((_magic1 = Random()) == MAGIC_CHECK_DONE)
    166 			;
    167 		_magic_addr[0] = _magic0;
    168 		_magic_addr[1] = _magic1;
    169 	}
    170 	BOOL checkMagic(vaddr_t v) {
    171 		volatile uint32_t *marker =(uint32_t *)v;
    172 		return (marker[0] == _magic0) && (marker[1] == _magic1);
    173 	}
    174 	void clearMagic(void) {
    175 		_magic_addr[0] = MAGIC_CHECK_DONE;
    176 		_magic_addr[1] = MAGIC_CHECK_DONE;
    177 	}
    178 	vaddr_t checkMagicRegion(vaddr_t start, vsize_t size,
    179 	    vsize_t step = 8) {
    180 		for (vaddr_t ref = start; ref < start + size; ref += step)
    181 			if (checkMagic(ref))
    182 				return ref - start;
    183 		return ~0;
    184 	}
    185 	paddr_t searchBank(int banknum);
    186 
    187 public:
    188 	MemoryManager_VirtualCopy(Console *&, size_t);
    189 	virtual ~MemoryManager_VirtualCopy(void);
    190 	paddr_t searchPage(vaddr_t vaddr);
    191 };
    192 
    193 #endif // _HPCBOOT_MEMORY_H_
    194