📄 boot_of.c
字号:
{ int ch; ofdn_t dn; ofdn_t dc; int val; int rc; char ofpath[256]; ch = of_finddevice("/chosen"); if (ch == OF_FAILURE) of_panic("/chosen not found\n"); rc = of_getprop(ch, "cpu", &val, sizeof (val)); if (rc != OF_FAILURE) { rc = of_instance_to_path(val, ofpath, sizeof (ofpath)); if (rc > 0) { dn = ofd_node_find(mem, ofpath); if (dn <= 0) of_panic("no node for: %s\n", ofpath); ofd_boot_cpu = dn; val = dn; dn = ofd_node_find(mem, "/chosen"); if (dn <= 0) of_panic("no /chosen node\n"); dc = ofd_prop_add(mem, dn, "cpu", &val, sizeof (val)); if (dc <= 0) of_panic("could not fix /chosen/cpu\n"); rc = 1; } else { of_printf("*** can't find path to booting cpu, " "SMP is disabled\n"); ofd_boot_cpu = -1; } } return rc;}/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges * property. The values are bad, and it doesn't even have the * right number of cells. */static void __init boot_of_fix_maple(void){ int isa; const char *ranges = "ranges"; u32 isa_ranges[3]; const u32 isa_test[] = { 0x00000001, 0xf4000000, 0x00010000 }; const u32 isa_fixed[] = { 0x00000001, 0x00000000, 0x00000000, /* 0xf4000000, matt says this */ 0x00000000, 0x00000000, 0x00010000 }; isa = of_finddevice("/ht@0/isa@4"); if (isa != OF_FAILURE) { if (of_getproplen(isa, ranges) == sizeof (isa_test)) { of_getprop(isa, ranges, isa_ranges, sizeof (isa_ranges)); if (memcmp(isa_ranges, isa_test, sizeof (isa_test)) == 0) { int rc; of_printf("OF: fixing bogus ISA range on maple\n"); rc = of_setprop(isa, ranges, isa_fixed, sizeof (isa_fixed)); if (rc == OF_FAILURE) { of_panic("of_setprop() failed\n"); } } } }}void __init boot_of_serial(void *oft){ int n; int p; int rc; u32 val[3]; char buf[128]; n = of_instance_to_package(of_out); if (n == OF_FAILURE) { of_panic("instance-to-package of /chosen/stdout: failed\n"); } /* Prune all serial devices from the device tree, including the * one pointed to by /chosen/stdout, because a guest domain can * initialize them and in so doing corrupt our console output. */ for (p = n; p > 0; p = of_getpeer(p)) { char type[32]; rc = of_package_to_path(p, buf, sizeof(buf)); if (rc == OF_FAILURE) of_panic("package-to-path failed\n"); rc = of_getprop(p, "device_type", type, sizeof (type)); if (rc == OF_FAILURE) { of_printf("%s: fetching type of `%s' failed\n", __func__, buf); continue; } if (strcmp(type, "serial") != 0) continue; of_printf("pruning `%s' from devtree\n", buf); rc = ofd_prune_path(oft, buf); if (rc < 0) of_panic("prune of `%s' failed\n", buf); } p = of_getparent(n); if (p == OF_FAILURE) { of_panic("no parent for: 0x%x\n", n); } buf[0] = '\0'; of_getprop(p, "device_type", buf, sizeof (buf)); if (strstr(buf, "isa") == NULL) { of_panic("only ISA UARTS supported\n"); } /* should get this from devtree */ isa_io_base = 0xf4000000; of_printf("%s: ISA base: 0x%lx\n", __func__, isa_io_base); buf[0] = '\0'; of_getprop(n, "device_type", buf, sizeof (buf)); if (strstr(buf, "serial") == NULL) { of_panic("only UARTS supported\n"); } rc = of_getprop(n, "reg", val, sizeof (val)); if (rc == OF_FAILURE) { of_panic("%s: no location for serial port\n", __func__); } ns16550.baud = BAUD_AUTO; ns16550.data_bits = 8; ns16550.parity = 'n'; ns16550.stop_bits = 1; rc = of_getprop(n, "interrupts", val, sizeof (val)); if (rc == OF_FAILURE) { of_printf("%s: no ISRC, forcing poll mode\n", __func__); ns16550.irq = 0; } else { ns16550.irq = val[0]; of_printf("%s: ISRC=0x%x, but forcing poll mode\n", __func__, ns16550.irq); ns16550.irq = 0; }}static int __init boot_of_rtas(void){ int rtas_node; int rtas_instance; uint size = 0; int res[2]; int mem; int ret; rtas_node = of_finddevice("/rtas"); if (rtas_node <= 0) { of_printf("No RTAS, Xen has no power control\n"); return 0; } of_getprop(rtas_node, "rtas-size", &size, sizeof (size)); if (size == 0) { of_printf("RTAS, has no size\n"); return 0; } rtas_instance = of_open("/rtas"); if (rtas_instance == OF_FAILURE) { of_printf("RTAS, could not open\n"); return 0; } size = ALIGN_UP(size, PAGE_SIZE); mem = boot_of_alloc(size); if (mem == 0) of_panic("Could not allocate RTAS tree\n"); of_printf("instantiating RTAS at: 0x%x\n", mem); ret = of_call("call-method", 3, 2, res, "instantiate-rtas", rtas_instance, mem); if (ret == OF_FAILURE) { of_printf("RTAS, could not open\n"); return 0; } rtas_entry = res[1]; rtas_base = mem; rtas_end = mem + size; rtas_msr = of_msr; return 1;}void __init *boot_of_devtree(void){ void *oft; ulong oft_sz = 48 * PAGE_SIZE; ulong alloc_sz = 32 << 10; /* 32KiB should be plenty */ ulong sz; /* snapshot the tree */ oft = (void *)boot_of_alloc(alloc_sz); if (oft == NULL) of_panic("Could not allocate OFD tree\n"); of_printf("creating oftree at: 0x%p\n", oft); of_test("package-to-path"); oft = ofd_create(oft, alloc_sz); pkg_save(oft); sz = ofd_size(oft); if (sz > alloc_sz) of_panic("Could not fit all of native devtree in 0x%lx of memory\n", alloc_sz); boot_of_fixup_refs(oft); boot_of_fixup_chosen(oft); if (sz > alloc_sz) of_panic("Could not fit all devtree fixupsin 0x%lx of memory\n", alloc_sz); ofd_walk(oft, __func__, OFD_ROOT, /* add_hype_props */ NULL, 2); oftree = (ulong)oft; oftree = (ulong)oft + oft_sz; oftree_len = oft_sz; return oft;}static int __init boot_of_cpus(void){ int cpus_node, cpu_node; int bootcpu_instance, bootcpu_node; int logical; int result; s32 cpuid; u32 cpu_clock[2]; extern uint cpu_hard_id[NR_CPUS]; u32 tbf; /* Look up which CPU we are running on right now and get all info * from there */ result = of_getprop(bof_chosen, "cpu", &bootcpu_instance, sizeof (bootcpu_instance)); if (result == OF_FAILURE) of_panic("Failed to look up boot cpu instance\n"); bootcpu_node = of_instance_to_package(bootcpu_instance); if (result == OF_FAILURE) of_panic("Failed to look up boot cpu package\n"); cpu_node = bootcpu_node; result = of_getprop(cpu_node, "timebase-frequency", &tbf, sizeof(tbf)); timebase_freq = tbf; if (result == OF_FAILURE) { of_panic("Couldn't get timebase frequency!\n"); } of_printf("OF: timebase-frequency = %ld Hz\n", timebase_freq); result = of_getprop(cpu_node, "clock-frequency", &cpu_clock, sizeof(cpu_clock)); if (result == OF_FAILURE || (result !=4 && result != 8)) { of_panic("Couldn't get clock frequency!\n"); } cpu_khz = cpu_clock[0]; if (result == 8) { cpu_khz <<= 32; cpu_khz |= cpu_clock[1]; } cpu_khz /= 1000; of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz); /* We want a continuous logical cpu number space and we'll make * the booting CPU logical 0. */ cpu_set(0, cpu_present_map); cpu_set(0, cpu_online_map); cpu_set(0, cpu_possible_map); result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid)); cpu_hard_id[0] = cpuid; /* Spin up all CPUS, even if there are more than NR_CPUS or we are * runnign nosmp, because Open Firmware has them spinning on cache * lines which will eventually be scrubbed, which could lead to * random CPU activation. */ /* Find the base of the multi-CPU package node */ cpus_node = of_finddevice("/cpus"); if (cpus_node <= 0) { of_printf("Single Processor System\n"); return 1; } /* Start with the first child */ cpu_node = of_getchild(cpus_node); for (logical = 1; cpu_node > 0; logical++) { unsigned int ping, pong; unsigned long now, then, timeout; if (cpu_node == bootcpu_node) { /* same CPU as boot CPU shich we have already made 0 so * reduce the logical count */ --logical; } else { result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid)); if (result == OF_FAILURE) of_panic("cpuid lookup failed\n"); cpu_hard_id[logical] = cpuid; of_printf("spinning up secondary processor #%d: ", logical); __spin_ack = ~0x0; ping = __spin_ack; pong = __spin_ack; of_printf("ping = 0x%x: ", ping); mb(); result = of_start_cpu(cpu_node, (ulong)spin_start, logical); if (result == OF_FAILURE) of_panic("start cpu failed\n"); /* We will give the secondary processor five seconds to reply. */ then = mftb(); timeout = then + (5 * timebase_freq); do { now = mftb(); if (now >= timeout) { of_printf("BROKEN: "); break; } mb(); pong = __spin_ack; } while (pong == ping); of_printf("pong = 0x%x\n", pong); if (pong != ping) { cpu_set(logical, cpu_present_map); cpu_set(logical, cpu_possible_map); } } cpu_node = of_getpeer(cpu_node); } return 1;}void __init boot_of_init(ulong vec, ulong orig_msr){ int r; of_vec = vec; of_msr = orig_msr; if (is_kernel(vec)) { of_panic("Hmm.. OF[0x%lx] seems to have stepped on our image " "that ranges: %p .. %p.\n", vec, _start, _end); } of_printf("%s: _start %p _end %p\n", __func__, _start, _end); bof_chosen = of_finddevice("/chosen"); of_getprop(bof_chosen, "stdout", &of_out, sizeof (of_out)); of_printf("%s\n", "---------------------------------------------------"); of_printf("OF: Xen/PPC version %d.%d%s (%s@%s) (%s) %s\n", xen_major_version(), xen_minor_version(), xen_extra_version(), xen_compile_by(), xen_compile_domain(), xen_compiler(), xen_compile_date()); boot_of_fix_maple(); r = boot_of_mem_init(); if (r == 0) of_panic("failure to initialize memory allocator"); boot_of_rtas(); boot_of_cpus();}void __init boot_of_finish(void){ /* end of OF */ of_printf("Quiescing Open Firmware ...\n"); of_call("quiesce", 0, 0, NULL);}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -