📄 init_cpuinfo.c
字号:
/* * $QNXLicenseC: * Copyright 2007, QNX Software Systems. * * Licensed under the Apache License, Version 2.0 (the "License"). You * may not reproduce, modify or distribute this software except in * compliance with the License. You may obtain a copy of the License * at: http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OF ANY KIND, either express or implied. * * This file may contain contributions from others, either as * contributors under the License or as licensors under other terms. * Please review this entire file for other proprietary rights or license * notices, as well as the QNX Development Suite License Guide at * http://licensing.qnx.com/license-guide/ for other information. * $ */#include "startup.h"/* * Initialize cpuinfo structures in the system page. * This code is hardware independant and should not have to be changed * changed by end users. */unsigned trap_vectors;unsigned mmu_control;/* * ----------------------------------------------------------------------- * Page flush callouts that go into the syspage.arm.mmu section * ----------------------------------------------------------------------- */static output_callout_t *page_prev_output_rtn;static output_callout_t *callout_output_page(int sizing){ struct arm_cpu_entry *cpu = lsp.cpu.arm_cpu.p; callout_output_one(sizing, &cpu->page_flush); callout_output_one(sizing, &cpu->page_flush_deferred); return page_prev_output_rtn;}static voidadd_page_callouts(const struct arm_core_config *core){ struct arm_cpu_entry *cpu = lsp.cpu.arm_cpu.p; /* * Hook into the callout sizing/output list */ if (page_prev_output_rtn == 0) { page_prev_output_rtn = callout_output_rtn; callout_output_rtn = (output_callout_t *)callout_output_page; } cpu->page_flush = (void *)core->flush; cpu->page_flush_deferred = (void *)core->deferred;}voidinit_cpuinfo(){ struct cpuinfo_entry *cpu = set_syspage_section(&lsp.cpuinfo, sizeof(*lsp.cpuinfo.p)); unsigned cpuid; const struct arm_core_info *core; const struct arm_core_config *config; __asm__("mrc p15, 0, %0, c0, c0, 0" : "=r" (cpuid) : ); cpu->cpu = cpuid; if (shdr->flags1 & STARTUP_HDR_FLAGS1_VIRTUAL) cpu->flags |= CPU_FLAG_MMU; else cpu->flags = 0; /* * Set default mmu_control and trap_vectors */ mmu_control = ARM_MMU_CR_S | ARM_MMU_CR_L | ARM_MMU_CR_D | ARM_MMU_CR_P | ARM_MMU_CR_A | ARM_MMU_CR_W | ARM_MMU_CR_C | ARM_MMU_CR_M | ARM_MMU_CR_X; trap_vectors = 0xffff0000; /* * Work out what core we are running on */ core = arm_core_detect(cpuid); config = core->config; if (config == 0) { crash("No core config for %s\n", core->name); } cpu->name = add_string(core->name); mmu_control |= config->mmu_cr; cycles_per_loop = config->cycles; /* * Add various callouts */ arm_add_cache(cpu, config->cache); add_page_callouts(config); if (config->power) { add_callout(offsetof(struct callout_entry, power), config->power); } /* * Do any extra CPU specific initialisation */ if (core->extra_init) { core->extra_init(cpu, cpuid); } /* * Set the CPU speed */ if (cpu_freq != 0) { cpu->speed = cpu_freq / 1000000; } else { cpu->speed = (cycles_per_loop != 0) ? arm_cpuspeed() : 0; } if (debug_flag) { kprintf("%s rev %d %dMHz\n", core->name, cpuid & 15, cpu->speed); } if (shdr->flags1 & STARTUP_HDR_FLAGS1_VIRTUAL) { int i; /* * Allocate and map the trap vector table */ paddr32_t pa = calloc_ram(__PAGESIZE, __PAGESIZE); arm_map(trap_vectors, pa , __PAGESIZE, ARM_PTE_RW | ARM_PTE_CB); /* * Set up the trap entry point to be "ldr pc, [pc, #0x18]" * These jump slot addresses are all zero, so until these have * been properly set up, any exception will result in a loop. */ for (i = 0; i < 8; i++) { *((unsigned *)pa + i) = 0xe59ff018; } }}/* * -------------------------------------------------------------------------- * CPU specific extra initialisation functions * -------------------------------------------------------------------------- *//* * Additional XScale specific CPU initialisation */voidxscale_extra_init(struct cpuinfo_entry *cpu, unsigned cpuid){ unsigned aux; /* * Make sure write-buffer coalescing is enabled. * * FIXME: set the mini-cache attributes once we support it */ __asm__("mrc p15, 0, %0, c1, c0, 1" : "=r" (aux) : ); aux &= ~1; // enable write buffer coalescing __asm__("mcr p15, 0, %0, c1, c0, 1" : : "r" (aux) ); /* * Enable access to CP0 (and disable all other coprocessors) */ aux = 1; __asm__("mcr p15, 0, %0, c15, c1, 0" : : "r" (aux) ); cpu->flags |= ARM_CPU_FLAG_XSCALE_CP0;}/* * Additional ARM920/922 specific CPU initialisation */voidarm920_extra_init(struct cpuinfo_entry *cpu, unsigned cpuid){ /* * Set async bus mode */ mmu_control |= ARM_MMU_CR_nF | ARM_MMU_CR_iA;}/* * Additional ARM1136 specific CPU initialisation */voidarm1136_extra_init(struct cpuinfo_entry *cpu, unsigned cpuid){ /* * Disable access to VFP if present */ __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 2" : : "r" (0));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -