📄 cvax.c
字号:
(*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);}cca_setup(){/* return the number of configured CPUs which are still in console mode */ register int i, j; register int cpustarted; register int num_cpu = 0; register int stkpaddr; u_char *cca_phys; int timeout; cca_phys = (u_char *)rpb.cca_addr; /* get CCA addr from RPB */#ifdef VAX6200 || VAX6400 if ((cpu == VAX_6200) || (cpu == VAX_6400)) nxaccess(cca_phys,CCAmap,4096); #endif VAX6200#ifdef VAX60 if (cpu == VAX_60) nxaccess(cca_phys,CCAmap, (12*512)); #endif VAX60 /* sanity check CCA */ if (cca_phys != (u_char *)ccabase.cca_base || (ccabase.cca_indent0 != 'C') || (ccabase.cca_indent1 != 'C')) { panic("no CCA"); } /* the only CPU which is running at this point is the boot * CPU. All other CPUs are still in console mode. Therefore to * determine how many CPUs are configured, count the CPUs in * console mode, and add 1. (note: the 1 is added by the caller * of this routine. */ for ( cpustarted=0, i=0; i < ccabase.cca_nproc; i++ ) { if (ccabase.cca_console & (1 << i)) { num_cpu++; } } return(num_cpu);}extern int max_vec_procs;char *hextochar = "0123456789ABCDEF";char *init_slave_stack = "d sp XXXXXXXX\r";char *init_cpu = "I X\r";cca_startcpu(cpunum)int cpunum;{ register int j; register int stkpaddr; int timeout; if (ccabase.cca_console & (1 << cpunum)) { /* Check for enabled CPU (assume no more than 32 CPUs) */ if (ccabase.cca_enabled & (1 << cpunum)) { get_cpudata(cpunum); if (cpu == VAX_6200) { if (!CPUDATA(cpunum)->cpu_machdep) /*Allocate memory to store machine check information */ KM_ALLOC((CPUDATA(cpunum)->cpu_machdep), char *, sizeof(struct xcp_machdep_data), KM_MBUF,KM_CLEAR | KM_CONTIG); } if (cpu == VAX_60) { cca_send("I\r", cpunum); /* * Since the VAX_60 console code requires us to * point it to a valid stack before sending the * start command, (which appears to be a violation * of the VAX SRM) we will set the stack pointer * to the address of the RX buffer in the CCA for * this processor. This will cause the first push * to start at the end of the TX buffer in the CCA * for this processor. */ stkpaddr = svtophy(ccabase.cca_buf[cpunum].rx); for(j = 12; init_slave_stack[j] == 'X'; j--) { init_slave_stack[j] = hextochar[stkpaddr & 0xf]; stkpaddr = stkpaddr >> 4; } cca_send(init_slave_stack, cpunum); } else { /* * Init the slave */ init_cpu[2] = hextochar[cpunum]; if((cpu != VAX_6400) || ((cpu == VAX_6400) && (cpu_sub_subtype != MARIAH_VARIANT))) cca_send(init_cpu, cpunum); /* Don't INIT if XMP */ } /* * cca revision determines whether or not there might be an * attached vector processor. vector processors are attached * to scalar cpu's only * after cca rev #3 */ if ((cpu == VAX_6400) && (ccabase.cca_b_revision > 3)) { if (max_vec_procs > 0) { /* if there is a scalar in this slot ... */ if ( CPUDATA(cpunum) ) { /* allocate memory for the vpdata structure */ KM_ALLOC (( CPUDATA ( cpunum)-> cpu_vpdata), struct vpdata *, sizeof(struct vpdata), KM_VECTOR , KM_CLEAR | KM_CONTIG); /* if this scalar has an attached vector ... */ /* NOTE: I am commenting out the call to * vp_reset. Since we are running on the boot * processor, and starting a secondary, * vp_reset would be accessing the wrong * registers if called from here. the call to * vp_reset has been moved to _slavestart in * locore.s */ /* test to see if there is an enabled VP on * cpunum. If there is not an enabled VP, then * clear the vector enabled bit */ if (! (vpmask & CPUDATA(cpunum)->cpu_mask) ) { /* disable the vector processor by writing a * 0 to the vector present bit in the ACCS * register of cpunum. ACCS is IPR #40 * (0x28). */ cca_send ("D/I 28 0\r", cpunum); } } } else { /* * disable the vector processor by writing a 0 to * the vector present bit in the ACCS register of * cpunum. ACCS is IPR #40 (0x28). */ cca_send ("D/I 28 0\r", cpunum); } } /* Start slave cpu at address 100 */ cca_send("S 100\r", cpunum); timeout=1000; while ( (ccabase.cca_console & (1<<cpunum)) ) { DELAY(10000) if (--timeout < 0) break; } if(!(ccabase.cca_console & (1 << cpunum))) { return(1); } } else { /* note disabled cpu in error log */ mprintf("CPU %x disabled\n",cpunum); } } return(0);}cca_send(str,cpunum) register char *str;register int cpunum;{ register int index; int timeout; timeout=1000; while ( (ccabase.cca_buf[cpunum].flags & RXRDY) != 0) { DELAY(10000); if (--timeout < 0) { printf("processor %x not ready\n",cpunum); return; } } index = 0; while (*str != '\0') { ccabase.cca_buf[cpunum].rx[index] = *str; str++; index++; } ccabase.cca_buf[cpunum].rxlen = index; ccabase.cca_buf[cpunum].flags |= RXRDY; timeout=1000; while ( (ccabase.cca_buf[cpunum].flags & RXRDY) != 0) { if((cpu == VAX_6400) && (cpu_sub_subtype == MARIAH_VARIANT)) { DELAY(100000); /* Extra delay for XMP */ } else { DELAY(10000); } if (--timeout < 0) { printf("processor %x not ready\n",cpunum); return; } }} /* * Prints the console message from a slave processor on the console */cca_print(cpunum)register int cpunum;{ int index; char *cp; if (ccabase.cca_ready & (1 << cpunum)) { cp = ccabase.cca_buf[cpunum].tx; printf("cpunum = 0x%x, flag = 0x%x, rxlen = 0x%x, txlen = 0x%x\n", cpunum, ccabase.cca_buf[cpunum].flags, ccabase.cca_buf[cpunum].rxlen, ccabase.cca_buf[cpunum].txlen); for (index = 0; index <= ccabase.cca_buf[cpunum].txlen; index++) { putchar((struct el_msg *)0, cp++, 0); } ccabase.cca_ready |= (ccabase.cca_ready & ~( 1 << cpunum)); }}/* * Stop the processor that is currently running. * */cca_stopcpu() { spl7(); CURRENT_CPUDATA->cpu_state &= ~CPU_RUN; bbssi((CURRENT_CPUDATA->cpu_num),&ccabase.cca_secstart); bbssi((CURRENT_CPUDATA->cpu_num),&ccabase.cca_restartip); asm("halt");}cca_check_input() { register int i,j; if(ccabase.cca_ready) { for (i = 0 ; i< 32; i++) { if (ccabase.cca_ready & (1<<i)){ /* decide what to do with the message */ cca_decode_message(i); bbcci(i,&ccabase.cca_ready); } } }}/* * look for halt code in the message. If it is a ?06 and the * percpu structure says this processor was halting then the processor * was stopped in a "nice" manner. If it is a ?02 (ctrl-P) then assume * debugging is taking place. Otherwise an error halt took * place and it is time to bring down the system. * */cca_decode_message(i)int i;{ int j;/*ccabase.cca_buf[i].tx[ccabase.cca_buf[i].txlen] = 0;printf("CPU %x: %s\n",i,ccabase.cca_buf[i].tx);*/ for(j = 0; j <ccabase.cca_buf[i].txlen; j++) { /* find start of halt code */ if (ccabase.cca_buf[i].tx[j] == '?') { if ((ccabase.cca_buf[i].tx[j+1] == '0')&& (ccabase.cca_buf[i].tx[j+2] == '6') && (CPUDATA(i)->cpu_state & CPU_STOP)) { /* Halt instruction when stopping cpu */ uprintf("CPU %d was halted \n",i); } else if ((ccabase.cca_buf[i].tx[j+1] == '0')&& (ccabase.cca_buf[i].tx[j+2] == '2')) { /* stopped by a control-P. Assume that someone is debugging using the console */ printf("CPU %d was stopped by ctrl-P\n",i); } else { /* ERROR HALT */ ccabase.cca_buf[i].tx[j+3]=0; /* clear string end */ printf("CPU %d halted with code %s\n", i,&ccabase.cca_buf[i].tx[j]); panic("secondary halted"); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -