Exemplo n.º 1
0
/* Initializes the block_list with info from a netlist */
void read_netlist(IN const char* net_file,
             IN int num_types,
             IN const struct s_type_descriptor block_types[],
             IN block_type_ptr IO_type,
             IN int io_ipin,
             IN int io_opin,
             OUT subblock_data_t* subblock_data_ptr,
             OUT int* num_blocks,
             OUT block_t* block_list[],
             OUT int* num_nets,
             OUT net_t* net_list[])
{
    int i, j, k, l, m;
    enum { COUNT, LOAD, MAP, STOP } pass;
    int line, prev_line;
    enum special_blk overide;
    char** block_tokens;
    char** pin_tokens;
    char** tokens;
    subblock_t** slist = NULL;
    int* scount = NULL;
    block_type_ptr type = NULL;
    FILE* infile = my_fopen(net_file, "r");
    int bcount = 0;
    block_t* blist = NULL;
    int ncount = 0;
    net_t* nlist = NULL;
    memset(subblock_data_ptr, 0, sizeof(subblock_data_t));

    /* Multi-pass load
     * COUNT
     *->count blocks
     *->count nets
     *
     * LOAD
     *->alloc num_subblocks_per_block list
     *->allocate s_block list at start
     *->allocate s_net list at start
     *->count subblocks per block
     *->sets block names
     *->sets block types
     *->allocs block net lists
     *->sets net names
     *
     * MAP
     *->fills in s_block:nets list
     *->fills in subblocks */

    for (pass = 0; pass < STOP; ++pass) {
        rewind(infile);
        line = 0;
        i = 0;
        j = 0;
        overide = NORMAL;

        /* Alloc the lists */
        if (LOAD == pass) {
            blist = (block_t*)my_malloc(sizeof(block_t) *
                                           bcount);
            memset(blist, 0, (sizeof(block_t) * bcount));

            nlist = (net_t*)my_malloc(sizeof(net_t) *
                                         ncount);
            memset(nlist, 0, (sizeof(net_t) * ncount));

            slist = (subblock_t**) my_malloc(sizeof(subblock_t*) *
                                         bcount);
            memset(slist, 0, (sizeof(subblock_t*) * bcount));

            scount = (int*)my_malloc(sizeof(int) * bcount);
            memset(scount, 0, (sizeof(int) * bcount));
        }

        /* Read file line by line */
        block_tokens = ReadLineTokens(infile, &line);
        prev_line = line;

        while (block_tokens) {
            /* .global directives have special meaning */
            if (0 == strcmp(block_tokens[0], ".global")) {
                if (MAP == pass) {
                    for (l = 0; l < ncount; ++l) {
                        if (0 == strcmp(nlist[l].name, block_tokens[1])) {
                            nlist[l].is_global = TRUE;
                            break;
                        }
                    }

                    if (l == ncount) {
                        printf(ERRTAG
                               "'%s':%d - '.global' specified an invalid net\n",
                               net_file, prev_line);
                        exit(1);
                    }
                }

                /* Don't do any more processing on this */
                FreeTokens(&block_tokens);
                block_tokens = ReadLineTokens(infile, &line);
                prev_line = line;
                continue;
            }

            pin_tokens = ReadLineTokens(infile, &line);

            if (CountTokens(block_tokens) != 2) {
                printf(ERRTAG "'%s':%d - block type line should "
                       "be in form '.type_name block_name'\n",
                       net_file, prev_line);
                exit(1);
            }

            if (NULL == pin_tokens) {
                printf(ERRTAG
                       "'%s':%d - blocks must be follow by a 'pinlist:' line\n",
                       net_file, line);
                exit(1);
            }

            if (0 != strcmp("pinlist:", pin_tokens[0])) {
                printf(ERRTAG
                       "'%s':%d - 'pinlist:' line must follow "
                       "block type line\n", net_file, line);
                exit(1);
            }

            type =
                get_type_by_name(block_tokens[0], num_types,
                                 block_types, IO_type, net_file,
                                 prev_line, &overide);

            /* Check if we are overiding the pinlist format for this block */
            if (overide) {
                if (CountTokens(pin_tokens) != 2) {
                    /* 'pinlist:' and name */
                    printf(ERRTAG
                           "'%s':%d - pinlist for .input and .output should "
                           "only have one item.\n", net_file,
                           line);
                    exit(1);
                }

                /* Make a new faked token list with 'pinlist:' and then pin mappings and a null */
                tokens = (char**)my_malloc(sizeof(char*) *
                                             (type->num_type_pins + 2));
                l = strlen(pinlist_str) + 1;
                k = strlen(pin_tokens[1]) + 1;
                tokens[0] = (char*)my_malloc(sizeof(char) * (k + l));
                memcpy(tokens[0], pinlist_str, l * sizeof(char));
                memcpy(tokens[0] + l, pin_tokens[1],
                       k * sizeof(char));

                /* Set all other pins to open */
                for (k = 0; k < type->num_type_pins; ++k) {
                    tokens[1 + k] = "open"; /* free wont be called on this so is safe */
                }

                tokens[1 + k] = NULL;   /* End of token list marker */

                /* Set the one pin with the value given */
                for (k = 0; k < type->num_type_pins; ++k) {
                    switch (overide) {
                        case INPAD:
                            tokens[1 + io_opin] = (tokens[0] + l);
                            break;

                        case OUTPAD:
                            tokens[1 + io_ipin] = (tokens[0] + l);
                            break;
                    }
                }

                FreeTokens(&pin_tokens);
                pin_tokens = tokens;
                tokens = NULL;
            }

            if (CountTokens(pin_tokens) != (type->num_type_pins + 1)) {
                printf(ERRTAG
                       "'%s':%d - 'pinlist:' line has %d pins instead of "
                       "expect %d pins.\n", net_file, line,
                       CountTokens(pin_tokens) - 1, type->num_type_pins);
                exit(1);
            }

            /* Load block name and type and alloc net list */
            if (LOAD == pass) {
                blist[i].name = my_strdup(block_tokens[1]);
                blist[i].block_type = type;

                blist[i].nets = (int*)my_malloc(sizeof(int) * type->num_type_pins);
                for (k = 0; k < type->num_type_pins; ++k) {
                    blist[i].nets[k] = OPEN;
                }
            }

            /* Examine pin list to determine nets */
            for (k = 0; k < type->num_type_pins; ++k) {
                if (0 != strcmp("open", pin_tokens[1 + k])) {
                    if (DRIVER == type->class_inf[type->pin_class[k]].type) {
                        if (LOAD == pass) {
                            nlist[j].name = my_strdup(pin_tokens[1 + k]);
                        }

                        if (MAP == pass) {
                            blist[i].nets[k] = j;   /* If we are net source we don't need to search */
                        }

                        ++j;    /* This was an active netlist */
                    } else {
                        if (MAP == pass) {
                            /* Map sinks by doing a linear search to find the net */
                            blist[i].nets[k] = OPEN;

                            for (l = 0; l < ncount; ++l) {
                                if (0 == strcmp(nlist[l].name,
                                                pin_tokens[1 + k])) {
                                    blist[i].nets[k] = l;
                                    break;
                                }
                            }

                            if (OPEN == blist[i].nets[k]) {
                                printf(ERRTAG
                                       "'%s':%d - Net '%s' not found\n",
                                       net_file,
                                       line,
                                       pin_tokens
                                       [1 + k]);
                                exit(1);
                            }
                        }
                    }
                }
            }

            /* Allocating subblocks */
            if (MAP == pass) {
                /* All blocks internally have subblocks but I/O subblocks are
                allocated and loaded elsewhere */
                if (scount[i] > 0) {
                    slist[i] = (subblock_t*)
                               my_malloc(sizeof(subblock_t) * scount[i]);

                    for (k = 0; k < scount[i]; ++k) {
                        slist[i][k].name = NULL;
                        slist[i][k].clock = OPEN;
                        slist[i][k].inputs =
                            (int*)my_malloc(sizeof(int) *
                                            type->max_subblock_inputs);

                        for (l = 0; l < type->max_subblock_inputs; ++l) {
                            slist[i][k].inputs[l] = OPEN;
                        }

                        slist[i][k].outputs =
                            (int*)my_malloc(sizeof(int) * type->max_subblock_outputs);

                        for (l = 0; l < type->max_subblock_outputs; ++l) {
                            slist[i][k].outputs[l] = OPEN;
                        }
                    }
                }
            }

            /* Ignore subblock data */
            tokens = ReadLineTokens(infile, &line);
            prev_line = line;
            m = 0;

            while (tokens && (0 == strcmp(tokens[0], "subblock:"))) {
                if (CountTokens(tokens) != (type->max_subblock_inputs + type->max_subblock_outputs + 1 + /* clocks */
                                            2)) {
                    /* 'subblock:', name */
                    printf("subblock wrong pin count, netlist has %d, architecture as %d on line %d \n" ,
                           CountTokens(tokens) - 2, (type->max_subblock_inputs + type->max_subblock_outputs + 1),
                           line);
                    exit(1);
                }

                /* Count subblocks given */
                if (LOAD == pass) {
                    scount[i]++;
                }

                /* Load subblock name */
                if (MAP == pass) {
                    assert(i < bcount);
                    assert(m < scount[i]);
                    slist[i][m].name = my_strdup(tokens[1]);

                    for (k = 0; k < type->max_subblock_inputs; ++k) {
                        /* Check prefix and load pin num */
                        l = 2 + k;

                        if (0 == strncmp("ble_", tokens[l], 4)) {
                            /* Skip the 'ble_' part */
                            slist[i][m].inputs[k] = type->num_type_pins + my_atoi(tokens[l] + 4);
                        } else if (0 != strcmp("open", tokens[l])) {
                            slist[i][m].inputs[k] = my_atoi(tokens[l]);
                        }
                    }

                    for (k = 0; k < type->max_subblock_outputs; ++k) {
                        l = 2 + type->max_subblock_inputs + k;

                        if (0 != strcmp("open", tokens[l])) {
                            slist[i][m].outputs[k] = my_atoi(tokens[l]);
                        }
                    }

                    l = 2 + type->max_subblock_inputs + type->max_subblock_outputs;

                    if (0 != strcmp("open", tokens[l])) {
                        slist[i][m].clock = my_atoi(tokens[l]);
                    }
                }

                ++m;    /* Next subblock */
                FreeTokens(&tokens);
                tokens = ReadLineTokens(infile, &line);
                prev_line = line;
            }

            if (pass > COUNT) {
                /* Check num of subblocks read */
                if (scount[i] > type->max_subblocks) {
                    printf("too many subblocks on block [%d] %s\n", i, blist[i].name);
                    exit(1);
                }
            }

            ++i;    /* End of this block */
            FreeTokens(&block_tokens);
            FreeTokens(&pin_tokens);
            block_tokens = tokens;
        }

        /* Save counts */
        if (COUNT == pass) {
            bcount = i;
            ncount = j;
        }
    }

    fclose(infile);
    /* Builds mappings from each netlist to the blocks contained */
    sync_nets_to_blocks(bcount, blist, ncount, nlist);
    /* Send values back to caller */
    *num_blocks = bcount;
    *block_list = blist;
    *num_nets = ncount;
    *net_list = nlist;
    subblock_data_ptr->subblock_inf = slist;
    subblock_data_ptr->num_subblocks_per_block = scount;
}
Exemplo n.º 2
0
static int hi6220_set_platform_data(struct platform_device *pdev)
{
	unsigned int base;
	unsigned int size;
	unsigned int id;
	const char *heap_name;
	const char *type_name;
	enum ion_heap_type type;
	int ret;
	struct device_node *np;
	struct ion_platform_heap *p_data;
	const struct device_node *dt_node = pdev->dev.of_node;
	int index = 0;

	for_each_child_of_node(dt_node, np)
		num_heaps++;

	heaps_data = devm_kzalloc(&pdev->dev,
				  sizeof(struct ion_platform_heap *) *
				  num_heaps,
				  GFP_KERNEL);
	if (!heaps_data)
		return -ENOMEM;

	for_each_child_of_node(dt_node, np) {
		ret = of_property_read_string(np, "heap-name", &heap_name);
		if (ret < 0) {
			pr_err("check the name of node %s\n", np->name);
			continue;
		}

		ret = of_property_read_u32(np, "heap-id", &id);
		if (ret < 0) {
			pr_err("check the id %s\n", np->name);
			continue;
		}

		ret = of_property_read_u32(np, "heap-base", &base);
		if (ret < 0) {
			pr_err("check the base of node %s\n", np->name);
			continue;
		}

		ret = of_property_read_u32(np, "heap-size", &size);
		if (ret < 0) {
			pr_err("check the size of node %s\n", np->name);
			continue;
		}

		ret = of_property_read_string(np, "heap-type", &type_name);
		if (ret < 0) {
			pr_err("check the type of node %s\n", np->name);
			continue;
		}

		ret = get_type_by_name(type_name, &type);
		if (ret < 0) {
			pr_err("type name error %s!\n", type_name);
			continue;
		}
		pr_info("heap index %d : name %s base 0x%x size 0x%x id %d type %d\n",
			index, heap_name, base, size, id, type);

		p_data = devm_kzalloc(&pdev->dev,
				      sizeof(struct ion_platform_heap),
				      GFP_KERNEL);
		if (!p_data)
			return -ENOMEM;

		p_data->name = heap_name;
		p_data->base = base;
		p_data->size = size;
		p_data->id = id;
		p_data->type = type;

		heaps_data[index] = p_data;
		index++;
	}