📄 kn02.c
字号:
}/* * Print error packet to the console. * This is only done when we are about to panic on the error. * It calls kn02_print_consinfo to actually print the information. * */kn02consprint(pkt, ep, kn02csr, erradr, chksyn_plus) int pkt; /* error pkt: Error & Stat Regs / memory pkt */ register u_int *ep; /* exception frame ptr */ u_int kn02csr; /* kn02csr to print */ u_int erradr; /* kn02 erradr to print */ u_int chksyn_plus; /* chksyn + error count + pc valid bit */{ register int i; struct kn02consinfo_t p; p.pkt_type = pkt; switch (pkt) { case ESR_INTR_PKT: p.pkt.intrp.cause = ep[EF_CAUSE]; p.pkt.intrp.sr = ep[EF_SR]; p.pkt.intrp.sp = ep[EF_SP]; p.pkt.intrp.csr = kn02csr; p.pkt.intrp.erradr = erradr; break; case ESR_BUS_PKT: p.pkt.busp.cause = ep[EF_CAUSE]; p.pkt.busp.epc = ep[EF_EPC]; p.pkt.busp.sr = ep[EF_SR]; p.pkt.busp.badvaddr = ep[EF_BADVADDR]; p.pkt.busp.sp = ep[EF_SP]; p.pkt.busp.csr = kn02csr; p.pkt.busp.erradr = erradr; break; case MEMPKT: if (chksyn_plus & 0x80000000) p.pkt.memp.epc = ep[EF_EPC]; p.pkt.memp.csr = kn02csr; p.pkt.memp.erradr = erradr; p.pkt.memp.chksyn_plus = chksyn_plus; break; default: cprintf("bad consprint\n"); return; } kn02_print_consinfo(&p); }/* * This routine is similar to kn02consprint(). * This is exported through the cpusw structure. * */kn02_print_consinfo(p)struct kn02consinfo_t *p;{ /* * If console is a graphics device, * force printf messages directly to screen. */ printstate |= PANICPRINT; switch (p->pkt_type) { case ESR_INTR_PKT: cprintf("\nException condition\n"); cprintf("\tCause reg\t= 0x%x\n", p->pkt.intrp.cause); cprintf("\tException PC\t= invalid for this error\n"); cprintf("\tStatus reg\t= 0x%x\n", p->pkt.intrp.sr); cprintf("\tBad virt addr\t= invalid for this error\n"); cprintf("\tStack ptr\t= 0x%x\n", p->pkt.intrp.sp); cprintf("\tSystem CSR\t= 0x%x\n", p->pkt.intrp.csr); cprintf("\tERRADR register\t= 0x%x\n", p->pkt.intrp.erradr); cprintf("\t Phys addr\t= 0x%x\n", (p->pkt.intrp.erradr&ERR_ADDR) << 2); break; case ESR_BUS_PKT: cprintf("\nException condition\n"); cprintf("\tCause reg\t= 0x%x\n", p->pkt.busp.cause); cprintf("\tException PC\t= 0x%x\n", p->pkt.busp.epc); cprintf("\tStatus reg\t= 0x%x\n", p->pkt.busp.sr); cprintf("\tBad virt addr\t= 0x%x\n", p->pkt.busp.badvaddr); cprintf("\tStack ptr\t= 0x%x\n", p->pkt.busp.sp); cprintf("\tSystem CSR\t= 0x%x\n", p->pkt.busp.csr); cprintf("\tERRADR register\t= 0x%x\n", p->pkt.busp.erradr); cprintf("\t Phys addr\t= 0x%x\n", (p->pkt.busp.erradr&ERR_ADDR) << 2); break; case MEMPKT: cprintf("\nMemory Error\n"); if (p->pkt.memp.chksyn_plus & 0x80000000) cprintf("\tException PC\t= 0x%x\n", p->pkt.memp.chksyn_plus); else cprintf("\tException PC\t= invalid for this error\n"); cprintf("\tSystem CSR\t= 0x%x\n", p->pkt.memp.csr); cprintf("\tERRADR register\t= 0x%x\n", p->pkt.memp.erradr); cprintf("\t Phys addr\t= 0x%x\n", (p->pkt.memp.erradr&ERR_ADDR) << 2); cprintf("\tError count for module %d = %d\n", ((p->pkt.memp.chksyn_plus & CPLUS_MMASK) >> CPLUS_MOFF), ((p->pkt.memp.chksyn_plus & CPLUS_EMASK) >> CPLUS_EOFF)); break; default: cprintf("bad print_consinfo \n"); break; }}/* * * kn02_config_nvram * * - initialize pointers to cpu specific routines for Prestoserve * - Check for nvram presence * - initialize status and control register location according to * nvram location * - make call to presto_init to initialize Prestoserve * * */int kn02_cache_nvram = 1;int kn02_nvram_mapped = 0;unsigned nv_csr = 0x1;unsigned nv_diag = 0x13;kn02_config_nvram(){ extern kn02_nvram_status(); extern kn02_nvram_battery_status(); extern kn02_nvram_battery_enable(); extern kn02_nvram_battery_disable(); extern u_int kn02_machineid(); extern int memlimit; unsigned kn02_nvram_start_addr; unsigned int kn02_nvram_location; unsigned kn02_nvram_size; unsigned kn02_nvram_physaddr; unsigned nvram_id = 0; short i = 0; static unsigned addr[] = { 0x800000, 0x1000000, 0x1800000, 0x2000000, 0x2800000, 0x3000000, 0x3800000, 0x4000000, 0x4800000, 0x5000000, 0x5800000, 0x6000000, 0x6800000, 0x7000000, 0x8000000, 0xa000000, 0xc000000, 0xe000000, 0x10000000, 0x12000000, 0x14000000, 0x16000000, 0x18000000, 0x1a000000, 0x1c000000 }; /* * For 3max testing, using main memory instead of NVRAM * Use memlimit to stop memory at 32Mb, memlimit=0x2000000 * Set up necessary registers, to simulate NVRAM interface * */ if (kn02_test) { if (memlimit) { printf("kn02 NVRAM debug: Simmulating NVRAM in manin memory\n"); printf("kn02 NVRAM debug: Starting address = 0x%x\n",memlimit); *(int *)PHYS_TO_K1((memlimit + 0x3f8)) = nv_diag; /* diag */ *(int *)PHYS_TO_K1((memlimit + 0x3fc)) = 0x03021966; /* id */ *(int *)PHYS_TO_K1((memlimit + 0x400000)) = nv_csr; /* csr */ } } /* * Initialize the structure that will point to the cpu specific * functions for Prestoserve */ presto_interface0.nvram_status = kn02_nvram_status; presto_interface0.nvram_battery_status= kn02_nvram_battery_status; presto_interface0.nvram_battery_disable= kn02_nvram_battery_disable; presto_interface0.nvram_battery_enable= kn02_nvram_battery_enable; /* * configure the NVRAM option if it is present * * Manually probe the possible locations where nvram address * space can begin, if there is memory there, then look for * the know signature at the id location. * */ for ( i=0 ; i <= 24 ; i+=1) { if ( bbadaddr(PHYS_TO_K1(addr[i]+KN02_NVRAM_ID),4) && bbadaddr(PHYS_TO_K1(addr[i]+KN02_NVRAM_ID),4)) { Dprintf("kn02: No memory board present at 0x%x, i=%d\n", PHYS_TO_K1(addr[i]+KN02_NVRAM_ID),i); } else { nvram_id = *(int *)PHYS_TO_K1(addr[i]+KN02_NVRAM_ID); Dprintf("%d: ID from memory = 0x%x\n",i, nvram_id); if ( nvram_id == KN02_NVRAM_IDENTIFIER) { kn02_nvram_found = 1; Dprintf("kn02: Found NVRAM board\n"); kn02_nvram_physaddr = addr[i]; break; } else Dprintf("kn02: Not an NVRAM board\n"); } } if (kn02_nvram_found) { kn02_nvram_location = PHYS_TO_K1(kn02_nvram_physaddr) ; kn02_nvram_start_addr = kn02_nvram_physaddr + KN02_NVRAM_START ; kn02_nvram_diag = PHYS_TO_K1(kn02_nvram_location+KN02_NVRAM_DIAG); kn02_nvram_csr = kn02_nvram_location + 0x400000; kn02_nvram_size = (*(int *)kn02_nvram_diag & NVRAM_SIZE) >> 4; kn02_nvram_size *= 0x100000; /* convert to bytes */ kn02_nvram_size -= 0x400; /* - reserved space */ Dprintf("NVRAM: Starting address = 0x%x\n", kn02_nvram_start_addr); Dprintf("NVRAM: Diag reg address = 0x%x\n", kn02_nvram_diag); Dprintf("NVRAM: Diag reg contents = 0x%x\n", *(int *)PHYS_TO_K1(kn02_nvram_diag)); presto_init(kn02_nvram_start_addr, kn02_nvram_size, kn02_nvram_mapped, kn02_cache_nvram, kn02_machineid()); }}/* * * kn02_nvram_status * * provide presto with status of diagnostics run on nvram * hence, let presto know what to do - recover, etc... * * RETURN value: -1 if no status set, otherwise pr.h defined value * */kn02_nvram_status(){ if ( *(int *)kn02_nvram_diag & KN02_NVRAM_FAILED) return(NVRAM_BAD); else if ( *(int *)kn02_nvram_diag & KN02_NVRAM_RO) return(NVRAM_RDONLY); else if ( *(int *)kn02_nvram_diag & KN02_NVRAM_RW) return(NVRAM_RDWR); else { printf("kn02_nvram_status: No nvram diag bits set for status"); return(-1); }}/* * kn02_nvram_battery_status * * update the global battery information structure for Prestoserve * * RETURN value: 0, if batteries are ok; 1, if problem */kn02_nvram_battery_status(){ nvram_batteries0.nv_nbatteries = 1; /* one battery */ nvram_batteries0.nv_minimum_ok = 1; /* it must be good */ nvram_batteries0.nv_primary_mandatory = 1; /* primary must be OK */ nvram_batteries0.nv_test_retries = 3; /* call this routine 3 times * for each "test" */ /* for 3max simulation - always return true, enable zeros BOK */ if ( (*(int *)kn02_nvram_csr & KN02_NVRAM_BOK) || (kn02_test) ) { nvram_batteries0.nv_status[0] = BATT_OK; return(0); } else return(1); }/* * kn02_nvram_battery_enable * * - arms the battery * - required action is to zero BDISC control bit, this disables the * battery disconect circuit. * * RETURN value: 1, if batteries successfully enabled, 0 if not */kn02_nvram_battery_enable(){ *(int *)kn02_nvram_csr = 0x0; wbflush(); if ( (*(int *)kn02_nvram_csr & KN02_NVRAM_BDISC)) return(1); else return(0);}/* * kn02_nvram_battery_disable * * - unarms battery * - required action is to send sequence "11001" to control register * - this enables the battery disconnect circuit * - The excessive wbflushes are used to protect against merged writes * * RETURN value: 0, if batteries successfully disabled, 1 if not */kn02_nvram_battery_disable(){/*psgfix - may be able to do dummy writes inbetween writes, and 1 wbflush*/ *(int *)kn02_nvram_csr = 0x1; wbflush(); *(int *)kn02_nvram_csr = 0x1; wbflush(); *(int *)kn02_nvram_csr = 0x0; wbflush(); *(int *)kn02_nvram_csr = 0x0; wbflush(); *(int *)kn02_nvram_csr = 0x1; wbflush(); if ( *(int *)kn02_nvram_csr & KN02_NVRAM_BDISC ) return(0); else return(1); }#include "../h/socket.h"#include "../net/net/if.h"/* * Get the hardware E_net address for on-board ln0 and use it * to build a poor man's version of a unique processor ID. */u_intkn02_machineid(){ register struct ifnet *ifp = ifnet; struct ifdevea ifr; u_int i = 0; int error; if (ifnet == NULL) { printf("kn220: ifnet NULL\n"); return (i); } while (ifp != NULL) { if (ifp->if_name[0] == 'l' && ifp->if_name[1] == 'n' && ifp->if_unit == 0) { /* found ln0 */ error = (*ifp->if_ioctl)(ifp, SIOCRPHYSADDR, &ifr); if (error) return (i); i = (u_int)ifr.default_pa[2]; i = i << 8; i += (u_int)ifr.default_pa[3]; i = i << 8; i += (u_int)ifr.default_pa[4]; i = i << 8; i += (u_int)ifr.default_pa[5]; return (i); } ifp = ifp->if_next; } return (i);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -