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