Home | History | Annotate | Download | only in common
      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, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <sys/types.h>
     30 #include <sys/bitmap.h>
     31 #include <assert.h>
     32 #include <strings.h>
     33 #include <stdlib.h>
     34 
     35 #include <dt_regset.h>
     36 
     37 dt_regset_t *
     38 dt_regset_create(ulong_t size)
     39 {
     40 	ulong_t n = BT_BITOUL(size + 1); /* + 1 for %r0 */
     41 	dt_regset_t *drp = malloc(sizeof (dt_regset_t));
     42 
     43 	if (drp == NULL)
     44 		return (NULL);
     45 
     46 	drp->dr_bitmap = malloc(sizeof (ulong_t) * n);
     47 	drp->dr_size = size + 1;
     48 
     49 	if (drp->dr_bitmap == NULL) {
     50 		dt_regset_destroy(drp);
     51 		return (NULL);
     52 	}
     53 
     54 	bzero(drp->dr_bitmap, sizeof (ulong_t) * n);
     55 	return (drp);
     56 }
     57 
     58 void
     59 dt_regset_destroy(dt_regset_t *drp)
     60 {
     61 	free(drp->dr_bitmap);
     62 	free(drp);
     63 }
     64 
     65 void
     66 dt_regset_reset(dt_regset_t *drp)
     67 {
     68 	bzero(drp->dr_bitmap, sizeof (ulong_t) * BT_BITOUL(drp->dr_size));
     69 }
     70 
     71 int
     72 dt_regset_alloc(dt_regset_t *drp)
     73 {
     74 	ulong_t nbits = drp->dr_size - 1;
     75 	ulong_t maxw = nbits >> BT_ULSHIFT;
     76 	ulong_t wx;
     77 
     78 	for (wx = 0; wx <= maxw; wx++) {
     79 		if (drp->dr_bitmap[wx] != ~0UL)
     80 			break;
     81 	}
     82 
     83 	if (wx <= maxw) {
     84 		ulong_t maxb = (wx == maxw) ? nbits & BT_ULMASK : BT_NBIPUL - 1;
     85 		ulong_t word = drp->dr_bitmap[wx];
     86 		ulong_t bit, bx;
     87 		int reg;
     88 
     89 		for (bit = 1, bx = 0; bx <= maxb; bx++, bit <<= 1) {
     90 			if ((word & bit) == 0) {
     91 				reg = (int)((wx << BT_ULSHIFT) | bx);
     92 				BT_SET(drp->dr_bitmap, reg);
     93 				return (reg);
     94 			}
     95 		}
     96 	}
     97 
     98 	return (-1); /* no available registers */
     99 }
    100 
    101 void
    102 dt_regset_free(dt_regset_t *drp, int reg)
    103 {
    104 	assert(reg > 0 && reg < drp->dr_size);
    105 	assert(BT_TEST(drp->dr_bitmap, reg) != 0);
    106 	BT_CLEAR(drp->dr_bitmap, reg);
    107 }
    108