source: trunk/packages/xen-common/xen-common/xen/arch/powerpc/of_handler/xencomm.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 2.4 KB
Line 
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
15 *
16 * Copyright (C) IBM Corp. 2006
17 *
18 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
19 */
20
21#include "ofh.h"
22
23static int __xencomm_init(struct xencomm_desc *desc, void *buffer,
24        unsigned long bytes)
25{
26    int recorded = 0;
27    int i = 0;
28
29    /* record the physical pages used */
30    while ((recorded < bytes) && (i < desc->nr_addrs)) {
31        unsigned long paddr = (unsigned long)buffer + recorded;
32        int offset;
33        int chunksz;
34
35        offset = (unsigned long)paddr % PAGE_SIZE; /* handle partial pages */
36        chunksz = MIN(PAGE_SIZE - offset, (unsigned long)bytes - recorded);
37
38        desc->address[i++] = paddr;
39        recorded += chunksz;
40    }
41
42    if (recorded < bytes)
43        return -1;
44
45    desc->magic = XENCOMM_MAGIC;
46
47    return 0;
48}
49
50static void *__xencomm_alloc_mini(void *area, int arealen)
51{
52    unsigned long base = (unsigned long)area;
53    unsigned int left_in_page;
54
55    left_in_page = PAGE_SIZE - base % PAGE_SIZE;
56
57    /* we probably fit right at the front of area */
58    if (left_in_page >= sizeof(struct xencomm_mini)) {
59        return area;
60    }
61
62    /* if not, see if area is big enough to advance to the next page */
63    if ((arealen - left_in_page) >= sizeof(struct xencomm_mini))
64        return (void *)(base + left_in_page);
65
66    /* area was too small */
67    return NULL;
68}
69
70/* allocate a xencomm_mini out of a preallocated memory area */
71int xencomm_create_mini(void *area, int arealen, void *buffer,
72            unsigned long bytes, struct xencomm_desc **ret)
73{
74    struct xencomm_desc *desc = __xencomm_alloc_mini(area, arealen);
75    if (!desc)
76        return -1;
77
78    desc->nr_addrs = XENCOMM_MINI_ADDRS;
79    if (__xencomm_init(desc, buffer, bytes))
80        return -1;
81
82    *ret = desc;
83    return 0;
84}
Note: See TracBrowser for help on using the repository browser.