diff -r 56e1802303e5 xen/arch/ppc/boot_of.c
--- a/xen/arch/ppc/boot_of.c Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/arch/ppc/boot_of.c Fri Apr 21 10:41:42 2006 -0400
@@ -24,6 +24,36 @@
#include <xen/compile.h>
#include <public/of-devtree.h>
#include <asm/page.h>
+#include <xen/string.h>
+
+struct global_hardware_stuff {
+ int platform_type;
+ #define UNKNOWN_PLATFORM 1
+ #define PMAC_HARDWARE 2
+ #define MAPLE_SIM 3
+ #define MAPLE_HARDWARE 4
+ #define JS2X_HARDWARE 5
+
+ /* these are not definite platform but we start to isolate the type */
+ #define MAPLE_GENERIC 10 /* could be simulator(MAPLE_SIM) or
+ hardware(MAPLE_HARDWARE) or JX20 */
+
+ int hv_supported;
+
+ struct {
+ int type;
+ #define UART_UNKNOWN 0
+ #define UART_ZILOG 2
+ #define UART_NS16550 3
+
+ u64 uart_io_base;
+ u64 isa_io_base;
+ u32 clock;
+ // function serial port initialization routine
+ } serial_port;
+};
+static struct global_hardware_stuff global_hs;
+extern int opt_nohv;
static ulong of_vec;
static ulong of_msr;
@@ -152,6 +182,7 @@ static int __init of_getprop(int ph, con
if (rets[0] == OF_FAILURE) {
DBG("getprop 0x%x %s -> FAILURE\n", ph, name);
+ if (buflen > 0) memset(buf, 0, 1);
return OF_FAILURE;
}
@@ -301,6 +332,7 @@ static int __init of_instance_to_package
return rets[0];
}
+#endif
static int __init of_getparent(int ph)
{
@@ -311,8 +343,6 @@ static int __init of_getparent(int ph)
DBG("getparent 0x%x -> 0x%x\n", ph, rets[0]);
return rets[0];
}
-
-#endif
extern char _start[];
extern char _end[];
@@ -331,7 +361,6 @@ static void boot_of_probemem(multiboot_i
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",
@@ -786,10 +815,282 @@ static void boot_of_module(ulong r3, ulo
}
-int __init boot_of_serial(void)
-{
- /* right now we are punting and using mambo writes which is the
- * hardcoded setup */
+static void search_by_property_value(int p, const char *prop_name,
+ const char *prop_value)
+{
+ int pnext; /* of handdle */
+
+ do {
+ // does this package have the property 'prop_name' with
+ // value "prop_value"?
+ char of_property[256];
+ of_property[0] = '\0';
+ of_getprop(p, prop_name, of_property, sizeof (of_property));
+ if (strncmp(of_property, prop_value, sizeof (prop_value)) == 0) {
+ char path[256];
+ int sz = of_package_to_path(p, path, sizeof(path));
+ of_printf("\npackage with property '%s' with value '%s' found. "
+ "path is %s (size %d)\n", prop_name, prop_value,
+ path, sz);
+#ifdef OF_DEBUG
+ // Print all its properties
+ char name[128];
+ int result = of_nextprop(p, 0, name); /* first prop. */
+ while (result > 0) {
+ int sz;
+ u64 obj[1024];
+ sz = of_getproplen(p, name);
+ if (sz > 0) {
+ int actual = of_getprop(p, name, obj, sz);
+ of_printf("device property *%s* size %d value %s ",
+ name, actual, (char*)obj);
+ int i;
+ for (i=0; i<=(actual/sizeof(obj[0])); i++)
+ of_printf("0x%016lx ", obj[i]);
+ of_printf("\n");
+ } else if (0 == sz) {
+ of_printf("device property *%s* size 0\n",
+ name);
+ }
+
+ result = of_nextprop(p, name, name);
+ }
+#endif
+ }
+
+ /* do children first */
+ pnext = of_getchild(p);
+ if (pnext != 0) {
+ search_by_property_value(pnext, prop_name, prop_value);
+ }
+
+ p = of_getpeer(p);
+ } while (p != OF_FAILURE && p != 0);
+}
+
+
+/*
+ * Returns the value of the property '/#size-cells'
+ */
+int __init boot_of_get_sizecells_prop()
+{
+ int of_root;
+ u32 cell = 1;
+
+ of_root = of_finddevice("/");
+ if (OF_FAILURE != of_root)
+ of_getprop(of_root, "#size-cells", &cell, sizeof(cell));
+ return cell;
+}
+
+int __init boot_of_serial()
+{
+ int p, ofout; /* of handle */
+ int rc;
+ char of_property[256];
+ char ofout_path[256] = {0,};
+ const char serial[] = "serial";
+ const char macio[] = "mac-io";
+ const char escc[] = "escc";
+
+ #ifdef OF_DEBUG
+ {
+ p = of_finddevice("/");
+ const char device_type[] = "device_type";
+ search_by_property_value(p, device_type, serial);
+ }
+ #endif
+
+ global_hs.serial_port.type = UART_UNKNOWN;
+
+ /* copied and adapted from rhype */
+ ofout = OF_FAILURE;
+
+ /* probe /options tree */
+ rc = p = of_finddevice("/options");
+ if (p != OF_FAILURE) {
+ rc = of_getprop(p, "output-device", ofout_path, sizeof(ofout_path));
+ }
+ if (OF_FAILURE == rc) {
+ strncpy(ofout_path, serial, sizeof(serial));
+ }
+
+ /*
+ * if the options are not a path (they do not start with '/')
+ * then they are aliases and we must look them up. we look it
+ * up in aliases because it is possible that the OF does not
+ * support finddevice() of an alias.
+ */
+ if (ofout_path[0] != '/') {
+ p = of_finddevice("/aliases");
+ if (p != OF_FAILURE) {
+ char alias[256];
+ memcpy(alias, ofout_path, sizeof(alias));
+ rc = of_getprop(p, alias, ofout_path, sizeof (ofout_path));
+ }
+ }
+
+ if (OF_FAILURE != rc) {
+ ofout = of_finddevice(ofout_path);
+ } else {
+ s32 iout; /* ihandle ?? */
+ /*
+ * Our last chance is to figure out the package for
+ * the current console and hopefully discover it to be
+ * a serial device.
+ */
+ p = of_finddevice("/chosen");
+ if (p != OF_FAILURE) {
+ rc = of_getprop(p, "stdout", &iout, sizeof(iout));
+ }
+ if (rc != OF_FAILURE) {
+ rc = of_instance_to_path(iout, ofout_path, sizeof(ofout_path));
+ if (rc != OF_FAILURE)
+ ofout = of_finddevice(ofout_path);
+ }
+ }
+
+ DBG("serial port OF handle=0x%x\n", ofout);
+
+ if (OF_FAILURE == ofout) {
+ /* can try the rtas device. Code not written yet */
+ of_printf("Could not find any serial device\n");
+ return OF_FAILURE;
+ }
+
+
+ /* Now we have the OF handle of the serial device. Let's find out
+ * what it is and its address.
+ *
+ * The device must have of type 'serial'
+ *
+ * If the grandparent directory has the name 'mac-io', then this must
+ * be a power mac. The serial device is a zilog.
+ *
+ * Otherwise (we are assuming that) the grandparent has the name
+ * 'pci' and the parent 'isa'. The serial device is a NS16550.
+ *
+ * And what about the ns16750?
+ *
+ */
+ rc = of_getprop(ofout, "device_type", of_property, sizeof(of_property));
+ of_printf("serial device type %s\n", of_property);
+
+ union of_pci_hi {
+ u32 word;
+ struct {
+ u32 opa_n: 1; /* relocatable */
+ u32 opa_p: 1; /* prefetchable */
+ u32 opa_t: 1; /* aliased */
+ u32 _opa_res: 3;
+ u32 opa_s: 2; /* space code */
+ u32 opa_b: 8; /* bus number */
+ u32 opa_d: 5; /* device number */
+ u32 opa_f: 3; /* function number */
+ u32 opa_r: 8; /* register number */
+ } bits;
+ };
+ struct of_pci_addr_s {
+ union of_pci_hi opa_hi;
+ u32 opa_mid;
+ u32 opa_lo;
+ };
+
+ if (strncmp(of_property, serial, sizeof(serial))) {
+ of_printf("Serial device is not serial\n");
+ return OF_FAILURE;
+ }
+
+ int parent, grandparent; /* of handles */
+ parent = of_getparent(ofout);
+ if (OF_FAILURE == parent) return OF_FAILURE;
+ grandparent = of_getparent(parent);
+ if (OF_FAILURE == grandparent) return OF_FAILURE;
+
+ of_getprop(grandparent, "name", of_property, sizeof(of_property));
+ if (0 == strncmp(of_property, macio, sizeof(macio))) {
+ struct reg_property32 {
+ u32 address;
+ u32 size;
+ } reg;
+ struct of_pci_range32_s {
+ struct of_pci_addr_s opr_addr;
+ u32 opr_phys;
+ u32 opr_size;
+ } r32;
+
+ of_getprop(parent, "device_type", of_property, sizeof(of_property));
+ if (strncmp(of_property, escc, sizeof(escc))) {
+ of_printf("Serial device parent's type is not escc\n");
+ return OF_FAILURE;
+ }
+
+ if (global_hs.platform_type != PMAC_HARDWARE) {
+ of_printf("WARNING: serial device found in path mac-io"
+ "but we don't think this is a power mac\n");
+ return OF_FAILURE;
+ }
+
+ global_hs.serial_port.type = UART_ZILOG;
+ of_getprop(grandparent , "ranges", &r32, sizeof(r32));
+ of_getprop(ofout, "reg", ®, sizeof(reg));
+
+ of_printf("reg property address=0x%08x size=0x%08x\n",
+ reg.address, reg.size);
+ of_printf("ranges property %x:%x:%x %x %x\n",
+ r32.opr_addr.opa_hi.word,
+ r32.opr_addr.opa_mid,
+ r32.opr_addr.opa_lo,
+ r32.opr_phys, r32.opr_size);
+
+ global_hs.serial_port.uart_io_base = reg.address;
+ global_hs.serial_port.isa_io_base = r32.opr_phys;
+ /* io_addr = isa_io_base + uart_io_base; */
+ } else {
+ /* grandparent directory is not 'mac-io'. We are assuming 'pci/isa' */
+ struct isa_reg_property {
+ u32 space;
+ u32 address;
+ u32 size;
+ } isa_reg;
+ struct of_pci_range64_s {
+ struct of_pci_addr_s opr_addr;
+ u32 opr_phys_hi;
+ u32 opr_phys_lo;
+ u32 opr_size_hi;
+ u32 opr_size_lo;
+ } r64;
+ u32 clock;
+
+ global_hs.serial_port.type = UART_NS16550;
+ of_getprop(grandparent , "ranges", &r64, sizeof(r64));
+ of_getprop(ofout, "clock-frequency", &clock, sizeof (clock));
+ of_getprop(ofout, "reg", &isa_reg, sizeof(isa_reg));
+
+ of_printf("reg property address=0x%08x size=0x%08x\n",
+ isa_reg.address, isa_reg.size);
+ of_printf("ranges property %x:%x:%x %x:%x %x:%x\n",
+ r64.opr_addr.opa_hi.word,
+ r64.opr_addr.opa_mid,
+ r64.opr_addr.opa_lo,
+ r64.opr_phys_hi,
+ r64.opr_phys_lo,
+ r64.opr_size_hi, r64.opr_size_lo);
+
+ global_hs.serial_port.uart_io_base = isa_reg.address;
+ global_hs.serial_port.isa_io_base =
+ (((u64)r64.opr_phys_hi) << 32) | r64.opr_phys_lo;
+ global_hs.serial_port.clock = clock;
+ /* io_addr = isa_io_base + uart_io_base; */
+ }
+
+ of_printf("%s: serial type=%d io base=0x%016lx isa io@=0x%016lx "
+ "clock=%d\n",
+ __func__, global_hs.serial_port.type,
+ global_hs.serial_port.uart_io_base,
+ global_hs.serial_port.isa_io_base,
+ global_hs.serial_port.clock
+ );
return 1;
}
@@ -825,6 +1126,119 @@ int __init boot_of_rtas(void)
return 1;
}
+/*
+ * Returns the length of the OF compatible property; OF_FAILURE on error
+ * The value of the property itself is returned in the first parameter.
+ */
+int __init boot_of_get_compatible_prop(char *cstring, int cstring_size)
+{
+ int of_root;
+ int comp_length;
+
+ of_root = of_finddevice("/");
+ if (OF_FAILURE == of_root) return OF_FAILURE;
+
+ comp_length = of_getprop(of_root, "compatible", cstring, cstring_size);
+ #if 0
+ if (comp_length != OF_FAILURE) {
+ // null separated string yuck
+ int used_length;
+ of_printf("%s :\n", __func__);
+ for (used_length = 0; used_length < comp_length; used_length++) {
+ if (cstring[used_length] == '\0' ) {
+ of_printf(" NULL\n");
+ } else {
+ of_printf("%c", cstring[used_length]);
+ }
+ }
+ }
+ #endif
+
+ return comp_length;
+}
+
+/*
+ * Does the compatible of property indicate that the platform is a Power
+ * Macintosh, or a maple (hardware or simulated), or ..
+ * return 0 if not an known value;
+ */
+int __init boot_of_platform(char * compatible_p, int c_length)
+{
+ static const char pmac_string[] = "Power Macintosh";
+ static const char maple_string[] = "Momentum,Maple";
+ static const char JS_20[] = "junk";
+
+ char *cmpstr;
+ int used_length;
+
+ // loop over each null terminated piece of the compatible property
+ for (cmpstr = compatible_p, used_length = 0; used_length < c_length;
+ cmpstr = &compatible_p[used_length]) {
+ if (strstr(cmpstr, pmac_string)) return PMAC_HARDWARE;
+ if (strstr(cmpstr, maple_string)) return MAPLE_GENERIC;
+ if (strstr(cmpstr, JS_20)) return JS2X_HARDWARE;
+ used_length += strlen(cmpstr) + 1;
+ }
+
+ return 0;
+}
+
+void __init boot_of_hardware_specific()
+{
+ int rc;
+ char compatible_string[256];
+ int compatible_length;
+ int cell;
+
+ memset(&global_hs, 0, sizeof(global_hs));
+ global_hs.platform_type = UNKNOWN_PLATFORM;
+
+ compatible_length = boot_of_get_compatible_prop(compatible_string,
+ sizeof(compatible_string));
+
+ if (compatible_length != OF_FAILURE) {
+ rc = boot_of_platform(compatible_string, compatible_length);
+ cell = boot_of_get_sizecells_prop();
+ switch (rc) {
+ default:
+ of_printf("Warning: %s is not aware of this machine type %d\n",
+ __func__, rc);
+ break;
+
+ case 0:
+ // did not learn anything
+ break;
+
+ case PMAC_HARDWARE:
+ global_hs.platform_type = rc;
+ if (cell != 1) of_panic("powermac with cell %d\n", cell);
+
+ /*
+ * Power Macintosh' do not distinguish between supervisor and
+ * hypervisor mode. Hence, we run, if at all, with in a special
+ * mode called non-hypervisor hypervisor. (nohv)
+ */
+ of_printf("Non hypervisor hardware found.\n");
+ global_hs.hv_supported = 0;
+ opt_nohv = 1;
+ break;
+
+ case MAPLE_GENERIC:
+ global_hs.platform_type = rc;
+ if (cell != 2) of_panic("maple like thing with cell %d\n", cell);
+ global_hs.hv_supported = 1;
+ break;
+ }
+ }
+
+ of_printf("%s: type=%d hv=%d\n", __func__, global_hs.platform_type,
+ global_hs.hv_supported);
+
+ boot_of_serial();
+ boot_of_rtas();
+}
+
+
multiboot_info_t __init *boot_of_init(
ulong r3, ulong r4, ulong vec, ulong r6, ulong r7, ulong orig_msr)
{
@@ -858,9 +1272,16 @@ multiboot_info_t __init *boot_of_init(
boot_of_probemem(&mbi);
boot_of_bootargs(&mbi);
boot_of_module(r3, r4, &mbi);
- boot_of_serial();
boot_of_cpus();
- boot_of_rtas();
+
+ /* Note: serial and rtas were before cpus, but should really happen after
hardware
+ * specific, since we want to use the machine type as a hint of where/what
+ * the serial device might be
+ *
+ * If serial initalization needs to be before cpus, then we need to move up
+ * hardware specific as well.
+ */
+ boot_of_hardware_specific();
/* end of OF */
of_printf("closing OF stdout...\n");
diff -r 56e1802303e5 xen/arch/ppc/setup.c
--- a/xen/arch/ppc/setup.c Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/arch/ppc/setup.c Fri Apr 21 10:41:42 2006 -0400
@@ -43,6 +43,12 @@ int opt_noht = 0;
int opt_noht = 0;
boolean_param("noht", opt_noht);
+/* opt_nohv: If true, hardware has no hypervisor (HV) mode or nohv boot
+ * parameter was specified.
+ */
+int opt_nohv = 0;
+boolean_param("nohv", opt_nohv);
+
int opt_earlygdb = 0;
boolean_param("earlygdb", opt_earlygdb);
@@ -282,6 +288,8 @@ static void __init __start_xen(multiboot
if (dom0 == NULL)
panic("Error creating domain 0\n");
set_bit(_DOMF_privileged, &dom0->domain_flags);
+ if (opt_nohv)
+ set_bit(_DOMF_prob, &dom0->domain_flags);
/* Grab the DOM0 command line. Skip past the image name. */
cmdline = (char *)(mod[0].string ? __va((ulong)mod[0].string) : NULL);
diff -r 56e1802303e5 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/include/xen/sched.h Fri Apr 21 10:41:42 2006 -0400
@@ -392,6 +392,10 @@ extern struct domain *domain_list;
/* Domain is being debugged by controller software. */
#define _DOMF_debugging 4
#define DOMF_debugging (1UL<<_DOMF_debugging)
+ /* run domain in prob mode */
+#define _DOMF_prob 7
+#define DOMF_prob (1UL<<_DOMF_prob)
+
static inline int vcpu_runnable(struct vcpu *v)
{
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel