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

📄 boot_of.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            if (size_cells == 2 && (r < l) )                size = (size << 32) | a[r++];                            end = ALIGN_DOWN(start + size, PAGE_SIZE);            start = ALIGN_UP(start, PAGE_SIZE);            DBG("%s: marking 0x%x - 0x%lx\n", __func__,                pg << PAGE_SHIFT, start);            start >>= PAGE_SHIFT;            while (pg < MEM_AVAILABLE_PAGES && pg < start) {                set_bit(pg, mem_available_pages);                pg++;            }            pg = end  >> PAGE_SHIFT;        }    }    /* Now make sure we mark our own memory */    pg =  (ulong)_start >> PAGE_SHIFT;    start = (ulong)_end >> PAGE_SHIFT;    DBG("%s: marking 0x%x - 0x%lx\n", __func__,        pg << PAGE_SHIFT, start << PAGE_SHIFT);    /* Lets try and detect if our image has stepped on something. It     * is possible that FW has already subtracted our image from     * available memory so we must make sure that the previous bits     * are the same for the whole image */    tst = test_and_set_bit(pg, mem_available_pages);    ++pg;    while (pg <= start) {        if (test_and_set_bit(pg, mem_available_pages) != tst)            of_panic("%s: pg :0x%x of our image is different\n",                     __func__, pg);        ++pg;    }    DBG("%s: marking 0x%x - 0x%x\n", __func__,        0 << PAGE_SHIFT, 3 << PAGE_SHIFT);    /* First for pages (where the vectors are) should be left alone as well */    set_bit(0, mem_available_pages);    set_bit(1, mem_available_pages);    set_bit(2, mem_available_pages);    set_bit(3, mem_available_pages);}#ifdef BOOT_OF_FREE/* this is here in case we ever need a free call at a later date */static void boot_of_free(ulong addr, ulong size){    ulong bits;    ulong pos;    ulong i;    size = ALIGN_UP(size, PAGE_SIZE);    bits = size >> PAGE_SHIFT;    pos = addr >> PAGE_SHIFT;    for (i = 0; i < bits; i++) {        if (!test_and_clear_bit(pos + i, mem_available_pages))            of_panic("%s: pg :0x%lx was never allocated\n",                     __func__, pos + i);    }}#endifstatic ulong boot_of_alloc(ulong size){    ulong bits;    ulong pos;    if (size == 0)        return 0;    DBG("%s(0x%lx)\n", __func__, size);    size = ALIGN_UP(size, PAGE_SIZE);    bits = size >> PAGE_SHIFT;    pos = 0;    for (;;) {        ulong i;        pos = find_next_zero_bit(mem_available_pages,                                 MEM_AVAILABLE_PAGES, pos);        DBG("%s: found start bit at: 0x%lx\n", __func__, pos);        /* found nothing */        if ((pos + bits) > MEM_AVAILABLE_PAGES) {            of_printf("%s: allocation of size: 0x%lx failed\n",                     __func__, size);            return 0;        }        /* find a set that fits */        DBG("%s: checking for 0x%lx bits: 0x%lx\n", __func__, bits, pos);        i = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, pos);          if (i - pos >= bits) {            uint addr = pos << PAGE_SHIFT;            /* make sure OF is happy with our choice */            if (of_claim(addr, size, 0) != OF_FAILURE) {                for (i = 0; i < bits; i++)                    set_bit(pos + i, mem_available_pages);                DBG("%s: 0x%lx is good returning 0x%x\n",                    __func__, pos, addr);                return addr;            }            /* if OF did not like the address then simply start from             * the next bit */            i = 1;        }        pos = pos + i;    }}int boot_of_mem_avail(int pos, ulong *startpage, ulong *endpage){    ulong freebit;    ulong usedbit;    if (pos >= MEM_AVAILABLE_PAGES)        /* Stop iterating. */        return -1;    /* Find first free page. */    freebit = find_next_zero_bit(mem_available_pages, MEM_AVAILABLE_PAGES, pos);    if (freebit >= MEM_AVAILABLE_PAGES) {        /* We know everything after MEM_AVAILABLE_PAGES is still free. */        *startpage = MEM_AVAILABLE_PAGES << PAGE_SHIFT;        *endpage = ~0UL;        return freebit;    }    *startpage = freebit << PAGE_SHIFT;    /* Now find first used page after that. */    usedbit = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, freebit);    if (usedbit >= MEM_AVAILABLE_PAGES) {        /* We know everything after MEM_AVAILABLE_PAGES is still free. */        *endpage = ~0UL;        return usedbit;    }    *endpage = usedbit << PAGE_SHIFT;    return usedbit;}static ulong boot_of_mem_init(void){    int root;    int p;    int rc;    uint addr_cells;    uint size_cells;    root = of_finddevice("/");    p = of_getchild(root);    /* code is writen to assume sizes of 1 */    of_getprop(root, "#address-cells", &addr_cells,               sizeof (addr_cells));    of_getprop(root, "#size-cells", &size_cells,               sizeof (size_cells));    DBG("%s: address_cells=%d  size_cells=%d\n",                    __func__, addr_cells, size_cells);    /* We do ream memory discovery later, for now we only want to find     * the first LMB */    do {        const char memory[] = "memory";        char type[32];        type[0] = '\0';        of_getprop(p, "device_type", type, sizeof (type));        if (strncmp(type, memory, sizeof (memory)) == 0) {            uint reg[48];              u64 start;            u64 size;            int r;            int l;            rc = of_getprop(p, "reg", reg, sizeof (reg));            if (rc == OF_FAILURE) {                of_panic("no reg property for memory node: 0x%x.\n", p);            }            l = rc / sizeof(reg[0]); /* number reg element */            DBG("%s: number of bytes in property 'reg' %d\n",                            __func__, rc);                        r = 0;            while (r < l) {                start = reg[r++];                if (addr_cells == 2 && (r < l) )                    start = (start << 32) | reg[r++];                if (r >= l)                    break;  /* partial line.  Skip */                if (start > 0) {                    /* this is not the first LMB so we skip it */                    break;                }                size = reg[r++];                if (size_cells == 2 && (r < l) )                    size = (size << 32) | reg[r++];                                if (r > l)                    break;  /* partial line.  Skip */                boot_of_alloc_init(p, addr_cells, size_cells);                                eomem = size;                return size;            }        }        p = of_getpeer(p);    } while (p != OF_FAILURE && p != 0);    return 0;}static int save_props(void *m, ofdn_t n, int pkg){    int ret;    char name[128];    int result = 1;    int found_name = 0;    int found_device_type = 0;    const char name_str[] = "name";    const char devtype_str[] = "device_type";    /* get first */    result = of_nextprop(pkg, 0, name);    while (result > 0) {        int sz;        u64 obj[1024];        sz = of_getproplen(pkg, name);        if (sz >= 0) {            ret = OF_SUCCESS;        } else {            ret = OF_FAILURE;        }        if (ret == OF_SUCCESS) {            int actual = 0;            ofdn_t pos;            if (sz > 0) {                if (sz > sizeof (obj)) {                    of_panic("obj array not big enough for 0x%x\n", sz);                }                actual = of_getprop(pkg, name, obj, sz);                if (actual > sz)                    of_panic("obj too small");            }            if (strncmp(name, name_str, sizeof(name_str)) == 0) {                found_name = 1;            }            if (strncmp(name, devtype_str, sizeof(devtype_str)) == 0) {                found_device_type = 1;            }            pos = ofd_prop_add(m, n, name, obj, actual);            if (pos == 0)                of_panic("prop_create");        }        result = of_nextprop(pkg, name, name);    }    return 1;}static void do_pkg(void *m, ofdn_t n, int p, char *path, size_t psz){    int pnext;    ofdn_t nnext;    int sz;retry:    save_props(m, n, p);    /* do children first */    pnext = of_getchild(p);    if (pnext != 0) {        sz = of_package_to_path(pnext, path, psz);        if (sz == OF_FAILURE)            of_panic("bad path\n");        nnext = ofd_node_child_create(m, n, path, sz);        if (nnext == 0)            of_panic("out of mem\n");        do_pkg(m, nnext, pnext, path, psz);    }    /* do peer */    pnext = of_getpeer(p);    if (pnext != 0) {        sz = of_package_to_path(pnext, path, psz);        nnext = ofd_node_peer_create(m, n, path, sz);        if (nnext <= 0)            of_panic("out of space in OFD tree.\n");        n = nnext;        p = pnext;        goto retry;    }}static long pkg_save(void *mem){    int root;    char path[256];    int r;    path[0]='/';    path[1]='\0';    /* get root */    root = of_getpeer(0);    if (root == OF_FAILURE)        of_panic("no root package\n");    do_pkg(mem, OFD_ROOT, root, path, sizeof(path));    r = ofd_size(mem);    of_printf("%s: saved device tree in 0x%x bytes\n", __func__, r);    return r;}static int boot_of_fixup_refs(void *mem){    static const char *fixup_props[] = {        "interrupt-parent",    };    int i;    int count = 0;    for (i = 0; i < ARRAY_SIZE(fixup_props); i++) {        ofdn_t c;        const char *name = fixup_props[i];        c = ofd_node_find_by_prop(mem, OFD_ROOT, name, NULL, 0);        while (c > 0) {            const char *path;            int rp;            int ref;            ofdn_t dp;            int rc;            ofdn_t upd;            char ofpath[256];            path = ofd_node_path(mem, c);            if (path == NULL)                of_panic("no path to found prop: %s\n", name);            rp = of_finddevice(path);            if (rp == OF_FAILURE)                of_panic("no real device for: name %s, path %s\n",                          name, path);            /* Note: In theory 0 is a valid node handle but it is highly             * unlikely.             */            if (rp == 0) {                of_panic("%s: of_finddevice returns 0 for path %s\n",                                    __func__, path);            }             rc = of_getprop(rp, name, &ref, sizeof(ref));            if ((rc == OF_FAILURE) || (rc == 0))                of_panic("no prop: name %s, path %s, device 0x%x\n",                         name, path, rp);            rc = of_package_to_path(ref, ofpath, sizeof (ofpath));            if (rc == OF_FAILURE)                of_panic("no package: name %s, path %s, device 0x%x,\n"                         "ref 0x%x\n", name, path, rp, ref);            dp = ofd_node_find(mem, ofpath);            if (dp <= 0)                of_panic("no ofd node for OF node[0x%x]: %s\n",                         ref, ofpath);            ref = dp;            upd = ofd_prop_add(mem, c, name, &ref, sizeof(ref));            if (upd <= 0)                of_panic("update failed: %s\n", name);#ifdef DEBUG            of_printf("%s: %s/%s -> %s\n", __func__,                    path, name, ofpath);#endif            ++count;            c = ofd_node_find_next(mem, c);        }    }    return count;}static int boot_of_fixup_chosen(void *mem)

⌨️ 快捷键说明

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