2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * MD primitives supporting placement of module data
30 * XXX should check load address/size against memory top.
36 #define READIN_BUF (4 * 1024)
37 #define PAGE_SIZE 0x1000
38 #define PAGE_MASK 0x0fff
39 #define MAPMEM_PAGE_INC 128 /* Half-MB at a time */
42 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
45 ofw_mapmem(vm_offset_t dest
, const size_t len
)
51 static vm_offset_t last_dest
= 0;
52 static size_t last_len
= 0;
56 * Check to see if this region fits in a prior mapping.
57 * Allocations are generally sequential, so only check
60 if (dest
>= last_dest
&&
61 (dest
+ len
) <= (last_dest
+ last_len
)) {
66 * Trim area covered by existing mapping, if any
68 if (dest
< (last_dest
+ last_len
) && dest
>= last_dest
) {
69 nlen
-= (last_dest
+ last_len
) - dest
;
70 dest
= last_dest
+ last_len
;
73 destp
= (void *)(dest
& ~PAGE_MASK
);
74 resid
= dest
& PAGE_MASK
;
77 * To avoid repeated mappings on small allocations,
78 * never map anything less than MAPMEM_PAGE_INC pages at a time
80 if ((nlen
+ resid
) < PAGE_SIZE
*MAPMEM_PAGE_INC
) {
81 dlen
= PAGE_SIZE
*MAPMEM_PAGE_INC
;
83 dlen
= roundup(nlen
+ resid
, PAGE_SIZE
);
85 if (OF_call_method("claim", memory
, 3, 1, destp
, dlen
, 0, &addr
)
87 printf("ofw_mapmem: physical claim failed\n");
92 * We only do virtual memory management when real_mode is false.
95 if (OF_call_method("claim", mmu
, 3, 1, destp
, dlen
, 0, &addr
)
97 printf("ofw_mapmem: virtual claim failed\n");
101 if (OF_call_method("map", mmu
, 4, 0, destp
, destp
, dlen
, 0)
103 printf("ofw_mapmem: map failed\n");
107 last_dest
= (vm_offset_t
) destp
;
114 ofw_copyin(const void *src
, vm_offset_t dest
, const size_t len
)
116 if (ofw_mapmem(dest
, len
)) {
117 printf("ofw_copyin: map error\n");
121 bcopy(src
, (void *)dest
, len
);
126 ofw_copyout(const vm_offset_t src
, void *dest
, const size_t len
)
128 bcopy((void *)src
, dest
, len
);
133 ofw_readin(readin_handle_t fd
, vm_offset_t dest
, const size_t len
)
136 size_t resid
, chunk
, get
;
142 chunk
= min(READIN_BUF
, len
);
145 printf("ofw_readin: buf malloc failed\n");
149 if (ofw_mapmem(dest
, len
)) {
150 printf("ofw_readin: map error\n");
155 for (resid
= len
; resid
> 0; resid
-= got
, p
+= got
) {
156 get
= min(chunk
, resid
);
157 got
= VECTX_READ(fd
, buf
, get
);
161 printf("ofw_readin: read failed\n");
165 bcopy(buf
, (void *)p
, got
);
169 return (len
- resid
);