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 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <sys/types.h>
27#include <sys/param.h>
28#include <sys/systm.h>
29
30#include <sys/bootconf.h>
31#include <sys/kobj_impl.h>
32#include <sys/cmn_err.h>
33
34/*
35 * Standalone utility functions for use within krtld.
36 * Many platforms implement optimized platmod versions of
37 * utilities such as bcopy and any such are not yet available
38 * until the kernel is more completely stitched together.
39 * These standalones are referenced through vectors
40 * kobj_bzero, etc.  Throughout krtld, the usual utility
41 * is redefined to reference through the corresponding
42 * vector so that krtld may simply refer to bzero etc.
43 * as usual.  See kobj_impl.h.
44 */
45extern void vprintf(const char *, va_list);
46
47/*ARGSUSED*/
48static void
49vkprintf(void *op, const char *fmt, va_list adx)
50{
51	vprintf(fmt, adx);
52}
53
54static void
55kprintf(void *op, const char *fmt, ...)
56{
57	va_list adx;
58
59	va_start(adx, fmt);
60	vkprintf(op, fmt, adx);
61	va_end(adx);
62}
63
64static void
65stand_bzero(void *p_arg, size_t count)
66{
67	char zero = 0;
68	caddr_t p = p_arg;
69
70	while (count != 0)
71		*p++ = zero, count--;
72}
73
74static void
75stand_bcopy(const void *src_arg, void *dest_arg, size_t count)
76{
77	caddr_t src = (caddr_t)src_arg;
78	caddr_t dest = dest_arg;
79
80	if (src < dest && (src + count) > dest) {
81		/* overlap copy */
82		while (--count != -1)
83			*(dest + count) = *(src + count);
84	} else {
85		while (--count != -1)
86			*dest++ = *src++;
87	}
88}
89
90static size_t
91stand_strlcat(char *dst, const char *src, size_t dstsize)
92{
93	char *df = dst;
94	size_t left = dstsize;
95	size_t l1;
96	size_t l2 = strlen(src);
97	size_t copied;
98
99	while (left-- != 0 && *df != '\0')
100		df++;
101	l1 = df - dst;
102	if (dstsize == l1)
103		return (l1 + l2);
104
105	copied = l1 + l2 >= dstsize ? dstsize - l1 - 1 : l2;
106	bcopy(src, dst + l1, copied);
107	dst[l1+copied] = '\0';
108	return (l1 + l2);
109}
110
111/*
112 * Set up the krtld standalone utilty vectors
113 */
114void
115kobj_setup_standalone_vectors()
116{
117	_kobj_printf = bop_printf;
118	_vkobj_printf = vbop_printf;
119	kobj_bcopy = stand_bcopy;
120	kobj_bzero = stand_bzero;
121	kobj_strlcat = stand_strlcat;
122}
123
124/*
125 * Restore the kprintf/vkprintf/bcopy/bzero kobj vectors.
126 * We need to undefine the override macros to
127 * accomplish this.
128 *
129 * Do NOT add new code after the point or at least
130 * certainly not code using bcopy or bzero which would
131 * need to be vectored to the krtld equivalents.
132 */
133#undef	bcopy
134#undef	bzero
135#undef	strlcat
136
137void
138kobj_restore_vectors()
139{
140	_kobj_printf = kprintf;
141	_vkobj_printf = vkprintf;
142	kobj_bcopy = bcopy;
143	kobj_bzero = bzero;
144	kobj_strlcat = strlcat;
145}
146