From b1e09fa0542841fee16e0ed62e789cee22bd74a4 Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Wed, 11 Apr 2001 21:38:46 +0000 Subject: [PATCH] Chances for the new superio setup. pci.h has new structs. newpci.c has some new functions. asus config is fixed for i386 stuff. NLBconfig has a new command (nsuperio) and will take arch, mainboard, or target as the first command. sis 950 superio has changes for the new superio model --- src/arch/i386/lib/hardwaremain.c | 23 ++++- src/include/pci.h | 64 +++++++++++++ src/lib/newpci.c | 89 ++++++++++++++++++ src/mainboard/asus/cua/Config | 1 + src/mainboard/compaq/ds10/Config | 1 + src/mainboard/gigabit/ga-6bxc/Config | 1 + src/mainboard/intel/l440gx/Config | 1 + src/mainboard/irobot/proto1/Config | 1 + src/mainboard/lanner/em-370/Config | 1 + src/mainboard/leadtek/winfast6300/Config | 4 +- src/mainboard/leadtek/winfast6300/mainboard.c | 2 + src/mainboard/matsonic/ms7308e/Config | 1 + src/mainboard/pcchips/m810lmr/Config | 1 + src/mainboard/via/vt5292/Config | 1 + src/mainboard/via/vt5426/Config | 1 + src/superio/sis/950/superio.c | 53 +++++++---- util/config/NLBConfig.py | 90 +++++++++++++++++-- 17 files changed, 304 insertions(+), 31 deletions(-) diff --git a/src/arch/i386/lib/hardwaremain.c b/src/arch/i386/lib/hardwaremain.c index 0e548318eb..3da89a45f7 100644 --- a/src/arch/i386/lib/hardwaremain.c +++ b/src/arch/i386/lib/hardwaremain.c @@ -58,7 +58,11 @@ void intel_main() #ifdef FINAL_MAINBOARD_FIXUP void final_mainboard_fixup(void); #endif /* FINAL_MAINBOARD_FIXUP */ - +#ifdef USE_NEW_SUPERIO_INTERFACE + extern struct superio *all_superio; + extern int nsuperio; + extern void handle_superio(int pass, struct superio *s, int nsuperio); +#endif #ifdef CONFIGURE_L2_CACHE int intel_l2_configure(); #endif /* CONFIGURE_L2_CACHE */ @@ -98,7 +102,9 @@ void intel_main() printk(KERN_INFO "Finding PCI confiuration type...\n"); pci_set_method(); post_code(0x5f); - +#ifdef USE_NEW_SUPERIO_INTERFACE + handle_superio(0, all_superio, nsuperio); +#endif printk(KERN_INFO "Scanning PCI bus..."); pci_enumerate(); post_code(0x66); @@ -150,14 +156,21 @@ void intel_main() intel_display_cpuid(); intel_mtrr_check(); + #ifndef NO_KEYBOARD + keyboard_on(); #endif /* NO_KEYBOARD */ +#ifndef USE_NEW_SUPERIO_INTERFACE #ifdef MUST_ENABLE_FLOPPY enable_floppy(); post_code(0x95); #endif /* MUST_ENABLE_FLOPPY */ +#endif +#ifdef USE_NEW_SUPERIO_INTERFACE + handle_superio(1, all_superio, nsuperio); +#endif #ifdef SMP /* copy the smp block to address 0 */ @@ -194,6 +207,10 @@ void intel_main() #endif /* MAINBOARD_FIXUP_IN_CHARGE */ +#ifdef USE_NEW_SUPERIO_INTERFACE + handle_superio(2, all_superio, nsuperio); +#endif + #ifdef LINUXBIOS printk(KERN_INFO "Jumping to linuxbiosmain()...\n"); // we could go to argc, argv, for main but it seems like overkill. @@ -201,3 +218,5 @@ void intel_main() linuxbiosmain(0, totalram); #endif /* LINUXBIOS */ } + + diff --git a/src/include/pci.h b/src/include/pci.h index 23fabf37b6..9f66ac084e 100644 --- a/src/include/pci.h +++ b/src/include/pci.h @@ -439,4 +439,68 @@ unsigned char intel_conf_readb(unsigned long port); #include +/* linkages from devices of a type (e.g. superio devices) + * to the actual physical PCI device. This type is used in an array of + * structs built by NLBConfig.py. We owe this idea to Plan 9. + */ + +struct superio; + +struct superio_control { + void (*pre_pci_init)(struct superio *s); + void (*init)(struct superio *s); + void (*finishup)(struct superio *s); + unsigned int defaultport; /* the defaultport. Can be overridden + * by commands in config + */ + // This is the print name for debugging + char *name; +}; + +struct com_ports { + unsigned int enable,baud, base, irq; +}; + +struct superio { + struct superio_control *super; // the ops for the device. + unsigned int port; // if non-zero, overrides the default port + // com ports. This is not done as an array (yet). + // We think it's easier to set up from python if it is not an array. + struct com_ports com1, com2, com3, com4; + /* flags for each device type. Unsigned int. */ + // low order bit ALWAYS means enable. Next bit means to enable + // DMA, if it exists. + unsigned int ide, floppy, lpt; +}; + +struct southbridge; + +struct southbridge_control { + void (*pre_pci_init)(struct southbridge *s); + void (*init)(struct southbridge *s); + void (*finishup)(struct southbridge *s); + // this is the vendor and device id + unsigned int vendor, device; + // This is the print name for debugging + char *name; +}; + +struct southbridge { + struct pci_dev *device; // the device. + struct southbridge_control *southbridge; // the ops for the device. + unsigned int devfn; /* the devfn. + * if devfn is known, the device can be + * configured for PCI discovery. + * this is needed for some devices such as acer m1535 + */ + /* flags for each device type. Unsigned int. */ + // low order bit ALWAYS means enable. Next bit means to enable + // DMA, if it exists. + unsigned int ide; +}; + #endif /* PCI_H */ + + + + diff --git a/src/lib/newpci.c b/src/lib/newpci.c index 9455f85955..f409b39153 100644 --- a/src/lib/newpci.c +++ b/src/lib/newpci.c @@ -785,3 +785,92 @@ void pci_enable() // now enable everything. enable_resources(&pci_root); } + +void +handle_superio(int pass, struct superio *s, int nsuperio) +{ + int i; + printk(KERN_INFO "handle_superio start, s %p nsuperio %d s->super %p\n", + s, nsuperio, s->super); + for(i = 0; i < nsuperio; i++, s++){ + + if (!s->super) + continue; + printk(KERN_INFO "handle_superio: Pass %d, Superio %s\n", pass, + s->super->name); + // need to have both pre_pci_init and devfn defined. + if (s->super->pre_pci_init && (pass == 0)) { + printk(KERN_INFO " Call pre_pci_init\n"); + s->super->pre_pci_init(s); + } + else + if (s->super->init && (pass == 1)) + { + printk(KERN_INFO " Call init\n"); + s->super->init(s); + } + else + if (s->super->finishup && (pass == 2)) + { + printk(KERN_INFO " Call finishup\n"); + s->super->finishup(s); + } + } + printk(KERN_INFO "handle_superio done\n"); +} + +void +handle_southbridge(int pass, struct southbridge *s, int nsouthbridge) +{ + int i; + for(i = 0; i < nsouthbridge; i++, s++){ + + if (!s->southbridge) + continue; + printk(KERN_INFO "handle_southbridge: Pass %d, Superio %s\n", pass, + s->southbridge->name); + + // need to have both pre_pci_init and devfn defined. + if (s->southbridge->pre_pci_init && (pass == 0) && (s->devfn)) { + printk(KERN_INFO " Call pre_pci_init\n"); + s->southbridge->pre_pci_init(s); + } + else + { + // first, have to set up any device not set up. + // policy: we ignore the devfn here. First, it's in the pcidev, and + // second, it's really only to be used BEFORE pci config is done. + if (! s->device) + s->device = pci_find_device(s->southbridge->vendor, + s->southbridge->device, 0); + + if (! s->device) { // not there! + printk(KERN_INFO " No such device\n"); + continue; + } + // problem. We have to handle multiple devices of same type. + // We don't do this yet. One way is to mark the pci device used at + // this point, i.e. + // s->device->inuse = 1 + // and then continue looking if the device is in use. + // For now, let's get this basic thing to work. + if (s->southbridge->init && (pass == 1)) { + printk(KERN_INFO " Call init\n"); + s->southbridge->init(s); + } + else + if (s->southbridge->finishup && (pass == 2)) { + printk(KERN_INFO " Call finishup\n"); + s->southbridge->finishup(s); + } + } + } +} + + + + + + + + diff --git a/src/mainboard/asus/cua/Config b/src/mainboard/asus/cua/Config index 1e2c3edf8b..4b7ddb0920 100644 --- a/src/mainboard/asus/cua/Config +++ b/src/mainboard/asus/cua/Config @@ -1,3 +1,4 @@ +arch i386 northbridge acer/m1631 southbridge acer/m1535 superio acer/m1535 diff --git a/src/mainboard/compaq/ds10/Config b/src/mainboard/compaq/ds10/Config index 711cd7514e..79216b400f 100644 --- a/src/mainboard/compaq/ds10/Config +++ b/src/mainboard/compaq/ds10/Config @@ -1,3 +1,4 @@ +arch alpha northbridge alpha/tsunami southbridge acer/m1543 #southbridge... diff --git a/src/mainboard/gigabit/ga-6bxc/Config b/src/mainboard/gigabit/ga-6bxc/Config index 4a7866883c..c728c6a7a2 100644 --- a/src/mainboard/gigabit/ga-6bxc/Config +++ b/src/mainboard/gigabit/ga-6bxc/Config @@ -1,3 +1,4 @@ +arch i386 northbridge intel/440bx southbridge intel/piix4e diff --git a/src/mainboard/intel/l440gx/Config b/src/mainboard/intel/l440gx/Config index e18cb22ddf..2f5c8275ed 100644 --- a/src/mainboard/intel/l440gx/Config +++ b/src/mainboard/intel/l440gx/Config @@ -1,3 +1,4 @@ +arch i386 northbridge intel/440gx southbridge intel/piix4e diff --git a/src/mainboard/irobot/proto1/Config b/src/mainboard/irobot/proto1/Config index 85f4dcddd0..812c7e092b 100644 --- a/src/mainboard/irobot/proto1/Config +++ b/src/mainboard/irobot/proto1/Config @@ -1,3 +1,4 @@ +arch i386 northbridge intel/440bx southbridge intel/piix4e diff --git a/src/mainboard/lanner/em-370/Config b/src/mainboard/lanner/em-370/Config index 4fa96dd0a8..3303002c5a 100644 --- a/src/mainboard/lanner/em-370/Config +++ b/src/mainboard/lanner/em-370/Config @@ -1,3 +1,4 @@ +arch i386 northbridge intel/440bx southbridge intel/piix4e superio winbond/w83977ef diff --git a/src/mainboard/leadtek/winfast6300/Config b/src/mainboard/leadtek/winfast6300/Config index 8c63079630..1969024725 100644 --- a/src/mainboard/leadtek/winfast6300/Config +++ b/src/mainboard/leadtek/winfast6300/Config @@ -1,5 +1,7 @@ +arch i386 northsouthbridge sis/630 -superio sis/950 +# superio sis/950 +nsuperio sis/950 com1={1} floppy=1 lpt=1 option ENABLE_FIXED_AND_VARIABLE_MTRRS option FINAL_MAINBOARD_FIXUP diff --git a/src/mainboard/leadtek/winfast6300/mainboard.c b/src/mainboard/leadtek/winfast6300/mainboard.c index 57cf14f1db..2ad71a157c 100644 --- a/src/mainboard/leadtek/winfast6300/mainboard.c +++ b/src/mainboard/leadtek/winfast6300/mainboard.c @@ -15,5 +15,7 @@ final_mainboard_fixup(void) "Winfast 6300 (and similar)..."); final_southbridge_fixup(); +#ifndef USE_NEW_SUPERIO_INTERFACE final_superio_fixup(); +#endif } diff --git a/src/mainboard/matsonic/ms7308e/Config b/src/mainboard/matsonic/ms7308e/Config index 8c63079630..b2a8539cec 100644 --- a/src/mainboard/matsonic/ms7308e/Config +++ b/src/mainboard/matsonic/ms7308e/Config @@ -1,3 +1,4 @@ +arch i386 northsouthbridge sis/630 superio sis/950 diff --git a/src/mainboard/pcchips/m810lmr/Config b/src/mainboard/pcchips/m810lmr/Config index 53b18d2a1a..b06d4549e1 100644 --- a/src/mainboard/pcchips/m810lmr/Config +++ b/src/mainboard/pcchips/m810lmr/Config @@ -1,3 +1,4 @@ +arch i386 northsouthbridge sis/730 superio sis/950 diff --git a/src/mainboard/via/vt5292/Config b/src/mainboard/via/vt5292/Config index e537beec7d..f626c24985 100644 --- a/src/mainboard/via/vt5292/Config +++ b/src/mainboard/via/vt5292/Config @@ -1,3 +1,4 @@ +arch i386 northbridge via/vt8601 southbridge via/vt82c686 superio via/vt82c686 diff --git a/src/mainboard/via/vt5426/Config b/src/mainboard/via/vt5426/Config index e537beec7d..f626c24985 100644 --- a/src/mainboard/via/vt5426/Config +++ b/src/mainboard/via/vt5426/Config @@ -1,3 +1,4 @@ +arch i386 northbridge via/vt8601 southbridge via/vt82c686 superio via/vt82c686 diff --git a/src/superio/sis/950/superio.c b/src/superio/sis/950/superio.c index 03e2d057d1..f08147a728 100644 --- a/src/superio/sis/950/superio.c +++ b/src/superio/sis/950/superio.c @@ -7,9 +7,10 @@ static char rcsid[] = "$Id$"; #define PNP_COM2_DEVICE 0x2 #include +#include #include -void +static void enter_pnp(void) { // unlock it XXX make this a subr at some point @@ -19,7 +20,7 @@ enter_pnp(void) outb(0x55, 0x2e); } -void +static void exit_pnp(void) { /* all done. */ @@ -28,8 +29,8 @@ exit_pnp(void) outb(2, 0x2f); } -#ifdef MUST_ENABLE_FLOPPY -void + +static void enable_floppy(void) { /* now set the LDN to floppy LDN */ @@ -40,9 +41,9 @@ enable_floppy(void) outb(0x30, 0x2e); outb(0x1, 0x2f); } -#endif /* MUST_ENABLE_FLOPPY */ -void + +static void enable_com(int com) { unsigned char b; @@ -61,8 +62,8 @@ enable_com(int com) outb(b, 0x2f); } -#ifdef MUST_ENABLE_LPT -void + +static void enable_lpt(void) { /* now set the LDN to floppy LDN */ @@ -73,23 +74,37 @@ enable_lpt(void) outb(0x30, 0x2e); outb(0x1, 0x2f); } -#endif /* MUST_ENABLE_LPT */ -void -final_superio_fixup(void) +static void +finishup(struct superio *s) { enter_pnp(); -#ifdef MUST_ENABLE_FLOPPY - enable_floppy(); -#endif /* MUST_ENABLE_LPT */ + // don't fool with IDE just yet ... + if (s->floppy) + enable_floppy(); - enable_com(PNP_COM1_DEVICE); - enable_com(PNP_COM2_DEVICE); + if (s->com1.enable) + enable_com(PNP_COM1_DEVICE); + if (s->com2.enable) + enable_com(PNP_COM2_DEVICE); -#ifdef MUST_ENABLE_LPT - enable_lpt(); -#endif /* MUST_ENABLE_LPT */ + if (s->lpt) + enable_lpt(); exit_pnp(); } + +struct superio_control superio_sis_950_control = { + (void *)0, (void *)0, finishup, 0x2e, "SiS 950" +}; + +#if 0 +void +final_superio_fixup(void) +{ + superio_sis_950.finishup((struct superio *) 0); +} +#endif + + diff --git a/util/config/NLBConfig.py b/util/config/NLBConfig.py index 3cbf8726e0..94b20ee8af 100644 --- a/util/config/NLBConfig.py +++ b/util/config/NLBConfig.py @@ -7,6 +7,11 @@ import string debug = 0; +# device variables +superio_decls = ''; +superio_devices = []; +numsuperio = 0; + # Architecture variables arch = ''; makebase = ''; @@ -159,6 +164,55 @@ def superio(dir, superio_name): dir = os.path.join(treetop, 'src', 'superio', superio_name) addobject_defaultrule('superio.o', dir) +# commands are of the form: +# superio_name [name=val]* +def nsuperio(dir, superio_commands): + global superio_decls, superio_devices, numsuperio, outputdir + # need python code to bust this into separate words ... + wspc = string.whitespace + rest = "(.*)" + w = "[" + wspc + "]*" + name = "([^" + wspc + "]*)" + # break into name + commands + pat = name + w + rest + w + # print "pat :", pat, ":", rule + command_re = re.compile(pat) + m = command_re.match(superio_commands) + # note that superio is w.r.t. treetop + superio_name = m.group(1); + superio_decl_name = re.sub("/", "_", superio_name) + buildfullpath('superio', superio_name) + dir = os.path.join(treetop, 'src', 'superio', superio_name) + defaultrule = "\t $(CC) -c $(CFLAGS) -o $@ $<" + object="superio_%s.o" % superio_decl_name + superio_source = dir + "/superio.c" + objectrules.append([object, superio_source, defaultrule]) + addobject_defaultrule('nsuperio.o', "") + rest = m.group(2) + superio_cmds = ''; + m = command_re.match(rest) + cmd = m.group(1) + rest = m.group(2) + while (cmd): + superio_cmds = superio_cmds + ", ." + cmd + m = command_re.match(rest) + cmd = m.group(1) + rest = m.group(2) + # now build the declaration + decl = ''; + decl = "extern struct superio_control superio_" + decl = decl + superio_decl_name + "_control; \n" + decl = decl + "struct superio superio_" + superio_decl_name + decl = decl + "= { " + decl = decl + "&superio_" + superio_decl_name+ "_control" + decl = decl + superio_cmds + "};\n" + superio_decls = superio_decls + decl; + superio_devices.append("&superio_" + superio_decl_name); + # note that we're using the new interface + option(dir, "USE_NEW_SUPERIO_INTERFACE") + numsuperio = numsuperio + 1 + + # arg, what's a good way to do this ... # basically raminit can have a whole list of files. That's why # this is a list. @@ -206,9 +260,9 @@ def addaction(dir, rule): m = command_re.match(rule) rulename = m.group(1) actions = m.group(2) - print "rulename :", rulename - print " actions ", actions, "\n" - print "rules[rulename]=", makebaserules[rulename], "\n" + # print "rulename :", rulename + # print " actions ", actions, "\n" + # print "rules[rulename]=", makebaserules[rulename], "\n" makebaserules[rulename].append(actions) # add a dependency @@ -302,6 +356,7 @@ command_actions = { 'northsouthbridge' : northsouthbridge, 'pcibridge' : pcibridge, 'superio' : superio, + 'nsuperio' : nsuperio, 'object' : object, 'linux' : linux, 'raminit' : raminit, @@ -352,8 +407,11 @@ def doconfigfile(dir, filename): verb = command.group(1) args = command.group(3) - if ((arch == '') and (verb != 'arch')): - print "arch must be the first command not ", verb, "\n" + if ((arch == '') and ( + (verb != 'arch') and (verb != 'mainboard') and + (verb != 'target')) ): + print "arch, target, or mainboard must be " + print "the first commands not ", verb, "\n" sys.exit() if command_actions.has_key(verb): command_actions[verb](dir, args) @@ -474,10 +532,12 @@ def writemakefile(path): for i in range(len(makebaserules[z]) - 1): file.write("\t%s\n" % makebaserules[z][i+1]) for i in range(len(objectrules)): - base = objectrules[i][0] - base = base[0:len(base)-2] - source = os.path.join(objectrules[i][1], base) - source = source + ".c" + source = objectrules[i][1] + if (source[-2:] != '.c'): # no suffix. Build name. + base = objectrules[i][0] + base = base[0:len(base)-2] + source = os.path.join(objectrules[i][1], base) + source = source + ".c" file.write( "%s: %s\n" % (objectrules[i][0], source)) file.write( "%s\n" % objectrules[i][2]) @@ -491,6 +551,17 @@ def writemakefile(path): # except IOError: # print "File open and write failed for ", makefilepath +def writesuperiofile(path): + superiofile = os.path.join(path, "nsuperio.c") + file = open(superiofile, 'w+') + file.write("#include \n") + file.write(superio_decls) + file.write("struct superio *all_superio[] = {"); + for i in range(len(superio_devices)): + file.write("%s,\n" %superio_devices[i]) + file.write("};\n") + file.write("unsigned long nsuperio = %d;\n" % numsuperio) + # --------------------------------------------------------------------- # MAIN # --------------------------------------------------------------------- @@ -526,3 +597,4 @@ doconfigfile(treetop, sys.argv[1]) writemakefile(outputdir) writeldscript(outputdir) writecrt0(outputdir) +writesuperiofile(outputdir)