diff --git a/Makefile b/Makefile index 0680db73a6..140ef175e5 100644 --- a/Makefile +++ b/Makefile @@ -299,7 +299,7 @@ AFLAGS_KERNEL = # Use LINUXBIOSINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option -LINUXBIOSINCLUDE := -Iinclude \ +LINUXBIOSINCLUDE := -I$(srctree) -Iinclude \ -I$(srctree)/include \ -I$(srctree)/include/cpu/generic/$(ARCH)/ \ -include $(srctree)/include/linuxbios/autoconf.h diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 27113c00b8..6328ccc6fe 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -20,3 +20,10 @@ #obj-y += init/ +define archhelp + echo '* linuxbios.rom - Compressed kernel image (arch/$(ARCH)/linuxbios.rom)' + echo ' install - Install kernel using' + echo ' fdimage - Create a bios update floppy image' +endef + + diff --git a/arch/x86/Makefile.target b/arch/x86/Makefile.target index 686ccd6dd7..b0c31605a2 100644 --- a/arch/x86/Makefile.target +++ b/arch/x86/Makefile.target @@ -93,10 +93,10 @@ linuxbios.init: # Do we want to put our own stuff there, too? # -linuxbios.vpd: - $(Q)printf "Building dummy VPD ..." - $(Q)dd if=/dev/zero of=$(objtree)/linuxbios.vpd bs=240 count=1 # 0xf0 - $(Q)printf "ok.\n" +#linuxbios.vpd: +# $(Q)printf "Building dummy VPD ..." +# $(Q)dd if=/dev/zero of=$(objtree)/linuxbios.vpd bs=240 count=1 # 0xf0 +# $(Q)printf "ok.\n" # # Compose the image: @@ -111,7 +111,7 @@ linuxbios.rom: linuxbios.lar linuxbios.init linuxbios.vpd linuxbios.jump $(objtree)/mainboard.o: $(objtree)/statictree.o $(objtree)/statictree.o: $(objtree)/statictree.c - $(CC) -c -o $(objtree)/statictree.o $(objtree)/statictree.c + $(CC) $(CFLAGS) $(LINUXBIOSINCLUDE) -c -o $(objtree)/statictree.o $(objtree)/statictree.c $(objtree)/statictree.c: $(shell echo $(srctree)/mainboard/$(CONFIG_MAINBOARD_NAME)/dts) $(objtree)/dtc $(objtree)/dtc -O lb $(shell echo $(srctree)/mainboard/$(CONFIG_MAINBOARD_NAME)/dts) >$(objtree)/statictree.c diff --git a/mainboard/emulation/qemu-i386/Makefile b/mainboard/emulation/qemu-i386/Makefile index 7d0e5ea5e6..1f58f8aa05 100644 --- a/mainboard/emulation/qemu-i386/Makefile +++ b/mainboard/emulation/qemu-i386/Makefile @@ -18,13 +18,4 @@ obj-y = setup_before_car.o # $(MAKE) -C $(srctree)/util/dtc/ # cp $(srctree)/util/dtc/dtc $(obj) -# -# This is duplicate in arch/x86/ where it does not belong. -# How can we cross reference? -# -linuxbios.vpd: - $(Q)printf "Building dummy VPD ..." - $(Q)dd if=/dev/zero of=$(objtree)/linuxbios.vpd bs=$(( 0xf0 )) count=1 - $(Q)printf "ok.\n" - diff --git a/mainboard/emulation/qemu-i386/dts b/mainboard/emulation/qemu-i386/dts index f14ada765b..25ead1adbf 100644 --- a/mainboard/emulation/qemu-i386/dts +++ b/mainboard/emulation/qemu-i386/dts @@ -1,50 +1,29 @@ /{ - model = "qemu"; - #address-cells = <1>; - #size-cells = <1>; - compatible = "emulation-i386,qemu"; cpus { - #address-cells = <1>; - #size-cells = <0>; - + config="mainboard,emulation,qemu-i386"; emulation,qemu-i386@0{ - name = "emulation,qemu-i386"; + enabled; + on_mainboard; device_type = "cpu"; - clock-frequency = <5f5e1000>; - timebase-frequency = <1FCA055>; - linux,boot-cpu; - reg = <0>; - i-cache-size = <2000>; - d-cache-size = <2000>; - }; - }; + name = "emulation,qemu-i386"; + pcidomain = "0"; - memory@0 { - device_type = "memory"; - reg = <00000000 20000000>; - }; - - /* the I/O stuff */ - northbridge,intel,440bx{ - associated-cpu = <&/cpus/emulation,qemu-i386@0>; - southbridge,intel,piix4{ - superio,nsc,sucks{ - uart@0{ - enabled=<1>; + /* the I/O stuff */ + northbridge,intel,440bx{ + pcipath = "0,0"; + southbridge,intel,piix4{ }; }; }; }; - chosen { - bootargs = "root=/dev/sda2"; - linux,platform = <00000600>; - linux,stdout-path="/dev/ttyS0"; - }; - options { - normal="normal"; - fallback="fallback"; - }; - }; + +%% + +struct mainboard_emulation_qemu_i386_config cpus = { + .nothing = 1, +}; + + diff --git a/util/dtc/dtc-lexer.l b/util/dtc/dtc-lexer.l index c0822282cd..0778af0c88 100644 --- a/util/dtc/dtc-lexer.l +++ b/util/dtc/dtc-lexer.l @@ -23,6 +23,7 @@ %x CELLDATA %x BYTESTRING %x MEMRESERVE +%x PASSTHROUGH PROPCHAR [a-zA-Z0-9,._+*#?-] UNITCHAR [0-9a-f,] @@ -43,7 +44,7 @@ REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@]) #define DPRINT(fmt, ...) do { } while (0) #endif - +char *code = 0; %} @@ -58,6 +59,22 @@ REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@]) return DT_STRING; } +^%%\n { + DPRINT("Begin passthrough\n"); + /* let's be stupid. 1 MB is way more than enough ... */ + code = malloc(1048576); + *code = 0; + BEGIN(PASSTHROUGH); + } + +.* { + DPRINT("Matchingin passthrough %s\n", yytext); + /* you tell me why echo does not work */ + /*ECHO;*/ + strcat(code, yytext); + strcat(code, "\n"); + } + "/memreserve/" { yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); diff --git a/util/dtc/dtc-parser.y b/util/dtc/dtc-parser.y index 16d22770c8..76257ef5b6 100644 --- a/util/dtc/dtc-parser.y +++ b/util/dtc/dtc-parser.y @@ -46,7 +46,7 @@ extern struct boot_info *the_boot_info; struct reserve_info *re; } -%token DT_MEMRESERVE +%token DT_MEMRESERVE %token DT_ADDR %token DT_PROPNAME %token DT_NODENAME @@ -56,9 +56,13 @@ extern struct boot_info *the_boot_info; %token DT_UNIT %token DT_LABEL %token DT_REF +%token DT_CONFIG %type propdata %type memreserve +/* +%type config + */ %type memreserves %type celllist %type bytestring @@ -71,11 +75,14 @@ extern struct boot_info *the_boot_info; %type subnodes %type label %type nodename - +%type includepath +%type structname %% -sourcefile: memreserves devicetree { - the_boot_info = build_boot_info($1, $2); +/*sourcefile: memreserves devicetree {*/ +sourcefile: devicetree { +/* the_boot_info = build_boot_info($1, $2);*/ + the_boot_info = build_boot_info(0, $1); } ; @@ -113,6 +120,23 @@ proplist: propdef proplist { } ; +/* I doubt we will do this +config: DT_CONFIG '(' includepath ',' structname ')' ';' { + $$ = setupconfig($3, $5); + } + | + { + $$ = NULL; + } + ; + */ + +includepath: DT_STRING { $$ = $1; } + ; + +structname: DT_STRING {$$ = $1; } + ; + propdef: label DT_PROPNAME '=' propdata ';' { $$ = build_property($2, $4, $1); } diff --git a/util/dtc/dtc.h b/util/dtc/dtc.h index 188c45ab21..2ba319d58b 100644 --- a/util/dtc/dtc.h +++ b/util/dtc/dtc.h @@ -152,6 +152,7 @@ struct node { struct node *parent; struct node *next_sibling; + struct node *next; char *fullpath; int basenamelen; diff --git a/util/dtc/flattree.c b/util/dtc/flattree.c index bb693f77fb..2174b85223 100644 --- a/util/dtc/flattree.c +++ b/util/dtc/flattree.c @@ -79,6 +79,31 @@ clean(char *name, int instantiate){ return cleanname; } +char * +topath(struct property *p){ + struct data d = p->val; + int i = 0; + char *pathname, *cp; + + pathname = malloc(d.len + 1); + + for(cp = pathname, i = 0; i < d.len; i++, cp++) { + switch(d.val[i]){ + case '@': + *cp = 0; + break; + case ',': + *cp = '/'; + break; + default: + *cp = d.val[i]; + break; + } + } + *cp++ = 0; + return pathname; +} + static void bin_emit_cell(void *e, cell_t val) @@ -473,15 +498,62 @@ static void linuxbios_emit_property(void *e, char *label) static void linuxbios_emit_special(void *e, struct node *tree) { FILE *f = e; + struct property *prop; fprintf(f, "struct device dev_%s = {\n", tree->label); - if (tree->next_sibling) - fprintf(f, "\t.sibling = dev_%s\n", tree->next_sibling->label); - /* now do we do next? */ - if (tree->children) - fprintf(f, "\t.children = dev_%s\n", tree->children->label); + /* special case -- the root has a distinguished path */ + if (! strncmp(tree->label, "root", 4)){ + fprintf(f, "\t.path = { .type = DEVICE_PATH_ROOT },\n"); + } - fprintf(f, "}\n"); + for_each_property(tree, prop) { + if (streq(prop->name, "pcidomain")){ + fprintf(f, "\t.path = {.type=DEVICE_PATH_PCI_DOMAIN,.u={.pci_domain={ .domain = %s }}},\n", + prop->val.val); + } + if (streq(prop->name, "pcipath")){ + fprintf(f, "\t.path = {.type=DEVICE_PATH_PCI,.u={.pci={ .devfn = PCI_DEVFN(%s)}}},\n", + prop->val.val); + } + /* to do: check the value, maybe. Kinda pointless though. */ + if (streq(prop->name, "on_mainboard")){ + fprintf(f, "\t.on_mainboard = 1,\n"); + } + if (streq(prop->name, "enabled")){ + fprintf(f, "\t.enabled = 1,\n"); + } + + if (streq(prop->name, "config")){ + fprintf(f, "\t.chip_ops = &%s_ops,\n", clean(prop->val.val, 0)); + fprintf(f, "\t.chip_info = &%s,\n", clean(tree->label, 1)); + } + + } + if (tree->next_sibling) + fprintf(f, "\t.sibling = dev_%s;\n", tree->next_sibling->label); + /* now do we do next? */ + /* this will need to do a bus for every child. And, below, we're going to need to find which bus we're on*/ + /* for now, let's keep it to the minimum that will work, while we see if we like this. */ + if (tree->children){ + fprintf(f,"\t.links = 1,\n"); + fprintf(f,"\t.link = {\n"); + fprintf(f,"\t\t[0] = {\n"); + fprintf(f,"\t\t\t.dev = &dev_%s,\n", tree->label); + fprintf(f,"\t\t\t.link = 0,\n"); + fprintf(f,"\t\t\t.children = &dev_%s\n", tree->children->label); + fprintf(f,"\t\t},\n"); + fprintf(f,"\t},\n"); + } + /* fill in the 'bus I am on' entry */ + if (tree->parent) + fprintf(f, "\t.bus = &dev_%s.link[0],\n", tree->parent->label); + else + fprintf(f, "\t.bus = &dev_%s.link[0],\n", tree->label); + + if (tree->next) + fprintf(f, "\t.next = &dev_%s,\n", tree->next->label); + + fprintf(f, "};\n"); } static struct emitter linuxbios_emitter = { @@ -511,6 +583,31 @@ static int stringtable_insert(struct data *d, char *str) return i; } +/* we're going to overload the name node for testing. This may be the wrong thing long-term */ +static void flatten_tree_emit_includes(struct node *tree, struct emitter *emit, + void *etarget, struct data *strbuf, + struct version_info *vi) +{ + char *pathname; + struct property *prop; + struct node *child; + FILE *f = etarget; + + for_each_property(tree, prop) { + if (streq(prop->name, "config")) { + pathname = topath(prop); + fprintf(f, "#include <%s/config.h>\n", pathname); + free(pathname); + } + } + + for_each_child(tree, child) { + flatten_tree_emit_includes(child, emit, etarget, strbuf, vi); + } + + +} + static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emit, void *etarget, struct data *strbuf, @@ -570,31 +667,33 @@ static void flatten_tree_emit_structinits(struct node *tree, struct emitter *emi struct node *child; int seen_name_prop = 0; FILE *f = etarget; - +/* treename = clean(tree->name, 0); fprintf(f, "struct %s %s = {\n", treename, tree->label); free(treename); - +*/ #if 0 if (vi->flags & FTF_FULLPATH) emit->string(etarget, tree->fullpath, 0); else emit->string(etarget, tree->name, 0); #endif - +/* for_each_property(tree, prop) { if (streq(prop->name, "name")) seen_name_prop = 1; emit->data(etarget, prop); } + */ #if 0 if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) { fprintf(f, "\tu8 %s[%d]\n", prop->name, prop->data.len); } #endif - +/* emit->endnode(etarget, tree->label); +*/ /* now emit the device for this node, with sibling and child pointers etc. */ emit->special(f, tree); @@ -978,6 +1077,9 @@ void dt_to_linuxbios(FILE *f, struct boot_info *bi, int version, int boot_cpuid_ int i; struct data strbuf = empty_data; char *symprefix = "dt"; + extern char *code; + struct node *next; + extern struct node *first_node; labeltree(bi->dt); @@ -994,9 +1096,23 @@ void dt_to_linuxbios(FILE *f, struct boot_info *bi, int version, int boot_cpuid_ bi->dt->name = bi->dt->label = "root"; /* steps: emit all structs. Then emit the initializers, with the pointers to other structs etc. */ - flatten_tree_emit_structdecls(bi->dt, &linuxbios_emitter, f, &strbuf, vi); + /* emit any includes that we need -- TODO: ONLY ONCE PER TYPE*/ + fprintf(f, "#include \n#include \n"); + flatten_tree_emit_includes(bi->dt, &linuxbios_emitter, f, &strbuf, vi); + /* forward declarations */ + for(next = first_node; next; next = next->next) + fprintf(f, "struct device dev_%s;\n", next->label); + + /* emit the code, if any */ + if (code) + fprintf(f, "%s\n", code); + + +// flatten_tree_emit_structdecls(bi->dt, &linuxbios_emitter, f, &strbuf, vi); flatten_tree_emit_structinits(bi->dt, &linuxbios_emitter, f, &strbuf, vi); data_free(strbuf); + /* */ + } diff --git a/util/dtc/livetree.c b/util/dtc/livetree.c index f64de0174d..bacee0df1c 100644 --- a/util/dtc/livetree.c +++ b/util/dtc/livetree.c @@ -24,6 +24,8 @@ * Tree building functions */ +struct node *first_node = NULL; + struct property *build_property(char *name, struct data val, char *label) { struct property *new = xmalloc(sizeof(*new)); @@ -48,6 +50,8 @@ struct property *chain_property(struct property *first, struct property *list) struct node *build_node(struct property *proplist, struct node *children) { + static struct node *last_node = NULL; + struct node *new = xmalloc(sizeof(*new)); struct node *child; @@ -60,6 +64,14 @@ struct node *build_node(struct property *proplist, struct node *children) child->parent = new; } + if (last_node) + last_node->next = new; + + last_node = new; + + if (! first_node) + first_node = new; + return new; } @@ -288,6 +300,7 @@ static struct { } prop_checker_table[] = { {"name", must_be_string}, {"name", name_prop_check}, +/* we don't care about these things now -- we think */ {"linux,phandle", must_be_one_cell}, {"#address-cells", must_be_one_cell}, {"#size-cells", must_be_one_cell}, @@ -446,12 +459,12 @@ static int check_root(struct node *root) struct property *prop; int ok = 1; - CHECK_HAVE_STRING(root, "model"); +// CHECK_HAVE_STRING(root, "model"); - CHECK_HAVE(root, "#address-cells"); - CHECK_HAVE(root, "#size-cells"); +// CHECK_HAVE(root, "#address-cells"); +// CHECK_HAVE(root, "#size-cells"); - CHECK_HAVE_WARN(root, "compatible"); +// CHECK_HAVE_WARN(root, "compatible"); return ok; } @@ -469,20 +482,20 @@ static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys) return 0; } - CHECK_HAVE_WARN(cpus, "#address-cells"); - CHECK_HAVE_WARN(cpus, "#size-cells"); +// CHECK_HAVE_WARN(cpus, "#address-cells"); +// CHECK_HAVE_WARN(cpus, "#size-cells"); for_each_child(cpus, cpu) { CHECK_HAVE_STREQ(cpu, "device_type", "cpu"); - +#ifdef NOTDEF if (cpu->addr_cells != 1) DO_ERR("%s has bad #address-cells value %d (should be 1)\n", cpu->fullpath, cpu->addr_cells); if (cpu->size_cells != 0) DO_ERR("%s has bad #size-cells value %d (should be 0)\n", cpu->fullpath, cpu->size_cells); - - CHECK_HAVE_ONECELL(cpu, "reg"); +#endif +// CHECK_HAVE_ONECELL(cpu, "reg"); if (prop) { cell_t unitnum; char *eptr; @@ -499,12 +512,13 @@ static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys) /* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */ /* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */ - CHECK_HAVE_ONECELL(cpu, "d-cache-size"); - CHECK_HAVE_ONECELL(cpu, "i-cache-size"); +// CHECK_HAVE_ONECELL(cpu, "d-cache-size"); +// CHECK_HAVE_ONECELL(cpu, "i-cache-size"); - CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency"); - CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency"); +// CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency"); +// CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency"); +#ifdef NOT prop = get_property(cpu, "linux,boot-cpu"); if (prop) { if (prop->val.len) @@ -516,8 +530,10 @@ static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys) else bootcpu = cpu; } +#endif } +#ifdef NOT if (outversion < 2) { if (! bootcpu) WARNMSG("No cpu has \"linux,boot-cpu\" property\n"); @@ -527,6 +543,7 @@ static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys) if (boot_cpuid_phys == 0xfeedbeef) WARNMSG("physical boot CPU not set. Use -b option to set\n"); } +#endif return ok; } @@ -721,8 +738,8 @@ int check_device_tree(struct node *dt, int outversion, int boot_cpuid_phys) ok = ok && check_root(dt); ok = ok && check_cpus(dt, outversion, boot_cpuid_phys); - ok = ok && check_memory(dt); - ok = ok && check_chosen(dt); +// ok = ok && check_memory(dt); +// ok = ok && check_chosen(dt); if (! ok) return 0;