Пример #1
0
int cvmx_l2c_get_core_way_partition(uint32_t core)
{
	uint32_t field;

	/* Validate the core number */
	if (core >= cvmx_octeon_num_cores())
		return -1;

	if (OCTEON_IS_MODEL(OCTEON_CN63XX))
		return cvmx_read_csr(CVMX_L2C_WPAR_PPX(core)) & 0xffff;

	/*
	 * Use the lower two bits of the coreNumber to determine the
	 * bit offset of the UMSK[] field in the L2C_SPAR register.
	 */
	field = (core & 0x3) * 8;

	/*
	 * Return the UMSK[] field from the appropriate L2C_SPAR
	 * register based on the coreNumber.
	 */

	switch (core & 0xC) {
	case 0x0:
		return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >> field;
	case 0x4:
		return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >> field;
	case 0x8:
		return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >> field;
	case 0xC:
		return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >> field;
	}
	return 0;
}
Пример #2
0
int cvmx_l2c_get_core_way_partition(uint32_t core)
{
    uint32_t    field;

    /* Validate the core number */
    if (core >= cvmx_octeon_num_cores())
        return -1;

    /* Use the lower two bits of the coreNumber to determine the bit offset
     * of the UMSK[] field in the L2C_SPAR register.
     */
    field = (core & 0x3) * 8;

    /* Return the UMSK[] field from the appropriate L2C_SPAR register based
     * on the coreNumber.
     */
    switch (core & 0xC)
    {
        case 0x0:
            return((cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >> field);
        case 0x4:
            if (OCTEON_IS_MODEL(OCTEON_CN38XX))
                return((cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >> field);
            else
                return 0;
        case 0x8:
            if (OCTEON_IS_MODEL(OCTEON_CN38XX))
                return((cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >> field);
            else
                return 0;
Пример #3
0
int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask)
{
	uint32_t field;
	uint32_t valid_mask;

	valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1;

	mask &= valid_mask;

	/* A UMSK setting which blocks all L2C Ways is an error on some chips */
	if (mask == valid_mask && !OCTEON_IS_MODEL(OCTEON_CN63XX))
		return -1;

	/* Validate the core number */
	if (core >= cvmx_octeon_num_cores())
		return -1;

	if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
		cvmx_write_csr(CVMX_L2C_WPAR_PPX(core), mask);
		return 0;
	}

	/*
	 * Use the lower two bits of core to determine the bit offset of the
	 * UMSK[] field in the L2C_SPAR register.
	 */
	field = (core & 0x3) * 8;

	/*
	 * Assign the new mask setting to the UMSK[] field in the appropriate
	 * L2C_SPAR register based on the core_num.
	 *
	 */
	switch (core & 0xC) {
	case 0x0:
		cvmx_write_csr(CVMX_L2C_SPAR0,
			       (cvmx_read_csr(CVMX_L2C_SPAR0) & ~(0xFF << field)) |
			       mask << field);
		break;
	case 0x4:
		cvmx_write_csr(CVMX_L2C_SPAR1,
			       (cvmx_read_csr(CVMX_L2C_SPAR1) & ~(0xFF << field)) |
			       mask << field);
		break;
	case 0x8:
		cvmx_write_csr(CVMX_L2C_SPAR2,
			       (cvmx_read_csr(CVMX_L2C_SPAR2) & ~(0xFF << field)) |
			       mask << field);
		break;
	case 0xC:
		cvmx_write_csr(CVMX_L2C_SPAR3,
			       (cvmx_read_csr(CVMX_L2C_SPAR3) & ~(0xFF << field)) |
			       mask << field);
		break;
	}
	return 0;
}
Пример #4
0
static void __init octeon_smp_setup(void)
{
	const int coreid = cvmx_get_core_num();
	int cpus;
	int id;
	struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();

#ifdef CONFIG_HOTPLUG_CPU
	int core_mask = octeon_get_boot_coremask();
	unsigned int num_cores = cvmx_octeon_num_cores();
#endif

	/* The present CPUs are initially just the boot cpu (CPU 0). */
	for (id = 0; id < NR_CPUS; id++) {
		set_cpu_possible(id, id == 0);
		set_cpu_present(id, id == 0);
	}

	__cpu_number_map[coreid] = 0;
	__cpu_logical_map[0] = coreid;

	/* The present CPUs get the lowest CPU numbers. */
	cpus = 1;
	for (id = 0; id < NR_CPUS; id++) {
		if ((id != coreid) && cvmx_coremask_is_core_set(&sysinfo->core_mask, id)) {
			set_cpu_possible(cpus, true);
			set_cpu_present(cpus, true);
			__cpu_number_map[id] = cpus;
			__cpu_logical_map[cpus] = id;
			cpus++;
		}
	}

#ifdef CONFIG_HOTPLUG_CPU
	/*
	 * The possible CPUs are all those present on the chip.	 We
	 * will assign CPU numbers for possible cores as well.	Cores
	 * are always consecutively numberd from 0.
	 */
	for (id = 0; setup_max_cpus && octeon_bootloader_entry_addr &&
		     id < num_cores && id < NR_CPUS; id++) {
		if (!(core_mask & (1 << id))) {
			set_cpu_possible(cpus, true);
			__cpu_number_map[id] = cpus;
			__cpu_logical_map[cpus] = id;
			cpus++;
		}
	}
#endif

	octeon_smp_hotplug_setup();
}
Пример #5
0
/*
 * Version of octeon_model_get_string() that takes buffer as argument,
 * as running early in u-boot static/global variables don't work when
 * running from flash.
 */
const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
{
	const char *family;
	const char *core_model;
	char pass[4];
	int clock_mhz;
	const char *suffix;
	union cvmx_l2d_fus3 fus3;
	int num_cores;
	union cvmx_mio_fus_dat2 fus_dat2;
	union cvmx_mio_fus_dat3 fus_dat3;
	char fuse_model[10];
	uint32_t fuse_data = 0;

	fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
	fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
	fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);

	num_cores = cvmx_octeon_num_cores();

	/* Make sure the non existant devices look disabled */
	switch ((chip_id >> 8) & 0xff) {
	case 6:		/* CN50XX */
	case 2:		/* CN30XX */
		fus_dat3.s.nodfa_dte = 1;
		fus_dat3.s.nozip = 1;
		break;
	case 4:		/* CN57XX or CN56XX */
		fus_dat3.s.nodfa_dte = 1;
		break;
	default:
		break;
	}

	/* Make a guess at the suffix */
	/* NSP = everything */
	/* EXP = No crypto */
	/* SCP = No DFA, No zip */
	/* CP = No DFA, No crypto, No zip */
	if (fus_dat3.s.nodfa_dte) {
		if (fus_dat2.s.nocrypto)
			suffix = "CP";
		else
			suffix = "SCP";
	} else if (fus_dat2.s.nocrypto)
		suffix = "EXP";
	else
		suffix = "NSP";

	/*
	 * Assume pass number is encoded using <5:3><2:0>. Exceptions
	 * will be fixed later.
	 */
	sprintf(pass, "%u.%u", ((chip_id >> 3) & 7) + 1, chip_id & 7);

	/*
	 * Use the number of cores to determine the last 2 digits of
	 * the model number. There are some exceptions that are fixed
	 * later.
	 */
	switch (num_cores) {
	case 16:
		core_model = "60";
		break;
	case 15:
		core_model = "58";
		break;
	case 14:
		core_model = "55";
		break;
	case 13:
		core_model = "52";
		break;
	case 12:
		core_model = "50";
		break;
	case 11:
		core_model = "48";
		break;
	case 10:
		core_model = "45";
		break;
	case 9:
		core_model = "42";
		break;
	case 8:
		core_model = "40";
		break;
	case 7:
		core_model = "38";
		break;
	case 6:
		core_model = "34";
		break;
	case 5:
		core_model = "32";
		break;
	case 4:
		core_model = "30";
		break;
	case 3:
		core_model = "25";
		break;
	case 2:
		core_model = "20";
		break;
	case 1:
		core_model = "10";
		break;
	default:
		core_model = "XX";
		break;
	}

	/* Now figure out the family, the first two digits */
	switch ((chip_id >> 8) & 0xff) {
	case 0:		/* CN38XX, CN37XX or CN36XX */
		if (fus3.cn38xx.crip_512k) {
			/*
			 * For some unknown reason, the 16 core one is
			 * called 37 instead of 36.
			 */
			if (num_cores >= 16)
				family = "37";
			else
				family = "36";
		} else
			family = "38";
		/*
		 * This series of chips didn't follow the standard
		 * pass numbering.
		 */
		switch (chip_id & 0xf) {
		case 0:
			strcpy(pass, "1.X");
			break;
		case 1:
			strcpy(pass, "2.X");
			break;
		case 3:
			strcpy(pass, "3.X");
			break;
		default:
			strcpy(pass, "X.X");
			break;
		}
		break;
	case 1:		/* CN31XX or CN3020 */
		if ((chip_id & 0x10) || fus3.cn31xx.crip_128k)
			family = "30";
		else
			family = "31";
		/*
		 * This series of chips didn't follow the standard
		 * pass numbering.
		 */
		switch (chip_id & 0xf) {
		case 0:
			strcpy(pass, "1.0");
			break;
		case 2:
			strcpy(pass, "1.1");
			break;
		default:
			strcpy(pass, "X.X");
			break;
		}
		break;
	case 2:		/* CN3010 or CN3005 */
		family = "30";
		/* A chip with half cache is an 05 */
		if (fus3.cn30xx.crip_64k)
			core_model = "05";
		/*
		 * This series of chips didn't follow the standard
		 * pass numbering.
		 */
		switch (chip_id & 0xf) {
		case 0:
			strcpy(pass, "1.0");
			break;
		case 2:
			strcpy(pass, "1.1");
			break;
		default:
			strcpy(pass, "X.X");
			break;
		}
		break;
	case 3:		/* CN58XX */
		family = "58";
		/* Special case. 4 core, no crypto */
		if ((num_cores == 4) && fus_dat2.cn38xx.nocrypto)
			core_model = "29";

		/* Pass 1 uses different encodings for pass numbers */
		if ((chip_id & 0xFF) < 0x8) {
			switch (chip_id & 0x3) {
			case 0:
				strcpy(pass, "1.0");
				break;
			case 1:
				strcpy(pass, "1.1");
				break;
			case 3:
				strcpy(pass, "1.2");
				break;
			default:
				strcpy(pass, "1.X");
				break;
			}
		}
		break;
	case 4:		/* CN57XX, CN56XX, CN55XX, CN54XX */
		if (fus_dat2.cn56xx.raid_en) {
			if (fus3.cn56xx.crip_1024k)
				family = "55";
			else
				family = "57";
			if (fus_dat2.cn56xx.nocrypto)
				suffix = "SP";
			else
				suffix = "SSP";
		} else {
			if (fus_dat2.cn56xx.nocrypto)
				suffix = "CP";
			else {
				suffix = "NSP";
				if (fus_dat3.s.nozip)
					suffix = "SCP";
			}
			if (fus3.cn56xx.crip_1024k)
				family = "54";
			else
				family = "56";
		}
		break;
	case 6:		/* CN50XX */
		family = "50";
		break;
	case 7:		/* CN52XX */
		if (fus3.cn52xx.crip_256k)
			family = "51";
		else
			family = "52";
		break;
	default:
		family = "XX";
		core_model = "XX";
		strcpy(pass, "X.X");
		suffix = "XXX";
		break;
	}

	clock_mhz = octeon_get_clock_rate() / 1000000;

	if (family[0] != '3') {
		/* Check for model in fuses, overrides normal decode */
		/* This is _not_ valid for Octeon CN3XXX models */
		fuse_data |= cvmx_fuse_read_byte(51);
		fuse_data = fuse_data << 8;
		fuse_data |= cvmx_fuse_read_byte(50);
		fuse_data = fuse_data << 8;
		fuse_data |= cvmx_fuse_read_byte(49);
		fuse_data = fuse_data << 8;
		fuse_data |= cvmx_fuse_read_byte(48);
		if (fuse_data & 0x7ffff) {
			int model = fuse_data & 0x3fff;
			int suffix = (fuse_data >> 14) & 0x1f;
			if (suffix && model) {
				/*
				 * Have both number and suffix in
				 * fuses, so both
				 */
				sprintf(fuse_model, "%d%c",
					model, 'A' + suffix - 1);
				core_model = "";
				family = fuse_model;
			} else if (suffix && !model) {
				/*
				 * Only have suffix, so add suffix to
				 * 'normal' model number.
				 */
				sprintf(fuse_model, "%s%c", core_model,
					'A' + suffix - 1);
				core_model = fuse_model;
			} else {
				/*
				 * Don't have suffix, so just use
				 * model from fuses.
				 */
				sprintf(fuse_model, "%d", model);
				core_model = "";
				family = fuse_model;
			}
		}
Пример #6
0
void __cvmx_pow_display_v2(void *buffer, int buffer_size)
{
    __cvmx_pow_dump_t *dump = (__cvmx_pow_dump_t*)buffer;
    int num_pow_entries = cvmx_pow_get_num_entries();
    int num_cores;
    int core;
    int index;
    uint8_t entry_list[2048];

    if (buffer_size < (int)sizeof(__cvmx_pow_dump_t))
    {
        cvmx_dprintf("cvmx_pow_dump: Buffer too small, pow_dump_t = 0x%x, buffer_size = 0x%x\n", (int)sizeof(__cvmx_pow_dump_t), buffer_size);
        return;
    }

    memset(entry_list, 0, sizeof(entry_list));
    num_cores = cvmx_octeon_num_cores();

    /* Print the free list info */
    {
        int valid[3], has_one[3], head[3], tail[3], qnum_head, qnum_tail;
        int idx;

        valid[0] = dump->sindexload[0][4].sindexload1_cn68xx.queue_val;
        valid[1] = dump->sindexload[0][5].sindexload1_cn68xx.queue_val;
        valid[2] = dump->sindexload[0][6].sindexload1_cn68xx.queue_val;
        has_one[0] = dump->sindexload[0][4].sindexload1_cn68xx.queue_one;
        has_one[1] = dump->sindexload[0][5].sindexload1_cn68xx.queue_one;
        has_one[2] = dump->sindexload[0][6].sindexload1_cn68xx.queue_one;
        head[0] = dump->sindexload[0][4].sindexload1_cn68xx.queue_head;
        head[1] = dump->sindexload[0][5].sindexload1_cn68xx.queue_head;
        head[2] = dump->sindexload[0][6].sindexload1_cn68xx.queue_head;
        tail[0] = dump->sindexload[0][4].sindexload1_cn68xx.queue_tail;
        tail[1] = dump->sindexload[0][5].sindexload1_cn68xx.queue_tail;
        tail[2] = dump->sindexload[0][6].sindexload1_cn68xx.queue_tail;
        qnum_head = dump->sindexload[0][4].sindexload1_cn68xx.qnum_head;
        qnum_tail = dump->sindexload[0][4].sindexload1_cn68xx.qnum_tail;

        printf("Free List: qnum_head=%d, qnum_tail=%d\n", qnum_head, qnum_tail);
        printf("Free0: valid=%d, one=%d, head=%llu, tail=%llu\n", valid[0], has_one[0], CAST64(head[0]), CAST64(tail[0]));
        printf("Free1: valid=%d, one=%d, head=%llu, tail=%llu\n", valid[1], has_one[1], CAST64(head[1]), CAST64(tail[1]));
        printf("Free2: valid=%d, one=%d, head=%llu, tail=%llu\n", valid[2], has_one[2], CAST64(head[2]), CAST64(tail[2]));
        
        idx=qnum_head;
        while (valid[0] || valid[1] || valid[2])
        {
            int qidx = idx % 3;

            if (head[qidx] == tail[qidx])
                valid[qidx] = 0;

            if (__cvmx_pow_entry_mark_list(head[qidx], CVMX_POW_LIST_FREE, entry_list))   
                break;
            head[qidx] = dump->smemload[head[qidx]][4].s_smemload3_cn68xx.fwd_index;
            //printf("qidx = %d, idx = %d, head[qidx] = %d\n", qidx, idx, head[qidx]);
            idx++;
        }
    }
            
    /* Print the core state */
    for (core = 0; core < num_cores; core++)
    {
        int pendtag = 1;
        int pendwqp = 2;
        int tag = 3;
        int wqp = 4;
        int links = 5;

        printf("Core %d State: tag=%s,0x%08x", core, 
               OCT_TAG_TYPE_STRING(dump->sstatus[core][tag].s_sstatus2_cn68xx.tag_type),
               dump->sstatus[core][tag].s_sstatus2_cn68xx.tag);
        if (dump->sstatus[core][tag].s_sstatus2_cn68xx.tag_type != CVMX_POW_TAG_TYPE_NULL_NULL)
        {
            __cvmx_pow_entry_mark_list(dump->sstatus[core][tag].s_sstatus2_cn68xx.index, CVMX_POW_LIST_CORE + core, entry_list);
            printf(" grp=%d",                   dump->sstatus[core][tag].s_sstatus2_cn68xx.grp);
            printf(" wqp=0x%016llx",            CAST64(dump->sstatus[core][wqp].s_sstatus3_cn68xx.wqp));
            printf(" index=%d",                 dump->sstatus[core][tag].s_sstatus2_cn68xx.index);
            if (dump->sstatus[core][links].s_sstatus4_cn68xx.head)
                printf(" head");
            else
                printf(" prev=%d", dump->sstatus[core][links].s_sstatus4_cn68xx.revlink_index);
            if (dump->sstatus[core][links].s_sstatus4_cn68xx.tail)
                printf(" tail");
            else
                printf(" next=%d", dump->sstatus[core][links].s_sstatus4_cn68xx.link_index);
        }
        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_switch)
        {
            printf(" pend_switch=%d",           dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_switch);
        }
                                                                                
        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_desched)
        {
            printf(" pend_desched=%d",          dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_desched);
            printf(" pend_nosched=%d",          dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_nosched);
        }
        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_get_work)
        {
            if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_get_work_wait)
                printf(" (Waiting for work)");
            else
                printf(" (Getting work)");
        }
        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_alloc_we)
            printf(" pend_alloc_we=%d",          dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_alloc_we);
        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_nosched_clr)
        {
            printf(" pend_nosched_clr=%d",      dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_nosched_clr);
            printf(" pend_index=%d",            dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_index);
        }
        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_switch)
        {
            printf(" pending tag=%s,0x%08x",
                   OCT_TAG_TYPE_STRING(dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_type),
                   dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_tag);
        }
        if (dump->sstatus[core][pendwqp].s_sstatus1_cn68xx.pend_nosched_clr)
            printf(" pend_wqp=0x%016llx\n",     CAST64(dump->sstatus[core][pendwqp].s_sstatus1_cn68xx.pend_wqp));
        printf("\n");
    }

    /* Print out the state of the nosched list and the 16 deschedule lists. */
    __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_NOSCHED, dump, entry_list,
                            dump->sindexload[0][3].sindexload0_cn68xx.queue_val,
                            dump->sindexload[0][3].sindexload0_cn68xx.queue_one,
                            dump->sindexload[0][3].sindexload0_cn68xx.queue_head,
                            dump->sindexload[0][3].sindexload0_cn68xx.queue_tail);
    for (index=0; index<64; index++)
    {
        __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_DESCHED + index, dump, entry_list,
                                dump->sindexload[index][2].sindexload0_cn68xx.queue_val,
                                dump->sindexload[index][2].sindexload0_cn68xx.queue_one,
                                dump->sindexload[index][2].sindexload0_cn68xx.queue_head,
                                dump->sindexload[index][2].sindexload0_cn68xx.queue_tail);
    }

    /* Print out the state of the 8 internal input queues */
    for (index=0; index<8; index++)
    {
        __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_INPUT + index, dump, entry_list,
                                dump->sindexload[index][1].sindexload0_cn68xx.queue_val,
                                dump->sindexload[index][1].sindexload0_cn68xx.queue_one,
                                dump->sindexload[index][1].sindexload0_cn68xx.queue_head,
                                dump->sindexload[index][1].sindexload0_cn68xx.queue_tail);
    }

    /* Print out the state of the 16 memory queues */
    for (index=0; index<8; index++)
    {
        const char *name;
        if (dump->sindexload[index][1].sindexload0_cn68xx.queue_head)
            name = "Queue %da Memory (is head)";
        else
            name = "Queue %da Memory";
        __cvmx_pow_display_list(name, index,
                                dump->sindexload[index][1].sindexload0_cn68xx.queue_val,
                                dump->sindexload[index][1].sindexload0_cn68xx.queue_one,
                                dump->sindexload[index][1].sindexload0_cn68xx.queue_head,
                                dump->sindexload[index][1].sindexload0_cn68xx.queue_tail);
        if (dump->sindexload[index+8][1].sindexload0_cn68xx.queue_head)
            name = "Queue %db Memory (is head)";
        else
            name = "Queue %db Memory";
        __cvmx_pow_display_list(name, index,
                                dump->sindexload[index+8][1].sindexload0_cn68xx.queue_val,
                                dump->sindexload[index+8][1].sindexload0_cn68xx.queue_one,
                                dump->sindexload[index+8][1].sindexload0_cn68xx.queue_head,
                                dump->sindexload[index+8][1].sindexload0_cn68xx.queue_tail);
    }

    /* Print out each of the internal POW entries. Each entry has a tag, group,
       wqe, and possibly a next pointer. The next pointer is only valid if this
       entry isn't make as a tail */
    for (index=0; index<num_pow_entries; index++)
    {
        printf("Entry %d(%-10s): tag=%s,0x%08x grp=%d wqp=0x%016llx", index,
               __cvmx_pow_list_names[entry_list[index]],
               OCT_TAG_TYPE_STRING(dump->smemload[index][1].s_smemload0_cn68xx.tag_type),
               dump->smemload[index][1].s_smemload0_cn68xx.tag,
               dump->smemload[index][2].s_smemload1_cn68xx.grp,
               CAST64(dump->smemload[index][2].s_smemload1_cn68xx.wqp));
        if (dump->smemload[index][1].s_smemload0_cn68xx.tail)
            printf(" tail");
        else
            printf(" next=%d", dump->smemload[index][4].s_smemload3_cn68xx.fwd_index);
        if (entry_list[index] >= CVMX_POW_LIST_DESCHED)
        {
            printf(" prev=%d", dump->smemload[index][4].s_smemload3_cn68xx.fwd_index);
            printf(" nosched=%d", dump->smemload[index][1].s_smemload1_cn68xx.nosched);
            if (dump->smemload[index][3].s_smemload2_cn68xx.pend_switch)
            {
                printf(" pending tag=%s,0x%08x",
                       OCT_TAG_TYPE_STRING(dump->smemload[index][3].s_smemload2_cn68xx.pend_type),
                       dump->smemload[index][3].s_smemload2_cn68xx.pend_tag);
            }
        }
        printf("\n");
    }
}
Пример #7
0
void __cvmx_pow_display_v1(void *buffer, int buffer_size)
{
    __cvmx_pow_dump_t *dump = (__cvmx_pow_dump_t*)buffer;
    int num_pow_entries = cvmx_pow_get_num_entries();
    int num_cores;
    int core;
    int index;
    uint8_t entry_list[2048];

    if (buffer_size < (int)sizeof(__cvmx_pow_dump_t))
    {
        cvmx_dprintf("cvmx_pow_dump: Buffer too small\n");
        return;
    }

    memset(entry_list, 0, sizeof(entry_list));
    num_cores = cvmx_octeon_num_cores();

    /* Print the free list info */
    __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_FREE, dump, entry_list,
                                     dump->sindexload[0][0].sindexload0.free_val,
                                     dump->sindexload[0][0].sindexload0.free_one,
                                     dump->sindexload[0][0].sindexload0.free_head,
                                     dump->sindexload[0][0].sindexload0.free_tail);

    /* Print the core state */
    for (core=0; core<num_cores; core++)
    {
        const int bit_rev = 1;
        const int bit_cur = 2;
        const int bit_wqp = 4;
        printf("Core %d State:  tag=%s,0x%08x", core,
               OCT_TAG_TYPE_STRING(dump->sstatus[core][bit_cur].s_sstatus2.tag_type),
               dump->sstatus[core][bit_cur].s_sstatus2.tag);
        if (dump->sstatus[core][bit_cur].s_sstatus2.tag_type != CVMX_POW_TAG_TYPE_NULL_NULL)
        {
            __cvmx_pow_entry_mark_list(dump->sstatus[core][bit_cur].s_sstatus2.index, CVMX_POW_LIST_CORE + core, entry_list);
            printf(" grp=%d",                   dump->sstatus[core][bit_cur].s_sstatus2.grp);
            printf(" wqp=0x%016llx",            CAST64(dump->sstatus[core][bit_cur|bit_wqp].s_sstatus4.wqp));
            printf(" index=%d",                 dump->sstatus[core][bit_cur].s_sstatus2.index);
            if (dump->sstatus[core][bit_cur].s_sstatus2.head)
                printf(" head");
            else
                printf(" prev=%d", dump->sstatus[core][bit_cur|bit_rev].s_sstatus3.revlink_index);
            if (dump->sstatus[core][bit_cur].s_sstatus2.tail)
                printf(" tail");
            else
                printf(" next=%d", dump->sstatus[core][bit_cur].s_sstatus2.link_index);
        }

        if (dump->sstatus[core][0].s_sstatus0.pend_switch)
        {
            printf(" pend_switch=%d",           dump->sstatus[core][0].s_sstatus0.pend_switch);
            printf(" pend_switch_full=%d",      dump->sstatus[core][0].s_sstatus0.pend_switch_full);
            printf(" pend_switch_null=%d",      dump->sstatus[core][0].s_sstatus0.pend_switch_null);
        }

        if (dump->sstatus[core][0].s_sstatus0.pend_desched)
        {
            printf(" pend_desched=%d",          dump->sstatus[core][0].s_sstatus0.pend_desched);
            printf(" pend_desched_switch=%d",   dump->sstatus[core][0].s_sstatus0.pend_desched_switch);
            printf(" pend_nosched=%d",          dump->sstatus[core][0].s_sstatus0.pend_nosched);
            if (dump->sstatus[core][0].s_sstatus0.pend_desched_switch)
                printf(" pend_grp=%d",              dump->sstatus[core][0].s_sstatus0.pend_grp);
        }

        if (dump->sstatus[core][0].s_sstatus0.pend_new_work)
        {
            if (dump->sstatus[core][0].s_sstatus0.pend_new_work_wait)
                printf(" (Waiting for work)");
            else
                printf(" (Getting work)");
        }
        if (dump->sstatus[core][0].s_sstatus0.pend_null_rd)
            printf(" pend_null_rd=%d",          dump->sstatus[core][0].s_sstatus0.pend_null_rd);
        if (dump->sstatus[core][0].s_sstatus0.pend_nosched_clr)
        {
            printf(" pend_nosched_clr=%d",      dump->sstatus[core][0].s_sstatus0.pend_nosched_clr);
            printf(" pend_index=%d",            dump->sstatus[core][0].s_sstatus0.pend_index);
        }
        if (dump->sstatus[core][0].s_sstatus0.pend_switch ||
            (dump->sstatus[core][0].s_sstatus0.pend_desched &&
            dump->sstatus[core][0].s_sstatus0.pend_desched_switch))
        {
            printf(" pending tag=%s,0x%08x",
                   OCT_TAG_TYPE_STRING(dump->sstatus[core][0].s_sstatus0.pend_type),
                   dump->sstatus[core][0].s_sstatus0.pend_tag);
        }
        if (dump->sstatus[core][0].s_sstatus0.pend_nosched_clr)
            printf(" pend_wqp=0x%016llx\n",     CAST64(dump->sstatus[core][bit_wqp].s_sstatus1.pend_wqp));
        printf("\n");
    }

    /* Print out the state of the nosched list and the 16 deschedule lists. */
    __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_NOSCHED, dump, entry_list,
                            dump->sindexload[0][2].sindexload1.nosched_val,
                            dump->sindexload[0][2].sindexload1.nosched_one,
                            dump->sindexload[0][2].sindexload1.nosched_head,
                            dump->sindexload[0][2].sindexload1.nosched_tail);
    for (index=0; index<16; index++)
    {
        __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_DESCHED + index, dump, entry_list,
                                dump->sindexload[index][2].sindexload1.des_val,
                                dump->sindexload[index][2].sindexload1.des_one,
                                dump->sindexload[index][2].sindexload1.des_head,
                                dump->sindexload[index][2].sindexload1.des_tail);
    }

    /* Print out the state of the 8 internal input queues */
    for (index=0; index<8; index++)
    {
        __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_INPUT + index, dump, entry_list,
                                dump->sindexload[index][0].sindexload0.loc_val,
                                dump->sindexload[index][0].sindexload0.loc_one,
                                dump->sindexload[index][0].sindexload0.loc_head,
                                dump->sindexload[index][0].sindexload0.loc_tail);
    }

    /* Print out the state of the 16 memory queues */
    for (index=0; index<8; index++)
    {
        const char *name;
        if (dump->sindexload[index][1].sindexload2.rmt_is_head)
            name = "Queue %da Memory (is head)";
        else
            name = "Queue %da Memory";
        __cvmx_pow_display_list(name, index,
                                dump->sindexload[index][1].sindexload2.rmt_val,
                                dump->sindexload[index][1].sindexload2.rmt_one,
                                dump->sindexload[index][1].sindexload2.rmt_head,
                                dump->sindexload[index][3].sindexload3.rmt_tail);
        if (dump->sindexload[index+8][1].sindexload2.rmt_is_head)
            name = "Queue %db Memory (is head)";
        else
            name = "Queue %db Memory";
        __cvmx_pow_display_list(name, index,
                                dump->sindexload[index+8][1].sindexload2.rmt_val,
                                dump->sindexload[index+8][1].sindexload2.rmt_one,
                                dump->sindexload[index+8][1].sindexload2.rmt_head,
                                dump->sindexload[index+8][3].sindexload3.rmt_tail);
    }

    /* Print out each of the internal POW entries. Each entry has a tag, group,
        wqe, and possibly a next pointer. The next pointer is only valid if this
        entry isn't make as a tail */
    for (index=0; index<num_pow_entries; index++)
    {
        printf("Entry %d(%-10s): tag=%s,0x%08x grp=%d wqp=0x%016llx", index,
               __cvmx_pow_list_names[entry_list[index]],
               OCT_TAG_TYPE_STRING(dump->smemload[index][0].s_smemload0.tag_type),
               dump->smemload[index][0].s_smemload0.tag,
               dump->smemload[index][0].s_smemload0.grp,
               CAST64(dump->smemload[index][2].s_smemload1.wqp));
        if (dump->smemload[index][0].s_smemload0.tail)
            printf(" tail");
        else
            printf(" next=%d", dump->smemload[index][0].s_smemload0.next_index);
        if (entry_list[index] >= CVMX_POW_LIST_DESCHED)
        {
            printf(" nosched=%d", dump->smemload[index][1].s_smemload2.nosched);
            if (dump->smemload[index][1].s_smemload2.pend_switch)
            {
                printf(" pending tag=%s,0x%08x",
                       OCT_TAG_TYPE_STRING(dump->smemload[index][1].s_smemload2.pend_type),
                       dump->smemload[index][1].s_smemload2.pend_tag);
            }
        }
        printf("\n");
    }
}
Пример #8
0
static int __cvmx_pow_capture_v2(void *buffer, int buffer_size)
{
    __cvmx_pow_dump_t *dump = (__cvmx_pow_dump_t*)buffer;
    int num_cores;
    int num_pow_entries = cvmx_pow_get_num_entries();
    int core;
    int index;
    int bits;

    if (buffer_size < (int)sizeof(__cvmx_pow_dump_t))
    {
        cvmx_dprintf("cvmx_pow_capture: Buffer too small\n");
        return -1;
    }

    num_cores = cvmx_octeon_num_cores();

    /* Read all core related state */
    for (core=0; core<num_cores; core++)
    {
        cvmx_pow_load_addr_t load_addr;
        load_addr.u64 = 0;
        load_addr.sstatus_cn68xx.mem_region = CVMX_IO_SEG;
        load_addr.sstatus_cn68xx.is_io = 1;
        load_addr.sstatus_cn68xx.did = CVMX_OCT_DID_TAG_TAG5;
        load_addr.sstatus_cn68xx.coreid = core;
        for (bits=1; bits<6; bits++)
        {
            load_addr.sstatus_cn68xx.opcode = bits;
            dump->sstatus[core][bits].u64 = cvmx_read_csr(load_addr.u64);
        }
    }
    /* Read all internal POW entries */
    for (index=0; index<num_pow_entries; index++)
    {
        cvmx_pow_load_addr_t load_addr;
        load_addr.u64 = 0;
        load_addr.smemload_cn68xx.mem_region = CVMX_IO_SEG;
        load_addr.smemload_cn68xx.is_io = 1;
        load_addr.smemload_cn68xx.did = CVMX_OCT_DID_TAG_TAG2;
        load_addr.smemload_cn68xx.index = index;
        for (bits=1; bits<5; bits++)
        {
            load_addr.smemload_cn68xx.opcode = bits;
            dump->smemload[index][bits].u64 = cvmx_read_csr(load_addr.u64);
        }
    }

    /* Read all group and queue pointers */
    for (index=0; index<64; index++)
    {
        cvmx_pow_load_addr_t load_addr;
        load_addr.u64 = 0;
        load_addr.sindexload_cn68xx.mem_region = CVMX_IO_SEG;
        load_addr.sindexload_cn68xx.is_io = 1;
        load_addr.sindexload_cn68xx.did = CVMX_OCT_DID_TAG_TAG3;
        load_addr.sindexload_cn68xx.qos_grp = index;
        for (bits=1; bits<7; bits++)
        {
            load_addr.sindexload_cn68xx.opcode = bits;
            dump->sindexload[index][bits].u64 = cvmx_read_csr(load_addr.u64);
        }
    }
    return 0;
}
Пример #9
0
static int __cvmx_pow_capture_v1(void *buffer, int buffer_size)
{
    __cvmx_pow_dump_t *dump = (__cvmx_pow_dump_t*)buffer;
    int num_cores;
    int num_pow_entries = cvmx_pow_get_num_entries();
    int core;
    int index;
    int bits;

    if (buffer_size < (int)sizeof(__cvmx_pow_dump_t))
    {
        cvmx_dprintf("cvmx_pow_capture: Buffer too small\n");
        return -1;
    }

    num_cores = cvmx_octeon_num_cores();

    /* Read all core related state */
    for (core=0; core<num_cores; core++)
    {
        cvmx_pow_load_addr_t load_addr;
        load_addr.u64 = 0;
        load_addr.sstatus.mem_region = CVMX_IO_SEG;
        load_addr.sstatus.is_io = 1;
        load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
        load_addr.sstatus.coreid = core;
        for (bits=0; bits<8; bits++)
        {
            load_addr.sstatus.get_rev = (bits & 1) != 0;
            load_addr.sstatus.get_cur = (bits & 2) != 0;
            load_addr.sstatus.get_wqp = (bits & 4) != 0;
            if ((load_addr.sstatus.get_cur == 0) && load_addr.sstatus.get_rev)
                dump->sstatus[core][bits].u64 = -1;
            else
                dump->sstatus[core][bits].u64 = cvmx_read_csr(load_addr.u64);
        }
    }

    /* Read all internal POW entries */
    for (index=0; index<num_pow_entries; index++)
    {
        cvmx_pow_load_addr_t load_addr;
        load_addr.u64 = 0;
        load_addr.smemload.mem_region = CVMX_IO_SEG;
        load_addr.smemload.is_io = 1;
        load_addr.smemload.did = CVMX_OCT_DID_TAG_TAG2;
        load_addr.smemload.index = index;
        for (bits=0; bits<3; bits++)
        {
            load_addr.smemload.get_des = (bits & 1) != 0;
            load_addr.smemload.get_wqp = (bits & 2) != 0;
            dump->smemload[index][bits].u64 = cvmx_read_csr(load_addr.u64);
        }
    }

    /* Read all group and queue pointers */
    for (index=0; index<16; index++)
    {
        cvmx_pow_load_addr_t load_addr;
        load_addr.u64 = 0;
        load_addr.sindexload.mem_region = CVMX_IO_SEG;
        load_addr.sindexload.is_io = 1;
        load_addr.sindexload.did = CVMX_OCT_DID_TAG_TAG3;
        load_addr.sindexload.qosgrp = index;
        for (bits=0; bits<4; bits++)
        {
            load_addr.sindexload.get_rmt =  (bits & 1) != 0;
            load_addr.sindexload.get_des_get_tail =  (bits & 2) != 0;
            /* The first pass only has 8 valid index values */
            if ((load_addr.sindexload.get_rmt == 0) &&
                (load_addr.sindexload.get_des_get_tail == 0) &&
                (index >= 8))
                dump->sindexload[index][bits].u64 = -1;
            else
                dump->sindexload[index][bits].u64 = cvmx_read_csr(load_addr.u64);
        }
    }
    return 0;
}