ofw_copy.c revision 124140
138712Smsmith/*-
238712Smsmith * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
338712Smsmith * All rights reserved.
438712Smsmith *
538712Smsmith * Redistribution and use in source and binary forms, with or without
638712Smsmith * modification, are permitted provided that the following conditions
738712Smsmith * are met:
838712Smsmith * 1. Redistributions of source code must retain the above copyright
938712Smsmith *    notice, this list of conditions and the following disclaimer.
1038712Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1138712Smsmith *    notice, this list of conditions and the following disclaimer in the
1238712Smsmith *    documentation and/or other materials provided with the distribution.
1338712Smsmith *
1438712Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1538712Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1638712Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1738712Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1838712Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1938712Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2038712Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2138712Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2238712Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2338712Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2438712Smsmith * SUCH DAMAGE.
2538712Smsmith */
26124140Sobrien
27124140Sobrien#include <sys/cdefs.h>
28124140Sobrien__FBSDID("$FreeBSD: head/sys/boot/ofw/libofw/ofw_copy.c 124140 2004-01-04 23:30:47Z obrien $");
29124140Sobrien
3038712Smsmith/*
3138712Smsmith * MD primitives supporting placement of module data
3238712Smsmith *
3338712Smsmith * XXX should check load address/size against memory top.
3438712Smsmith */
3538712Smsmith#include <stand.h>
3638712Smsmith
3767227Sobrien#include "libofw.h"
3838712Smsmith
3984617Sbenno#define	READIN_BUF	(4 * 1024)
40100318Sbenno#define	PAGE_SIZE	0x1000
41100318Sbenno#define	PAGE_MASK	0x0fff
4284617Sbenno
43100318Sbenno#define	roundup(x, y)	((((x)+((y)-1))/(y))*(y))
44100318Sbenno
4564188Sjhbssize_t
4667227Sobrienofw_copyin(const void *src, vm_offset_t dest, const size_t len)
4738712Smsmith{
48100318Sbenno	void	*destp, *addr;
49100318Sbenno	size_t	dlen;
50100318Sbenno
51100318Sbenno	destp = (void *)(dest & ~PAGE_MASK);
52100318Sbenno	dlen = roundup(len, PAGE_SIZE);
53100318Sbenno
54100318Sbenno	if (OF_call_method("claim", memory, 3, 1, destp, dlen, 0, &addr)
55100318Sbenno	    == -1) {
56100318Sbenno		printf("ofw_copyin: physical claim failed\n");
57100318Sbenno		return (0);
58100318Sbenno	}
59100318Sbenno
60100318Sbenno	if (OF_call_method("claim", mmu, 3, 1, destp, dlen, 0, &addr) == -1) {
61100318Sbenno		printf("ofw_copyin: virtual claim failed\n");
62100318Sbenno		return (0);
63100318Sbenno	}
64100318Sbenno
65100318Sbenno	if (OF_call_method("map", mmu, 4, 0, destp, destp, dlen, 0) == -1) {
66100318Sbenno		printf("ofw_copyin: map failed\n");
67100318Sbenno		return (0);
68100318Sbenno	}
69100318Sbenno
7084620Sbenno	bcopy(src, (void *)dest, len);
7184620Sbenno	return(len);
7238712Smsmith}
7338712Smsmith
7464188Sjhbssize_t
7567227Sobrienofw_copyout(const vm_offset_t src, void *dest, const size_t len)
7638764Smsmith{
7784620Sbenno	bcopy((void *)src, dest, len);
7884620Sbenno	return(len);
7938764Smsmith}
8038764Smsmith
8164188Sjhbssize_t
8267227Sobrienofw_readin(const int fd, vm_offset_t dest, const size_t len)
8338712Smsmith{
8484617Sbenno	void		*buf;
8584617Sbenno	size_t		resid, chunk, get;
8684617Sbenno	ssize_t		got;
8784617Sbenno	vm_offset_t	p;
8884617Sbenno
8984617Sbenno	p = dest;
9084617Sbenno
9184617Sbenno	chunk = min(READIN_BUF, len);
9284617Sbenno	buf = malloc(chunk);
9384617Sbenno	if (buf == NULL) {
9484617Sbenno		printf("ofw_readin: buf malloc failed\n");
9584617Sbenno		return(0);
9684617Sbenno	}
9784617Sbenno
9884617Sbenno	for (resid = len; resid > 0; resid -= got, p += got) {
9984617Sbenno		get = min(chunk, resid);
10084617Sbenno		got = read(fd, buf, get);
10184617Sbenno
10284617Sbenno		if (got <= 0) {
103123701Sgrehan			if (got < 0)
104123701Sgrehan				printf("ofw_readin: read failed\n");
10584617Sbenno			break;
10684617Sbenno		}
10784617Sbenno
108100318Sbenno		ofw_copyin(buf, p, got);
10984617Sbenno	}
11084617Sbenno
11184617Sbenno	free(buf);
11284617Sbenno	return(len - resid);
11338712Smsmith}
114