[OpenBIOS] r33 - openbios-devel/arch/sparc32

svn@openbios.org svn at openbios.org
Fri May 26 12:37:37 CEST 2006


Author: stepan
Date: 2006-05-26 12:37:37 +0200 (Fri, 26 May 2006)
New Revision: 33

Modified:
   openbios-devel/arch/sparc32/romvec.c
Log:
make sparc32 boot linux. This should be stripped down again


Modified: openbios-devel/arch/sparc32/romvec.c
===================================================================
--- openbios-devel/arch/sparc32/romvec.c	2006-05-25 21:02:53 UTC (rev 32)
+++ openbios-devel/arch/sparc32/romvec.c	2006-05-26 10:37:37 UTC (rev 33)
@@ -26,6 +26,418 @@
 
 #define PAGE_SIZE 4096
 
+struct ob_property {
+    struct ob_property *next;
+    char *name;
+    char *value;
+    int length;
+};
+
+struct ob_node {
+    struct ob_node *next;
+    struct ob_node *peer;
+    struct ob_node *child;
+    struct ob_property *prop;
+    int id;
+};
+
+// Workarounds:
+
+// Proll device tree happens to work, why?
+#define PROLL_TREE
+
+// Build a static device tree to avoid Forth access from deep kernel
+//#define STATIC_TREE
+
+#ifdef PROLL_TREE
+struct property {
+	const char *name;
+	const char *value;
+	int length;
+};
+
+struct node {
+	const struct property *properties;
+	/* short */ const int sibling;
+	/* short */ const int child;
+};
+
+static const unsigned char obp_idprom[32] = { 1, 0x80, 0x52, 0x54, 0x00, 0x12, 0x34, 0x56,
+                                              0,0,0,0, 0,0,0, 0xf7 };
+static const struct property null_properties = { NULL, NULL, -1 };
+static const int prop_true = -1;
+
+static const struct property propv_root[] = {
+	{"name",	"SUNW,SparcStation-5", sizeof("SUNW,SparcStation-5") },
+	{"idprom",	(char *)obp_idprom, 32},
+	{"banner-name", "SparcStation", sizeof("SparcStation")},
+	{"compatible",	"sun4m", 6},
+	{NULL, NULL, -1}
+};
+
+static const int prop_iommu_reg[] = {
+	0x0, 0x10000000, 0x00000300,
+};
+static const struct property propv_iommu[] = {
+	{"name",	"iommu", sizeof("iommu")},
+	{"reg",		(char*)&prop_iommu_reg[0], sizeof(prop_iommu_reg) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_sbus_ranges[] = {
+	0x0, 0x0, 0x0, 0x30000000, 0x10000000,
+	0x1, 0x0, 0x0, 0x40000000, 0x10000000,
+	0x2, 0x0, 0x0, 0x50000000, 0x10000000,
+	0x3, 0x0, 0x0, 0x60000000, 0x10000000,
+	0x4, 0x0, 0x0, 0x70000000, 0x10000000,
+};
+static const struct property propv_sbus[] = {
+	{"name",	"sbus", 5},
+	{"ranges",	(char*)&prop_sbus_ranges[0], sizeof(prop_sbus_ranges)},
+	{"device_type",	"hierarchical", sizeof("hierarchical") },
+	{NULL, NULL, -1}
+};
+
+static const int prop_tcx_regs[] = {
+	0x2, 0x00800000, 0x00100000,
+	0x2, 0x02000000, 0x00000001,
+	0x2, 0x04000000, 0x00800000,
+	0x2, 0x06000000, 0x00800000,
+	0x2, 0x0a000000, 0x00000001,
+	0x2, 0x0c000000, 0x00000001,
+	0x2, 0x0e000000, 0x00000001,
+	0x2, 0x00700000, 0x00001000,
+	0x2, 0x00200000, 0x00000004,
+	0x2, 0x00300000, 0x0000081c,
+	0x2, 0x00000000, 0x00010000,
+	0x2, 0x00240000, 0x00000004,
+	0x2, 0x00280000, 0x00000001,
+};
+
+#if 1	/* Zaitcev */
+static const int pixfreq = 0x03dfd240;
+static const int hbporch = 0xa0;
+static const int vfreq = 0x3c;
+#endif
+#if 0	/* Kevin Boone - 70Hz refresh */
+static const int pixfreq = 0x047868C0;
+static const int hbporch = 0x90;
+static const int vfreq = 0x46;
+#endif
+
+static const int vbporch = 0x1d;
+static const int vsync = 0x6;
+static const int hsync = 0x88;
+static const int vfporch = 0x3;
+static const int hfporch = 0x18;
+static const int height = 0x300;
+static const int width = 0x400;
+static const int linebytes = 0x400;
+static const int depth = 24;
+static const int tcx_intr[] = { 5, 0 };
+static const int tcx_interrupts = 5;
+static const struct property propv_sbus_tcx[] = {
+	{"name",	"SUNW,tcx", sizeof("SUNW,tcx")},
+	{"vbporch",	(char*)&vbporch, sizeof(int)},
+	{"hbporch",	(char*)&hbporch, sizeof(int)},
+	{"vsync",	(char*)&vsync, sizeof(int)},
+	{"hsync",	(char*)&hsync, sizeof(int)},
+	{"vfporch",	(char*)&vfporch, sizeof(int)},
+	{"hfporch",	(char*)&hfporch, sizeof(int)},
+	{"pixfreq",	(char*)&pixfreq, sizeof(int)},
+	{"vfreq",	(char*)&vfreq, sizeof(int)},
+	{"height",	(char*)&height, sizeof(int)},
+	{"width",	(char*)&width, sizeof(int)},
+	{"linebytes",	(char*)&linebytes, sizeof(int)},
+	{"depth",	(char*)&depth, sizeof(int)},
+	{"reg",		(char*)&prop_tcx_regs[0], sizeof(prop_tcx_regs)},
+	{"tcx-8-bit",	0, -1},
+	{"intr",	(char*)&tcx_intr[0], sizeof(tcx_intr)},
+	{"interrupts",	(char*)&tcx_interrupts, sizeof(tcx_interrupts)},
+	{"device_type",	"display", sizeof("display")},
+	{NULL, NULL, -1}
+};
+
+static const int prop_cs4231_reg[] = {
+	0x3, 0x0C000000, 0x00000040
+};
+static const int cs4231_interrupts = 5;
+static const int cs4231_intr[] = { 5, 0 };
+
+static const struct property propv_sbus_cs4231[] = {
+	{"name",	"SUNW,CS4231", sizeof("SUNW,CS4231") },
+	{"intr",	(char*)&cs4231_intr[0], sizeof(cs4231_intr) },
+	{"interrupts",  (char*)&cs4231_interrupts, sizeof(cs4231_interrupts) },	
+	{"reg",		(char*)&prop_cs4231_reg[0], sizeof(prop_cs4231_reg) },
+	{"device_type", "serial", sizeof("serial") },
+	{"alias",	"audio", sizeof("audio") },
+	{NULL, NULL, -1}
+};
+
+static const int cpu_nctx = 256;
+static const int cpu_cache_line_size = 0x20;
+static const int cpu_cache_nlines = 0x200;
+static const struct property propv_cpu[] = {
+	{"name",	"STP1012PGA", sizeof("STP1012PGA") },
+	{"device_type",	"cpu", 4 },
+	{"mmu-nctx",	(char*)&cpu_nctx, sizeof(int)},
+	{"cache-line-size",	(char*)&cpu_cache_line_size, sizeof(int)},
+	{"cache-nlines",	(char*)&cpu_cache_nlines, sizeof(int)},
+	{NULL, NULL, -1}
+};
+
+static const int prop_obio_ranges[] = {
+	0x0, 0x0, 0x0, 0x71000000, 0x01000000,
+};
+static const struct property propv_obio[] = {
+	{"name",	"obio", 5 },
+	{"ranges",	(char*)&prop_obio_ranges[0], sizeof(prop_obio_ranges) },
+	{"device_type",	"hierarchical", sizeof("hierarchical") },
+	{NULL, NULL, -1}
+};
+
+static const int prop_auxio_reg[] = {
+	0x0, 0x00900000, 0x00000001,
+};
+static const struct property propv_obio_auxio[] = {
+	{"name",	"auxio", sizeof("auxio") },
+	{"reg",		(char*)&prop_auxio_reg[0], sizeof(prop_auxio_reg) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_int_reg[] = {
+	0x0, 0x00e00000, 0x00000010,
+	0x0, 0x00e10000, 0x00000010,
+};
+static const struct property propv_obio_int[] = {
+	{"name",	"interrupt", sizeof("interrupt")},
+	{"reg",		(char*)&prop_int_reg[0], sizeof(prop_int_reg) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_cnt_reg[] = {
+	0x0, 0x00d00000, 0x00000010,
+	0x0, 0x00d10000, 0x00000010,
+};
+static const struct property propv_obio_cnt[] = {
+	{"name",	"counter", sizeof("counter")},
+	{"reg",		(char*)&prop_cnt_reg[0], sizeof(prop_cnt_reg) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_eeprom_reg[] = {
+	0x0, 0x00200000, 0x00002000,
+};
+static const struct property propv_obio_eep[] = {
+	{"name",	"eeprom", sizeof("eeprom")},
+	{"reg",		(char*)&prop_eeprom_reg[0], sizeof(prop_eeprom_reg) },
+	{"model",	"mk48t08", sizeof("mk48t08")},
+	{NULL, NULL, -1}
+};
+
+static const int prop_su_reg[] = {
+	0x0, 0x003002f8, 0x00000008,
+};
+static const struct property propv_obio_su[] = {
+	{"name",	"su", sizeof("su")},
+	{"reg",		(char*)&prop_su_reg[0], sizeof(prop_su_reg) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_zs_intr[] = { 0x2c, 0x0 };
+static const int prop_zs_reg[] = {
+	0x0, 0x00000000, 0x00000008,
+};
+static void *prop_zs_addr;
+static const int prop_zs_slave = 1;
+static const struct property propv_obio_zs[] = {
+	{"name",	"zs", sizeof("zs")},
+	{"reg",		(char*)&prop_zs_reg[0], sizeof(prop_zs_reg) },
+	{"slave",	(char*)&prop_zs_slave, sizeof(prop_zs_slave) },
+	{"device_type", "serial", sizeof("serial") },
+	{"intr",	(char*)&prop_zs_intr[0], sizeof(prop_zs_intr) },
+	{"address",	(char*)&prop_zs_addr, sizeof(prop_zs_addr) },
+	{"keyboard",	(char*)&prop_true, 0},
+	{"mouse",	(char*)&prop_true, 0},
+	{NULL, NULL, -1}
+};
+
+static const int prop_zs1_intr[] = { 0x2c, 0x0 };
+static const int prop_zs1_reg[] = {
+	0x0, 0x00100000, 0x00000008,
+};
+static void *prop_zs1_addr;
+static const int prop_zs1_slave = 0;
+static const struct property propv_obio_zs1[] = {
+	{"name",	"zs", sizeof("zs")},
+	{"reg",		(char*)&prop_zs1_reg[0], sizeof(prop_zs1_reg) },
+	{"slave",	(char*)&prop_zs1_slave, sizeof(prop_zs1_slave) },
+	{"device_type", "serial", sizeof("serial") },
+	{"intr",	(char*)&prop_zs1_intr[0], sizeof(prop_zs1_intr) },
+	{"address",	(char*)&prop_zs1_addr, sizeof(prop_zs1_addr) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_ledma_reg[] = {
+	0x4, 0x08400010, 0x00000020,
+};
+static const int prop_ledma_burst = 0x3f;
+static const struct property propv_sbus_ledma[] = {
+	{"name",	"ledma", sizeof("ledma")},
+	{"reg",		(char*)&prop_ledma_reg[0], sizeof(prop_ledma_reg) },
+	{"burst-sizes",	(char*)&prop_ledma_burst, sizeof(int) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_le_reg[] = {
+	0x4, 0x08c00000, 0x00000004,
+};
+static const int prop_le_busmaster_regval = 0x7;
+static const int prop_le_intr[] = { 0x26, 0x0 };
+static const struct property propv_sbus_ledma_le[] = {
+	{"name",	"le", sizeof("le")},
+	{"reg",		(char*)&prop_le_reg[0], sizeof(prop_le_reg) },
+	{"busmaster-regval",	(char*)&prop_le_busmaster_regval, sizeof(int)},
+	{"intr",	(char*)&prop_le_intr[0], sizeof(prop_le_intr) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_espdma_reg[] = {
+	0x4, 0x08400000, 0x00000010,
+};
+
+static const struct property propv_sbus_espdma[] = {
+	{"name",	"espdma", sizeof("espdma")}, 
+	{"reg",		(char*)&prop_espdma_reg[0], sizeof(prop_espdma_reg) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_esp_reg[] = {
+	0x4, 0x08800000, 0x00000040,
+};
+static const int prop_esp_intr[] = { 0x24, 0x0 };
+static const struct property propv_sbus_espdma_esp[] = {
+	{"name",	"esp", sizeof("esp")},
+	{"reg",		(char*)&prop_esp_reg[0], sizeof(prop_esp_reg) },
+	{"intr",	(char*)&prop_esp_intr[0], sizeof(prop_esp_intr) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_bpp_reg[] = {
+	0x4, 0x0c800000, 0x0000001c,
+};
+static const int prop_bpp_intr[] = { 0x33, 0x0 };
+static const struct property propv_sbus_bpp[] = {
+	{"name",	"SUNW,bpp", sizeof("SUNW,bpp")},
+	{"reg",		(char*)&prop_bpp_reg[0], sizeof(prop_bpp_reg) },
+	{"intr",	(char*)&prop_bpp_intr[0], sizeof(prop_bpp_intr) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_apc_reg[] = {
+	0x4, 0x0a000000, 0x00000010,
+};
+static const struct property propv_sbus_apc[] = {
+	{"name",	"xxxpower-management", sizeof("xxxpower-management")},
+	{"reg",		(char*)&prop_apc_reg[0], sizeof(prop_apc_reg) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_fd_intr[] = { 0x2b, 0x0 };
+static const int prop_fd_reg[] = {
+	0x0, 0x00400000, 0x0000000f,
+};
+static const struct property propv_obio_fd[] = {
+	{"name",	"SUNW,fdtwo", sizeof("SUNW,fdtwo")},
+	{"reg",		(char*)&prop_fd_reg[0], sizeof(prop_fd_reg) },
+	{"device_type", "block", sizeof("block") },
+	{"intr",	(char*)&prop_fd_intr[0], sizeof(prop_fd_intr) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_pw_intr[] = { 0x22, 0x0 };
+static const int prop_pw_reg[] = {
+	0x0, 0x00910000, 0x00000001,
+};
+static const struct property propv_obio_pw[] = {
+	{"name",	"power", sizeof("power")},
+	{"reg",		(char*)&prop_pw_reg[0], sizeof(prop_pw_reg) },
+	{"intr",	(char*)&prop_pw_intr[0], sizeof(prop_pw_intr) },
+	{NULL, NULL, -1}
+};
+
+static const int prop_cf_reg[] = {
+	0x0, 0x00800000, 0x00000001,
+};
+static const struct property propv_obio_cf[] = {
+	{"name",	"slavioconfig", sizeof("slavioconfig")},
+	{"reg",		(char*)&prop_cf_reg[0], sizeof(prop_cf_reg) },
+	{NULL, NULL, -1}
+};
+
+static const struct property propv_options[] = {
+	{"name",	"options", sizeof("options")},
+	{"screen-#columns",	"80", sizeof("80")},
+	{"screen-#rows",	"25", sizeof("25")},
+	{"tpe-link-test?",	(char *)&prop_true, 0},
+	{"ttya-mode",		"9600,8,n,1,-", sizeof("9600,8,n,1,-")},
+	{"ttya-ignore-cd",	(char *)&prop_true, 0},
+	{"ttya-rts-dtr-off",	0, -1},
+	{"ttyb-mode",		"9600,8,n,1,-", sizeof("9600,8,n,1,-")},
+	{"ttyb-ignore-cd",	(char *)&prop_true, 0},
+	{"ttyb-rts-dtr-off",	0, -1},
+	{NULL, NULL, -1}
+};
+
+static int prop_mem_reg[3];
+static int prop_mem_avail[3];
+
+static const struct property propv_memory[] = {
+	{"name",	"memory", sizeof("memory")},
+	{"reg",		(char*)&prop_mem_reg[0], sizeof(prop_mem_reg) },
+	{"available",	(char*)&prop_mem_avail[0], sizeof(prop_mem_avail) },
+	{NULL, NULL, -1}
+};
+
+static int prop_vmem_avail[6];
+
+static const struct property propv_vmemory[] = {
+	{"name",	"virtual-memory", sizeof("virtual-memory")},
+	{"available",	(char*)&prop_vmem_avail[0], sizeof(prop_vmem_avail) },
+	{NULL, NULL, -1}
+};
+
+static const struct node nodes[] = {
+	{ &null_properties,	 1,  0 }, /* 0 = big brother of root */
+	{ propv_root,		 0,  2 }, /*  1 "/" */
+	{ propv_iommu,		12,  3 }, /*  2 "/iommu" */
+	{ propv_sbus,		 0,  4 }, /*  3 "/iommu/sbus" */
+	{ propv_sbus_tcx,	 5,  0 }, /*  4 "/iommu/sbus/SUNW,tcx" */
+	{ propv_sbus_ledma,	 7,  6 }, /*  5 "/iommu/sbus/ledma" */
+	{ propv_sbus_ledma_le,	 0,  0 }, /*  6 "/iommu/sbus/ledma/le" */
+	{ propv_sbus_cs4231,	 8,  0 }, /*  7 "/iommu/sbus/SUNW,CS4231 */
+	{ propv_sbus_bpp,	 9,  0 }, /*  8 "/iommu/sbus/SUNW,bpp */
+	{ propv_sbus_espdma,	11, 10 }, /*  9 "/iommu/sbus/espdma" */
+	{ propv_sbus_espdma_esp, 0,  0 }, /* 10 "/iommu/sbus/espdma/esp" */
+	{ propv_sbus_apc,	 0,  0 }, /* 11 "/iommu/sbus/power-management */
+	{ propv_cpu,		13,  0 }, /* 12 "/STP1012PGA" */
+	{ propv_obio,		23, 14 }, /* 13 "/obio" */
+	{ propv_obio_int,	15,  0 }, /* 14 "/obio/interrupt" */
+	{ propv_obio_cnt,	16,  0 }, /* 15 "/obio/counter" */
+	{ propv_obio_eep,	17,  0 }, /* 16 "/obio/eeprom" */
+	{ propv_obio_auxio,	18,  0 }, /* 17 "/obio/auxio" */
+	{ propv_obio_zs1,	19,  0 }, /* 18 "/obio/zs at 0,100000"
+					     Must be before zs at 0,0! */
+	{ propv_obio_zs,	20,  0 }, /* 19 "/obio/zs at 0,0" */
+	{ propv_obio_fd,	21,  0 }, /* 20 "/obio/SUNW,fdtwo" */
+	{ propv_obio_pw,	22,  0 }, /* 21 "/obio/power" */
+	{ propv_obio_cf,	 0,  0 }, /* 22 "/obio/slavioconfig at 0,800000" */
+	{ propv_options,	24,  0 }, /* 23 "/options" */
+	{ propv_memory,		25,  0 }, /* 24 "/memory" */
+	{ propv_vmemory,	 0,  0 }, /* 25 "/virtual-memory" */
+};
+#endif
+
 static struct linux_mlist_v0 totphys[1];
 static struct linux_mlist_v0 totmap[1];
 static struct linux_mlist_v0 totavail[1];
@@ -45,16 +457,6 @@
 static int obp_devread(int dev_desc, char *buf, int nbytes);
 static int obp_devseek(int dev_desc, int hi, int lo);
 
-static const struct linux_nodeops nodeops0 = {
-    obp_nextnode,	/* int (*no_nextnode)(int node); */
-    obp_child,	/* int (*no_child)(int node); */
-    obp_proplen,	/* int (*no_proplen)(int node, char *name); */
-    obp_getprop,	/* int (*no_getprop)(int node,char *name,char *val); */
-    obp_setprop,	/* int (*no_setprop)(int node, char *name,
-                           char *val, int len); */
-    obp_nextprop	/* char * (*no_nextprop)(int node, char *name); */
-};
-
 static struct linux_arguments_v0 obp_arg;
 static const struct linux_arguments_v0 * const obp_argp = &obp_arg;
 
@@ -67,8 +469,83 @@
 {
 }
 
+#ifdef PROLL_TREE
+static const struct property *find_property(int node,char *name)
+{
+	const struct property *prop = &nodes[node].properties[0];
+	while (prop && prop->name) {
+		if (strcmp(prop->name, name) == 0)
+                    return prop;
+		prop++;
+	}
+	return NULL;
+}
+
 static int obp_nextnode(int node)
 {
+        DPRINTF("obp_nextnode(%d) = %d\n", node, nodes[node].sibling);
+	return nodes[node].sibling;
+}
+
+static int obp_child(int node)
+{
+        DPRINTF("obp_child(%d) = %d\n", node, nodes[node].child);
+	return nodes[node].child;
+}
+
+static int obp_proplen(int node, char *name)
+{
+	const struct property *prop = find_property(node,name);
+	if (prop) {
+	    DPRINTF("obp_proplen(%d, %s) = %d\n", node, name, prop->length);
+	    return prop->length;
+	}
+	DPRINTF("obp_proplen(%d, %s) (no prop)\n", node, name);
+	return -1;
+}
+
+static int obp_getprop(int node, char *name, char *value)
+{
+	const struct property *prop;
+
+	if (!name || *name == '\0') {
+	    // NULL name means get first property
+	    DPRINTF("obp_getprop(%d, (NULL)) = %s\n", node,
+		   nodes[node].properties[0].name);
+	    return (int)nodes[node].properties[0].name;
+	}
+	prop = find_property(node,name);
+	if (prop) {
+		memcpy(value,prop->value,prop->length);
+		DPRINTF("obp_getprop(%d, %s) = %s\n", node, name, value);
+		return prop->length;
+	}
+        DPRINTF("obp_getprop(%d, %s): not found\n", node, name);
+	return -1;
+}
+
+static const char *obp_nextprop(int node,char *name)
+{
+	const struct property *prop;
+	
+	if (!name || *name == '\0') {
+	    // NULL name means get first property
+	    DPRINTF("obp_nextprop(%d, NULL) = %s\n", node,
+		   nodes[node].properties[0].name);
+	    return nodes[node].properties[0].name;
+	}
+	prop = find_property(node,name);
+	if (prop && prop[1].name) {
+	    DPRINTF("obp_nextprop(%d, %s) = %s\n", node, name, prop[1].name);
+	    return prop[1].name;
+	}
+        DPRINTF("obp_nextprop(%d, %s): not found\n", node, name);
+	return "";
+}
+
+#else
+static int obp_nextnode(int node)
+{
     int peer;
 
     PUSH(node);
@@ -117,16 +594,26 @@
 
 static int obp_getprop(int node, char *name, char *value)
 {
-    int notfound;
+    int notfound, found;
+    int len;
+    char *str;
 
     if (!name) {
         // NULL name means get first property
-        name = "NULL";
         push_str("");
         PUSH(node);
         fword("next-property");
-        notfound = POP();
-        notfound = !notfound; // Different return value
+        found = POP();
+        if (found) {
+            len = POP();
+            str = (char *) POP();
+            DPRINTF("obp_getprop(0x%x, NULL) = %s\n", node, str);
+
+            return (int)str;
+        }
+        DPRINTF("obp_getprop(0x%x, NULL) (not found)\n", node);
+
+        return -1;
     } else {
         push_str(name);
         PUSH(node);
@@ -138,12 +625,12 @@
 
         return -1;
     } else {
-        int len;
-        char *str;
-            
         len = POP();
         str = (char *) POP();
-        memcpy(value, str, len);
+        if (len > 0)
+            memcpy(value, str, len);
+        else
+            str = "NULL";
 
         DPRINTF("obp_getprop(0x%x, %s) = %s\n", node, name, str);
 
@@ -151,16 +638,6 @@
     }
 }
 
-static int obp_setprop(__attribute__((unused)) int node,
-		       __attribute__((unused)) char *name,
-		       __attribute__((unused)) char *value,
-		       __attribute__((unused)) int len)
-{
-    DPRINTF("obp_setprop(0x%x, %s) = %s (%d)\n", node, name, value, len);
-
-    return -1;
-}
-
 static const char *obp_nextprop(int node, char *name)
 {
     int found;
@@ -177,8 +654,6 @@
     found = POP();
     if (!found) {
         DPRINTF("obp_nextprop(0x%x, %s) (not found)\n", node, name);
-        (void) POP();
-        (void) POP();
 
         return "";
     } else {
@@ -193,7 +668,229 @@
         return str;
     }
 }
+#endif
 
+#ifdef STATIC_TREE
+static void
+get_props(struct ob_node *node)
+{
+    struct ob_property *currprop;
+    const char *name;
+
+    name = obp_nextprop(node->id, NULL);
+    if (!name || (int)name == -1) {
+        node->prop = NULL;
+        return;
+    }
+    node->prop = malloc(sizeof(*node->prop));
+    currprop = node->prop;
+    for (;;) {
+        currprop->length = obp_proplen(node->id, (char *)name);
+        currprop->name = malloc(strlen(name) + 1);
+        strcpy(currprop->name, name);
+        if (currprop->length > 0) {
+            currprop->value = malloc(currprop->length);
+            obp_getprop(node->id, currprop->name, currprop->value);
+        }
+
+        name = obp_nextprop(node->id, currprop->name);
+        if (!name || *name == '\0') {
+            currprop->next = NULL;
+            return;
+        } else {
+            currprop->next = malloc(sizeof(*currprop->next));
+            currprop = currprop->next;
+        }
+    }
+}
+
+static struct ob_node *
+get_node(struct ob_node *tree)
+{
+    struct ob_node *chain = tree;
+    int node;
+
+    if (tree->id)
+        get_props(tree);
+
+    DPRINTF("visiting 0x%x\n", tree->id);
+    node = obp_child(tree->id);
+    if (node) {
+        DPRINTF("visiting 0x%x's child 0x%x\n", tree->id, node);
+        tree->child = malloc(sizeof(*tree->child));
+        tree->child->id = node;
+        chain->next = tree->child;
+        chain = get_node(tree->child);
+    } else {
+        tree->child = NULL;
+    }
+    node = obp_nextnode(tree->id);
+    if (node) {
+        DPRINTF("visiting 0x%x's peer 0x%x\n", tree->id, node);
+        tree->peer = malloc(sizeof(*tree->peer));
+        tree->peer->id = node;
+        chain->next = tree->peer;
+        chain = get_node(tree->peer);
+    } else {
+        tree->peer = NULL;
+    }
+    return chain;
+}
+
+static struct ob_node *tree;
+
+static void
+get_tree(void)
+{
+    tree = malloc(sizeof(*tree));
+    tree->id = 0;
+    (void)get_node(tree);
+    DPRINTF("Static tree finished.\n");
+}
+
+static struct ob_node *find_node(int node)
+{
+    struct ob_node *onode;
+
+    for (onode = tree; onode != NULL && onode->id != node; onode = onode->next);
+
+    return onode;
+}
+
+static struct ob_property *find_static_property(int node, char *name)
+{
+    struct ob_node *onode = find_node(node);
+    struct ob_property *prop = onode->prop;
+
+    while (prop && prop->name) {
+        if (strcmp(prop->name, name) == 0)
+            return prop;
+        prop = prop->next;
+    }
+
+    return NULL;
+}
+
+static int obp_static_nextnode(int node)
+{
+    int nextnode = -1;
+    struct ob_node *onode = find_node(node);
+
+    if (onode && onode->peer)
+        nextnode = onode->peer->id;
+
+    DPRINTF("obp_static_nextnode(%d) = %d\n", node, nextnode);
+
+    return nextnode;
+}
+
+static int obp_static_child(int node)
+{
+    int child = -1;
+    struct ob_node *onode = find_node(node);
+
+    if (onode && onode->child)
+        child = onode->child->id;
+
+    DPRINTF("obp_static_child(%d) = %d\n", node, child);
+
+    return child;
+}
+
+static int obp_static_proplen(int node, char *name)
+{
+    struct ob_property *prop = find_static_property(node, name);
+
+    if (prop) {
+        DPRINTF("obp_static_proplen(%d, %s) = %d\n", node, name, prop->length);
+
+        return prop->length;
+    }
+
+    DPRINTF("obp_static_proplen(%d, %s) (no prop)\n", node, name);
+
+    return -1;
+}
+
+static int obp_static_getprop(int node, char *name, char *value)
+{
+    struct ob_node *currnode;
+    struct ob_property *prop;
+
+    if (!name || *name == '\0') {
+        // NULL name means get first property
+        currnode = find_node(node);
+        if (!currnode->prop) {
+            DPRINTF("obp_static_getprop(%d, (NULL)): not found\n", node);
+            return -1;
+        }
+        name = "NULL";
+        prop = currnode->prop;
+    } else {
+        prop = find_static_property(node, name);
+    }
+    if (prop && prop->length > 0) {
+        memcpy(value, prop->value, prop->length);
+        DPRINTF("obp_static_getprop(%d, %s) = %s\n", node, name, value);
+
+        return prop->length;
+    }
+
+    DPRINTF("obp_static_getprop(%d, %s): not found\n", node, name);
+
+    return -1;
+}
+
+static const char *obp_static_nextprop(int node, char *name)
+{
+    struct ob_property *prop;
+    struct ob_node *currnode = find_node(node);
+
+    if (!name || *name == '\0') {
+        // NULL name means get first property
+        if (!currnode->prop) {
+            DPRINTF("obp_static_nextprop(%d, (NULL)): not found\n", node);
+            return "";
+        }
+        prop = currnode->prop;
+    } else {
+	prop = find_static_property(node, name);
+        prop = prop->next;
+    }
+    if (prop && prop->name) {
+        DPRINTF("obp_static_nextprop(%d, %s) = %s\n", node, name, prop->name);
+        return prop->name;
+    }
+    DPRINTF("obp_static_nextprop(%d, %s): not found\n", node, name);
+    return "";
+}
+#define obp_nextnode obp_static_nextnode
+#define obp_child obp_static_child
+#define obp_proplen obp_static_proplen
+#define obp_getprop obp_static_getprop
+#define obp_nextprop obp_static_nextprop
+#endif
+
+static int obp_setprop(__attribute__((unused)) int node,
+		       __attribute__((unused)) char *name,
+		       __attribute__((unused)) char *value,
+		       __attribute__((unused)) int len)
+{
+    DPRINTF("obp_setprop(0x%x, %s) = %s (%d)\n", node, name, value, len);
+
+    return -1;
+}
+
+static const struct linux_nodeops nodeops0 = {
+    obp_nextnode,	/* int (*no_nextnode)(int node); */
+    obp_child,	        /* int (*no_child)(int node); */
+    obp_proplen,	/* int (*no_proplen)(int node, char *name); */
+    obp_getprop,	/* int (*no_getprop)(int node,char *name,char *val); */
+    obp_setprop,	/* int (*no_setprop)(int node, char *name,
+                           char *val, int len); */
+    obp_nextprop	/* char * (*no_nextprop)(int node, char *name); */
+};
+
 static int obp_nbgetchar(void)
 {
     return getchar();
@@ -209,21 +906,21 @@
 static void obp_reboot(char *str)
 {
     printk("rebooting (%s)\n", str);
-    outb(0x71f00000, 1);
+    outb(1, 0x71f00000);
     for (;;) {}
 }
 
 static void obp_abort(void)
 {
     printk("abort, power off\n");
-    outb(0x71910000, 1);
+    outb(1, 0x71910000);
     for (;;) {}
 }
 
 static void obp_halt(void)
 {
     printk("halt, power off\n");
-    outb(0x71910000, 1);
+    outb(1, 0x71910000);
     for (;;) {}
 }
 
@@ -427,6 +1124,21 @@
     totmap[0].start_adr = &_start;
     totmap[0].num_bytes = (unsigned long) &_iomem - (unsigned long) &_start;
 
+#ifdef PROLL_TREE
+    prop_mem_reg[0] = 0;
+    prop_mem_reg[1] = 0;
+    prop_mem_reg[2] = memsize;
+    prop_mem_avail[0] = 0;
+    prop_mem_avail[1] = 0;
+    prop_mem_avail[2] = va2pa((int)&_data) - 1;
+    prop_vmem_avail[0] = 0;
+    prop_vmem_avail[1] = 0;
+    prop_vmem_avail[2] = (int)&_start - 1;
+    prop_vmem_avail[3] = 0;
+    prop_vmem_avail[4] = 0xffe00000;
+    prop_vmem_avail[5] = 0x00200000;
+#endif
+
     // Linux wants a R/W romvec table
     romvec0.pv_magic_cookie = LINUX_OPPROM_MAGIC;
     romvec0.pv_romvers = 0;
@@ -462,7 +1174,7 @@
     romvec0.pv_v2devops.v2_dev_seek = obp_devseek;
     obp_arg.boot_dev_ctrl = 0;
     obp_arg.boot_dev_unit = 0;
-    obp_arg.dev_partition = 4;
+    obp_arg.dev_partition = 0;
     obp_arg.argv[0] = "sd(0,0,0):d";
 
     switch(boot_device) {
@@ -473,7 +1185,7 @@
         obp_arg.boot_dev[1] = 'd';
         break;
     case 'd':
-        obp_arg.boot_dev_unit = '2';
+        obp_arg.boot_dev_unit = 2;
         obp_arg.argv[0] = "sd(0,2,0):d";
         // Fall through
     case 'c':
@@ -507,5 +1219,8 @@
     romvec0.v3_cpuidle = obp_cpuidle;
     romvec0.v3_cpuresume = obp_cpuresume;
 
+#ifdef STATIC_TREE
+    get_tree();
+#endif
     return &romvec0;
 }




More information about the OpenBIOS mailing list