Ejemplo n.º 1
0
int config_L2(int size)
{
    int i;
    struct cpumask mask; 
    int cur_size = get_l2c_size();
	
    if (size != SZ_256K && size != SZ_512K) {
        printk("inlvalid input size %x\n", size);
        return -1;
    }
    if (in_interrupt()) {
        printk(KERN_ERR "Cannot use %s in interrupt/softirq context\n",
               __func__);
        return -1;
    }
    if (size == cur_size) {
        printk("Config L2 size %x is equal to current L2 size %x\n",
               size, cur_size);
        return 0;
    }
    cpumask_clear(&mask);
	for(i = 0; i < get_cluster_core_count(); i++)
		cpumask_set_cpu(i, &mask);
	
    atomic_set(&L1_flush_done, 0);
    get_online_cpus();
    //printk("[Config L2] Config L2 start, on line cpu = %d\n",num_online_cpus());    
    
    /* disable cache and flush L1 on Cluster0*/
    on_each_cpu_mask(&mask, (smp_call_func_t)atomic_flush, NULL, true);
    //while(atomic_read(&L1_flush_done) != num_online_cpus());    
    //printk("[Config L2] L1 flush done\n");
    
    /* Only need to flush Cluster0's L2 */    
    smp_call_function_any(&mask, (smp_call_func_t)inner_dcache_flush_L2, NULL, true);
    //printk("[Config L2] L2 flush done\n");
    
    /* change L2 size */    
    config_L2_size(size);
    //printk("[Config L2] Change L2 flush size done(size = %d)\n",size);
        
    /* enable Cluster0's cache */
    atomic_set(&L1_flush_done, 0);
    on_each_cpu_mask(&mask, (smp_call_func_t)__enable_cache, NULL, true);
    
    //update cr_alignment for other kernel function usage 
    cr_alignment = cr_alignment | (0x4); //C1_CBIT
    put_online_cpus();
    printk("Config L2 size %x done\n", size);
    return 0;
}
Ejemplo n.º 2
0
int config_L2(int size)
{ 
	int cur_size = get_l2c_size();
	if (size != SZ_256K && size != SZ_512K) {
		printk("inlvalid input size %x\n", size);
		return -1;
	}
	if (in_interrupt()) {
		printk(KERN_ERR "Cannot use %s in interrupt/softirq context\n",
		       __func__);
		return -1;
	}
	if (size == cur_size) {
		printk("Config L2 size %x is equal to current L2 size %x\n",
		       size, cur_size);
		return 0;
	}

    atomic_set(&L1_flush_done, 0);
	get_online_cpus();
	//printk("[Config L2] Config L2 start, on line cpu = %d\n",num_online_cpus());	
	
	/* disable cache and flush L1 */
	on_each_cpu((smp_call_func_t)atomic_flush, NULL, true);
	//while(atomic_read(&L1_flush_done) != num_online_cpus());	
    //printk("[Config L2] L1 flush done\n");
    
    /* flush L2 */	
	inner_dcache_flush_L2();
	//printk("[Config L2] L2 flush done\n");
	
	/* change L2 size */	
	config_L2_size(size);
	//printk("[Config L2] Change L2 flush size done(size = %d)\n",size);
		
	/* enable cache */
	atomic_set(&L1_flush_done, 0);
	on_each_cpu((smp_call_func_t)__enable_cache, NULL, true);
	
	//update cr_alignment for other kernel function usage 
	cr_alignment = cr_alignment | (0x4); //C1_CBIT
	put_online_cpus();
	printk("Config L2 size %x done\n", size);
	return 0;
}
Ejemplo n.º 3
0
void bl31_early_platform_setup(bl31_params_t *from_bl2,
				void *plat_params_from_bl2)
{
    unsigned long long normal_base;
    unsigned long long atf_base;

    config_L2_size();

    atf_arg_t_ptr teearg = (atf_arg_t_ptr)(uintptr_t)TEE_BOOT_INFO_ADDR;

    // overwrite core0 reset address, to avoid overwrite tee boot argument 
    mmio_write_32(MP0_MISC_CONFIG_BOOT_ADDR(0), (unsigned long)bl31_on_entrypoint);

    normal_base = 0;
    /* in ATF boot time, tiemr for cntpct_el0 is not initialized
     * so it will not count now. 
     */
    atf_base = read_cntpct_el0();
    atf_sched_clock_init(normal_base, atf_base);
    
	/* Initialize the console to provide early debug support */
//    console_init(UART0_BASE); // without boot argument
	console_init(teearg->atf_log_port);
    printf("LK boot argument location=0x%x\n\r", BOOT_ARGUMENT_LOCATION);
    printf("KL boot argument size=0x%x\n\r", BOOT_ARGUMENT_SIZE);
    printf("atf_magic=0x%x\n\r", teearg->atf_magic);
    printf("tee_support=0x%x\n\r", teearg->tee_support);
    printf("tee_entry=0x%x\n\r", teearg->tee_entry);
    printf("tee_boot_arg_addr=0x%x\n\r", teearg->tee_boot_arg_addr);
    printf("atf_log_port=0x%x\n\r", teearg->atf_log_port);
    printf("atf_log_baudrate=0x%x\n\r", teearg->atf_log_baudrate);
    printf("atf_log_buf_start=0x%x\n\r", teearg->atf_log_buf_start);
    printf("atf_log_buf_size=0x%x\n\r", teearg->atf_log_buf_size);
    printf("atf_aee_debug_buf_start=0x%x\n\r", teearg->atf_aee_debug_buf_start);
    printf("atf_aee_debug_buf_size=0x%x\n\r", teearg->atf_aee_debug_buf_size);
    printf("atf_irq_num=%d\n\r", teearg->atf_irq_num);
    printf("BL33_START_ADDRESS=0x%x\n\r", BL33_START_ADDRESS);

	/* Initialize the platform config for future decision making */
	mt_config_setup();

    printf("bl31_setup\n\r");
#if RESET_TO_BL31
	/* There are no parameters from BL2 if BL31 is a reset vector */
	assert(from_bl2 == NULL);
	assert(plat_params_from_bl2 == NULL);
    printf("RESET_TO_BL31\n\r");


	/*
	 * Do initial security configuration to allow DRAM/device access. On
	 * Base MTK_platform only DRAM security is programmable (via TrustZone), but
	 * other platforms might have more programmable security devices
	 * present.
	 */
	//FIXME, do not set TZC400 now 
	//mt_security_setup();
#else
	/* Check params passed from BL2 should not be NULL,
	 * We are not checking plat_params_from_bl2 as NULL as we are not
	 * using it on MTK_platform
	 */
    printf("not RESET_TO_BL31\n");

	assert(from_bl2 != NULL);
	assert(from_bl2->h.type == PARAM_BL31);
	assert(from_bl2->h.version >= VERSION_1);

	bl2_to_bl31_params = from_bl2;
	assert(((unsigned long)plat_params_from_bl2) == MT_BL31_PLAT_PARAM_VAL);
#endif
    /*If no TEE, initial devapc in ATF*/
    if(! (teearg->tee_support))
        start_devapc();
}
int switch_L2(enum options option)
{
	int i, cpu;
	int err = 0;
	int retry=0;    
	u64 t1;
	u64 t2;
	unsigned long mask = (1<<0);

	if(option >= BORROW_NONE) {
		pr_err("wrong option %d\n", option);
		return -1;
	}

	t1 = sched_clock();

	/* bind this process to main cpu */    
	while(sched_setaffinity(0, (struct cpumask*) &mask) < 0)
	{
		pr_err("Could not set cpu 0 affinity for current process(%d).\n", retry);
		retry++;
		if(retry > 100)
		{
			return -1;
		}
	}

	/*disable hot-plug*/
	hps_set_enabled(0);

	is_l2_borrowed = 0;

	for(i=1; i<NR_CPUS; i++)
	{
		if(cpu_online(i))
		{
			err = cpu_down(i);
			if(err < 0)
			{
				pr_err("[L2$ sharing] disable cpu %d failed!\n", i);
				
				hps_set_enabled(1);
				return -1;
			}
		}
	}

	/* disable preemption */
	cpu = get_cpu();
	
	/* enable other clusters' power */
	enable_secondary_clusters_pwr();

	config_L2_size(option);

	if(option == BORROW_L2)
	{
		is_l2_borrowed = 1;        
	}
	else // if(option == RETURN_L2)
	{
		is_l2_borrowed = 0;
		/* Disable other clusters' power */
		disable_secondary_clusters_pwr();
	}

	/*enable hot-plug*/
	hps_set_enabled(1);	
	put_cpu();

	t2 = sched_clock();
    
	if(option == BORROW_L2)
	{
		pr_notice("[%s]: borrow L2$ cost %llu ns\n", __func__, t2 - t1);
	}
	else
	{
		pr_notice("[%s]: return L2$ cost %llu ns\n", __func__, t2 - t1);
	}

	return err;
}