📄 kn220.c
字号:
#ifndef lintstatic char *sccsid = "@(#)kn220.c 4.6 (ULTRIX) 1/25/91";#endif lint/************************************************************************ * * * Copyright (c) 1990 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. * * * ************************************************************************//* * Debug HINTS ( some of the following console commands are not * supported but will be in the console. * * Hint 1) In the "maint" mode (CVAX diag code) enter "t 9e" * at the >>> prompt to get a list of all the diag * tests that can be run from the console. * * Hint 2) At the >> prompt; "dump_hs" (dump halt state) will print * out the systems register states at the time of the " * LAST" time the console halt handler was entered. * The "dep_hr" command can be used in conjunction with this * command. * * Hint 3) At the >> prompt; "dep_hr (deposit halt register) can * be used to change the contents of a system register. * The syntax is "dep_hr register_name value". * * Hint 4) At the >> prompt; "dump_reg" Will save all the system * registers and the print their values. * * Hint 5) At the >> prompt; "dump_ex" prints the last saved values * of the system registers (When a dreg or a exception was done.) * * Revision History: * * 19 Aug 90 -- chet * Changes for presto interface. * * 07-Sep-90 sekhar * Fixed to log write timeout packet only when crashing. * * 13-Aug-90 sekhar * changes to support memory mapped devices: * 1. added kn220consinfo_t kn220log_errinfo_t to capture error information. * 2. added new functions kn220_print_consinfo() and kn220_log_errinfo * exported through cpusw to print information to console and to log * information in the error log buffer. * 3. modified bus timeout code to capture error information and * post softnet() interrupt. * 4. integrated kn220_print_consinfo() and kn220consprint() * 5. integrated kn220logesrpkt and kn220_log_errinfo(() * * 04-Aug-90 Randall Brown * Added call to spl_init() to intialize spl function pointers and * the intr() function pointer. * * 01-Aug-90 robin * Changed memory intrrupt routine to clear the interrupt early, the * code as it was caused panic to loop because the interrupt was * still pending and panic path lowers IPL with interrupts enabled; * which causes memoery interrupt to be re-entered. (sigh) * * 09-Aug-90 Robin * Fixed bug in battery test routine that read the iopres status * register from an un-init var on the stack. * * Fixed the memory interrupt routine to not try to use the "ep" * because its out of context. * * I also changed the kn220consprint routine to return and not break * out of a bad format packet type. * * 15-Jun-90 map (Mark Parenti) * Add hooks to call VME configuration routine. * * 29 May 90 -- chet * Add call to presto NVRAM pseudo driver initialization routine. * * 05-15-90 Robin * Changed the VME present bit to be a option present bit. We read * locations on the VME or the FDDI to know whats there. We don't have * hardware yet so its to early to know if it will work. * * 04-05-90 Robin * Added code to test NVRAM Battery voltage and get go values. the old * code never worked. * * 11-22-1989 Robin * File Created * * */#include "../h/presto.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/map.h"#include "../h/types.h"#include "../h/user.h" /* gets time.h and debug.h too */#include "../h/proc.h"#include "../h/vm.h"#include "../h/buf.h"#include "../h/errlog.h"#include "../h/cmap.h"#include "../h/config.h"#include "../machine/cpu.h"#include "../machine/ssc.h"#include "../machine/hwconf.h"#include "../../machine/common/cpuconf.h"#include "../machine/reg.h"#include "../machine/kn220.h"#include "../io/uba/ubavar.h"/* Read location 1610005c to clear memory interrupts. */#define CLEAR_MEM_INTR 0x1610005c#define BIT29 0x20000000#define BIT28 0x10000000#define GOOD_ADDR 0x00000002#define ITS_A_QBUS 1/* VME base address used to see if the VME is on the slot */#define VME_BASE_ADDR 0x19000000/* FDDI base address used to see if the FDDI is on the slot */#define FDDI_BASE_ADDR 0x1b000000/* * QBUS mapping info for Non-Volatile Ram (NVRAM) which * is used by Prestoserve to speed up synchronous filesystem writes. * * The size is 8K smaller than it really is and the start address * is 8K higher than it should be. The first 8K of NVRAM is * reserved for use by the console micro code and we can't * use it. */#define NVRAM_SIZE (0x80000 - 0x2000) /* (512K - 8K) */#define NVRAM_ADDR (0x98000000 + 0x2000) /* start phys 0x18000000+8K */#define ESRPKT 1#define MEMPKT 2#define CVAX_TO_R3000 0x10000000#define CVAX_TO_K1SEG (K1BASE - CVAX_TO_R3000)#define CVAX_TABLE_PTR (0x20040024)#define CVAX_TABLE ((*(int *)(CVAX_TABLE_PTR+CVAX_TO_K1SEG)) \ + CVAX_TO_K1SEG)#define NVRAM_STATUS_PTR_OFFSET (9 * 4)#define NVRAM_STATUS_ADDR ((*(int *)(CVAX_TABLE + NVRAM_STATUS_PTR_OFFSET))\ + CVAX_TO_K1SEG)#define NVRAMSTATUS (*(char *)(NVRAM_STATUS_ADDR))/* This is an array which holds address values on ECC single * bit errors. When a single bit error is seen an error * log is generated, if and only if, its address is not in this * array. If its in the array nothing is logged but if its * not the error is loged and the address is stored here. * At some later time a routine will zero this array and any * single bit error seen will be loged and the process starts over. */unsigned int Sbit_error[SBIT_SIZE];extern struct qbm_regs *qb_ptr ; /* Points to unibus adaptor regs */struct esr { u_long esr_dser; /* DMA System Error Reg */ u_long esr_qbear; /* QBus Error Address Reg */ u_long esr_dear; /* DMA Error Address Reg */ u_long esr_cbtcr; /* CDAL Bus Timeout Control Reg */ u_long esr_isr; /* Interrupt Status Reg */ u_long esr_ipcr; /* Inter Process Communication Reg. */ u_long esr_mesr; /* Memory Error Syndrome Reg. */ u_long esr_mear; /* Memory Error Address Reg. */} esr[1];extern u_int printstate;extern int nNMSI, nummsi, qmapbase;extern int softclock(),softnet(),kn220hardintr0(),kn220hardintr1(), kn220hardintr2(),kn220memintr(),kn220haltintr(),fpuintr(), xviaconf();extern struct config_adpt config_adpt[];/* The routines that correspond to each of the 8 interrupt lines */int (*kn220intr_vec[8])() = { softclock, /* softint 1 */ softnet, /* softint 2 */ kn220hardintr0, /* hardint 1 */ kn220hardintr1, /* hardint 2 */ kn220hardintr2, /* hardint 3 */ kn220memintr, /* hardint 4 */ kn220haltintr, /* hardint 5 */ fpuintr /* hardint 6 */};/* The masks to use to look at each of the 8 interrupt lines */int kn220iplmask[8] = { SR_IMASK1|SR_IEC, SR_IMASK2|SR_IEC, SR_IMASK3|SR_IEC, SR_IMASK4|SR_IEC, SR_IMASK5|SR_IEC, SR_IMASK6|SR_IEC, SR_IMASK7|SR_IEC, SR_IMASK8|SR_IEC};/* The status register masks for splxxx usage */int kn220splm[SPLMSIZE] = {#define SR_HALT 0x4000 /* Halt interrupt */ SR_IEC | SR_IMASK0 | SR_HALT, /* 0 SPLNONE */ SR_IEC | SR_IMASK1 | SR_HALT, /* 1 SPLSOFTC */ SR_IEC | SR_IMASK2 | SR_HALT, /* 2 SPLNET */ 0, /* 3 NOT_USED */ 0, /* 4 NOT_USED */ SR_IEC | SR_IMASK4 | SR_HALT, /* 5 SPLBIO, SPLIMP, SPLTTY */ SR_IEC | SR_IMASK5 | SR_HALT, /* 6 SPLCLOCK */ SR_IEC | SR_IMASK6 | SR_HALT, /* 7 SPLMEM */ SR_IEC | SR_IMASK8 | SR_HALT, /* 8 SPLFPU */};/* A record of each memory board size in each of four slots on the system */int memory_slot[4];int kn220_usenvram = 1;int kn220_battdelay = 1000;int kn220_cache_nvram = 1;int kn220_nvram_mapped = 0;/* * The structure kn220consinfo_t can be used to store information * to be printed on a console. This information can then be printed * by kn220_print_consinfo() which is exported through the cpusw. * * Currently this is used only by the bus timeout code(although it * is a general pupose mechanism). */ /* error information to be dumped on a MEMPKT and ESRPKT type */struct kn220consinfo_mem_t { u_int cause; /* from the exception frame */ u_int epc; u_int sr; /* from the exception frame */ u_int badvaddr; u_int pa; /* physical address */};struct kn220consinfo_t { int pkt_type; /* pkt type */ int qbus; /* 1 if qbus addr; 0 otherwise */ struct kn220consinfo_mem_t pkt;} kn220consinfo;struct kn220log_errinfo_t { int pkt_type; u_int cause; /* from exception frame */ u_int epc; /* from exception frame */ u_int sr; /* from exception frame */ u_int badvaddr; /* from exception frame */ u_int sp; /* from exception frame */ struct esr logesr; /* from the esr registers */} kn220log_errinfo;/* * Configuration routine. */kn220conf(){ extern unsigned cpu_systype; extern (*(scb[]))(); /* 1st page of scb vectors */ extern int cold; register unsigned int *mp; register int i, *memid; extern cnrint(),cnxint(); extern kn220memerr(); extern timeout(); extern prom_getenv(); extern kn220_ZSbit(); extern int hz; extern int nNUBA; extern kn220_nvram_status(); extern kn220_battery_status(); int iopres, vmepres, found, B1, B2; int slot, mem_mask, memory_descptr; u_int kn220_machineid(); /* Set boot flag */ cold = 1; memid =(int *) KN220MIDR; /* * Fill in the vector in SCB for handling console interrupts. * */ scb[0xf8/4] = cnrint; /* general console receive interrupt */ scb[0xfc/4] = cnxint; /* general console transmit interrupt */ printf("DECsystem 5500 - system rev %d\n", GETHRDREV(cpu_systype)); /* Check to make sure the I/O board is present. If its not * panic. */ iopres = *(int *)KN220IOPRES; /* Read content of IOPRES */ if (((iopres) & KN220_IOP) == 0)/* no I/O board */ { panic("DS5500 I/O Board is missing"); } /* Init the structure that will point to the correct * hardware dependent functions that the presto code * depends on. */ presto_interface0.nvram_status = kn220_nvram_status; presto_interface0.nvram_battery_status = kn220_battery_status; presto_interface0.nvram_battery_disable = NULL; presto_interface0.nvram_battery_enable = NULL; if (prom_getenv("memdescriptor")) { /* If the memory descriptor is set by the console we use it to * compute which memory board a problem was logged on. This must * be set by field service when they install memory boards (good luck). * * Each board get two bits in a byte to recore what is in the slot. * 00 no memory in slot * 01 32 meg board in slot * 10 64 meg board in slot * 11 128 meg board in slot * * If its not set up at all we log it and ask them to run console test * "T 9A" to establish a variable. If its there but wrong we will * never know. */ memory_descptr = xtob(prom_getenv("memdescriptor")); for(slot=0, mem_mask=3; slot < 4; slot++, (mem_mask << 2)) { memory_slot[slot] = 32 * 1048576 * (memory_descptr & mem_mask); if((memory_descptr & mem_mask) == 3) memory_slot[slot] += (32 * 1048576); } } else mprintf("Run the console test \">>t 9a\" to \nestablish memory size boards in each slot.\n"); /* Now we will check the state of the NVRAM battery * which backs up the presto functions. */ *memid = KN220BLOAD; /* Get old state */ wbflush(); DELAY(kn220_battdelay); iopres = *(int *)KN220IOPRES; /* Read content of IOPRES */ B1 = iopres & KN220_BOK; *memid = KN220JUMPER & KN220BLOAD; /* Update state */ wbflush(); DELAY(kn220_battdelay); iopres = *(int *)KN220IOPRES; /* Read content of IOPRES */ B2 = iopres & KN220_BOK; *memid = 0; /* Turn it off battery load*/ wbflush(); if (B1 == B2) /* check for NVRAM battery low */ { if( B1 != KN220_BOK) printf("DS5500 NVRAM lost battery backup\n"); } else printf("DS5500 NVRAM battery backup disabled\n"); /* Deal with FPU */ coproc_find(); /* Turn on interupts */ splnone(); if (nNUBA > 0){ printf("Q22 bus\n"); uba_hd[0].uba_type = UBAUVII; /* Set up the Qbus map base register */ *(int *)PHYS_TO_K1(KN220QMAPBASEREG) = qmapbase; /* * This call to unifind uses mapped address space (KSEG2) * to touch the Q bus csrs. It also initialises the i/o * data structures to use KSEG2 to access the csrs. * * Unifind will set the scb entries to stray catcher then * load the entries. Because of this the unifind() call
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -