]>
Commit | Line | Data |
---|---|---|
3affbe6d BB |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License (the "License"). | |
6 | * You may not use this file except in compliance with the License. | |
7 | * | |
8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 | * or http://www.opensolaris.org/os/licensing. | |
10 | * See the License for the specific language governing permissions | |
11 | * and limitations under the License. | |
12 | * | |
13 | * When distributing Covered Code, include this CDDL HEADER in each | |
14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 | * If applicable, add the following below this CDDL HEADER, with the | |
16 | * fields enclosed by brackets "[]" replaced with your own identifying | |
17 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 | * | |
19 | * CDDL HEADER END | |
20 | */ | |
21 | ||
22 | /* | |
23 | * Copyright 2006 Sun Microsystems, Inc. All rights reserved. | |
24 | * Use is subject to license terms. | |
25 | */ | |
26 | ||
3affbe6d BB |
27 | #include <sys/isa_defs.h> |
28 | #include <sys/nvpair.h> | |
29 | #include <sys/sysmacros.h> | |
3affbe6d BB |
30 | |
31 | /* | |
32 | * This allocator is very simple. | |
33 | * - it uses a pre-allocated buffer for memory allocations. | |
34 | * - it does _not_ free memory in the pre-allocated buffer. | |
35 | * | |
4e33ba4c | 36 | * The reason for the selected implementation is simplicity. |
3affbe6d BB |
37 | * This allocator is designed for the usage in interrupt context when |
38 | * the caller may not wait for free memory. | |
39 | */ | |
40 | ||
41 | /* pre-allocated buffer for memory allocations */ | |
42 | typedef struct nvbuf { | |
43 | uintptr_t nvb_buf; /* address of pre-allocated buffer */ | |
44 | uintptr_t nvb_lim; /* limit address in the buffer */ | |
45 | uintptr_t nvb_cur; /* current address in the buffer */ | |
46 | } nvbuf_t; | |
47 | ||
48 | /* | |
49 | * Initialize the pre-allocated buffer allocator. The caller needs to supply | |
50 | * | |
51 | * buf address of pre-allocated buffer | |
52 | * bufsz size of pre-allocated buffer | |
53 | * | |
54 | * nv_fixed_init() calculates the remaining members of nvbuf_t. | |
55 | */ | |
56 | static int | |
57 | nv_fixed_init(nv_alloc_t *nva, va_list valist) | |
58 | { | |
59 | uintptr_t base = va_arg(valist, uintptr_t); | |
60 | uintptr_t lim = base + va_arg(valist, size_t); | |
61 | nvbuf_t *nvb = (nvbuf_t *)P2ROUNDUP(base, sizeof (uintptr_t)); | |
62 | ||
63 | if (base == 0 || (uintptr_t)&nvb[1] > lim) | |
64 | return (EINVAL); | |
65 | ||
66 | nvb->nvb_buf = (uintptr_t)&nvb[0]; | |
67 | nvb->nvb_cur = (uintptr_t)&nvb[1]; | |
68 | nvb->nvb_lim = lim; | |
69 | nva->nva_arg = nvb; | |
70 | ||
71 | return (0); | |
72 | } | |
73 | ||
74 | static void * | |
75 | nv_fixed_alloc(nv_alloc_t *nva, size_t size) | |
76 | { | |
77 | nvbuf_t *nvb = nva->nva_arg; | |
78 | uintptr_t new = nvb->nvb_cur; | |
79 | ||
80 | if (size == 0 || new + size > nvb->nvb_lim) | |
81 | return (NULL); | |
82 | ||
83 | nvb->nvb_cur = P2ROUNDUP(new + size, sizeof (uintptr_t)); | |
84 | ||
85 | return ((void *)new); | |
86 | } | |
87 | ||
88 | /*ARGSUSED*/ | |
89 | static void | |
90 | nv_fixed_free(nv_alloc_t *nva, void *buf, size_t size) | |
91 | { | |
92 | /* don't free memory in the pre-allocated buffer */ | |
93 | } | |
94 | ||
95 | static void | |
96 | nv_fixed_reset(nv_alloc_t *nva) | |
97 | { | |
98 | nvbuf_t *nvb = nva->nva_arg; | |
99 | ||
100 | nvb->nvb_cur = (uintptr_t)&nvb[1]; | |
101 | } | |
102 | ||
103 | const nv_alloc_ops_t nv_fixed_ops_def = { | |
56d8d8ac MW |
104 | .nv_ao_init = nv_fixed_init, |
105 | .nv_ao_fini = NULL, | |
106 | .nv_ao_alloc = nv_fixed_alloc, | |
107 | .nv_ao_free = nv_fixed_free, | |
108 | .nv_ao_reset = nv_fixed_reset | |
3affbe6d BB |
109 | }; |
110 | ||
111 | const nv_alloc_ops_t *nv_fixed_ops = &nv_fixed_ops_def; | |
c28b2279 | 112 | |
93ce2b4c | 113 | #if defined(_KERNEL) |
c28b2279 BB |
114 | EXPORT_SYMBOL(nv_fixed_ops); |
115 | #endif |