Exemplo n.º 1
0
int appf_warm_reset(void)
{
    int ret;

    struct appf_cpu *cpu;
    struct appf_cluster *cluster;
    int cpu_index, cluster_index;

	writel(0,0xC810001C);
	writel(0,0xC8100020);
	writel(0,0xC110990C);

	//**********************//
	//writel(readl(0xDA00434c)&(~(0x1<<29)),0xDA00434c);// Disable GPO filter for 32k
//	writel(0x3600000,0xDA00434c);// Disable GPO filter for 32k
	//**********************//
    
    cpu_index = appf_platform_get_cpu_index();
    cluster_index = appf_platform_get_cluster_index();

    cluster = main_table.cluster_table + cluster_index;
    cpu = cluster->cpu_table + cpu_index;

    get_spinlock(cpu_index, cluster->context->lock);

    appf_platform_restore_context(cluster, cpu);
	
    ret = appf_platform_leave_cstate(cpu_index, cpu, cluster);
    
    release_spinlock(cpu_index, cluster->context->lock);

	pwr_delay(10);
		
    return ret;
}
Exemplo n.º 2
0
/*free a block.*/
void kcache_free(struct kcache_struct *pcs,void *ptr)
{
	size_t p=(size_t)ptr;
	size_t i=(p-(size_t)pcs->c_bpool)/pcs->c_bsize;
	get_spinlock(pcs->c_bmaplck);
	test1andset(i,pcs->c_bmap);
	release_spinlock(pcs->c_bmaplck);
}
Exemplo n.º 3
0
/**
 * This function is called when the OS makes a firmware call with the 
 * function code APPF_POWER_UP_CPUS
 *
 * It brings powered down CPUs/clusters back to running state.
 */
static int power_up_cpus(unsigned cluster_index, unsigned cpus)
{
    struct appf_cpu *cpu;
    struct appf_cluster *cluster;
    unsigned cpu_index, this_cpu_index;
    int ret = APPF_OK;

    if (cluster_index >= main_table.num_clusters)
    {
        return APPF_BAD_CLUSTER;
    }
    
    cluster = main_table.cluster_table + cluster_index;

    if (cpus >= (1<<cluster->num_cpus))
    {
        return APPF_BAD_CPU;
    }
    
    /* TODO: add cluster-waking code for multi-cluster systems */
    /* TODO: locks will have to be expanded once extra-cluster CPUs can contend for them */

    this_cpu_index = appf_platform_get_cpu_index();
    get_spinlock(this_cpu_index, cluster->context->lock);
    
    for (cpu_index=0; cpu_index < cluster->num_cpus; ++cpu_index)
    {
        cpu = cluster->cpu_table + cpu_index;
        if (cpu->power_state == 0)
        {
            continue;
        }
        ret = appf_platform_power_up_cpu(cpu, cluster);
        if (ret)
        {
            break;
        }
    }

    release_spinlock(this_cpu_index, cluster->context->lock);
    return ret;
}
Exemplo n.º 4
0
/*malloc a block.*/
void *kcache_malloc(struct kcache_struct *pcs)
{
	if (0==pcs->c_avaliable){
		return NULL;
	}
	else {
		size_t i;
		int d;
		unsigned char *p=NULL;
		get_spinlock(pcs->c_bmaplck);
		for (i=0;i<pcs->c_bcnt;i++) 
		{
			d=bitread(i,pcs->c_bmap);
			if (0==d)
			{
				bitset(i,pcs->c_bmap);
				p=pcs->c_bpool+i*pcs->c_bsize;
				break;
			}
		}
		release_spinlock(pcs->c_bmaplck);
		return (void*)p;
	}
}
Exemplo n.º 5
0
/**
 * This function is called when the OS makes a firmware call with the 
 * function code APPF_POWER_DOWN_CPU
 */
static int power_down_cpu(unsigned cstate, unsigned rstate, unsigned flags)
{
    struct appf_cpu *cpu;
    struct appf_cluster *cluster;
    int cpu_index, cluster_index;
    int i, rc, cluster_can_enter_cstate1;
    struct appf_main_table* pmaintable = (struct appf_main_table*)reloc_addr((unsigned)&main_table);
#ifdef USE_REALVIEW_EB_RESETS
    int system_reset = FALSE, last_cpu = FALSE;
#endif
    cpu_index = appf_platform_get_cpu_index();
    cluster_index = appf_platform_get_cluster_index();
	 
    cluster = pmaintable->cluster_table;
    cluster += cluster_index;
	 	
    dbg_print("cluster:",cluster);
    
    cpu = cluster->cpu_table;
    cpu += cpu_index;   
   
    dbg_print("cpu:",cpu_index);
    dbg_print("cluster_index:",cluster_index);

    /* Validate arguments */
    if (cstate > 3)
    {
        return APPF_BAD_CSTATE;
    }
    if (rstate > 3)
    {
        return APPF_BAD_RSTATE;
    }
    /* If we're just entering standby mode, we don't mark the CPU as inactive */
    if (cstate == 1)
    {
        get_spinlock(cpu_index, cluster->context->lock);
        cpu->power_state = 1;
        
        /* See if we can make the cluster standby too */
        if (rstate == 1)
        {
            cluster_can_enter_cstate1 = TRUE;
            for(i=0; i<cluster->num_cpus; ++i)
            {
                if (cluster->cpu_table[i].power_state != 1)
                {
                    cluster_can_enter_cstate1 = FALSE;
                    break;
                }
            }
            if (cluster_can_enter_cstate1)
            {
                cluster->power_state = 1;
            }
        }
                
        rc = appf_platform_enter_cstate1(cpu_index, cpu, cluster);

        if (rc == 0)
        {
            release_spinlock(cpu_index, cluster->context->lock);
            dsb();
            wfi();
            get_spinlock(cpu_index, cluster->context->lock);
            rc = appf_platform_leave_cstate1(cpu_index, cpu, cluster);
        }
        
        cpu->power_state = 0;
        cluster->power_state = 0;
        release_spinlock(cpu_index, cluster->context->lock);
        return rc;
    }

    /* Ok, we're not just entering standby, so we are going to lose the context on this CPU */
		dbg_prints("step1\n");
	  get_spinlock(cpu_index, cluster->context->lock);
    --cluster->active_cpus;
		dbg_prints("step2\n");
		
    cpu->power_state = cstate;
    if (cluster->active_cpus == 0)
    {
        cluster->power_state = rstate;
#ifdef USE_REALVIEW_EB_RESETS
        /* last CPU down must not issue WFI, or we get stuck! */
        last_cpu = TRUE;
        if (rstate > 1)
        {
            system_reset = TRUE;
        }
#endif
    }
  
    /* add flags as required by hardware (e.g. APPF_SAVE_L2 if L2 is on) */
    flags |= cpu->context->flags;
    appf_platform_save_context(cluster, cpu, flags);
		
	dbg_prints("step3\n");
			

    /* Call the platform-specific shutdown code */
    rc = appf_platform_enter_cstate(cpu_index, cpu, cluster);
   
     /* Did the power down succeed? */
    if (rc == APPF_OK)
    {

        release_spinlock(cpu_index, cluster->context->lock);

        while (1) 
        {
#if 0
#if defined(NO_PCU) || defined(USE_REALVIEW_EB_RESETS)
            extern void platform_reset_handler(unsigned, unsigned, unsigned, unsigned);
            void (*reset)(unsigned, unsigned, unsigned, unsigned) = platform_reset_handler;

#ifdef USE_REALVIEW_EB_RESETS
            /* Unlock system registers */
            *(volatile unsigned *)0x10000020 = 0xa05f;
            if (system_reset)
            {
                /* Tell the Realview EB to do a system reset */
                *(volatile unsigned *)0x10000040 = 6;
                /* goto reset vector! */
            }
            else
            {
                if (!last_cpu)
                {
                    /* Tell the Realview EB to put this CPU into reset */
                    *(volatile unsigned *)0x10000074 &= ~(1 << (6 + cpu_index));
                    /* goto reset vector! (when another CPU takes us out of reset) */
                }
            }
#endif
            /*
             * If we get here, either we are the last CPU, or the EB resets 
             * aren't present (e.g. Emulator). So, fake a reset: Turn off MMU, 
             * corrupt registers, wait for a while, jump to warm reset entry point
             */
            write_sctlr(read_sctlr() & ~0x10001807); /* clear TRE, I Z C M */
            dsb();
            for (i=0; i<10000; ++i)
            {
                __nop();
            }
            reset(0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef);
#endif
#endif

            dsb();    
            wfi(); /* This signals the power controller to cut the power */
            /* Next stop, reset vector! */
        }
    }
    else
    {
        /* Power down failed for some reason, return to the OS */
        appf_platform_restore_context(cluster, cpu);
        cpu->power_state = 0;
        cluster->power_state = 0;
        ++cluster->active_cpus;
        release_spinlock(cpu_index, cluster->context->lock);
    }
    return rc;
}