Beispiel #1
0
static int
ntb_map_pci_bars(struct ntb_softc *ntb)
{
	int rc;

	ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0);
	rc = map_pci_bar(ntb, map_mmr_bar, &ntb->bar_info[NTB_CONFIG_BAR]);
	if (rc != 0)
		return (rc);

	ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2);
	rc = map_pci_bar(ntb, map_memory_window_bar,
	    &ntb->bar_info[NTB_B2B_BAR_1]);
	if (rc != 0)
		return (rc);

	ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4);
	if (HAS_FEATURE(NTB_REGS_THRU_MW) && !HAS_FEATURE(NTB_SPLIT_BAR))
		rc = map_pci_bar(ntb, map_mmr_bar,
		    &ntb->bar_info[NTB_B2B_BAR_2]);
	else
		rc = map_pci_bar(ntb, map_memory_window_bar,
		    &ntb->bar_info[NTB_B2B_BAR_2]);
	if (!HAS_FEATURE(NTB_SPLIT_BAR))
		return (rc);

	ntb->bar_info[NTB_B2B_BAR_3].pci_resource_id = PCIR_BAR(5);
	if (HAS_FEATURE(NTB_REGS_THRU_MW))
		rc = map_pci_bar(ntb, map_mmr_bar,
		    &ntb->bar_info[NTB_B2B_BAR_3]);
	else
		rc = map_pci_bar(ntb, map_memory_window_bar,
		    &ntb->bar_info[NTB_B2B_BAR_3]);
	return (rc);
}
Beispiel #2
0
static void
configure_xeon_secondary_side_bars(struct ntb_softc *ntb)
{

	if (ntb->dev_type == NTB_DEV_USD) {
		ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, MBAR23_DSD_ADDR);
		if (HAS_FEATURE(NTB_REGS_THRU_MW))
			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
			    MBAR01_DSD_ADDR);
		else {
			if (HAS_FEATURE(NTB_SPLIT_BAR)) {
				ntb_reg_write(4, XEON_PBAR4XLAT_OFFSET,
				    MBAR4_DSD_ADDR);
				ntb_reg_write(4, XEON_PBAR5XLAT_OFFSET,
				    MBAR5_DSD_ADDR);
			} else
				ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
				    MBAR4_DSD_ADDR);
			/*
			 * B2B_XLAT_OFFSET is a 64-bit register but can only be
			 * written 32 bits at a time.
			 */
			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETL,
			    MBAR01_DSD_ADDR & 0xffffffff);
			ntb_reg_write(4, XEON_B2B_XLAT_OFFSETU,
			    MBAR01_DSD_ADDR >> 32);
		}
		ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_USD_ADDR);
		ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_USD_ADDR);
		if (HAS_FEATURE(NTB_SPLIT_BAR)) {
			ntb_reg_write(4, XEON_SBAR4BASE_OFFSET, MBAR4_USD_ADDR);
			ntb_reg_write(4, XEON_SBAR5BASE_OFFSET, MBAR5_USD_ADDR);
		} else
			ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR4_USD_ADDR);
	} else {
Beispiel #3
0
static void
configure_xeon_secondary_side_bars(struct ntb_softc *ntb)
{

	if (ntb->dev_type == NTB_DEV_USD) {
		ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR);
		if (HAS_FEATURE(NTB_REGS_THRU_MW))
			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
			    MBAR01_DSD_ADDR);
		else
			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
			    PBAR4XLAT_USD_ADDR);
		ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_USD_ADDR);
		ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_USD_ADDR);
		ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_USD_ADDR);
	} else {
		ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR);
		if (HAS_FEATURE(NTB_REGS_THRU_MW))
			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
			    MBAR01_USD_ADDR);
		else
			ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET,
			    PBAR4XLAT_DSD_ADDR);
		ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_DSD_ADDR);
		ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_DSD_ADDR);
		ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_DSD_ADDR);
	}
}
static void
cliWriteConfig(void) {
    int16_t result;
    if (!HAS_FEATURE(PPSEN) && (cfg.flags & FLAG_PPSEN)) {
        cli_puts("WARNING: PPS output not available on this hardware\r\n");
        cfg.flags &= ~FLAG_PPSEN;
    }
    if ((cfg.flags & (FLAG_GPSEXT | FLAG_GPSOUT)) == (FLAG_GPSEXT | FLAG_GPSOUT)) {
        cli_puts("WARNING: gps_ext_in and gps_ext_out are mutually exclusive.\r\n");
        cfg.flags &= ~FLAG_GPSOUT;
    }
    /* Check for more than one ntpkey type */
    result = 0;
    if (cfg.flags & FLAG_NTPKEY_MD5) {
        result++;
    }
    if (cfg.flags & FLAG_NTPKEY_SHA1) {
        result++;
    }
    if (result > 1) {
        cli_puts("WARNING: More than one ntpkey type specified\r\n");
        cfg.flags &= ~(FLAG_NTPKEY_MD5 | FLAG_NTPKEY_SHA1);
    }
    cli_puts("Writing EEPROM...\r\n");
    result = eeprom_write_cfg();
    if (result == EERR_OK) {
        cli_puts("OK\r\n");
        serial_drain(cl_out);
        vTaskDelay(pdMS_TO_TICKS(1000));
        NVIC_SystemReset();
    } else {
        show_eeprom_error(result);
    }
}
Beispiel #5
0
static int
map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
{
	int rc;
	uint8_t bar_size_bits = 0;

	bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
	    &bar->pci_resource_id, RF_ACTIVE);

	if (bar->pci_resource == NULL)
		return (ENXIO);

	save_bar_parameters(bar);
	/*
	 * Ivytown NTB BAR sizes are misreported by the hardware due to a
	 * hardware issue. To work around this, query the size it should be
	 * configured to by the device and modify the resource to correspond to
	 * this new size. The BIOS on systems with this problem is required to
	 * provide enough address space to allow the driver to make this change
	 * safely.
	 *
	 * Ideally I could have just specified the size when I allocated the
	 * resource like:
	 *  bus_alloc_resource(ntb->device,
	 *	SYS_RES_MEMORY, &bar->pci_resource_id, 0ul, ~0ul,
	 *	1ul << bar_size_bits, RF_ACTIVE);
	 * but the PCI driver does not honor the size in this call, so we have
	 * to modify it after the fact.
	 */
	if (HAS_FEATURE(NTB_BAR_SIZE_4K)) {
		if (bar->pci_resource_id == PCIR_BAR(2))
			bar_size_bits = pci_read_config(ntb->device,
			    XEON_PBAR23SZ_OFFSET, 1);
		else
			bar_size_bits = pci_read_config(ntb->device,
			    XEON_PBAR45SZ_OFFSET, 1);

		rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY,
		    bar->pci_resource, bar->pbase,
		    bar->pbase + (1ul << bar_size_bits) - 1);
		if (rc != 0) {
			device_printf(ntb->device,
			    "unable to resize bar\n");
			return (rc);
		}

		save_bar_parameters(bar);
	}

	/* Mark bar region as write combining to improve performance. */
	rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size,
	    VM_MEMATTR_WRITE_COMBINING);
	if (rc != 0) {
		device_printf(ntb->device,
		    "unable to mark bar as WRITE_COMBINING\n");
		return (rc);
	}
	return (0);
}
Beispiel #6
0
static void
ntb_detect_max_mw(struct ntb_softc *ntb)
{

	if (ntb->type == NTB_SOC) {
		ntb->limits.max_mw = SOC_MAX_MW;
		return;
	}

	if (HAS_FEATURE(NTB_SPLIT_BAR))
		ntb->limits.max_mw = XEON_HSXSPLIT_MAX_MW;
	else
		ntb->limits.max_mw = XEON_SNB_MAX_MW;
}
Beispiel #7
0
static void
main_thread(void *pdata) {
    QueueSetHandle_t qs;
    QueueSetMemberHandle_t active;

    ASSERT((qs = xQueueCreateSet(SERIAL_RX_SIZE * 3)));
    serial_start(cli_serial, 115200, qs);
    serial_start(&Serial4, 57600, qs);
    serial_start(&Serial5, cfg.gps_baud_rate ? cfg.gps_baud_rate : 57600, qs);
    cli_set_output(cli_serial);
    log_start(cli_serial);
    cl_enabled = 1;

    load_eeprom();
    cfg.flags &= ~FLAG_HOLDOVER_TEST;
    if (cfg.flags & FLAG_GPSEXT) {
        gps_serial = &Serial5;
    } else {
        gps_serial = &Serial4;
    }
    if (!cfg.holdover) {
        cfg.holdover = 60;
    }
    if (!cfg.loopstats_interval) {
        cfg.loopstats_interval = 60;
    }
    ppscapture_start();
    vtimer_start();
    tcpip_start();
    test_reset();
    cli_banner();
    if (!(cfg.flags & FLAG_GPSEXT)) {
        ublox_configure();
        if (HAS_FEATURE(PPSEN) && (cfg.flags & FLAG_PPSEN)) {
            GPIO_OFF(PPSEN);
        }
    }
    cl_enabled = 0;
    while (1) {
        watchdog_main = 5;
        active = xQueueSelectFromSet(qs, pdMS_TO_TICKS(1000));
        if (active == cli_serial->rx_q) {
            int16_t val = serial_get(cli_serial, TIMEOUT_NOBLOCK);
            ASSERT(val >= 0);
            cli_feed(val);
        } else if (active == gps_serial->rx_q) {
            int16_t val = serial_get(gps_serial, TIMEOUT_NOBLOCK);
            ASSERT(val >= 0);
            gps_byte_received(val);
            if (cfg.flags & FLAG_GPSOUT) {
                char tmp = val;
                serial_write(&Serial5, &tmp, 1);
            }
#if 0
        } else if (active == Serial5.rx_q) {
            char tmp = serial_get(&Serial5, TIMEOUT_NOBLOCK);
            serial_write(&Serial4, &tmp, 1);
#endif
        }
    }
}
Beispiel #8
0
		static void
createNativeEvents( )
{
		char name[64];
		char sanitized_name[PAPI_MAX_STR_LEN];
		char names[device_count][64];

		int i, nameLen = 0, j;
		int isUnique = 1;

		nvml_native_event_entry_t* entry;
		nvmlReturn_t ret;

		nvml_native_table = (nvml_native_event_entry_t*) papi_malloc( 
						sizeof(nvml_native_event_entry_t) * num_events ); 	
		memset( nvml_native_table, 0x0, sizeof(nvml_native_event_entry_t) * num_events );
		entry = &nvml_native_table[0];

		for (i=0; i < device_count; i++ ) {
				memset( names[i], 0x0, 64 );
				isUnique = 1;
				ret = nvmlDeviceGetName( devices[i], name, 64 );

				for (j=0; j < i; j++ ) 
				{
						if ( 0 == strncmp( name, names[j], 64 ) )
								isUnique = 0;
				}

				if ( isUnique ) {
						nameLen = strlen(name);
						strncpy(sanitized_name, name, PAPI_MAX_STR_LEN );
						for (j=0; j < nameLen; j++)
								if ( ' ' == sanitized_name[j] )
										sanitized_name[j] = '_';



						if ( HAS_FEATURE( features[i], FEATURE_CLOCK_INFO ) ) {
								sprintf( entry->name, "NVML.%s.graphics_clock", sanitized_name );
								strncpy(entry->description,"Graphics clock domain (MHz).", PAPI_MAX_STR_LEN );
								entry->options.clock = NVML_CLOCK_GRAPHICS;
								entry->type = FEATURE_CLOCK_INFO;
								entry++;

								sprintf( entry->name, "NVML.%s.sm_clock", sanitized_name);
								strncpy(entry->description,"SM clock domain (MHz).", PAPI_MAX_STR_LEN);
								entry->options.clock = NVML_CLOCK_SM;
								entry->type = FEATURE_CLOCK_INFO;
								entry++;

								sprintf( entry->name, "NVML.%s.memory_clock", sanitized_name);
								strncpy(entry->description,"Memory clock domain (MHz).", PAPI_MAX_STR_LEN);
								entry->options.clock = NVML_CLOCK_MEM;
								entry->type = FEATURE_CLOCK_INFO;
								entry++;
						}	

						if ( HAS_FEATURE( features[i], FEATURE_ECC_LOCAL_ERRORS ) ) { 
								sprintf(entry->name, "NVML.%s.l1_single_ecc_errors", sanitized_name);
								strncpy(entry->description,"L1 cache single bit ECC", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){
										.bits = NVML_SINGLE_BIT_ECC,
												.which_one = LOCAL_ECC_L1,
								};
								entry->type = FEATURE_ECC_LOCAL_ERRORS;
								entry++;

								sprintf(entry->name, "NVML.%s.l2_single_ecc_errors", sanitized_name);
								strncpy(entry->description,"L2 cache single bit ECC", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){
										.bits = NVML_SINGLE_BIT_ECC,
												.which_one = LOCAL_ECC_L2,
								};
								entry->type = FEATURE_ECC_LOCAL_ERRORS;
								entry++;

								sprintf(entry->name, "NVML.%s.memory_single_ecc_errors", sanitized_name);
								strncpy(entry->description,"Device memory single bit ECC", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){
										.bits = NVML_SINGLE_BIT_ECC,
												.which_one = LOCAL_ECC_MEM,
								};
								entry->type = FEATURE_ECC_LOCAL_ERRORS;
								entry++;

								sprintf(entry->name, "NVML.%s.regfile_single_ecc_errors", sanitized_name);
								strncpy(entry->description,"Register file single bit ECC", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){
										.bits = NVML_SINGLE_BIT_ECC,
												.which_one = LOCAL_ECC_REGFILE,
								};
								entry->type = FEATURE_ECC_LOCAL_ERRORS;
								entry++;

								sprintf(entry->name, "NVML.%s.1l_double_ecc_errors", sanitized_name);
								strncpy(entry->description,"L1 cache double bit ECC", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){
										.bits = NVML_DOUBLE_BIT_ECC,
												.which_one = LOCAL_ECC_L1,
								};
								entry->type = FEATURE_ECC_LOCAL_ERRORS;
								entry++;

								sprintf(entry->name, "NVML.%s.l2_double_ecc_errors", sanitized_name);
								strncpy(entry->description,"L2 cache double bit ECC", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){
										.bits = NVML_DOUBLE_BIT_ECC,
												.which_one = LOCAL_ECC_L2,
								};
								entry->type = FEATURE_ECC_LOCAL_ERRORS;
								entry++;

								sprintf(entry->name, "NVML.%s.memory_double_ecc_errors", sanitized_name);
								strncpy(entry->description,"Device memory double bit ECC", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){
										.bits = NVML_DOUBLE_BIT_ECC,
												.which_one = LOCAL_ECC_MEM,
								};
								entry->type = FEATURE_ECC_LOCAL_ERRORS;
								entry++;

								sprintf(entry->name, "NVML.%s.regfile_double_ecc_errors", sanitized_name);
								strncpy(entry->description,"Register file double bit ECC", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){
										.bits = NVML_DOUBLE_BIT_ECC,
												.which_one = LOCAL_ECC_REGFILE,
								};
								entry->type = FEATURE_ECC_LOCAL_ERRORS;
								entry++;
						}

						if ( HAS_FEATURE( features[i], FEATURE_FAN_SPEED ) ) {
								sprintf( entry->name, "NVML.%s.fan_speed", sanitized_name);
								strncpy(entry->description,"The fan speed expressed as a percent of the maximum, i.e. full speed is 100%", PAPI_MAX_STR_LEN);
								entry->type = FEATURE_FAN_SPEED;
								entry++;
						}

						if ( HAS_FEATURE( features[i], FEATURE_MAX_CLOCK ) ) {
								sprintf( entry->name, "NVML.%s.graphics_max_clock", sanitized_name);
								strncpy(entry->description,"Maximal Graphics clock domain (MHz).", PAPI_MAX_STR_LEN);
								entry->options.clock = NVML_CLOCK_GRAPHICS;
								entry->type = FEATURE_MAX_CLOCK;
								entry++;

								sprintf( entry->name, "NVML.%s.sm_max_clock", sanitized_name);
								strncpy(entry->description,"Maximal SM clock domain (MHz).", PAPI_MAX_STR_LEN);
								entry->options.clock = NVML_CLOCK_SM;
								entry->type = FEATURE_MAX_CLOCK;
								entry++;

								sprintf( entry->name, "NVML.%s.memory_max_clock", sanitized_name);
								strncpy(entry->description,"Maximal Memory clock domain (MHz).", PAPI_MAX_STR_LEN);
								entry->options.clock = NVML_CLOCK_MEM;
								entry->type = FEATURE_MAX_CLOCK;
								entry++;
						}

						if ( HAS_FEATURE( features[i], FEATURE_MEMORY_INFO ) ) {
								sprintf( entry->name, "NVML.%s.total_memory", sanitized_name);
								strncpy(entry->description,"Total installed FB memory (in bytes).", PAPI_MAX_STR_LEN);
								entry->options.which_one = MEMINFO_TOTAL_MEMORY;
								entry->type = FEATURE_MEMORY_INFO;
								entry++;

								sprintf( entry->name, "NVML.%s.unallocated_memory", sanitized_name);
								strncpy(entry->description,"Uncallocated FB memory (in bytes).", PAPI_MAX_STR_LEN);
								entry->options.which_one = MEMINFO_UNALLOCED;
								entry->type = FEATURE_MEMORY_INFO;
								entry++;

								sprintf( entry->name, "NVML.%s.allocated_memory", sanitized_name);
								strncpy(entry->description,	"Allocated FB memory (in bytes). Note that the driver/GPU always sets aside a small amount of memory for bookkeeping.", PAPI_MAX_STR_LEN);
								entry->options.which_one = MEMINFO_ALLOCED;
								entry->type = FEATURE_MEMORY_INFO;
								entry++;
						}

						if ( HAS_FEATURE( features[i], FEATURE_PERF_STATES ) ) {
								sprintf( entry->name, "NVML.%s.pstate", sanitized_name);
								strncpy(entry->description,"The performance state of the device.", PAPI_MAX_STR_LEN);
								entry->type = FEATURE_PERF_STATES;
								entry++;
						}

						if ( HAS_FEATURE( features[i], FEATURE_POWER ) ) {
								sprintf( entry->name, "NVML.%s.power", sanitized_name);
								strncpy(entry->description,"Power usage reading for the device, in miliwatts. This is the power draw for the entire board, including GPU, memory, etc.\n The reading is accurate to within a range of +/-5 watts.", PAPI_MAX_STR_LEN);
								entry->type = FEATURE_POWER;
								entry++;
						}

						if ( HAS_FEATURE( features[i], FEATURE_TEMP ) ) {
								sprintf( entry->name, "NVML.%s.temperature", sanitized_name);
								strncpy(entry->description,"Current temperature readings for the device, in degrees C.", PAPI_MAX_STR_LEN);
								entry->type = FEATURE_TEMP;
								entry++;
						}

						if ( HAS_FEATURE( features[i], FEATURE_ECC_TOTAL_ERRORS ) ) {
								sprintf( entry->name, "NVML.%s.total_ecc_errors", sanitized_name);
								strncpy(entry->description,"Total single bit errors.", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){ 
										.bits = NVML_SINGLE_BIT_ECC, 
								};
								entry->type = FEATURE_ECC_TOTAL_ERRORS;
								entry++;

								sprintf( entry->name, "NVML.%s.total_ecc_errors", sanitized_name);
								strncpy(entry->description,"Total double bit errors.", PAPI_MAX_STR_LEN);
								entry->options.ecc_opts = (struct local_ecc){ 
										.bits = NVML_DOUBLE_BIT_ECC, 
								};
								entry->type = FEATURE_ECC_TOTAL_ERRORS;
								entry++;
						}

						if ( HAS_FEATURE( features[i], FEATURE_UTILIZATION ) ) {
								sprintf( entry->name, "NVML.%s.gpu_utilization", sanitized_name);
								strncpy(entry->description,"Percent of time over the past second during which one or more kernels was executing on the GPU.", PAPI_MAX_STR_LEN);
								entry->options.which_one = GPU_UTILIZATION;
								entry->type = FEATURE_UTILIZATION;
								entry++;

								sprintf( entry->name, "NVML.%s.memory_utilization", sanitized_name);
								strncpy(entry->description,"Percent of time over the past second during which global (device) memory was being read or written.", PAPI_MAX_STR_LEN);
								entry->options.which_one = MEMORY_UTILIZATION;
								entry->type = FEATURE_UTILIZATION;
								entry++;
						}
						strncpy( names[i], name, 64); 
				}
		}
}
Beispiel #9
0
/*   hardware or reads values from the operatings system. */
		static int 
nvml_hardware_read( long long *value, int which_one)
		//, nvml_context_t *ctx)
{
		nvml_native_event_entry_t *entry;
		nvmlDevice_t handle;
		int cudaIdx = -1;

		entry = &nvml_native_table[which_one];
		*value = (long long) -1;
		/* replace entry->resources with the current cuda_device->nvml device */
		cudaGetDevice( &cudaIdx );

		if ( cudaIdx < 0 || cudaIdx > device_count )
			return PAPI_EINVAL;

		/* Make sure the device we are running on has the requested event */
		if ( !HAS_FEATURE( features[cudaIdx] , entry->type) ) 
				return PAPI_EINVAL;

		handle = devices[cudaIdx];

		switch (entry->type) {
				case FEATURE_CLOCK_INFO:
						*value =  getClockSpeed( 	handle, 
										(nvmlClockType_t)entry->options.clock );
						break;
				case FEATURE_ECC_LOCAL_ERRORS:
						*value = getEccLocalErrors( 	handle, 
										(nvmlEccBitType_t)entry->options.ecc_opts.bits, 
										(int)entry->options.ecc_opts.which_one);
						break;
				case FEATURE_FAN_SPEED:
						*value = getFanSpeed( handle );
						break;
				case FEATURE_MAX_CLOCK:
						*value = getMaxClockSpeed( 	handle, 
										(nvmlClockType_t)entry->options.clock );
						break;
				case FEATURE_MEMORY_INFO:
						*value = getMemoryInfo( 	handle, 
										(int)entry->options.which_one );
						break;
				case FEATURE_PERF_STATES:
						*value = getPState( handle );
						break;
				case FEATURE_POWER:
						*value = getPowerUsage( handle );
						break;
				case FEATURE_TEMP:
						*value = getTemperature( handle );
						break;
				case FEATURE_ECC_TOTAL_ERRORS:
						*value = getTotalEccErrors( 	handle, 
										(nvmlEccBitType_t)entry->options.ecc_opts.bits );
						break;
				case FEATURE_UTILIZATION:
						*value = getUtilization( 	handle, 
										(int)entry->options.which_one );
						break;
				default:
						return PAPI_EINVAL;
		}

		return PAPI_OK;


}
Beispiel #10
0
static int
ntb_setup_xeon(struct ntb_softc *ntb)
{

	ntb->reg_ofs.ldb	= XEON_PDOORBELL_OFFSET;
	ntb->reg_ofs.ldb_mask	= XEON_PDBMSK_OFFSET;
	ntb->reg_ofs.spad_local	= XEON_SPAD_OFFSET;
	ntb->reg_ofs.bar2_xlat	= XEON_SBAR2XLAT_OFFSET;
	ntb->reg_ofs.bar4_xlat	= XEON_SBAR4XLAT_OFFSET;
	if (HAS_FEATURE(NTB_SPLIT_BAR))
		ntb->reg_ofs.bar5_xlat = XEON_SBAR5XLAT_OFFSET;

	switch (ntb->conn_type) {
	case NTB_CONN_B2B:
		/*
		 * reg_ofs.rdb and reg_ofs.spad_remote are effectively ignored
		 * with the NTB_REGS_THRU_MW errata mode enabled.  (See
		 * ntb_ring_doorbell() and ntb_read/write_remote_spad().)
		 */
		ntb->reg_ofs.rdb	 = XEON_B2B_DOORBELL_OFFSET;
		ntb->reg_ofs.spad_remote = XEON_B2B_SPAD_OFFSET;

		ntb->limits.max_spads	 = XEON_MAX_SPADS;
		break;

	case NTB_CONN_RP:
		/*
		 * Every Xeon today needs NTB_REGS_THRU_MW, so punt on RP for
		 * now.
		 */
		KASSERT(HAS_FEATURE(NTB_REGS_THRU_MW),
		    ("Xeon without MW errata unimplemented"));
		device_printf(ntb->device,
		    "NTB-RP disabled to due hardware errata.\n");
		return (ENXIO);

	case NTB_CONN_TRANSPARENT:
	default:
		device_printf(ntb->device, "Connection type %d not supported\n",
		    ntb->conn_type);
		return (ENXIO);
	}

	/*
	 * There is a Xeon hardware errata related to writes to SDOORBELL or
	 * B2BDOORBELL in conjunction with inbound access to NTB MMIO space,
	 * which may hang the system.  To workaround this use the second memory
	 * window to access the interrupt and scratch pad registers on the
	 * remote system.
	 *
	 * There is another HW errata on the limit registers -- they can only
	 * be written when the base register is (?)4GB aligned and < 32-bit.
	 * This should already be the case based on the driver defaults, but
	 * write the limit registers first just in case.
	 */
	if (HAS_FEATURE(NTB_REGS_THRU_MW)) {
		/*
		 * Set the Limit register to 4k, the minimum size, to prevent
		 * an illegal access.
		 *
		 * XXX: Should this be PBAR5LMT / get_mw_size(, max_mw - 1)?
		 */
		ntb_reg_write(8, XEON_PBAR4LMT_OFFSET,
		    ntb_get_mw_size(ntb, 1) + 0x1000);
		/* Reserve the last MW for mapping remote spad */
		ntb->limits.max_mw--;
	} else
		/*
		 * Disable the limit register, just in case it is set to
		 * something silly.  A 64-bit write will also clear PBAR5LMT in
		 * split-bar mode, and this is desired.
		 */
		ntb_reg_write(8, XEON_PBAR4LMT_OFFSET, 0);

	ntb->reg_ofs.lnk_cntl	 = XEON_NTBCNTL_OFFSET;
	ntb->reg_ofs.lnk_stat	 = XEON_LINK_STATUS_OFFSET;
	ntb->reg_ofs.spci_cmd	 = XEON_PCICMD_OFFSET;

	ntb->limits.max_db_bits	 = XEON_MAX_DB_BITS;
	ntb->limits.msix_cnt	 = XEON_MSIX_CNT;
	ntb->bits_per_vector	 = XEON_DB_BITS_PER_VEC;

	/*
	 * HW Errata on bit 14 of b2bdoorbell register.  Writes will not be
	 * mirrored to the remote system.  Shrink the number of bits by one,
	 * since bit 14 is the last bit.
	 *
	 * On REGS_THRU_MW errata mode, we don't use the b2bdoorbell register
	 * anyway.  Nor for non-B2B connection types.
	 */
	if (HAS_FEATURE(NTB_B2BDOORBELL_BIT14) &&
	    !HAS_FEATURE(NTB_REGS_THRU_MW) &&
	    ntb->conn_type == NTB_CONN_B2B)
		ntb->limits.max_db_bits = XEON_MAX_DB_BITS - 1;

	configure_xeon_secondary_side_bars(ntb);

	/* Enable Bus Master and Memory Space on the secondary side */
	if (ntb->conn_type == NTB_CONN_B2B)
		ntb_reg_write(2, ntb->reg_ofs.spci_cmd,
		    PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);

	/* Enable link training */
	ntb_hw_link_up(ntb);

	return (0);
}