📄 machdep.c
字号:
/* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department, The Mach Operating System project at * Carnegie-Mellon University and Ralph Campbell. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)machdep.c 8.3 (Berkeley) 1/12/94 *//* from: Utah $Hdr: machdep.c 1.63 91/04/24$ */#include <sys/param.h>#include <sys/systm.h>#include <sys/signalvar.h>#include <sys/kernel.h>#include <sys/map.h>#include <sys/proc.h>#include <sys/buf.h>#include <sys/reboot.h>#include <sys/conf.h>#include <sys/file.h>#include <sys/clist.h>#include <sys/callout.h>#include <sys/malloc.h>#include <sys/mbuf.h>#include <sys/msgbuf.h>#include <sys/ioctl.h>#include <sys/tty.h>#include <sys/user.h>#include <sys/exec.h>#include <sys/sysctl.h>#ifdef SYSVSHM#include <sys/shm.h>#endif#include <vm/vm_kern.h>#include <machine/cpu.h>#include <machine/reg.h>#include <machine/psl.h>#include <machine/pte.h>#include <machine/dc7085cons.h>#include <pmax/stand/dec_prom.h>#include <pmax/dev/device.h>#include <pmax/dev/sccreg.h>#include <pmax/dev/ascreg.h>#include <pmax/pmax/clockreg.h>#include <pmax/pmax/kn01.h>#include <pmax/pmax/kn02.h>#include <pmax/pmax/kmin.h>#include <pmax/pmax/maxine.h>#include <pmax/pmax/kn03.h>#include <pmax/pmax/asic.h>#include <pmax/pmax/turbochannel.h>#include <pmax/pmax/pmaxtype.h>#include <pmax/pmax/cons.h>#include <pm.h>#include <cfb.h>#include <mfb.h>#include <xcfb.h>#include <dc.h>#include <dtop.h>#include <scc.h>#include <le.h>#include <asc.h>#if NDC > 0extern int dcGetc(), dcparam();extern void dcPutc();#endif#if NDTOP > 0extern int dtopKBDGetc();#endif#if NSCC > 0extern int sccGetc(), sccparam();extern void sccPutc();#endifextern int KBDGetc();extern void fbPutc();extern struct consdev cn_tab;/* Will scan from max to min, inclusive */static int tc_max_slot = KN02_TC_MAX;static int tc_min_slot = KN02_TC_MIN;static u_int tc_slot_phys_base [TC_MAX_SLOTS] = { /* use 3max for default values */ KN02_PHYS_TC_0_START, KN02_PHYS_TC_1_START, KN02_PHYS_TC_2_START, KN02_PHYS_TC_3_START, KN02_PHYS_TC_4_START, KN02_PHYS_TC_5_START, KN02_PHYS_TC_6_START, KN02_PHYS_TC_7_START};/* the following is used externally (sysctl_hw) */char machine[] = "DEC"; /* cpu "architecture" */char cpu_model[30];vm_map_t buffer_map;/* * Declare these as initialized data so we can patch them. */int nswbuf = 0;#ifdef NBUFint nbuf = NBUF;#elseint nbuf = 0;#endif#ifdef BUFPAGESint bufpages = BUFPAGES;#elseint bufpages = 0;#endifint msgbufmapped = 0; /* set when safe to use msgbuf */int maxmem; /* max memory per process */int physmem; /* max supported memory, changes to actual */int pmax_boardtype; /* Mother board type */u_long le_iomem; /* 128K for lance chip via. ASIC */u_long asc_iomem; /* and 7 * 8K buffers for the scsi */u_long asic_base; /* Base address of I/O asic */const struct callback *callv; /* pointer to PROM entry points */void (*tc_enable_interrupt)();extern int (*pmax_hardware_intr)();void pmax_slot_hand_fill();int kn02_intr(), kmin_intr(), xine_intr(), pmax_intr();#ifdef DS5000_240int kn03_intr();#endifextern int Mach_spl0(), Mach_spl1(), Mach_spl2(), Mach_spl3(), splhigh();int (*Mach_splnet)() = splhigh;int (*Mach_splbio)() = splhigh;int (*Mach_splimp)() = splhigh;int (*Mach_spltty)() = splhigh;int (*Mach_splclock)() = splhigh;int (*Mach_splstatclock)() = splhigh;void (*tc_slot_hand_fill)();extern volatile struct chiptime *Mach_clock_addr;u_long kmin_tc3_imask, xine_tc3_imask;#ifdef DS5000_240u_long kn03_tc3_imask;#endiftc_option_t tc_slot_info[TC_MAX_LOGICAL_SLOTS];static void asic_init();extern void RemconsInit();#ifdef DS5000void kn02_enable_intr(), kn02_slot_hand_fill(), kmin_enable_intr(), kmin_slot_hand_fill(), xine_enable_intr(), xine_slot_hand_fill(), tc_find_all_options();#ifdef DS5000_240void kn03_enable_intr(), kn03_slot_hand_fill();#endif#endif /* DS5000 *//* * safepri is a safe priority for sleep to set for a spin-wait * during autoconfiguration or after a panic. */int safepri = PSL_LOWIPL;struct user *proc0paddr;struct proc nullproc; /* for use by swtch_exit() *//* * Do all the stuff that locore normally does before calling main(). * Process arguments passed to us by the prom monitor. * Return the first page address following the system. */mach_init(argc, argv, code, cv) int argc; char *argv[]; u_int code; const struct callback *cv;{ register char *cp; register int i; register unsigned firstaddr; register caddr_t v; caddr_t start; extern char edata[], end[]; extern char MachUTLBMiss[], MachUTLBMissEnd[]; extern char MachException[], MachExceptionEnd[]; /* clear the BSS segment */ v = (caddr_t)pmax_round_page(end); bzero(edata, v - edata); /* check for direct boot from DS5000 PROM */ if (argc > 0 && strcmp(argv[0], "boot") == 0) { argc--; argv++; } /* look at argv[0] and compute bootdev */ makebootdev(argv[0]); /* * Look at arguments passed to us and compute boothowto. */#ifdef GENERIC boothowto = RB_SINGLE | RB_ASKNAME;#else boothowto = RB_SINGLE;#endif#ifdef KADB boothowto |= RB_KDB;#endif if (argc > 1) { for (i = 1; i < argc; i++) { for (cp = argv[i]; *cp; cp++) { switch (*cp) { case 'a': /* autoboot */ boothowto &= ~RB_SINGLE; break; case 'd': /* use compiled in default root */ boothowto |= RB_DFLTROOT; break; case 'm': /* mini root present in memory */ boothowto |= RB_MINIROOT; break; case 'n': /* ask for names */ boothowto |= RB_ASKNAME; break; case 'N': /* don't ask for names */ boothowto &= ~RB_ASKNAME; } } } }#ifdef MFS /* * Check to see if a mini-root was loaded into memory. It resides * at the start of the next page just after the end of BSS. */ if (boothowto & RB_MINIROOT) { boothowto |= RB_DFLTROOT; v += mfs_initminiroot(v); }#endif /* * Init mapping for u page(s) for proc[0], pm_tlbpid 1. */ start = v; curproc->p_addr = proc0paddr = (struct user *)v; curproc->p_md.md_regs = proc0paddr->u_pcb.pcb_regs; firstaddr = MACH_CACHED_TO_PHYS(v); for (i = 0; i < UPAGES; i++) { MachTLBWriteIndexed(i, (UADDR + (i << PGSHIFT)) | (1 << VMMACH_TLB_PID_SHIFT), curproc->p_md.md_upte[i] = firstaddr | PG_V | PG_M); firstaddr += NBPG; } v += UPAGES * NBPG; MachSetPID(1); /* * init nullproc for swtch_exit(). * init mapping for u page(s), pm_tlbpid 0 * This could be used for an idle process. */ nullproc.p_addr = (struct user *)v; nullproc.p_md.md_regs = nullproc.p_addr->u_pcb.pcb_regs; bcopy("nullproc", nullproc.p_comm, sizeof("nullproc")); for (i = 0; i < UPAGES; i++) { nullproc.p_md.md_upte[i] = firstaddr | PG_V | PG_M; firstaddr += NBPG; } v += UPAGES * NBPG; /* clear pages for u areas */ bzero(start, v - start); /* * Copy down exception vector code. */ if (MachUTLBMissEnd - MachUTLBMiss > 0x80) panic("startup: UTLB code too large"); bcopy(MachUTLBMiss, (char *)MACH_UTLB_MISS_EXC_VEC, MachUTLBMissEnd - MachUTLBMiss); bcopy(MachException, (char *)MACH_GEN_EXC_VEC, MachExceptionEnd - MachException); /* * Clear out the I and D caches. */ MachConfigCache(); MachFlushCache(); /* * Determine what model of computer we are running on. */ if (code == DEC_PROM_MAGIC) { callv = cv; i = (*cv->getsysid)(); cp = ""; } else { callv = &callvec; if (cp = (*callv->getenv)("systype")) i = atoi(cp); else { cp = ""; i = 0; } } /* check for MIPS based platform */ if (((i >> 24) & 0xFF) != 0x82) { printf("Unknown System type '%s' 0x%x\n", cp, i); boot(RB_HALT | RB_NOSYNC); } /* check what model platform we are running on */ pmax_boardtype = ((i >> 16) & 0xff); switch (pmax_boardtype) { case DS_PMAX: /* DS3100 Pmax */ /* * Set up interrupt handling and I/O addresses. */ pmax_hardware_intr = pmax_intr; Mach_splnet = Mach_spl1; Mach_splbio = Mach_spl0; Mach_splimp = Mach_spl1; Mach_spltty = Mach_spl2; Mach_splclock = Mach_spl3; Mach_splstatclock = Mach_spl3; Mach_clock_addr = (volatile struct chiptime *) MACH_PHYS_TO_UNCACHED(KN01_SYS_CLOCK); pmax_slot_hand_fill(); strcpy(cpu_model, "3100"); break;#ifdef DS5000 case DS_3MAX: /* DS5000/200 3max */ { volatile int *csr_addr = (volatile int *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR); /* * Enable ECC memory correction, turn off LEDs, and * disable all TURBOchannel interrupts. */ i = *csr_addr; *csr_addr = (i & ~(KN02_CSR_WRESERVED | KN02_CSR_IOINTEN)) | KN02_CSR_CORRECT | 0xff; tc_slot_hand_fill = kn02_slot_hand_fill; pmax_hardware_intr = kn02_intr; tc_enable_interrupt = kn02_enable_intr; Mach_splnet = Mach_spl0; Mach_splbio = Mach_spl0; Mach_splimp = Mach_spl0; Mach_spltty = Mach_spl0; Mach_splclock = Mach_spl1; Mach_splstatclock = Mach_spl1; Mach_clock_addr = (volatile struct chiptime *) MACH_PHYS_TO_UNCACHED(KN02_SYS_CLOCK); /* * Probe the TURBOchannel to see what controllers are present. */ tc_find_all_options(); /* clear any memory errors from probes */ *(unsigned *)MACH_PHYS_TO_UNCACHED(KN02_SYS_ERRADR) = 0; } strcpy(cpu_model, "5000/200"); break; case DS_3MIN: /* DS5000/1xx 3min */ tc_max_slot = KMIN_TC_MAX; tc_min_slot = KMIN_TC_MIN; tc_slot_phys_base[0] = KMIN_PHYS_TC_0_START; tc_slot_phys_base[1] = KMIN_PHYS_TC_1_START; tc_slot_phys_base[2] = KMIN_PHYS_TC_2_START; asic_base = MACH_PHYS_TO_UNCACHED(KMIN_SYS_ASIC); tc_slot_hand_fill = kmin_slot_hand_fill; pmax_hardware_intr = kmin_intr; tc_enable_interrupt = kmin_enable_intr; kmin_tc3_imask = (KMIN_INTR_CLOCK | KMIN_INTR_PSWARN | KMIN_INTR_TIMEOUT); /* * Since all the motherboard interrupts come through the * I/O ASIC, it has to be turned off for all the spls and * since we don't know what kinds of devices are in the * turbochannel option slots, just splhigh(). */ Mach_splnet = splhigh; Mach_splbio = splhigh; Mach_splimp = splhigh; Mach_spltty = splhigh; Mach_splclock = splhigh; Mach_splstatclock = splhigh; Mach_clock_addr = (volatile struct chiptime *) MACH_PHYS_TO_UNCACHED(KMIN_SYS_CLOCK); /* * Probe the TURBOchannel to see what controllers are present. */ tc_find_all_options(); /* * Initialize interrupts. */ *(u_int *)ASIC_REG_IMSK(asic_base) = KMIN_IM0; *(u_int *)ASIC_REG_INTR(asic_base) = 0; /* clear any memory errors from probes */ *(unsigned *)MACH_PHYS_TO_UNCACHED(KMIN_REG_TIMEOUT) = 0; strcpy(cpu_model, "5000/1xx"); break; case DS_MAXINE: /* DS5000/xx maxine */ tc_max_slot = XINE_TC_MAX; tc_min_slot = XINE_TC_MIN; tc_slot_phys_base[0] = XINE_PHYS_TC_0_START; tc_slot_phys_base[1] = XINE_PHYS_TC_1_START; asic_base = MACH_PHYS_TO_UNCACHED(XINE_SYS_ASIC); tc_slot_hand_fill = xine_slot_hand_fill; pmax_hardware_intr = xine_intr; tc_enable_interrupt = xine_enable_intr; Mach_splnet = Mach_spl3; Mach_splbio = Mach_spl3; Mach_splimp = Mach_spl3; Mach_spltty = Mach_spl3; Mach_splclock = Mach_spl1; Mach_splstatclock = Mach_spl1; Mach_clock_addr = (volatile struct chiptime *) MACH_PHYS_TO_UNCACHED(XINE_SYS_CLOCK); /* * Probe the TURBOchannel to see what controllers are present. */ tc_find_all_options(); /* * Initialize interrupts. */ *(u_int *)ASIC_REG_IMSK(asic_base) = XINE_IM0; *(u_int *)ASIC_REG_INTR(asic_base) = 0; /* clear any memory errors from probes */ *(unsigned *)MACH_PHYS_TO_UNCACHED(XINE_REG_TIMEOUT) = 0; strcpy(cpu_model, "5000/25"); break;#ifdef DS5000_240 case DS_3MAXPLUS: /* DS5000/240 3max+ UNTESTED!! */ tc_max_slot = KN03_TC_MAX; tc_min_slot = KN03_TC_MIN; tc_slot_phys_base[0] = KN03_PHYS_TC_0_START; tc_slot_phys_base[1] = KN03_PHYS_TC_1_START; tc_slot_phys_base[2] = KN03_PHYS_TC_2_START; asic_base = MACH_PHYS_TO_UNCACHED(KN03_SYS_ASIC); tc_slot_hand_fill = kn03_slot_hand_fill; pmax_hardware_intr = kn03_intr; tc_enable_interrupt = kn03_enable_intr; kn03_tc3_imask = KN03_INTR_PSWARN; Mach_splnet = Mach_spl0; Mach_splbio = Mach_spl0; Mach_splimp = Mach_spl0; Mach_spltty = Mach_spl0; Mach_splclock = Mach_spl1; Mach_splstatclock = Mach_spl1; Mach_clock_addr = (volatile struct chiptime *) MACH_PHYS_TO_UNCACHED(KN03_SYS_CLOCK); /* * Probe the TURBOchannel to see what controllers are present. */ tc_find_all_options(); /* * Initialize interrupts. */ *(u_int *)ASIC_REG_IMSK(asic_base) = KN03_IM0; *(u_int *)ASIC_REG_INTR(asic_base) = 0; /* clear any memory errors from probes */ *(unsigned *)MACH_PHYS_TO_UNCACHED(KN03_SYS_ERRADR) = 0; strcpy(cpu_model, "5000/240"); break;#endif /* DS5000_240 */#endif /* DS5000 */ default: printf("kernel not configured for systype 0x%x\n", i); boot(RB_HALT | RB_NOSYNC); } /* * Find out how much memory is available.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -