char *sti64cpy( // CONCATENATE I64 NUMBER char *tgt, // - target location signed_64 value ) // - value to be concatenated { sprintf( tgt, "%lld", VAL64( value ) ); return strend( tgt ); }
uint64_t pci_cfgacc_get64(dev_info_t *rcdip, uint16_t bdf, uint16_t off) { pci_cfgacc_req_t req; PCI_CFGACC_FILLREQ(req, rcdip, bdf, off, 8, B_FALSE, 0); (*pci_cfgacc_acc_p)(&req); return (VAL64(&req)); }
static bool ReadValue64(const libunwindInfo* info, unw_word_t* addr, uint64_t* valp) { uint64_t value; if (!info->ReadMemory((PVOID)*addr, &value, sizeof(value))) { return false; } *addr += sizeof(value); *valp = VAL64(value); return true; }
void DumpMDefn( // DUMP MACRO DEFINITION char *p ) // - definition { int c; TOKEN tok; if( p == NULL ) return; for( ; (tok = *(TOKEN *)p) != T_NULL; ) { p += sizeof( TOKEN ); switch( tok ) { case T_CONSTANT: switch( *p++ ) { case TYP_FLOAT : case TYP_DOUBLE : case TYP_LONG_DOUBLE : for( ; (c = *p++) != '\0'; ) putchar( c ); break; default: printf( F_S64, VAL64( Constant64 ) ); p += sizeof( Constant64 ); break; } break; case T_ID: for( ; (c = *p++) != '\0'; ) { putchar( c ); } break; case T_STRING: putchar( '\"' ); for( ; (c = *p++) != '\0'; ) { putchar( c ); } putchar( '\"' ); break; case T_WHITE_SPACE: putchar( ' ' ); break; case T_BAD_CHAR: putchar( *p++ ); break; case T_MACRO_PARM: printf( "parm#%c", '1' + *p++ ); break; default: printf( "%s", Tokens[tok] ); break; } } putchar( '\n' ); }
void pci_cfgacc_acc(pci_cfgacc_req_t *req) { if (!req->write) VAL64(req) = (uint64_t)-1; if (!pci_cfgacc_valid(req)) return; if (req->write) { pci_cfgacc_set(req->rcdip, req->bdf, req->offset, req->size, VAL64(req)); } else { VAL64(req) = pci_cfgacc_get(req->rcdip, req->bdf, req->offset, req->size); switch (req->size) { case 1: VAL8(req) = (uint8_t)VAL64(req); break; case 2: VAL16(req) = (uint16_t)VAL64(req); break; case 4: VAL32(req) = (uint32_t)VAL64(req); break; case 8: /* fall through, no special handling needed */ default: break; } } }
static void pci_cfgacc_io(pci_cfgacc_req_t *req) { uint8_t bus, dev, func; uint16_t ioacc_offset; /* 4K config access with IO ECS */ bus = PCI_BDF_BUS(req->bdf); dev = PCI_BDF_DEV(req->bdf); func = PCI_BDF_FUNC(req->bdf); ioacc_offset = req->offset; switch (req->size) { case 1: if (req->write) (*pci_putb_func)(bus, dev, func, ioacc_offset, VAL8(req)); else VAL8(req) = (*pci_getb_func)(bus, dev, func, ioacc_offset); break; case 2: if (req->write) (*pci_putw_func)(bus, dev, func, ioacc_offset, VAL16(req)); else VAL16(req) = (*pci_getw_func)(bus, dev, func, ioacc_offset); break; case 4: if (req->write) (*pci_putl_func)(bus, dev, func, ioacc_offset, VAL32(req)); else VAL32(req) = (*pci_getl_func)(bus, dev, func, ioacc_offset); break; case 8: if (req->write) { (*pci_putl_func)(bus, dev, func, ioacc_offset, VAL64(req) & 0xffffffff); (*pci_putl_func)(bus, dev, func, ioacc_offset + 4, VAL64(req) >> 32); } else {
static void dumpPTreeNode( // DUMP A PARSE TREE NODE PTREE node ) // - node in parse tree { static char buffer[128]; // - debugging buffer char *node_name; // - name of node VSTK_CTL ctl; // - VSTK control information (nodes) VSTK_CTL dup; // - VSTK control information (duplicates) int dup_out; // - last duplicate printed VstkOpen( &ctl, sizeof( PTREE ), 32 ); VstkOpen( &dup, sizeof( PTREE ), 8 ); dup_out = -1; for( ; ; ) { switch( node->op ) { case PT_ERROR : printf( "PT_ERROR" F_BADDR " ***** ERROR TREE *****" F_EOL , node ); break; case PT_INT_CONSTANT : node_name = "PT_INT_CONSTANT"; printf( F_NAME F_BADDR " flags" F_HEX_4 " type" F_PTR , node_name , node , node->flags , node->type ); if( NULL == Integral64Type( node->type ) ) { printf( " integer" F_HEX_4 , node->u.int_constant ); } else { printf( " integer-64" F_S64 , VAL64( node->u.int64_constant ) ); } dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); break; case PT_FLOATING_CONSTANT : { char buffer[256]; BFCnvFS( node->u.floating_constant, buffer, 256 ); printf( "PT_FLOATING_CONSTANT" F_BADDR " flags" F_HEX_4 " float" F_CPP_FLOAT , node , node->flags , buffer ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); } break; case PT_STRING_CONSTANT : stvcpy( buffer, node->u.string->string, node->u.string->len ); printf( "PT_STRING_CONSTANT" F_BADDR " flags" F_HEX_4 " string" F_STRING , node , node->flags , buffer ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); break; case PT_ID : printf( "PT_ID" F_BADDR " flags" F_HEX_4 " cgop" F_STRING F_NL " id" F_PTR "=" F_STRING " id_cgop" F_STRING " u.id.scope" F_PTR , node , node->flags , DbgOperator( node->cgop ) , node->u.id.name , NameStr( node->u.id.name ) , DbgOperator( node->id_cgop ) , node->u.id.scope ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); break; case PT_TYPE : printf( "PT_TYPE" F_BADDR " cgop" F_STRING " flags" F_HEX_4 " next" F_PTR " scope" F_PTR , node , DbgOperator( node->cgop ) , node->flags , node->u.type.next , node->u.type.scope ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); break; case PT_SYMBOL : if( node->cgop == CO_NAME_THIS ) { printf( "PT_SYMBOL" F_BADDR " flags" F_HEX_4 " this " , node , node->flags ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); } else if( node->cgop == CO_NAME_CDTOR_EXTRA ) { printf( "PT_SYMBOL" F_BADDR " flags" F_HEX_4 " cdtor_extra_parm " , node , node->flags ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); } else { printf( "PT_SYMBOL" F_BADDR " flags" F_HEX_4 " cgop" F_STRING F_NL " symbol" F_PTR " result" F_PTR , node , node->flags , DbgOperator( node->cgop ) , node->u.symcg.symbol , node->u.symcg.result ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); DumpSymbol( node->u.symcg.symbol ); } break; case PT_UNARY : printf( "PT_UNARY" F_BADDR F_POINTS F_ADDR " flags" F_HEX_4 " cgop" F_STRING , node , node->u.subtree[0] , node->flags , DbgOperator( node->cgop ) ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); PUSH_NODE( ctl, node->u.subtree[0] ); break; case PT_BINARY : printf( "PT_BINARY" F_BADDR F_POINTS F_ADDR "," F_ADDR " flags" F_HEX_4 " cgop" F_STRING , node , node->u.subtree[0] , node->u.subtree[1] , node->flags , DbgOperator( node->cgop ) ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); PUSH_NODE( ctl, node->u.subtree[1] ); PUSH_NODE( ctl, node->u.subtree[0] ); break; case PT_DUP_EXPR : { PTREE *duped; // - duplicated expression printf( "PT_DUP_EXPR" F_BADDR F_POINTS F_ADDR " flags" F_HEX_4 " node" F_ADDR , node , node->u.dup.subtree[0] , node->flags , node->u.dup.node ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); if( node->u.subtree[0] != NULL ) { for( duped = VstkTop( &dup ) ; ; duped = VstkNext( &dup, duped ) ) { if( duped == NULL ) { PUSH_NODE( dup, node->u.subtree[0] ); } else if( *duped == node->u.subtree[0] ) { break; } } } } break; case PT_IC : printf( "PT_IC" F_BADDR " " F_NAME " value" F_ADDR , node , DbgIcOpcode( node->u.ic.opcode ) , node->u.ic.value.pvalue ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); break; default : printf( "***INVALID***" F_BADDR " flags" F_HEX_4 " op" F_HEX_1 , node , node->flags , node->op ); dumpNodeType( node ); dumpLocation( &node->locn ); dumpPtreeFlags( node ); break; } { PTREE *next; // - addr[next node] next = VstkPop( &ctl ); if( next != NULL ) { node = *next; } else { ++dup_out; if( dup_out > VstkDimension( &dup ) ) break; next = VstkIndex( &dup, dup_out ); printf( "--------------- duplicate ------------\n" ); node = *next; } } } VstkClose( &ctl ); VstkClose( &dup ); }
int pxtool_pcicfg_access(px_t *px_p, pcitool_reg_t *prg_p, uint64_t *data_p, boolean_t is_write) { pci_cfg_data_t data; on_trap_data_t otd; dev_info_t *dip = px_p->px_dip; px_pec_t *pec_p = px_p->px_pec_p; size_t size = PCITOOL_ACC_ATTR_SIZE(prg_p->acc_attr); int rval = 0; pci_cfgacc_req_t req; if ((size <= 0) || (size > 8)) { DBG(DBG_TOOLS, dip, "not supported size.\n"); prg_p->status = PCITOOL_INVALID_SIZE; return (ENOTSUP); } /* Alignment checking. */ if (!IS_P2ALIGNED(prg_p->offset, size)) { DBG(DBG_TOOLS, dip, "not aligned.\n"); prg_p->status = PCITOOL_NOT_ALIGNED; return (EINVAL); } mutex_enter(&pec_p->pec_pokefault_mutex); pec_p->pec_ontrap_data = &otd; req.rcdip = dip; req.bdf = PCI_GETBDF(prg_p->bus_no, prg_p->dev_no, prg_p->func_no); req.offset = prg_p->offset; req.size = size; req.write = is_write; if (is_write) { if (PCITOOL_ACC_IS_BIG_ENDIAN(prg_p->acc_attr)) data.qw = pxtool_swap_endian(*data_p, size); else data.qw = *data_p; switch (size) { case sizeof (uint8_t): data.b = (uint8_t)data.qw; break; case sizeof (uint16_t): data.w = (uint16_t)data.qw; break; case sizeof (uint32_t): data.dw = (uint32_t)data.qw; break; case sizeof (uint64_t): break; } DBG(DBG_TOOLS, dip, "put: bdf:%d,%d,%d, off:0x%"PRIx64", size:" "0x%"PRIx64", data:0x%"PRIx64"\n", prg_p->bus_no, prg_p->dev_no, prg_p->func_no, prg_p->offset, size, data.qw); pec_p->pec_safeacc_type = DDI_FM_ERR_POKE; if (!on_trap(&otd, OT_DATA_ACCESS)) { otd.ot_trampoline = (uintptr_t)&poke_fault; VAL64(&req) = data.qw; pci_cfgacc_acc(&req); } else rval = H_EIO; if (otd.ot_trap & OT_DATA_ACCESS) rval = H_EIO; } else { data.qw = 0; pec_p->pec_safeacc_type = DDI_FM_ERR_PEEK; if (!on_trap(&otd, OT_DATA_ACCESS)) { otd.ot_trampoline = (uintptr_t)&peek_fault; pci_cfgacc_acc(&req); data.qw = VAL64(&req); } else rval = H_EIO; switch (size) { case sizeof (uint8_t): data.qw = (uint64_t)data.b; break; case sizeof (uint16_t): data.qw = (uint64_t)data.w; break; case sizeof (uint32_t): data.qw = (uint64_t)data.dw; break; case sizeof (uint64_t): break; } DBG(DBG_TOOLS, dip, "get: bdf:%d,%d,%d, off:0x%"PRIx64", size:" "0x%"PRIx64", data:0x%"PRIx64"\n", prg_p->bus_no, prg_p->dev_no, prg_p->func_no, prg_p->offset, size, data.qw); *data_p = data.qw; if (PCITOOL_ACC_IS_BIG_ENDIAN(prg_p->acc_attr)) *data_p = pxtool_swap_endian(*data_p, size); } /* * Workaround: delay taking down safe access env. * For more info, see comments where pxtool_cfg_delay_usec is declared. */ if (pxtool_cfg_delay_usec > 0) drv_usecwait(pxtool_cfg_delay_usec); no_trap(); pec_p->pec_ontrap_data = NULL; pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; mutex_exit(&pec_p->pec_pokefault_mutex); if (rval != SUCCESS) { prg_p->status = PCITOOL_INVALID_ADDRESS; rval = EINVAL; } else prg_p->status = PCITOOL_SUCCESS; return (rval); }
/*! ****************************************************************************** @Function SYSMEMKM_AllocPages ******************************************************************************/ static IMG_RESULT AllocPages( SYSMEM_Heap * heap, IMG_UINT32 ui32Size, SYSMEMU_sPages * psPages, SYS_eMemAttrib eMemAttrib ) { IMG_UINT32 Res; dma_addr_t dma; unsigned numPages, pg_i; IMG_UINT64 *pCpuPhysAddrs; IMG_VOID **pCpuKernAddrs = IMG_NULL; size_t physAddrArrSize; // This heap only supports uncached | write-combined memory allocations IMG_ASSERT(eMemAttrib == (SYS_MEMATTRIB_UNCACHED | SYS_MEMATTRIB_WRITECOMBINE)); eMemAttrib = SYS_MEMATTRIB_UNCACHED | SYS_MEMATTRIB_WRITECOMBINE; numPages = (ui32Size + HOST_MMU_PAGE_SIZE - 1)/HOST_MMU_PAGE_SIZE; // Memory for physical addresses physAddrArrSize = sizeof(*pCpuPhysAddrs) * numPages; pCpuPhysAddrs = IMG_BIGORSMALL_ALLOC(physAddrArrSize); if (!pCpuPhysAddrs) { Res = IMG_ERROR_OUT_OF_MEMORY; goto errPhysAddrsAlloc; } psPages->pvCpuKmAddr = dma_alloc_coherent(NULL, ui32Size, &dma, GFP_KERNEL | __GFP_HIGHMEM); if (!psPages->pvCpuKmAddr) { pCpuKernAddrs = IMG_BIGORSMALL_ALLOC(numPages*(sizeof(IMG_VOID **))); if (!pCpuKernAddrs) { Res = IMG_ERROR_OUT_OF_MEMORY; goto errKernAddrsAlloc; } for (pg_i = 0; pg_i < numPages; ++pg_i) { pCpuKernAddrs[pg_i] = dma_alloc_coherent(NULL, PAGE_SIZE, &dma, GFP_KERNEL | __GFP_HIGHMEM); if (!pCpuKernAddrs[pg_i]) { Res = IMG_ERROR_OUT_OF_MEMORY; goto errPageAlloc; } pCpuPhysAddrs[pg_i] = VAL64(dma); } psPages->pvImplData = (IMG_VOID *)((long)pCpuKernAddrs | 1); } else { int paddr; psPages->pvImplData = (IMG_VOID *)dma; paddr = dma; for (pg_i = 0; pg_i < numPages; ++pg_i) { pCpuPhysAddrs[pg_i] = VAL64(paddr + (PAGE_SIZE * pg_i)); } } // Set pointer to physical address in structure psPages->ppaPhysAddr = pCpuPhysAddrs; Res = SYSBRGU_CreateMappableRegion(psPages->ppaPhysAddr[0], ui32Size, eMemAttrib, IMG_TRUE, psPages, &psPages->hRegHandle); DEBUG_REPORT(REPORT_MODULE_SYSMEM, "%s (unified) region of size %u phys 0x%llx", __FUNCTION__, ui32Size, psPages->ppaPhysAddr[0]); IMG_ASSERT(Res == IMG_SUCCESS); if (Res != IMG_SUCCESS) { goto errCreateMapRegion; } return IMG_SUCCESS; errCreateMapRegion: errPageAlloc: for (--pg_i; pg_i >= 0; pg_i--) { dma_free_coherent(NULL, PAGE_SIZE, pCpuKernAddrs[pg_i], psPages->ppaPhysAddr[pg_i]); } IMG_BIGORSMALL_FREE(numPages * sizeof(*pCpuKernAddrs), pCpuKernAddrs); errKernAddrsAlloc: IMG_BIGORSMALL_FREE(numPages * sizeof(*pCpuPhysAddrs), pCpuPhysAddrs); errPhysAddrsAlloc: return Res; }