1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1994,1997-1998 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #ifndef _TNF_BUF_H 28*7c478bd9Sstevel@tonic-gate #define _TNF_BUF_H 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include <sys/tnf_com.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/machlock.h> 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 36*7c478bd9Sstevel@tonic-gate extern "C" { 37*7c478bd9Sstevel@tonic-gate #endif 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate /* 40*7c478bd9Sstevel@tonic-gate * Size of a TNF buffer block 41*7c478bd9Sstevel@tonic-gate */ 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #define TNF_BLOCK_SIZE 512 44*7c478bd9Sstevel@tonic-gate #define TNF_BLOCK_SHIFT 9 45*7c478bd9Sstevel@tonic-gate #define TNF_BLOCK_MASK ~(TNF_BLOCK_SIZE - 1) 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate /* 48*7c478bd9Sstevel@tonic-gate * Size of the file header and forwarding pointer (directory) area combined. 49*7c478bd9Sstevel@tonic-gate * Tag and data blocks start this many bytes into the file. 50*7c478bd9Sstevel@tonic-gate * The maximum size of this area is 64KB. 51*7c478bd9Sstevel@tonic-gate */ 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #define TNF_DIRECTORY_SIZE (4 * 1024) 54*7c478bd9Sstevel@tonic-gate #define TNFW_B_FW_ZONE TNF_DIRECTORY_SIZE 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * Reserved space for tag blocks, after directory area. 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate #define TNFW_B_TAG_RESERVE (28 * 1024) 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate #define TNFW_B_DATA_BLOCK_BEGIN (TNFW_B_FW_ZONE + TNFW_B_TAG_RESERVE) 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate /* 65*7c478bd9Sstevel@tonic-gate * Reserved directory entries, and their precomputed tags. These are byte 66*7c478bd9Sstevel@tonic-gate * offsets from start of file. 67*7c478bd9Sstevel@tonic-gate */ 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate #define TNF_DIRENT_FILE_HEADER (TNF_BLOCK_SIZE + 0) 70*7c478bd9Sstevel@tonic-gate #define TNF_DIRENT_BLOCK_HEADER (TNF_BLOCK_SIZE + 4) 71*7c478bd9Sstevel@tonic-gate #define TNF_DIRENT_ROOT (TNF_BLOCK_SIZE + 8) 72*7c478bd9Sstevel@tonic-gate #define TNF_DIRENT_LAST TNF_DIRENT_ROOT 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate #define TNF_FILE_HEADER_TAG \ 75*7c478bd9Sstevel@tonic-gate (TNF_REF32_MAKE_PERMANENT(TNF_DIRENT_FILE_HEADER) | TNF_REF32_T_TAG) 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate #define TNF_BLOCK_HEADER_TAG \ 78*7c478bd9Sstevel@tonic-gate (TNF_REF32_MAKE_PERMANENT(TNF_DIRENT_BLOCK_HEADER) | TNF_REF32_T_TAG) 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate #define TNF_ROOT_TAG \ 81*7c478bd9Sstevel@tonic-gate (TNF_REF32_MAKE_PERMANENT(TNF_DIRENT_ROOT) | TNF_REF32_T_TAG) 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate /* 84*7c478bd9Sstevel@tonic-gate * Allocation type: permanent or reusable 85*7c478bd9Sstevel@tonic-gate */ 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate enum tnf_alloc_mode { 88*7c478bd9Sstevel@tonic-gate TNF_ALLOC_REUSABLE = 0, 89*7c478bd9Sstevel@tonic-gate TNF_ALLOC_FIXED = 1 90*7c478bd9Sstevel@tonic-gate }; 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate /* 93*7c478bd9Sstevel@tonic-gate * Buffer status 94*7c478bd9Sstevel@tonic-gate */ 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate typedef enum { 97*7c478bd9Sstevel@tonic-gate TNFW_B_RUNNING = 0, 98*7c478bd9Sstevel@tonic-gate TNFW_B_NOBUFFER, 99*7c478bd9Sstevel@tonic-gate TNFW_B_BROKEN 100*7c478bd9Sstevel@tonic-gate } TNFW_B_STATE; 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* 103*7c478bd9Sstevel@tonic-gate * The STOPPED bit may be or-ed into the state field. 104*7c478bd9Sstevel@tonic-gate */ 105*7c478bd9Sstevel@tonic-gate #define TNFW_B_STOPPED 16 106*7c478bd9Sstevel@tonic-gate #define TNFW_B_SET_STOPPED(state) ((state) |= TNFW_B_STOPPED) 107*7c478bd9Sstevel@tonic-gate #define TNFW_B_UNSET_STOPPED(state) ((state) &= ~TNFW_B_STOPPED) 108*7c478bd9Sstevel@tonic-gate #define TNFW_B_IS_STOPPED(state) ((state) & TNFW_B_STOPPED) 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* 111*7c478bd9Sstevel@tonic-gate * Layout of the first block of TNF file (file header) 112*7c478bd9Sstevel@tonic-gate */ 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate typedef struct { 115*7c478bd9Sstevel@tonic-gate tnf_uint32_t magic; /* magic number */ 116*7c478bd9Sstevel@tonic-gate tnf_file_header_t com; /* common header */ 117*7c478bd9Sstevel@tonic-gate struct { 118*7c478bd9Sstevel@tonic-gate volatile ulong_t gen; /* generation */ 119*7c478bd9Sstevel@tonic-gate volatile ulong_t block[2]; /* block number */ 120*7c478bd9Sstevel@tonic-gate } next_alloc; 121*7c478bd9Sstevel@tonic-gate ulong_t next_tag_alloc; /* block counter */ 122*7c478bd9Sstevel@tonic-gate ulong_t next_fw_alloc; /* byte offset */ 123*7c478bd9Sstevel@tonic-gate lock_t lock; /* protects hint updates */ 124*7c478bd9Sstevel@tonic-gate /* Padding to end of block */ 125*7c478bd9Sstevel@tonic-gate } tnf_buf_file_header_t; 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate /* 128*7c478bd9Sstevel@tonic-gate * Per-thread write-control information 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate typedef struct tnfw_b_pos { 132*7c478bd9Sstevel@tonic-gate tnf_block_header_t *tnfw_w_block; 133*7c478bd9Sstevel@tonic-gate ushort_t tnfw_w_write_off; 134*7c478bd9Sstevel@tonic-gate uchar_t tnfw_w_dirty; 135*7c478bd9Sstevel@tonic-gate } TNFW_B_POS; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate typedef struct tnfw_b_wcb { 138*7c478bd9Sstevel@tonic-gate struct tnfw_b_pos tnfw_w_pos; 139*7c478bd9Sstevel@tonic-gate struct tnfw_b_pos tnfw_w_tag_pos; 140*7c478bd9Sstevel@tonic-gate } TNFW_B_WCB; 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate /* 143*7c478bd9Sstevel@tonic-gate * Global tracing state 144*7c478bd9Sstevel@tonic-gate */ 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate extern TNFW_B_STATE tnfw_b_state; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate /* 149*7c478bd9Sstevel@tonic-gate * Global trace buffer 150*7c478bd9Sstevel@tonic-gate */ 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate extern caddr_t tnf_buf; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate #define TNF_FILE_HEADER() ((tnf_buf_file_header_t *)tnf_buf) 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* 157*7c478bd9Sstevel@tonic-gate * External interface 158*7c478bd9Sstevel@tonic-gate */ 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate /* 161*7c478bd9Sstevel@tonic-gate * Allocate 'size' data bytes using 'wcb'; store result into 'buf'. 162*7c478bd9Sstevel@tonic-gate * This inlines the common trace case. 163*7c478bd9Sstevel@tonic-gate */ 164*7c478bd9Sstevel@tonic-gate #define TNFW_B_ALLOC(wcb, size, buf, typ) \ 165*7c478bd9Sstevel@tonic-gate { \ 166*7c478bd9Sstevel@tonic-gate TNFW_B_POS *xx_pos; \ 167*7c478bd9Sstevel@tonic-gate ushort_t xx_off, xx_nof; \ 168*7c478bd9Sstevel@tonic-gate tnf_block_header_t *xx_blk; \ 169*7c478bd9Sstevel@tonic-gate size_t xx_size; \ 170*7c478bd9Sstevel@tonic-gate \ 171*7c478bd9Sstevel@tonic-gate /* Round size up to a multiple of 8. */ \ 172*7c478bd9Sstevel@tonic-gate xx_size = (size + 7) & ~7; \ 173*7c478bd9Sstevel@tonic-gate xx_pos = &(wcb)->tnfw_w_pos; \ 174*7c478bd9Sstevel@tonic-gate xx_blk = xx_pos->tnfw_w_block; \ 175*7c478bd9Sstevel@tonic-gate xx_off = xx_pos->tnfw_w_write_off; \ 176*7c478bd9Sstevel@tonic-gate xx_nof = xx_off + xx_size; \ 177*7c478bd9Sstevel@tonic-gate if (xx_blk != NULL && xx_nof <= TNF_BLOCK_SIZE) { \ 178*7c478bd9Sstevel@tonic-gate buf = (typ)((char *)xx_blk + xx_off); \ 179*7c478bd9Sstevel@tonic-gate xx_pos->tnfw_w_write_off = xx_nof; \ 180*7c478bd9Sstevel@tonic-gate /* LINTED */ \ 181*7c478bd9Sstevel@tonic-gate *((int *)((char *)buf + xx_size - sizeof (int))) = 0; \ 182*7c478bd9Sstevel@tonic-gate } else \ 183*7c478bd9Sstevel@tonic-gate buf = tnfw_b_alloc((wcb), xx_size, TNF_ALLOC_REUSABLE);\ 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate /* 187*7c478bd9Sstevel@tonic-gate * Giveback words after new_pos. 188*7c478bd9Sstevel@tonic-gate */ 189*7c478bd9Sstevel@tonic-gate #define TNFW_B_GIVEBACK(wcb, new_pos) \ 190*7c478bd9Sstevel@tonic-gate ((wcb)->tnfw_w_pos.tnfw_w_write_off = \ 191*7c478bd9Sstevel@tonic-gate (((char *)(new_pos) \ 192*7c478bd9Sstevel@tonic-gate - (char *)((wcb)->tnfw_w_pos.tnfw_w_block) + 7) \ 193*7c478bd9Sstevel@tonic-gate & ~7), *(int *)(new_pos) = 0) 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate /* 196*7c478bd9Sstevel@tonic-gate * Commit transaction bytes allocated via 'pos' 197*7c478bd9Sstevel@tonic-gate */ 198*7c478bd9Sstevel@tonic-gate #define TNFW_B_COMMIT(pos) \ 199*7c478bd9Sstevel@tonic-gate { \ 200*7c478bd9Sstevel@tonic-gate tnf_block_header_t *xx_blk, *xx_nxt; \ 201*7c478bd9Sstevel@tonic-gate \ 202*7c478bd9Sstevel@tonic-gate xx_blk = (pos)->tnfw_w_block; \ 203*7c478bd9Sstevel@tonic-gate if (xx_blk != NULL) { \ 204*7c478bd9Sstevel@tonic-gate xx_blk->bytes_valid = (pos)->tnfw_w_write_off; \ 205*7c478bd9Sstevel@tonic-gate if ((pos)->tnfw_w_dirty) { \ 206*7c478bd9Sstevel@tonic-gate xx_nxt = xx_blk->next_block; \ 207*7c478bd9Sstevel@tonic-gate while (xx_nxt != NULL) { \ 208*7c478bd9Sstevel@tonic-gate xx_blk->next_block = NULL; \ 209*7c478bd9Sstevel@tonic-gate xx_blk = xx_nxt; \ 210*7c478bd9Sstevel@tonic-gate xx_nxt = xx_blk->next_block; \ 211*7c478bd9Sstevel@tonic-gate xx_blk->bytes_valid = TNF_BLOCK_SIZE;\ 212*7c478bd9Sstevel@tonic-gate lock_clear(&xx_blk->A_lock); \ 213*7c478bd9Sstevel@tonic-gate } \ 214*7c478bd9Sstevel@tonic-gate (pos)->tnfw_w_dirty = 0; \ 215*7c478bd9Sstevel@tonic-gate } \ 216*7c478bd9Sstevel@tonic-gate } \ 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate /* 220*7c478bd9Sstevel@tonic-gate * Rollback transaction bytes allocated via 'pos' 221*7c478bd9Sstevel@tonic-gate */ 222*7c478bd9Sstevel@tonic-gate #define TNFW_B_ROLLBACK(pos) \ 223*7c478bd9Sstevel@tonic-gate { \ 224*7c478bd9Sstevel@tonic-gate tnf_block_header_t *xx_blk, *xx_nxt; \ 225*7c478bd9Sstevel@tonic-gate \ 226*7c478bd9Sstevel@tonic-gate xx_blk = (pos)->tnfw_w_block; \ 227*7c478bd9Sstevel@tonic-gate if (xx_blk != NULL) { \ 228*7c478bd9Sstevel@tonic-gate (pos)->tnfw_w_write_off = xx_blk->bytes_valid; \ 229*7c478bd9Sstevel@tonic-gate if ((pos)->tnfw_w_dirty) { \ 230*7c478bd9Sstevel@tonic-gate xx_nxt = xx_blk->next_block; \ 231*7c478bd9Sstevel@tonic-gate while (xx_nxt != NULL) { \ 232*7c478bd9Sstevel@tonic-gate xx_blk->next_block = NULL; \ 233*7c478bd9Sstevel@tonic-gate xx_blk = xx_nxt; \ 234*7c478bd9Sstevel@tonic-gate xx_nxt = xx_blk->next_block; \ 235*7c478bd9Sstevel@tonic-gate lock_clear(&xx_blk->A_lock); \ 236*7c478bd9Sstevel@tonic-gate } \ 237*7c478bd9Sstevel@tonic-gate (pos)->tnfw_w_dirty = 0; \ 238*7c478bd9Sstevel@tonic-gate } \ 239*7c478bd9Sstevel@tonic-gate } \ 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate extern void tnfw_b_init_buffer(caddr_t, size_t); 243*7c478bd9Sstevel@tonic-gate extern void *tnfw_b_alloc(TNFW_B_WCB *, size_t, enum tnf_alloc_mode); 244*7c478bd9Sstevel@tonic-gate extern void *tnfw_b_fw_alloc(TNFW_B_WCB *); 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate #endif 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate #endif /* _TNF_BUF_H */ 251