📄 autoconf.c
字号:
#ifndef lintstatic char *sccsid = "@(#)autoconf.c 4.2 (ULTRIX) 9/11/90";#endif lint/************************************************************************ * * * Copyright (c) 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* ------------------------------------------------------------------ *//* | Copyright Unpublished, MIPS Computer Systems, Inc. All Rights | *//* | Reserved. This software contains proprietary and confidential | *//* | information of MIPS and its suppliers. Use, disclosure or | *//* | reproduction is prohibited without the prior express written | *//* | consent of MIPS. | *//* ------------------------------------------------------------------ *//* * Modification History: autoconf.c * * 10-Sep-90 Charles Richmond IIS Corp. * Moved the printing of a new line inorder to fix a bug that caused * SCSI devices on the Q bus to print the vendor ID fields at the * start of the next line. * * 10-Aug-89 -- afd * In ib_config_dev, added "ui" (ptr to uba_device struct) as a parameter * to probe routine. This is for systems that allow more than one * of a given device type. * * In ib_config_conf, added "um" (ptr to uba_ctlr struct) as a parameter * to probe routine. This is for systems that allow more than one * of a given controller type. * * 20-Feb-89 -- Kong * Changed ib_config_dev to set up the phyaddr field. * Added Unibus, Qbus support here. * * 01-Feb-89 -- Kong * Moved over VAX-like configuration routines. * * 13-Jan-89 -- Kong * Moved pmax specific configuration routines to kn01.c. Configuration * is called through the system switch table. * * 09-Nov-88 -- afd * Examine the "systype" from the PROM & log what we are (in configure()). * * 06-Sep-88 -- afd * Changed autoconfiguration messages from "cprintf" to "printf". * */#include "../machine/pte.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/map.h"#include "../h/buf.h"#include "../h/dk.h"#include "../h/vm.h"#include "../h/conf.h"#include "../h/dmap.h"#include "../h/config.h"#include "../h/kmalloc.h"#include "../io/uba/ubareg.h"#include "../io/uba/ubavar.h"#include "../machine/debug.h"#include "../machine/cpu.h"#include "../machine/fpu.h"#include "../machine/hwconf.h"#include "../machine/scb.h"#include "../../machine/common/cpuconf.h"extern int nNUBA;extern int nNKDB;extern int nNKLESIB;extern int nNKDM;/* * The following several variables are related to * the configuration process, and are used in initializing * the machine. */int cold; /* if 1, still working on cold-start */int dkn; /* number of iostat dk numbers assigned so far */int autoconf_cvec; /* global for interrupt vector from probe routines */int autoconf_br; /* global for IPL from probe routines */int (*autoconf_intr)(); /* interrupt handler */u_int autoconf_csr; /* csr base address in k1seg *//* * cache sizes */unsigned icache_size;unsigned dcache_size;/* * coprocessor revision identifiers */unsigned cputype_word; /* PRId word */unsigned fptype_word;extern unsigned cpu_systype; /* systype word in boot PROM */struct config_adpt *ni_port_adpt;struct imp_tbl cpu_imp_tbl[] = { { "MIPS R2000 Processor Chip", 0 }, { "MIPS R2000 Processor Chip", 1 }, { 0, 0 }};struct imp_tbl fp_imp_tbl[] = { { "MIPS R2360 Floating Point Board", 1 }, { "MIPS R2010 VLSI Floating Point Chip", 2 }, { 0, 0 }};coproc_find(){ char *imp_name(); union rev_id ri; extern char mfc0_start[], mfc0_end[]; hwconf.cpu_processor.ri_uint = ri.ri_uint = cputype_word = get_cpu_irr(); if (ri.ri_imp == 0) { ri.ri_majrev = 1; ri.ri_minrev = 5; } printf("cpu0 ( version %d.%d, implementation %d )\n", ri.ri_majrev, ri.ri_minrev,ri.ri_imp);#ifdef oldmips#ifndef SABLE /* * Make sure the PROBE_BUG option and the mfc0 assembler option * are turned on for the old 1.5 chips. */ if (ri.ri_majrev < 2) {#ifndef PROBE_BUG panic("Kernel must be compiled with -DPROBE_BUG for 1.5 revision cpu chip");#endif !PROBE_BUG if ((mfc0_end - mfc0_start) <= 4) panic("Kernel must be assembled with -Wb,-mfc0 for 1.5 revision cpu chip"); }#endif !SABLE /* * TODO: * check cpu_config register * print a message about vme or local memory */#ifdef SABLE hwconf.cpubd_config = CONFIG_NOCP1|CONFIG_NOCP2|CONFIG_POWERUP;#else !SABLE hwconf.cpubd_config = *(char *)PHYS_TO_K1(CPU_CONFIG);#endif SABLE#endif oldmips#ifdef oldmips/* This is out....if you don't have floating point you may hang */ if (hwconf.cpubd_config & CONFIG_NOCP1) { fptype_word = 0; hwconf.fpu_processor.ri_uint = 0; printf("No floating point processor\n"); } else { hwconf.fpu_processor.ri_uint =#endif oldmips ri.ri_uint = fptype_word = get_fpc_irr(); fptype_word &= IRR_IMP_MASK; printf("fpu0 ( version %d.%d, implementation %d )\n", ri.ri_majrev, ri.ri_minrev,ri.ri_imp); fp_init();#ifdef oldmips }#endif oldmips}char *imp_name(ri, itp)struct rev_id ri;struct imp_tbl *itp;{ for (; itp->it_name; itp++) if (itp->it_imp == ri.ri_imp) return(itp->it_name); return("Unknown implementation");}int fpu_inited;fp_init(){ int led; wbflush(); DELAY(10); wbflush(); DELAY(10); set_fpc_csr(0); fpu_inited++;}/* * Cpu board serial number */machineid(){#ifdef TODO fill this in based on cpu board id ??#endif TODO return (123);}/* * Name: ib_config_cont (nxv, nxp, slot, name, scb_vec_addr); * * Args: nxv - The virtual address of the "controller" * * nxp - The physicall address of the "controller" * * slot - The mbus slot number containing the "controller" * * name - The name of the "controller" to match with in the * ubminit and ubdinit structures * * scb_vec_addr - The offset from the begining of scb block * zero that you want the address of the * interrupt routine specified in the um * structure inserted. If the value equals * zero, do not insert the the address of the * interrupt routine into the scb. * * Returns: 1 - if the "controller" was found * 0 - if the "controller" wasn't found */ib_config_cont(nxv, nxp, slot, name, scb_vec_addr)char *nxv;char *nxp;u_long slot;char *name;int scb_vec_addr;{ register struct uba_device *ui; register struct uba_ctlr *um; register struct uba_driver *udp; register struct config_adpt *p_adpt; extern struct config_adpt config_adpt[]; int (**ivec)(); int i; int found = 0; um = ubminit; while (found == 0 && (um->um_driver)) { if ((um->um_adpt == slot) && (strcmp(um->um_ctlrname, name) == 0) && (um->um_alive == 0) && (um->um_ubanum == -1)) { found = 1; } else { if ((um->um_adpt == '?') && (strcmp(um->um_ctlrname, name) == 0) && (um->um_alive == 0) && (um->um_ubanum == -1)) { found = 1; } else { um++; } } } if (found == 0) { return(0); } udp = um->um_driver; for( p_adpt = &config_adpt[0]; p_adpt->p_name; p_adpt++) { /* first look for iobus entry for this board then * check if the driver is correct for this board then * check that the controller number is the same as the * iobus entry then * check that this iobus entry has not been used */ if (strcmp("ibus", p_adpt->p_name)==0 && (char *)udp == p_adpt->c_name && p_adpt->c_num == um->um_ctlr && p_adpt->c_ptr == 0) { found = 1; } } if (found == 0) { return(0); }/* DAD - do this here for now. Need to set up the vector since * sz_siiprobe goes and looks for devices */ if (scb_vec_addr) ibcon_vec(scb_vec_addr, um); i = (*udp->ud_probe)(nxv, um); if (i == 0) return(0); um->um_adpt = slot; um->um_alive = (i ? 1 : 0); um->um_addr = (char *)nxv; um->um_physaddr = (char *)svtophy(um->um_addr); udp->ud_minfo[um->um_ctlr] = um; config_fillin(um); printf("\n"); for (ui = ubdinit; ui->ui_driver; ui++) { if (ui->ui_driver != udp || ui->ui_alive || ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?') { continue; } if ((*udp->ud_slave)(ui, nxv)) { ui->ui_alive = 1; ui->ui_ctlr = um->um_ctlr; ui->ui_addr = (char *)nxv; ui->ui_ubanum = um->um_ubanum; ui->ui_hd = um->um_hd; ui->ui_physaddr = nxp; ui->ui_adpt = slot; if (ui->ui_dk && dkn < DK_NDRIVE) ui->ui_dk = dkn++; else ui->ui_dk = -1; ui->ui_mi = um; /* ui_type comes from driver */ udp->ud_dinfo[ui->ui_unit] = ui; if(ui->ui_slave >= 0) { printf("%s%d at %s%d slave %d", ui->ui_devname, ui->ui_unit, udp->ud_mname, um->um_ctlr, ui->ui_slave); } else { printf("%s%d at %s%d", ui->ui_devname, ui->ui_unit, udp->ud_mname, um->um_ctlr); } (*udp->ud_attach)(ui); printf("\n"); } } return (found);}/* * Name: ib_config_dev (nxv, nxp, slot, name, scb_vec_addr); * * Args: nxv - The virtual address of the "device" * * nxp - The physical address of the "device" * * slot - The ibus slot number containing the "device" * * name - The name of the "device" to match with in the * ubminit and ubdinit structures * * scb_vec_addr - The offset from the begining of scb block * zero that you want the address of the * interrupt routine specified in the um * structure inserted. If the value equals * zero, do not insert the the address of the * interrupt routine into the scb. * * Returns: 1 - if the "device" was found * 0 - if the "device" wasn't found */ib_config_dev(nxv, nxp, slot, name, scb_vec_addr)char *nxv;char *nxp;u_long slot;char *name;int scb_vec_addr;{ register struct uba_device *ui; register struct uba_ctlr *um; register struct uba_driver *udp; register struct config_adpt *p_adpt; extern struct config_adpt config_adpt[]; int (**ivec)(); int i; int found = 0; ui = ubdinit; while (found == 0 && (ui->ui_driver)) { if ((ui->ui_adpt == slot) && (strcmp(ui->ui_devname, name) == 0) && (ui->ui_alive == 0) && (ui->ui_slave == -1)) { found = 1; } else { if ((ui->ui_adpt == '?') && (strcmp(ui->ui_devname, name) == 0) && (ui->ui_alive == 0) && (ui->ui_slave == -1)) { found = 1; } else { ui++; } } } if (found == 0) return(0); udp = ui->ui_driver; i = (*udp->ud_probe)(nxv, ui); if (i == 0) { return(0); } ui->ui_adpt = slot; config_fillin(ui); printf("\n"); if (scb_vec_addr) ibdev_vec(scb_vec_addr, ui); ui->ui_alive = (i ? 1 : 0); ui->ui_addr = (char *)nxv; ui->ui_physaddr = (char *)nxp; ui->ui_dk = -1; udp->ud_dinfo[ui->ui_unit] = ui; (*udp->ud_attach)(ui); return (found);}/* * ibdev_vec(): To set up Mbus device interrupt vectors. * It is called with 3 parameters: * slot - The ibus slot number * scb_vec_addr - The offset from the start of slot specific vector space * ui: - the device structure (for names of interrupt routines) */ibdev_vec(scb_vec_addr, ui)int scb_vec_addr;struct uba_device *ui;{ register int (**ivec)(); register int (**addr)(); /* double indirection neccessary to keep the C compiler happy */ ivec = ui->ui_intr; addr = (int (**)())scb_vec_addr; *addr = scbentry(*ivec,SCB_ISTACK);}ibcon_vec(scb_vec_addr, um)int scb_vec_addr;struct uba_ctlr *um;{ register int (**ivec)(); register int (**addr)(); /* double indirection neccessary to keep the C compiler happy */ ivec = um->um_intr; addr = (int (**)())scb_vec_addr; *addr = scbentry(*ivec,SCB_ISTACK);return;}config_fillin(um) register struct uba_ctlr *um;{ register struct config_adpt *aptr; register int bitype = 0; register int xmitype = 0; for( aptr = &config_adpt[0]; aptr->p_name; aptr++) { if (aptr->c_name == ((char *)um->um_driver) && um->um_ctlr == aptr->c_num && ((aptr->c_type == 'C') || (aptr->c_type == 'D'))) { aptr->c_ptr = (caddr_t) um; /* if conected to NEXUS...done */ if (strcmp(aptr->p_name,"nexus") == 0) return; if (strcmp(aptr->p_name,"ibus") == 0) { aptr->p_num = um->um_adpt; } if (strcmp(aptr->p_name,"vaxbi") == 0) { aptr->p_num = um->um_adpt; bitype = 1; } if (strcmp(aptr->p_name,"xmi") == 0) { aptr->p_num = um->um_adpt; xmitype = 1; } if (strcmp(aptr->p_name,"uba") == 0) { aptr->p_num = um->um_ubanum; } if (strcmp(aptr->p_name,"aie") == 0) { ni_port_adpt = aptr; } config_find_adpt(aptr,um); printf("%s%d at %s%d", um->um_ctlrname, aptr->c_num, aptr->p_name, aptr->p_num); if (bitype|xmitype) printf(" node %d",um->um_nexus); } }}is_adapt_configured(name, number)char *name;int number;{ register struct config_adpt *p_adpt; for( p_adpt = &config_adpt[0]; p_adpt->p_name; p_adpt++) { if ((strcmp(p_adpt->c_name,name) == 0) && (p_adpt->c_num == number)) { return(1); } } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -