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

📄 boot_of.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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 IBM Corp. 2005, 2006, 2007 * * Authors: Jimi Xenidis <jimix@watson.ibm.com> *          Hollis Blanchard <hollisb@us.ibm.com> */#include <xen/config.h>#include <xen/init.h>#include <xen/lib.h>#include <xen/version.h>#include <xen/spinlock.h>#include <xen/serial.h>#include <xen/time.h>#include <xen/sched.h>#include <asm/page.h>#include <asm/io.h>#include <asm/boot.h>#include "exceptions.h"#include "of-devtree.h"#include "oftree.h"#include "rtas.h"/* Secondary processors use this for handshaking with main processor.  */volatile unsigned int __spin_ack;static ulong of_vec;static ulong of_msr;static int of_out;static ulong eomem;/* Track memory during early boot with a limited per-page bitmap. We need an * allocator to tell us where we can place RTAS, our copy of the device tree. * We could examine the "available" properties in memory nodes, but we * apparently can't depend on firmware to update those when we call "claim". So * we need to track it ourselves. * We can't dynamically allocate the bitmap, because we would need something * to tell us where it's safe to allocate... */#define MEM_AVAILABLE_PAGES ((32 << 20) >> PAGE_SHIFT)static DECLARE_BITMAP(mem_available_pages, MEM_AVAILABLE_PAGES);extern struct ns16550_defaults ns16550;#undef OF_DEBUG#undef OF_DEBUG_LOW#ifdef OF_DEBUG#define DBG(args...) of_printf(args)#else#define DBG(args...)#endif#ifdef OF_DEBUG_LOW#define DBG_LOW(args...) of_printf(args)#else#define DBG_LOW(args...)#endif#define of_panic(MSG...) \    do { of_printf(MSG); of_printf("\nHANG\n"); for (;;); } while (0)struct of_service {    u32 ofs_service;    u32 ofs_nargs;    u32 ofs_nrets;    u32 ofs_args[10];};static int bof_chosen;static struct of_service s;static int __init of_call(    const char *service, u32 nargs, u32 nrets, s32 rets[], ...){    int rc;    if (of_vec != 0) {        va_list args;        int i;        memset(&s, 0, sizeof (s));        s.ofs_service = (ulong)service;        s.ofs_nargs = nargs;        s.ofs_nrets = nrets;        s.ofs_nargs = nargs;        /* copy all the params into the args array */        va_start(args, rets);        for (i = 0; i < nargs; i++) {            s.ofs_args[i] = va_arg(args, u32);        }        va_end(args);        rc = prom_call(&s, 0, of_vec, of_msr);        /* yes always to the copy, just in case */        for (i = 0; i < nrets; i++) {            rets[i] = s.ofs_args[i + nargs];        }    } else {        rc = OF_FAILURE;    }    return rc;}/* popular OF methods */static int __init _of_write(int ih, const char *addr, u32 len){    int rets[1] = { OF_FAILURE };    if (of_call("write", 3, 1, rets, ih, addr, len) == OF_FAILURE) {        return OF_FAILURE;    }    return rets[0];}/* popular OF methods */static int __init of_write(int ih, const char *addr, u32 len){    int rc;    int i = 0;    int sum = 0;    while (i < len) {        if (addr[i] == '\n') {            if (i > 0) {                rc = _of_write(ih, addr, i);                if (rc == OF_FAILURE)                    return rc;                sum += rc;            }            rc = _of_write(ih, "\r\n", 2);            if (rc == OF_FAILURE)                return rc;            sum += rc;            i++;            addr += i;            len -= i;            i = 0;            continue;        }        i++;    }    if (len > 0) {        rc = _of_write(ih, addr, len);        if (rc == OF_FAILURE)            return rc;        sum += rc;    }                return sum;}static int of_printf(const char *fmt, ...)    __attribute__ ((format (printf, 1, 2)));static int __init of_printf(const char *fmt, ...){    static char buf[1024];    va_list args;    int sz;    if (of_out == 0) {        return OF_FAILURE;    }    va_start(args, fmt);    sz = vsnprintf(buf, sizeof (buf), fmt, args);    if (sz <= sizeof (buf)) {        of_write(of_out, buf, sz);    } else {        static const char trunc[] = "\n(TRUNCATED)\n";        sz = sizeof (buf);        of_write(of_out, buf, sz);        of_write(of_out, trunc, sizeof (trunc));    }    return sz;}static int __init of_finddevice(const char *devspec){    int rets[1] = { OF_FAILURE };    of_call("finddevice", 1, 1, rets, devspec);    if (rets[0] == OF_FAILURE) {        DBG("finddevice %s -> FAILURE %d\n",devspec,rets[0]);        return OF_FAILURE;    }    DBG_LOW("finddevice %s -> %d\n",devspec, rets[0]);    return rets[0];}static int __init of_getprop(int ph, const char *name, void *buf, u32 buflen){    int rets[1] = { OF_FAILURE };    of_call("getprop", 4, 1, rets, ph, name, buf, buflen);    if (rets[0] == OF_FAILURE) {        DBG_LOW("getprop 0x%x %s -> FAILURE\n", ph, name);        return OF_FAILURE;    }    DBG_LOW("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);    return rets[0];}static int __init of_setprop(    int ph, const char *name, const void *buf, u32 buflen){    int rets[1] = { OF_FAILURE };    of_call("setprop", 4, 1, rets, ph, name, buf, buflen);    if (rets[0] == OF_FAILURE) {        DBG("setprop 0x%x %s -> FAILURE\n", ph, name);        return OF_FAILURE;    }    DBG_LOW("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);    return rets[0];}/* * returns 0 if there are no children (of spec) */static int __init of_getchild(int ph){    int rets[1] = { OF_FAILURE };    of_call("child", 1, 1, rets, ph);    DBG_LOW("getchild 0x%x -> 0x%x\n", ph, rets[0]);    return rets[0];}/* * returns 0 is there are no peers */static int __init of_getpeer(int ph){    int rets[1] = { OF_FAILURE };    of_call("peer", 1, 1, rets, ph);    DBG_LOW("getpeer 0x%x -> 0x%x\n", ph, rets[0]);    return rets[0];}static int __init of_getproplen(int ph, const char *name){    int rets[1] = { OF_FAILURE };    of_call("getproplen", 2, 1, rets, ph, name);    if (rets[0] == OF_FAILURE) {        DBG("getproplen 0x%x %s -> FAILURE\n", ph, name);        return OF_FAILURE;    }    DBG_LOW("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);    return rets[0];}static int __init of_package_to_path(int ph, char *buffer, u32 buflen){    int rets[1] = { OF_FAILURE };    of_call("package-to-path", 3, 1, rets, ph, buffer, buflen);    if (rets[0] == OF_FAILURE) {        DBG("%s 0x%x -> FAILURE\n", __func__, ph);        return OF_FAILURE;    }    DBG_LOW("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);    if (rets[0] <= buflen)        buffer[rets[0]] = '\0';    return rets[0];}static int __init of_nextprop(int ph, const char *name, void *buf){    int rets[1] = { OF_FAILURE };    of_call("nextprop", 3, 1, rets, ph, name, buf);    if (rets[0] == OF_FAILURE) {        DBG("nextprop 0x%x %s -> FAILURE\n", ph, name);        return OF_FAILURE;    }    DBG_LOW("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);    return rets[0];}static int __init of_instance_to_path(int ih, char *buffer, u32 buflen){    int rets[1] = { OF_FAILURE };    if (of_call("instance-to-path", 3, 1, rets, ih, buffer, buflen)         == OF_FAILURE)        return OF_FAILURE;    if (rets[0] <= buflen)        buffer[rets[0]] = '\0';    return rets[0];}static int __init of_start_cpu(int cpu, u32 pc, u32 reg){    int ret;    ret = of_call("start-cpu", 3, 0, NULL, cpu, pc, reg);    return ret;}static void __init of_test(const char *of_method_name){    int rets[1] = { OF_FAILURE };        of_call("test", 1, 1, rets, of_method_name);    if (rets[0] == OF_FAILURE ) {        of_printf("Warning: possibly no OF method %s.\n"                  "(Ignore this warning on PIBS.)\n", of_method_name);    }}static int __init of_claim(u32 virt, u32 size, u32 align){    int rets[1] = { OF_FAILURE };        of_call("claim", 3, 1, rets, virt, size, align);    if (rets[0] == OF_FAILURE) {        DBG("%s 0x%08x 0x%08x  0x%08x -> FAIL\n", __func__, virt, size, align);        return OF_FAILURE;    }    DBG_LOW("%s 0x%08x 0x%08x  0x%08x -> 0x%08x\n", __func__, virt, size, align,        rets[0]);    return rets[0];}static int __init of_instance_to_package(int ih){    int rets[1] = { OF_FAILURE };    of_call("instance-to-package", 1, 1, rets, ih);    if (rets[0] == OF_FAILURE)        return OF_FAILURE;    return rets[0];}static int __init of_getparent(int ph){    int rets[1] = { OF_FAILURE };    of_call("parent", 1, 1, rets, ph);    DBG_LOW("getparent 0x%x -> 0x%x\n", ph, rets[0]);    return rets[0];}static int __init of_open(const char *devspec){    int rets[1] = { OF_FAILURE };    of_call("open", 1, 1, rets, devspec);    return rets[0];}static void boot_of_alloc_init(int m, uint addr_cells, uint size_cells){    int rc;    uint pg;    uint a[64];    int tst;    u64 start;    u64 size;    rc = of_getprop(m, "available", a, sizeof (a));    if (rc > 0) {        int l =  rc / sizeof(a[0]);        int r = 0;#ifdef OF_DEBUG        {             int i;            of_printf("avail:\n");            for (i = 0; i < l; i += 4)                of_printf("  0x%x%x, 0x%x%x\n",                          a[i], a[i + 1],                          a[i + 2] ,a[i + 3]);        }#endif                    pg = 0;        while (pg < MEM_AVAILABLE_PAGES && r < l) {            ulong end;            start = a[r++];            if (addr_cells == 2 && (r < l) )                start = (start << 32) | a[r++];                        size = a[r++];

⌨️ 快捷键说明

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