ia64/xen-unstable

view extras/mini-os/arch/ia64/xencomm.c @ 13907:ac18d251df63

[IA64][MINIOS] Port of mini-os to ia64

ia64 specific parts of mini-os.

Minimal config:

# Kernel image file.
kernel = "mini-os.gz"
# Initial memory allocation (in megabytes) for the new domain.
memory = 64
# A name for your domain.
name = "Mini-OS"

Signed-off-by: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
author awilliam@xenbuild2.aw
date Thu Feb 15 13:13:36 2007 -0700 (2007-02-15)
parents
children 0fadd0476e03
line source
1 /*
2 * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
3 * Tristan Gingold <tristan.gingold@bull.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
20 /*
21 * This code is mostly taken from ia64-xen files xcom_mini.c and xencomm.c.
22 * Changes: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com
23 */
26 #include <os.h>
27 #include <hypervisor.h>
28 #include <xen/xencomm.h>
29 #include <xen/grant_table.h>
32 #define XENCOMM_MINI_ADDRS 3
33 struct xencomm_mini
34 {
35 struct xencomm_desc _desc;
36 uint64_t address[XENCOMM_MINI_ADDRS];
37 };
39 #define xen_guest_handle(hnd) ((hnd).p)
42 /* Translate virtual address to physical address. */
43 uint64_t
44 xencomm_vaddr_to_paddr(uint64_t vaddr)
45 {
46 if (IA64_RR_EXTR(vaddr) == 5)
47 return KERN_VIRT_2_PHYS(vaddr);
49 if (IA64_RR_EXTR(vaddr) == 7)
50 return __pa(vaddr);
52 return 0;
53 }
55 #define min(a,b) (((a) < (b)) ? (a) : (b))
56 static int
57 xencomm_init_desc(struct xencomm_desc *desc, void *buffer, unsigned long bytes)
58 {
59 unsigned long recorded = 0;
60 int i = 0;
62 if ((buffer == NULL) && (bytes > 0))
63 BUG();
65 /* record the physical pages used */
66 if (buffer == NULL)
67 desc->nr_addrs = 0;
69 while ((recorded < bytes) && (i < desc->nr_addrs)) {
70 unsigned long vaddr = (unsigned long)buffer + recorded;
71 unsigned long paddr;
72 int offset;
73 int chunksz;
75 offset = vaddr % PAGE_SIZE; /* handle partial pages */
76 chunksz = min(PAGE_SIZE - offset, bytes - recorded);
78 paddr = xencomm_vaddr_to_paddr(vaddr);
79 if (paddr == ~0UL) {
80 printk("%s: couldn't translate vaddr %lx\n",
81 __func__, vaddr);
82 return -EINVAL;
83 }
85 desc->address[i++] = SWAP(paddr);
86 recorded += chunksz;
87 }
88 if (recorded < bytes) {
89 printk("%s: could only translate %ld of %ld bytes\n",
90 __func__, recorded, bytes);
91 return -ENOSPC;
92 }
94 /* mark remaining addresses invalid (just for safety) */
95 while (i < desc->nr_addrs)
96 desc->address[i++] = SWAP(XENCOMM_INVALID);
97 desc->magic = SWAP(XENCOMM_MAGIC);
98 return 0;
99 }
101 static void *
102 xencomm_alloc_mini(struct xencomm_mini *area, int *nbr_area)
103 {
104 unsigned long base;
105 unsigned int pageoffset;
107 while (*nbr_area >= 0) {
108 /* Allocate an area. */
109 (*nbr_area)--;
111 base = (unsigned long)(area + *nbr_area);
112 pageoffset = base % PAGE_SIZE;
114 /* If the area does not cross a page, use it. */
115 if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini))
116 return &area[*nbr_area];
117 }
118 /* No more area. */
119 return NULL;
120 }
122 int
123 xencomm_create_mini(struct xencomm_mini *area, int *nbr_area,
124 void *buffer, unsigned long bytes,
125 struct xencomm_handle **ret)
126 {
127 struct xencomm_desc *desc;
128 int rc;
129 unsigned long res;
131 desc = xencomm_alloc_mini(area, nbr_area);
132 if (!desc)
133 return -ENOMEM;
134 desc->nr_addrs = XENCOMM_MINI_ADDRS;
136 rc = xencomm_init_desc(desc, buffer, bytes);
137 if (rc)
138 return rc;
140 res = xencomm_vaddr_to_paddr((unsigned long)desc);
141 if (res == ~0UL)
142 return -EINVAL;
144 *ret = (struct xencomm_handle*)res;
145 return 0;
146 }
148 static int
149 xencommize_mini_grant_table_op(struct xencomm_mini *xc_area, int *nbr_area,
150 unsigned int cmd, void *op, unsigned int count,
151 struct xencomm_handle **desc)
152 {
153 struct xencomm_handle *desc1;
154 unsigned int argsize=0;
155 int rc;
157 switch (cmd) {
158 case GNTTABOP_map_grant_ref:
159 argsize = sizeof(struct gnttab_map_grant_ref);
160 break;
161 case GNTTABOP_unmap_grant_ref:
162 argsize = sizeof(struct gnttab_unmap_grant_ref);
163 break;
164 case GNTTABOP_setup_table:
165 {
166 struct gnttab_setup_table *setup = op;
168 argsize = sizeof(*setup);
170 if (count != 1)
171 return -EINVAL;
172 rc = xencomm_create_mini
173 (xc_area, nbr_area,
174 xen_guest_handle(setup->frame_list),
175 setup->nr_frames
176 * sizeof(*xen_guest_handle(setup->frame_list)),
177 &desc1);
178 if (rc)
179 return rc;
180 set_xen_guest_handle(setup->frame_list, (void *)desc1);
181 break;
182 }
183 case GNTTABOP_dump_table:
184 argsize = sizeof(struct gnttab_dump_table);
185 break;
186 case GNTTABOP_transfer:
187 argsize = sizeof(struct gnttab_transfer);
188 break;
189 case GNTTABOP_copy:
190 argsize = sizeof(struct gnttab_copy);
191 break;
192 default:
193 printk("%s: unknown mini grant table op %d\n", __func__, cmd);
194 BUG();
195 }
197 rc = xencomm_create_mini(xc_area, nbr_area, op, count * argsize, desc);
199 return rc;
200 }
202 int
203 xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op,
204 unsigned int count)
205 {
206 int rc;
207 struct xencomm_handle *desc;
208 int nbr_area = 2;
209 struct xencomm_mini xc_area[2];
211 rc = xencommize_mini_grant_table_op(xc_area, &nbr_area,
212 cmd, op, count, &desc);
213 if (rc)
214 return rc;
215 return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
216 }
218 static void
219 gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop)
220 {
221 uint32_t flags;
223 flags = uop->flags;
225 if (flags & GNTMAP_host_map) {
226 if (flags & GNTMAP_application_map) {
227 printk("GNTMAP_application_map is not supported yet: "
228 "flags 0x%x\n", flags);
229 BUG();
230 }
231 if (flags & GNTMAP_contains_pte) {
232 printk("GNTMAP_contains_pte is not supported yet flags "
233 "0x%x\n", flags);
234 BUG();
235 }
236 } else if (flags & GNTMAP_device_map) {
237 printk("GNTMAP_device_map is not supported yet 0x%x\n", flags);
238 BUG();//XXX not yet. actually this flag is not used.
239 } else {
240 BUG();
241 }
242 }
244 int
245 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
246 {
247 if (cmd == GNTTABOP_map_grant_ref) {
248 unsigned int i;
249 for (i = 0; i < count; i++) {
250 gnttab_map_grant_ref_pre(
251 (struct gnttab_map_grant_ref*)uop + i);
252 }
253 }
254 return xencomm_mini_hypercall_grant_table_op(cmd, uop, count);
255 }