⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppc970.c

📁 xen 3.2.2 源码
💻 C
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. * * Copyright (C) IBM Corp. 2005, 2006 * * Authors: Hollis Blanchard <hollisb@us.ibm.com> *          Jimi Xenidis <jimix@watson.ibm.com> *          Amos Waterland  <apw@us.ibm.com> */#include <xen/config.h>#include <xen/types.h>#include <xen/mm.h>#include <xen/sched.h>#include <xen/lib.h>#include <asm/time.h>#include <asm/current.h>#include <asm/powerpc64/procarea.h>#include <asm/powerpc64/processor.h>#include <asm/powerpc64/ppc970-hid.h>#include "scom.h"#undef DEBUG#undef SERIALIZEstruct cpu_caches cpu_caches = {    .dline_size = 0x80,    .log_dline_size = 7,    .dlines_per_page = PAGE_SIZE >> 7,    .isize = (64 << 10),        /* 64 KiB */    .iline_size = 0x80,    .log_iline_size = 7,    .ilines_per_page = PAGE_SIZE >> 7,};void cpu_flush_icache(void){    union hid1 hid1;    ulong flags;    ulong ea;    local_irq_save(flags);    /* uses special processor mode that forces a real address match on     * the whole line */    hid1.word = mfhid1();    hid1.bits.en_icbi = 1;    mthid1(hid1.word);    for (ea = 0; ea < cpu_caches.isize; ea += cpu_caches.iline_size)        icbi(ea);    sync();    hid1.bits.en_icbi = 0;    mthid1(hid1.word);    local_irq_restore(flags);}struct rma_settings {    int log;    int rmlr_0;    int rmlr_1_2;};static struct rma_settings rma_logs[] = {    { .log = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /*  64 MB */    { .log = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */    { .log = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */    { .log = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /*   1 GB */    { .log = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /*  16 GB */    { .log = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */};static uint log_large_page_sizes[] = {    4 + 20, /* (1 << 4) == 16M */};static struct rma_settings *cpu_find_rma(unsigned int log){    int i;    for (i = 0; i < ARRAY_SIZE(rma_logs); i++) {        if (rma_logs[i].log == log)            return &rma_logs[i];    }    return NULL;}unsigned int cpu_default_rma_order_pages(void){    return rma_logs[0].log - PAGE_SHIFT;}int cpu_rma_valid(unsigned int order){    return cpu_find_rma(order + PAGE_SHIFT) != NULL;}unsigned int cpu_large_page_orders(uint *sizes, uint max){    uint i = 0;    while (i < max && i < ARRAY_SIZE(log_large_page_sizes)) {        sizes[i] = log_large_page_sizes[i] - PAGE_SHIFT;        ++i;    }    return i;}unsigned int cpu_extent_order(void){    return log_large_page_sizes[0] - PAGE_SHIFT;}int cpu_threads(int cpuid){    return 1;}static u64 cpu0_hids[6];static u64 cpu0_hior;void cpu_initialize(int cpuid){    union hid0 hid0;    union hid1 hid1;    union hid4 hid4;    union hid5 hid5;    if (cpuid == 0) {        /* we can assume that these are sane to start with.  We         * _do_not_ store the results in case we want to mess with them         * on a per-cpu basis later. */        cpu0_hids[0] = mfhid0();        cpu0_hids[1] = mfhid1();        cpu0_hids[4] = mfhid4();        cpu0_hids[5] = mfhid5();        cpu0_hior = 0;    }    hid0.word = cpu0_hids[0];    hid1.word = cpu0_hids[1];    hid4.word = cpu0_hids[4];    hid5.word = cpu0_hids[5];    /* This is SMP safe because the compiler must use r13 for it.  */    parea = global_cpu_table[cpuid];    ASSERT(parea != NULL);    mthsprg0((ulong)parea); /* now ready for exceptions */    printk("CPU[PIR:%u IPI:%u Logical:%u] Hello World!\n",           mfpir(), hard_smp_processor_id(), smp_processor_id());#ifdef DEBUG    {        ulong r1, r2;        asm volatile ("mr %0, 1" : "=r" (r1));        asm volatile ("mr %0, 2" : "=r" (r2));        printk("  SP = %lx TOC = %lx\n",  r1, r2);    }#endif    /* Set decrementers for 1 second to keep them out of the way during     * intialization. */    /* XXX make tickless */    mtdec(timebase_freq);    mthdec(timebase_freq);    /* FIXME Do not set the NAP bit in HID0 until we have had a chance     * to audit the safe halt and idle loop code. */    hid0.bits.nap = 0;      /* NAP */    hid0.bits.dpm = 1;      /* Dynamic Power Management */    hid0.bits.nhr = 1;      /* Not Hard Reset */    hid0.bits.hdice_en = 1; /* enable HDEC */    hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */    /* only debug Xen should activate ATTN */    hid0.bits.en_attn = 1;  /* Enable attn instruction */    hid0.bits.en_mck = 1;   /* Enable external machine check interrupts */#ifdef SERIALIZE    hid0.bits.one_ppc = 1;    hid0.bits.isync_sc = 1;    hid0.bits.inorder = 1;    /* may not want these */    hid0.bits.do_single = 1;    hid0.bits.ser-gp = 1;#endif    mthid0(hid0.word);    hid1.bits.bht_pm = 7; /* branch history table prediction mode */    hid1.bits.en_ls = 1; /* enable link stack */    hid1.bits.en_cc = 1; /* enable count cache */    hid1.bits.en_ic = 1; /* enable inst cache */    hid1.bits.pf_mode = 2; /* prefetch mode */    hid1.bits.en_if_cach = 1; /* i-fetch cacheability control */    hid1.bits.en_ic_rec = 1; /* i-cache parity error recovery */    hid1.bits.en_id_rec = 1; /* i-dir parity error recovery */    hid1.bits.en_er_rec = 1; /* i-ERAT parity error recovery */    hid1.bits.en_sp_itw = 1; /* En speculative tablewalks */    mthid1(hid1.word);    /* no changes to hid4 but we want to make sure that secondaries     * are sane */    hid4.bits.lg_pg_dis = 0;    /* make sure we enable large pages */    mthid4(hid4.word);    hid5.bits.DC_mck = 1; /* Machine check enabled for dcache errors */    hid5.bits.DCBZ_size = 0; /* make dcbz size 32 bytes */    hid5.bits.DCBZ32_ill = 0; /* make dzbz 32byte illeagal */    mthid5(hid5.word);#ifdef DEBUG    printk("hid0 0x%016lx\n"           "hid1 0x%016lx\n"           "hid4 0x%016lx\n"           "hid5 0x%016lx\n",           mfhid0(), mfhid1(), mfhid4(), mfhid5());#endif    /* Make sure firmware has not left this dirty */    mthior(cpu0_hior);    /* some machine check goodness */    /* save this for checkstop processing */    if (cpuid == 0)        *mck_good_hid4 = hid4.word;    if (mfpir() > NR_CPUS)        panic("we do not expect a processor to have a PIR (%u) "              "to be larger that NR_CPUS(%u)\n",              mfpir(), NR_CPUS);    cpu_scom_init();    /* initialize the SLB */#ifdef DEBUG    dump_segments(1);#endif    flush_segments();    local_flush_tlb();}void cpu_init_vcpu(struct vcpu *v){    struct domain *d = v->domain;    union hid4 hid4;    struct rma_settings *rma_settings;    hid4.word = mfhid4();    hid4.bits.lpes_0 = 0; /* external exceptions set MSR_HV=1 */    hid4.bits.lpes_1 = 1; /* RMA applies */    hid4.bits.rmor_0_15 = page_to_maddr(d->arch.rma_page) >> 26;    hid4.bits.lpid_0_1 = d->domain_id & 3;    hid4.bits.lpid_2_5 = (d->domain_id >> 2) & 0xf;    rma_settings = cpu_find_rma(d->arch.rma_order + PAGE_SHIFT);    ASSERT(rma_settings != NULL);    hid4.bits.rmlr_0 = rma_settings->rmlr_0;    hid4.bits.rmlr_1_2 = rma_settings->rmlr_1_2;    v->arch.cpu.hid4.word = hid4.word;}void save_cpu_sprs(struct vcpu *v){    /* HID4 is initialized with a per-domain value at domain creation time, and     * does not change after that. */}void load_cpu_sprs(struct vcpu *v){    mthid4(v->arch.cpu.hid4.word);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -