2 * Copyright (c) 2006 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
31 #include <machine/param.h>
32 #include <machine/pte.h>
36 u_int ia64_legacy_kernel;
39 uint32_t ia64_pgtblsz;
42 pgtbl_extend(u_int idx)
49 pgtblsz = (idx + 1) << 3;
51 /* The minimum size is 4KB. */
55 /* Find the next higher power of 2. */
57 for (pot = 1; pot < 32; pot <<= 1)
58 pgtblsz = pgtblsz | (pgtblsz >> pot);
61 /* The maximum size is 1MB. */
62 if (pgtblsz > 1048576)
65 /* Make sure the size is a valid (mappable) page size. */
66 if (pgtblsz == 32*1024 || pgtblsz == 128*1024 || pgtblsz == 512*1024)
69 /* Allocate naturally aligned memory. */
70 pa = ia64_platform_alloc(0, pgtblsz);
75 /* Initialize new page table. */
76 if (ia64_pgtbl != NULL && ia64_pgtbl != pgtbl)
77 bcopy(ia64_pgtbl, pgtbl, ia64_pgtblsz);
78 bzero(pgtbl + (ia64_pgtblsz >> 3), pgtblsz - ia64_pgtblsz);
80 if (ia64_pgtbl != NULL && ia64_pgtbl != pgtbl)
81 ia64_platform_free(0, (uintptr_t)ia64_pgtbl, ia64_pgtblsz);
84 ia64_pgtblsz = pgtblsz;
89 ia64_va2pa(vm_offset_t va, size_t *len)
95 /* Backward compatibility. */
96 if (va >= IA64_RR_BASE(7)) {
97 ia64_legacy_kernel = 1;
98 pa = IA64_RR_MASK(va);
102 if (va < IA64_PBVM_BASE) {
107 ia64_legacy_kernel = 0;
109 idx = (va - IA64_PBVM_BASE) >> IA64_PBVM_PAGE_SHIFT;
110 if (idx >= (ia64_pgtblsz >> 3)) {
111 error = pgtbl_extend(idx);
116 ofs = va & IA64_PBVM_PAGE_MASK;
117 pte = ia64_pgtbl[idx];
118 if ((pte & PTE_PRESENT) == 0) {
119 pa = ia64_platform_alloc(va - ofs, IA64_PBVM_PAGE_SIZE);
124 pte = PTE_AR_RWX | PTE_DIRTY | PTE_ACCESSED | PTE_PRESENT;
125 pte |= (pa & PTE_PPN_MASK);
126 ia64_pgtbl[idx] = pte;
128 pa = (pte & PTE_PPN_MASK) + ofs;
130 /* We can not cross page boundaries (in general). */
131 if (*len + ofs > IA64_PBVM_PAGE_SIZE)
132 *len = IA64_PBVM_PAGE_SIZE - ofs;
142 ia64_copyin(const void *src, vm_offset_t va, size_t len)
151 pa = ia64_va2pa(va, &sz);
163 ia64_copyout(vm_offset_t va, void *dst, size_t len)
172 pa = ia64_va2pa(va, &sz);
184 ia64_loadaddr(u_int type, void *data, uint64_t addr)
189 * Align ELF objects at PBVM page boundaries. Align all other
190 * objects at cache line boundaries for good measure.
192 align = (type == LOAD_ELF) ? IA64_PBVM_PAGE_SIZE : CACHE_LINE_SIZE;
193 return ((addr + align - 1) & ~(align - 1));
197 ia64_readin(int fd, vm_offset_t va, size_t len)
206 pa = ia64_va2pa(va, &sz);
209 s = read(fd, pa, sz);