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

📄 ofd_fixup.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: Jimi Xenidis <jimix@watson.ibm.com> */#include <xen/config.h>#include <xen/lib.h>#include <xen/sched.h>#include <xen/version.h>#include <public/xen.h>#include "of-devtree.h"#include "oftree.h"#include "rtas.h"ofdn_t ofd_boot_cpu;#ifdef PAPR_VTERMstatic ofdn_t ofd_vdevice_vty(void *m, ofdn_t p, struct domain *d){    ofdn_t n;    static const char pathfmt[] = "/vdevice/vty@%x";    static const char name[] = "vty";    static const char compatible[] = "hvterm1";    static const char device_type[] = "serial";    char path[sizeof (pathfmt) + 8 - 2];    int client = 0;    snprintf(path, sizeof (path), pathfmt, client);    n = ofd_node_add(m, p, path, sizeof (path));    if (n > 0) {        u32 val32;        val32 = client;        ofd_prop_add(m, n, "name", name, sizeof (name));        ofd_prop_add(m, n, "reg", &val32, sizeof (val32));        ofd_prop_add(m, n, "compatible",                     compatible, sizeof (compatible));        ofd_prop_add(m, n, "device_type",                     device_type, sizeof (device_type));    }    return n;}#endif#ifdef PAPR_VDEVICEstatic ofdn_t ofd_vdevice(void *m, struct domain *d){    ofdn_t n;    static const char path[] = "/vdevice";    static const char name[] = "vdevice";    static const char compatible[] = "IBM,vdevice";    u32 val;    n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));    if (n > 0) {        ofd_prop_add(m, n, "name", name, sizeof (name));        val = 1;        ofd_prop_add(m, n, "#address-cells", &val, sizeof (val));        val = 0;        ofd_prop_add(m, n, "#size-cells", &val, sizeof (val));        ofd_prop_add(m, n, "compatible",                     compatible, sizeof (compatible));        ofd_prop_add(m, n, "device_type", name, sizeof (name));        ofd_prop_add(m, n, "interupt-controller", NULL, 0);#ifdef PAPR_VDEVICE        ofdn_t r;        /* add vty */        r = ofd_vdevice_vty(m, n, d);        printk("vdevice r: %x\n", r);        n = r;#endif    }    return n;}#endifstatic ofdn_t ofd_openprom_props(void *m){    static const char path[] = "/openprom";    static const char vernum[] = "IBM,XenOF0.1";    ofdn_t n;    n = ofd_node_find(m, path);    if (n == 0) {        n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));        ofd_prop_add(m, n, "name",                     &path[1], sizeof (path) - 1);    }    /* I want to override */    ofd_prop_add(m, n, "model", vernum, sizeof(vernum));    ofd_prop_add(m, n, "ibm,fw-vernum_encoded", vernum, sizeof(vernum));    ofd_prop_add(m, n, "relative-addressing", NULL, 0);    return n;}#ifdef PAPR_VTERMstatic ofdn_t ofd_aliases_props(void *m){    static const char path[] = "/aliases";    static const char screen[] = "/vdevice/vty@0";    ofdn_t n;    n = ofd_node_find(m, path);    if (n == 0) {        n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));        ofd_prop_add(m, n, "name",                     &path[1], sizeof (path) - 1);    }    ofd_prop_add(m, n, "screen", screen, sizeof(screen));    return n;}#endifstatic ofdn_t ofd_options_props(void *m){    static const char path[] = "/options";    static const char boot[] = "true";    ofdn_t n;    n = ofd_node_find(m, path);    if (n == 0) {        n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));        ofd_prop_add(m, n, "name",                     &path[1], sizeof (path) - 1);    }    ofd_prop_add(m, n, "auto-boot?", boot, sizeof(boot));    return n;}static ofdn_t ofd_cpus_props(void *m, struct domain *d){    static const char path[] = "/cpus";    static const char cpu[] = "cpu";    u32 val = 1;    ofdn_t n;    ofdn_t c;    static u32 ibm_pft_size[] = { 0x0, 0x0 };    n = ofd_node_find(m, path);    if (n == 0) {        n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));        ofd_prop_add(m, n, "name",                     &path[1], sizeof (path) - 1);    }    ofd_prop_add(m, n, "#address-cells", &val, sizeof(val));    ofd_prop_add(m, n, "#size-cells", &val, sizeof(val));    ofd_prop_add(m, n, "smp-enabled", NULL, 0);#ifdef HV_EXPOSE_PERFORMANCE_MONITOR    ofd_prop_add(m, n, "performance-monitor", NULL, 0);#endif    c = ofd_node_find_by_prop(m, n, "device_type", cpu, sizeof (cpu));    if (ofd_boot_cpu == -1)        ofd_boot_cpu = c;    while (c > 0) {        /* We do not use the OF tree to identify secondary processors         * so we must prune them from the tree */        if (c == ofd_boot_cpu) {            ofdn_t p;            ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE;            ofd_prop_add(m, c, "ibm,pft-size",                         ibm_pft_size, sizeof (ibm_pft_size));            /* get rid of non-standard properties */            p = ofd_prop_find(m, c, "cpu#");            if (p > 0) {                ofd_prop_remove(m, c, p);            }            /* FIXME: Check the the "l2-cache" property who's             * contents is an orphaned phandle? */        } else            ofd_node_prune(m, c);        c = ofd_node_find_next(m, c);    }    return n;}#ifdef ADD_XICSstatic ofdn_t ofd_xics_props(void *m){    ofdn_t n;    static const char path[] = "/interrupt-controller";    static const char compat[] = "IBM,ppc-xicp";    static const char model[] = "IBM, BoaC, PowerPC-PIC, 00";    static const char dtype[] =        "PowerPC-External-Interrupt-Presentation";    /*     * I don't think these are used for anything but linux wants     * it.  I seems to describe some per processor location for     * IPIs but that is a complete guess.     */    static const u32 reg[] = {        0x000003e0, 0x0f000000, 0x00000000, 0x00001000,        0x000003e0, 0x0f001000, 0x00000000, 0x00001000,        0x000003e0, 0x0f002000, 0x00000000, 0x00001000,        0x000003e0, 0x0f003000, 0x00000000, 0x00001000,        0x000003e0, 0x0f004000, 0x00000000, 0x00001000,        0x000003e0, 0x0f005000, 0x00000000, 0x00001000,        0x000003e0, 0x0f006000, 0x00000000, 0x00001000,        0x000003e0, 0x0f007000, 0x00000000, 0x00001000,        0x000003e0, 0x0f008000, 0x00000000, 0x00001000,        0x000003e0, 0x0f009000, 0x00000000, 0x00001000,        0x000003e0, 0x0f00a000, 0x00000000, 0x00001000,        0x000003e0, 0x0f00b000, 0x00000000, 0x00001000,        0x000003e0, 0x0f00c000, 0x00000000, 0x00001000,        0x000003e0, 0x0f00d000, 0x00000000, 0x00001000,        0x000003e0, 0x0f00e000, 0x00000000, 0x00001000,        0x000003e0, 0x0f00f000, 0x00000000, 0x00001000,    };    n = ofd_node_find(m, path);    if (n == 0) {        n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));        ofd_prop_add(m, n, "name",                     &path[1], sizeof (path) - 1);    }    ofd_prop_add(m, n, "built-in", NULL, 0);    ofd_prop_add(m, n, "compatible", compat, sizeof(compat));    ofd_prop_add(m, n, "device_type", dtype, sizeof(dtype));    ofd_prop_add(m, n, "model", model, sizeof(model));    ofd_prop_add(m, n, "reg", reg, sizeof(reg));    return n;}#endif/* * Good things you can stick here: *   init=/bin/bash ip=dhcp root=/dev/hda2 ide=nodma  */static char default_bootargs[] = ""; static ofdn_t ofd_chosen_props(void *m, const char *cmdline){    ofdn_t n;    ofdn_t p;    static const char path[] = "/chosen";    char bootargs[256] = { 0, };    int bsz;    int sz;    int rm;    n = ofd_node_find(m, path);    if (n == 0) {        n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));        ofd_prop_add(m, n, "name",                     &path[1], sizeof (path) - 1);    }    if (cmdline)        strlcpy(bootargs, cmdline, sizeof(bootargs));    bsz = strlen(bootargs) + 1;    rm = sizeof (bootargs) - bsz;    if (default_bootargs != NULL) {        sz = strlen(default_bootargs);        if (sz > rm) {            panic("default_bootargs is too big: 0x%x > 0x%x\n",                  sz, rm);        } else if (sz > 0) {            memcpy(&bootargs[bsz - 1], default_bootargs, sz + 1);            bsz += sz;            rm -= sz;        }    }    printk("DOM0 bootargs: %s\n", bootargs);    ofd_prop_add(m, n, "bootargs", bootargs, bsz);    ofd_prop_add(m, n, "bootpath", NULL, 0);    printk("Remove /chosen/mmu, stub will replace\n");    p = ofd_prop_find(m, n, "mmu");    if (p > 0) {        ofd_prop_remove(m, n, p);    }    return n;}static ofdn_t ofd_xen_props(void *m, struct domain *d, ulong shared_info){    ofdn_t n;    static const char path[] = "/xen";    static const char console[] = "/xen/console";    n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));    if (n > 0) {        char xen[256];        int xl;        u64 val[2];        s32 dom_id;        dom_id = d->domain_id;        ofd_prop_add(m, n, "reg", &dom_id, sizeof (dom_id));        ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);        xl = snprintf(xen, sizeof (xen), "Xen-%d.%d%s",                xen_major_version(), xen_minor_version(), xen_extra_version());        ASSERT(xl < sizeof (xen));        ofd_prop_add(m, n, "version", xen, xl + 1);        /* convert xen pointer to guest physical */        val[0] = shared_info;        val[1] = PAGE_SIZE;        ofd_prop_add(m, n, "shared-info", val, sizeof (val));        /* reserve PAGE_SIZE @ addr shared info */        ofd_prop_add(m, n, "reserved", val, sizeof (val));        /* flags |= SIF_PROVILEDGED; */        ofd_prop_add(m, n, "privileged", NULL, 0);        /* flags |= SIF_INITDOMAIN; */        ofd_prop_add(m, n, "initdomain", NULL, 0);        /* tell dom0 that Xen depends on it to have power control */        if (!rtas_entry)            ofd_prop_add(m, n, "power-control", NULL, 0);        /* tell dom0 where granted pages go in the linear map */        val[0] = cpu_foreign_map_order();        val[1] = d->arch.foreign_mfn_count;        ofd_prop_add(m, n, "foreign-map", val, sizeof (val));        n = ofd_node_add(m, n, console, sizeof (console));        if (n > 0) {            val[0] = 0;            ofd_prop_add(m, n, "interrupts", &val[0], sizeof (val[0]));        }    }    return n;}ulong ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,                     ulong shared_info){    const char compat[] = "Hypervisor,Maple";    const char d0[] = "dom0";    void *m;    const ofdn_t n = OFD_ROOT;    ofdn_t r;    u32 did;    m = (void *)mem;#ifdef PAPR_VDEVICE    printk("Add /vdevice\n");    ofd_vdevice(m, d);    printk("Add /aliases props\n");    ofd_aliases_props(m);#endif    printk("Add /openprom props\n");    ofd_openprom_props(m);    printk("Add /options props\n");    ofd_options_props(m);    printk("Add /cpus props\n");    ofd_cpus_props(m, d);    printk("Add /chosen props\n");    ofd_chosen_props(m, cmdline);    printk("fix /memory props\n");    ofd_memory_props(m, d);    printk("fix /xen props\n");    ofd_xen_props(m, d, shared_info);    printk("Remove original /dart\n");    ofd_prune_path(m, "/dart");    printk("Remove original /rtas\n");    ofd_prune_path(m, "/rtas");    rtas_proxy_init(m);#ifdef FIX_COMPAT     r = ofd_prop_add(m, n, "compatible", compat, sizeof (compat));    ASSERT( r > 0 );#else    (void)compat;#endif    did = d->domain_id;    r = ofd_prop_add(m, n, "ibm,partition-no", &did, sizeof(did));    ASSERT( r > 0 );    r = ofd_prop_add(m, n, "ibm,partition-name", d0, sizeof (d0));    ASSERT( r > 0 );#ifdef DEBUG    ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);#endif    return ofd_size(m);}

⌨️ 快捷键说明

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