int appf_runtime_init(void) { int ret,i; unsigned va, pa; struct appf_main_table* pmaintable = (struct appf_main_table*)reloc_addr((unsigned)&main_table); struct appf_cluster* pcluster; update_offset(); /* TODO: read U bit */ is_smp = FALSE; pa = reloc_addr((unsigned)&main_table); va = (unsigned)&main_table; if (pa == va) { __V(flat_mapped) = TRUE; } /* if (__V(flat_mapped) == 0 && use_smc == 0) { ret = 0; ret = appf_setup_translation_tables(); if (ret < 0) { return ret; } }*/ return appf_platform_runtime_init(); }
int appf_boottime_init(void) { /* Set up stack pointers per CPU, per cluster */ /* Discover devices, set up tables */ update_offset(); appf_platform_boottime_init(); *((unsigned*)reloc_addr((unsigned)&appf_runtime_call_flat_mapped)) = (unsigned)appf_runtime_call; *((unsigned*)reloc_addr((unsigned)&appf_device_memory_flat_mapped)) = reloc_addr((unsigned)appf_device_memory); appf_setup_translation_tables(); return 0; }
/** * This function is called when the OS makes a firmware call with the * function code APPF_INTIALIZE. * * It is called using the APPF translation tables that were set up in * appf_runtime_init, above. */ static int late_init(void) { struct appf_cluster *cluster; int cluster_index; unsigned maintable_pa; dbg_prints("late_init ...\n"); cluster_index = appf_platform_get_cluster_index(); maintable_pa = reloc_addr((unsigned)&main_table); cluster = ((struct appf_main_table*)maintable_pa)->cluster_table + cluster_index; /* * Clean the translation tables out of the L1 dcache * (see comments in disable_clean_inv_dcache_v7_l1) */ dsb(); // clean_dcache_v7_l1(); return appf_platform_late_init(cluster); }
/** * 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; }
/** * This function is called at boot time. Memory will be flat-mapped, and the code will use * the bootloader's stack . The code must examine the hardware and set up the APPF tables. * The values could alternatively be hard-coded if, for example, the platform always provides * certain hardware features. * * The values for the master table must be written to the global variable * main_table, which is a pointer to the start of the entry point section. * All the other tables must be in the APPF_TABLE_DATA section. */ int appf_platform_boottime_init(void) { int i; /* Ensure that the CPUs enter APPF code at reset */ /* TODO: Consider high vectors */ unsigned addr = update_mvbar(); unsigned* pstacks; // addr = 0x49000000; // addr &= 0xFFFFFFF; // dbg_wait(); // addr = va_to_pa(addr); // *(unsigned *)(addr) = reloc_addr((unsigned)&platform_reset_handler); // *(unsigned *)(addr +0x20) = (unsigned)reloc_addr(&platform_reset_handler); /* Also ensure that the SMC instruction reaches APPF code */ /* addr = read_mvbar(); // if (read_mvbar() ) if(addr != 0 && (addr & 0xF) == 0) { *(unsigned *)(read_mvbar() + 0x20) = reloc_addr((unsigned)&appf_smc_handler); }*/ /* Setup tables - Note that pointers are flat-mapped/physical addresses */ if (aem_cluster[0].scu_address) { aem_cluster[0].num_cpus = num_cpus_from_a9_scu(aem_cluster[0].scu_address); } else { aem_cluster[0].num_cpus = 1; } aem_cluster[0].active_cpus = aem_cluster[0].num_cpus; aem_cluster[0].cpu_table = &aem_cpu[0]; aem_cluster[0].context = (void *)get_memory(sizeof(struct appf_cluster_context)); aem_cluster[0].context->gic_dist_shared_data = (void *)get_memory(GIC_DIST_SHARED_DATA_SIZE); aem_cluster[0].context->l2_data = (void *)get_memory(L2_DATA_SIZE); aem_cluster[0].context->scu_data = (void *)get_memory(SCU_DATA_SIZE); aem_cluster[0].context->global_timer_data = (void *)get_memory(GLOBAL_TIMER_DATA_SIZE); aem_cluster[0].context->lock = (void *)reloc_addr((unsigned)&appf_device_memory); initialize_spinlock(aem_cluster[0].context->lock); for (i=0; i<aem_cluster[0].num_cpus; ++i) { aem_cpu[i].context = (void *)get_memory(sizeof(struct appf_cpu_context)); aem_cpu[i].context->pmu_data = (void *)get_memory(PMU_DATA_SIZE); aem_cpu[i].context->timer_data = (void *)get_memory(TIMER_DATA_SIZE); aem_cpu[i].context->vfp_data = (void *)get_memory(VFP_DATA_SIZE); aem_cpu[i].context->gic_interface_data = (void *)get_memory(GIC_INTERFACE_DATA_SIZE); aem_cpu[i].context->gic_dist_private_data = (void *)get_memory(GIC_DIST_PRIVATE_DATA_SIZE); aem_cpu[i].context->banked_registers = (void *)get_memory(BANKED_REGISTERS_SIZE); aem_cpu[i].context->cp15_data = (void *)get_memory(CP15_DATA_SIZE); aem_cpu[i].context->debug_data = (void *)get_memory(DEBUG_DATA_SIZE); aem_cpu[i].context->mmu_data = (void *)get_memory(MMU_DATA_SIZE); aem_cpu[i].context->other_data = (void *)get_memory(OTHER_DATA_SIZE); aem_cpu[i].context->flags = APPF_SAVE_PMU | APPF_SAVE_TIMERS | APPF_SAVE_L2 | APPF_SAVE_VFP | APPF_SAVE_DEBUG; // APPF_SAVE_L2; pstacks = (unsigned*)reloc_addr((unsigned)platform_cpu_stacks); pstacks[i] = get_memory(STACK_SIZE) + STACK_SIZE; } temp_main_table.cluster_table = &aem_cluster[0]; temp_main_table.num_clusters = sizeof(aem_cluster) / sizeof(aem_cluster[0]); temp_main_table.entry_point = (appf_entry_point_t *)reloc_addr((unsigned)appf_entry_point); /* Copy our temp table to the right place in memory */ appf_memcpy((void *)reloc_addr((unsigned)&main_table), &temp_main_table, sizeof(struct appf_main_table)); return APPF_OK; }
static Integer get_index_tab(CTXTdeclc FILE *fd, int clause_no) { Integer hashval, size, j; Integer count = 0; byte type ; CPtr label; Integer ival; Cell val; Integer dummy; /* used to squash warnings */ size = hsize(clause_no); indextab = (struct hrec *)mem_alloc(size*sizeof(struct hrec),COMPILED_SPACE); for (j = 0; j < size; j++) { indextab[j].l = 0; indextab[j].link = (CPtr)&(indextab[j].link); } for (j = 0; j < clause_no; j++) { dummy = get_obj_byte(&type); switch (type) { case 'i': get_obj_word_bbsig_notag(&ival); hashval = ihash((Cell) ival, size); count += 9; break; case 'f': get_obj_word_bbsig_notag(&ival); // printf("sfloat: %f, %x\n",(*(float *)(&ival)), (*(Integer *)(&ival)) ); #ifndef FAST_FLOATS val = float_val_to_hash(*(float *)(&ival)); #else val = ival; #endif hashval = ihash((Cell) val, size); count += 9; break; case 'd': { double fval; dummy = get_obj_string(&fval,8); #ifndef FAST_FLOATS val = float_val_to_hash(fval); #else { union { long intp; float fltp; } cvtr; cvtr.fltp = (float)fval; val = cvtr.intp; } #endif // printf("bld float index: %2.14f, %0x, size=%d\n",fval,val,size); hashval = ihash((Cell) val, size); count += 9; break; } case 'l': hashval = ihash((Cell)(list_pscPair), size); count += 5; break; case 'n': hashval = ihash((Cell) 0, size); count += 5; break; case 'c': get_obj_word_bb(&ival); count += 9; val = (Cell)ival ; st_pscname(&val); hashval = ihash(val, size) ; break; case 's': get_obj_word_bb(&ival); count += 9; val = (Cell)ival ; st_ptrpsc(&val); hashval = ihash(val, size) ; break; default: hashval = 0; xsb_exit( "illegal format"); } get_obj_word_bbsig_notag(&label); label = reloc_addr((Integer)label, seg_text(current_seg)); inserth(label, &indextab[hashval]); } return count; }
int appf_setup_translation_tables(void) { unsigned firmware_start_pa, firmware_start_va,attr; unsigned tab1_pa,pa; int i; firmware_start_va = ((unsigned)&main_table) & PAGE_MASK; firmware_start_pa = reloc_addr(firmware_start_va); tab1_pa = reloc_addr((unsigned)appf_translation_table1); // tex_remap = read_sctlr() & TRE_MASK;/* TRE: 0:remap disable, 1: remap enable*/ for (i = 0; i < 4096; ++i) { if(i == 0x04f) attr = 0xc0e; else if(i <=0x3FF) attr = 0x10c02; else if( i < 0x40F) attr = 0xc0e; else if( i == 0x490) attr = 0xc0e; else if(i == 0x498) attr = 0xc0e; else if(i >= 0x800 && i <= 0x9FF) attr = 0xc0e; else if(i >= 0xa00 && i <= 0xbff) attr = 0x10c02; else if(i == 0xc11) attr = 0x10412; else if(i == 0xc12) attr = 0x10412; else if(i == 0xc42) attr = 0x412; else if(i==0xc43) attr = 0x2412; else if(i>=0xc80 && i <= 0xCFF) attr = 0x412; else if(i>=0xe00 && i <= 0xfff) attr = 0xc0e; else attr = 0; if(i >= 0xC00 && i <= 0xC06) { ((unsigned*)tab1_pa) [i] = 0xc0e|((0x800 + (i - 0xc00))<<20); } else if(i >= 0xD00 & i < 0xDFF) { ((unsigned*)tab1_pa) [i] = 0xc0e|((0x900 + (i - 0xD00))<<20); } else if(i == 0xc4F) { ((unsigned*)tab1_pa) [i] = 0x402|(0x04F<<20);//0xc0e } else if(i == 0xc4D) { ((unsigned*)tab1_pa) [i] = 0x402|(0x04F<<20);//0xc0e } else if(i == 0xCFF) { ((unsigned*)tab1_pa) [i] = 0xc0e|(0xFF<<20); } else if(i == 0xF11) ((unsigned*)tab1_pa) [i] = 0x412|(0xC11<<20); else if(i == 0xF13) ((unsigned*)tab1_pa) [i] = 0x412|(0xC13<<20); else if(i == 0xF22) ((unsigned*)tab1_pa) [i] = 0x412|(0xC42<<20); else if(i == 0xF23) ((unsigned*)tab1_pa) [i] = 0x412|(0xC43<<20); else if(i == 0xF30) ((unsigned*)tab1_pa) [i] = 0x412|(0xC80<<20); else if(i == 0xF31) ((unsigned*)tab1_pa) [i] = 0x412|(0xC81<<20); else if(i == 0xF32) ((unsigned*)tab1_pa) [i] = 0x412|(0xC90<<20); else if(i == 0xF40) ((unsigned*)tab1_pa) [i] = 0x412|(0xCC0<<20); else if(i == 0xF80) ((unsigned*)tab1_pa) [i] = 0x412|(0xd00<<20); else if(i == 0xF90) ((unsigned*)tab1_pa) [i] = 0x412|(0xd90<<20); else if(i == 0xFA0) ((unsigned*)tab1_pa) [i] = 0x412|(0xda0<<20); else ((unsigned*)tab1_pa) [i] = attr|(i<<20); } // ((unsigned*)tab1_pa)[firmware_start_va >> SECTION_SHIFT] = reloc_addr((unsigned)appf_translation_table2a) | PAGE_TABLE; // ((unsigned*)tab1_pa)[firmware_start_pa >> SECTION_SHIFT] = reloc_addr((unsigned)appf_translation_table2b) | PAGE_TABLE; pa = reloc_addr((unsigned)&appf_ttbr0); *((volatile unsigned*)pa) = reloc_addr((unsigned)appf_translation_table1); __V(appf_ttbcr) = 0; clean_dcache_v7_l1(); return APPF_OK; }