1417eba8cSderaadt /* $NetBSD: machdep.c,v 1.19.4.5 1996/06/15 03:56:33 cgd Exp $ */ 2df930be7Sderaadt 3df930be7Sderaadt /* 4417eba8cSderaadt * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. 5df930be7Sderaadt * All rights reserved. 6df930be7Sderaadt * 7df930be7Sderaadt * Author: Chris G. Demetriou 8df930be7Sderaadt * 9df930be7Sderaadt * Permission to use, copy, modify and distribute this software and 10df930be7Sderaadt * its documentation is hereby granted, provided that both the copyright 11df930be7Sderaadt * notice and this permission notice appear in all copies of the 12df930be7Sderaadt * software, derivative works or modified versions, and any portions 13df930be7Sderaadt * thereof, and that both notices appear in supporting documentation. 14df930be7Sderaadt * 15df930be7Sderaadt * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16df930be7Sderaadt * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 17df930be7Sderaadt * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18df930be7Sderaadt * 19df930be7Sderaadt * Carnegie Mellon requests users of this software to return to 20df930be7Sderaadt * 21df930be7Sderaadt * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22df930be7Sderaadt * School of Computer Science 23df930be7Sderaadt * Carnegie Mellon University 24df930be7Sderaadt * Pittsburgh PA 15213-3890 25df930be7Sderaadt * 26df930be7Sderaadt * any improvements or extensions that they make and grant Carnegie the 27df930be7Sderaadt * rights to redistribute these changes. 28df930be7Sderaadt */ 29df930be7Sderaadt 30df930be7Sderaadt #include <sys/param.h> 31df930be7Sderaadt #include <sys/systm.h> 32df930be7Sderaadt #include <sys/signalvar.h> 33df930be7Sderaadt #include <sys/kernel.h> 34df930be7Sderaadt #include <sys/map.h> 35df930be7Sderaadt #include <sys/proc.h> 36df930be7Sderaadt #include <sys/buf.h> 37df930be7Sderaadt #include <sys/reboot.h> 38417eba8cSderaadt #include <sys/device.h> 39df930be7Sderaadt #include <sys/conf.h> 40df930be7Sderaadt #include <sys/file.h> 41df930be7Sderaadt #ifdef REAL_CLISTS 42df930be7Sderaadt #include <sys/clist.h> 43df930be7Sderaadt #endif 44df930be7Sderaadt #include <sys/callout.h> 45df930be7Sderaadt #include <sys/malloc.h> 46df930be7Sderaadt #include <sys/mbuf.h> 47df930be7Sderaadt #include <sys/msgbuf.h> 48df930be7Sderaadt #include <sys/ioctl.h> 49df930be7Sderaadt #include <sys/tty.h> 50df930be7Sderaadt #include <sys/user.h> 51df930be7Sderaadt #include <sys/exec.h> 52df930be7Sderaadt #include <sys/exec_ecoff.h> 53df930be7Sderaadt #include <sys/sysctl.h> 54df930be7Sderaadt #ifdef SYSVMSG 55df930be7Sderaadt #include <sys/msg.h> 56df930be7Sderaadt #endif 57df930be7Sderaadt #ifdef SYSVSEM 58df930be7Sderaadt #include <sys/sem.h> 59df930be7Sderaadt #endif 60df930be7Sderaadt #ifdef SYSVSHM 61df930be7Sderaadt #include <sys/shm.h> 62df930be7Sderaadt #endif 63df930be7Sderaadt 64df930be7Sderaadt #include <sys/mount.h> 65df930be7Sderaadt #include <sys/syscallargs.h> 66df930be7Sderaadt 67df930be7Sderaadt #include <vm/vm_kern.h> 68df930be7Sderaadt 69df930be7Sderaadt #include <dev/cons.h> 70df930be7Sderaadt 71df930be7Sderaadt #include <machine/cpu.h> 72df930be7Sderaadt #include <machine/reg.h> 73df930be7Sderaadt #include <machine/rpb.h> 74df930be7Sderaadt #include <machine/prom.h> 75df930be7Sderaadt 76df930be7Sderaadt #ifdef DEC_3000_500 77df930be7Sderaadt #include <alpha/alpha/dec_3000_500.h> 78df930be7Sderaadt #endif 79df930be7Sderaadt #ifdef DEC_3000_300 80df930be7Sderaadt #include <alpha/alpha/dec_3000_300.h> 81df930be7Sderaadt #endif 82df930be7Sderaadt #ifdef DEC_2100_A50 83df930be7Sderaadt #include <alpha/alpha/dec_2100_a50.h> 84df930be7Sderaadt #endif 8534fbf6deSderaadt #ifdef DEC_KN20AA 8634fbf6deSderaadt #include <alpha/alpha/dec_kn20aa.h> 8734fbf6deSderaadt #endif 8834fbf6deSderaadt #ifdef DEC_AXPPCI_33 8934fbf6deSderaadt #include <alpha/alpha/dec_axppci_33.h> 9034fbf6deSderaadt #endif 9134fbf6deSderaadt #ifdef DEC_21000 9234fbf6deSderaadt #include <alpha/alpha/dec_21000.h> 9334fbf6deSderaadt #endif 94df930be7Sderaadt 95df930be7Sderaadt #include <net/netisr.h> 96df930be7Sderaadt #include "ether.h" 97df930be7Sderaadt 98417eba8cSderaadt #include "le_ioasic.h" /* for le_iomem creation */ 99df930be7Sderaadt 100df930be7Sderaadt vm_map_t buffer_map; 101df930be7Sderaadt 102df930be7Sderaadt void dumpsys __P((void)); 103df930be7Sderaadt 104df930be7Sderaadt /* 105df930be7Sderaadt * Declare these as initialized data so we can patch them. 106df930be7Sderaadt */ 107df930be7Sderaadt int nswbuf = 0; 108df930be7Sderaadt #ifdef NBUF 109df930be7Sderaadt int nbuf = NBUF; 110df930be7Sderaadt #else 111df930be7Sderaadt int nbuf = 0; 112df930be7Sderaadt #endif 113df930be7Sderaadt #ifdef BUFPAGES 114df930be7Sderaadt int bufpages = BUFPAGES; 115df930be7Sderaadt #else 116df930be7Sderaadt int bufpages = 0; 117df930be7Sderaadt #endif 118df930be7Sderaadt int msgbufmapped = 0; /* set when safe to use msgbuf */ 119df930be7Sderaadt int maxmem; /* max memory per process */ 120df930be7Sderaadt 121df930be7Sderaadt int totalphysmem; /* total amount of physical memory in system */ 122df930be7Sderaadt int physmem; /* physical memory used by NetBSD + some rsvd */ 123df930be7Sderaadt int firstusablepage; /* first usable memory page */ 124df930be7Sderaadt int lastusablepage; /* last usable memory page */ 125df930be7Sderaadt int resvmem; /* amount of memory reserved for PROM */ 126df930be7Sderaadt int unusedmem; /* amount of memory for OS that we don't use */ 127df930be7Sderaadt int unknownmem; /* amount of memory with an unknown use */ 128df930be7Sderaadt 129df930be7Sderaadt int cputype; /* system type, from the RPB */ 130df930be7Sderaadt 131df930be7Sderaadt /* 132df930be7Sderaadt * XXX We need an address to which we can assign things so that they 133df930be7Sderaadt * won't be optimized away because we didn't use the value. 134df930be7Sderaadt */ 135df930be7Sderaadt u_int32_t no_optimize; 136df930be7Sderaadt 137df930be7Sderaadt /* the following is used externally (sysctl_hw) */ 138df930be7Sderaadt char machine[] = "alpha"; 139417eba8cSderaadt char cpu_model[128]; 140df930be7Sderaadt char *model_names[] = { 141df930be7Sderaadt "UNKNOWN (0)", 142df930be7Sderaadt "Alpha Demonstration Unit", 143df930be7Sderaadt "DEC 4000 (\"Cobra\")", 144df930be7Sderaadt "DEC 7000 (\"Ruby\")", 145df930be7Sderaadt "DEC 3000/500 (\"Flamingo\") family", 146df930be7Sderaadt "UNKNOWN (5)", 147df930be7Sderaadt "DEC 2000/300 (\"Jensen\")", 148df930be7Sderaadt "DEC 3000/300 (\"Pelican\")", 149df930be7Sderaadt "UNKNOWN (8)", 150df930be7Sderaadt "DEC 2100/A500 (\"Sable\")", 151df930be7Sderaadt "AXPvme 64", 152df930be7Sderaadt "AXPpci 33 (\"NoName\")", 15334fbf6deSderaadt "DEC 21000 (\"TurboLaser\")", 154df930be7Sderaadt "DEC 2100/A50 (\"Avanti\") family", 155df930be7Sderaadt "Mustang", 15634fbf6deSderaadt "DEC KN20AA", 15734fbf6deSderaadt "UNKNOWN (16)", 158df930be7Sderaadt "DEC 1000 (\"Mikasa\")", 159df930be7Sderaadt }; 160df930be7Sderaadt int nmodel_names = sizeof model_names/sizeof model_names[0]; 161df930be7Sderaadt 162df930be7Sderaadt struct user *proc0paddr; 163df930be7Sderaadt 164df930be7Sderaadt /* Number of machine cycles per microsecond */ 165df930be7Sderaadt u_int64_t cycles_per_usec; 166df930be7Sderaadt 167df930be7Sderaadt /* some memory areas for device DMA. "ick." */ 168df930be7Sderaadt caddr_t le_iomem; /* XXX iomem for LANCE DMA */ 169df930be7Sderaadt 170df930be7Sderaadt /* Interrupt vectors (in locore) */ 171df930be7Sderaadt extern int XentInt(), XentArith(), XentMM(), XentIF(), XentUna(), XentSys(); 172df930be7Sderaadt 173df930be7Sderaadt /* number of cpus in the box. really! */ 174df930be7Sderaadt int ncpus; 175df930be7Sderaadt 176df930be7Sderaadt /* various CPU-specific functions. */ 177df930be7Sderaadt char *(*cpu_modelname) __P((void)); 178417eba8cSderaadt void (*cpu_consinit) __P((void)); 179417eba8cSderaadt void (*cpu_device_register) __P((struct device *dev, void *aux)); 180df930be7Sderaadt char *cpu_iobus; 181df930be7Sderaadt 182417eba8cSderaadt char boot_flags[64]; 183417eba8cSderaadt 184417eba8cSderaadt /* for cpu_sysctl() */ 185417eba8cSderaadt char root_device[17]; 186df930be7Sderaadt 187df930be7Sderaadt int 188417eba8cSderaadt alpha_init(pfn, ptb) 189df930be7Sderaadt u_long pfn; /* first free PFN number */ 190df930be7Sderaadt u_long ptb; /* PFN of current level 1 page table */ 191df930be7Sderaadt { 192df930be7Sderaadt extern char _end[]; 193df930be7Sderaadt caddr_t start, v; 194df930be7Sderaadt struct mddt *mddtp; 195df930be7Sderaadt int i, mddtweird; 196df930be7Sderaadt char *p; 197df930be7Sderaadt 198df930be7Sderaadt /* 199df930be7Sderaadt * Turn off interrupts and floating point. 200df930be7Sderaadt * Make sure the instruction and data streams are consistent. 201df930be7Sderaadt */ 202df930be7Sderaadt (void)splhigh(); 203df930be7Sderaadt pal_wrfen(0); 204df930be7Sderaadt TBIA(); 205df930be7Sderaadt IMB(); 206df930be7Sderaadt 207df930be7Sderaadt /* 208df930be7Sderaadt * get address of the restart block, while we the bootstrap 209df930be7Sderaadt * mapping is still around. 210df930be7Sderaadt */ 211df930be7Sderaadt hwrpb = (struct rpb *) phystok0seg(*(struct rpb **)HWRPB_ADDR); 212df930be7Sderaadt 213df930be7Sderaadt /* 214df930be7Sderaadt * Remember how many cycles there are per microsecond, 215df930be7Sderaadt * so that we can use delay(). Round up, for safety. 216df930be7Sderaadt */ 217df930be7Sderaadt cycles_per_usec = (hwrpb->rpb_cc_freq + 999999) / 1000000; 218df930be7Sderaadt 219df930be7Sderaadt /* 220df930be7Sderaadt * Init the PROM interface, so we can use printf 221df930be7Sderaadt * until PROM mappings go away in consinit. 222df930be7Sderaadt */ 223df930be7Sderaadt init_prom_interface(); 224df930be7Sderaadt 225df930be7Sderaadt /* 226df930be7Sderaadt * Point interrupt/exception vectors to our own. 227df930be7Sderaadt */ 228df930be7Sderaadt pal_wrent(XentInt, 0); 229df930be7Sderaadt pal_wrent(XentArith, 1); 230df930be7Sderaadt pal_wrent(XentMM, 2); 231df930be7Sderaadt pal_wrent(XentIF, 3); 232df930be7Sderaadt pal_wrent(XentUna, 4); 233df930be7Sderaadt pal_wrent(XentSys, 5); 234df930be7Sderaadt 235df930be7Sderaadt /* 236df930be7Sderaadt * Find out how much memory is available, by looking at 237df930be7Sderaadt * the memory cluster descriptors. This also tries to do 238df930be7Sderaadt * its best to detect things things that have never been seen 239df930be7Sderaadt * before... 240df930be7Sderaadt * 241df930be7Sderaadt * XXX Assumes that the first "system" cluster is the 242df930be7Sderaadt * only one we can use. Is the second (etc.) system cluster 243df930be7Sderaadt * (if one happens to exist) guaranteed to be contiguous? or...? 244df930be7Sderaadt */ 245df930be7Sderaadt mddtp = (struct mddt *)(((caddr_t)hwrpb) + hwrpb->rpb_memdat_off); 246df930be7Sderaadt 247df930be7Sderaadt /* 248df930be7Sderaadt * BEGIN MDDT WEIRDNESS CHECKING 249df930be7Sderaadt */ 250df930be7Sderaadt mddtweird = 0; 251df930be7Sderaadt 252df930be7Sderaadt #define cnt mddtp->mddt_cluster_cnt 253df930be7Sderaadt #define usage(n) mddtp->mddt_clusters[(n)].mddt_usage 254df930be7Sderaadt if (cnt != 2 && cnt != 3) { 255df930be7Sderaadt printf("WARNING: weird number (%d) of mem clusters\n", cnt); 256df930be7Sderaadt mddtweird = 1; 257df930be7Sderaadt } else if (usage(0) != MDDT_PALCODE || 258df930be7Sderaadt usage(1) != MDDT_SYSTEM || 259df930be7Sderaadt (cnt == 3 && usage(2) != MDDT_PALCODE)) { 260df930be7Sderaadt mddtweird = 1; 261df930be7Sderaadt printf("WARNING: %d mem clusters, but weird config\n", cnt); 262df930be7Sderaadt } 263df930be7Sderaadt 264df930be7Sderaadt for (i = 0; i < cnt; i++) { 265df930be7Sderaadt if ((usage(i) & MDDT_mbz) != 0) { 266df930be7Sderaadt printf("WARNING: mem cluster %d has weird usage %lx\n", 267df930be7Sderaadt i, usage(i)); 268df930be7Sderaadt mddtweird = 1; 269df930be7Sderaadt } 270df930be7Sderaadt if (mddtp->mddt_clusters[i].mddt_pg_cnt == 0) { 271df930be7Sderaadt printf("WARNING: mem cluster %d has pg cnt == 0\n", i); 272df930be7Sderaadt mddtweird = 1; 273df930be7Sderaadt } 274df930be7Sderaadt /* XXX other things to check? */ 275df930be7Sderaadt } 276df930be7Sderaadt #undef cnt 277df930be7Sderaadt #undef usage 278df930be7Sderaadt 279df930be7Sderaadt if (mddtweird) { 280df930be7Sderaadt printf("\n"); 281df930be7Sderaadt printf("complete memory cluster information:\n"); 282df930be7Sderaadt for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { 283df930be7Sderaadt printf("mddt %d:\n", i); 284df930be7Sderaadt printf("\tpfn %lx\n", 285df930be7Sderaadt mddtp->mddt_clusters[i].mddt_pfn); 286df930be7Sderaadt printf("\tcnt %lx\n", 287df930be7Sderaadt mddtp->mddt_clusters[i].mddt_pg_cnt); 288df930be7Sderaadt printf("\ttest %lx\n", 289df930be7Sderaadt mddtp->mddt_clusters[i].mddt_pg_test); 290df930be7Sderaadt printf("\tbva %lx\n", 291df930be7Sderaadt mddtp->mddt_clusters[i].mddt_v_bitaddr); 292df930be7Sderaadt printf("\tbpa %lx\n", 293df930be7Sderaadt mddtp->mddt_clusters[i].mddt_p_bitaddr); 294df930be7Sderaadt printf("\tbcksum %lx\n", 295df930be7Sderaadt mddtp->mddt_clusters[i].mddt_bit_cksum); 296df930be7Sderaadt printf("\tusage %lx\n", 297df930be7Sderaadt mddtp->mddt_clusters[i].mddt_usage); 298df930be7Sderaadt } 299df930be7Sderaadt printf("\n"); 300df930be7Sderaadt } 301df930be7Sderaadt /* 302df930be7Sderaadt * END MDDT WEIRDNESS CHECKING 303df930be7Sderaadt */ 304df930be7Sderaadt 305df930be7Sderaadt for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { 306df930be7Sderaadt totalphysmem += mddtp->mddt_clusters[i].mddt_pg_cnt; 307df930be7Sderaadt #define usage(n) mddtp->mddt_clusters[(n)].mddt_usage 308df930be7Sderaadt #define pgcnt(n) mddtp->mddt_clusters[(n)].mddt_pg_cnt 309df930be7Sderaadt if ((usage(i) & MDDT_mbz) != 0) 310df930be7Sderaadt unknownmem += pgcnt(i); 311df930be7Sderaadt else if ((usage(i) & ~MDDT_mbz) == MDDT_PALCODE) 312df930be7Sderaadt resvmem += pgcnt(i); 313df930be7Sderaadt else if ((usage(i) & ~MDDT_mbz) == MDDT_SYSTEM) { 314df930be7Sderaadt /* 315df930be7Sderaadt * assumes that the system cluster listed is 316df930be7Sderaadt * one we're in... 317df930be7Sderaadt */ 318df930be7Sderaadt if (physmem != resvmem) { 319df930be7Sderaadt physmem += pgcnt(i); 320df930be7Sderaadt firstusablepage = 321df930be7Sderaadt mddtp->mddt_clusters[i].mddt_pfn; 322df930be7Sderaadt lastusablepage = firstusablepage + pgcnt(i) - 1; 323df930be7Sderaadt } else 324df930be7Sderaadt unusedmem += pgcnt(i); 325df930be7Sderaadt } 326df930be7Sderaadt #undef usage 327df930be7Sderaadt #undef pgcnt 328df930be7Sderaadt } 329df930be7Sderaadt if (totalphysmem == 0) 330df930be7Sderaadt panic("can't happen: system seems to have no memory!"); 331df930be7Sderaadt maxmem = physmem; 332df930be7Sderaadt 333df930be7Sderaadt #if 0 334df930be7Sderaadt printf("totalphysmem = %d\n", totalphysmem); 335df930be7Sderaadt printf("physmem = %d\n", physmem); 336df930be7Sderaadt printf("firstusablepage = %d\n", firstusablepage); 337df930be7Sderaadt printf("lastusablepage = %d\n", lastusablepage); 338df930be7Sderaadt printf("resvmem = %d\n", resvmem); 339df930be7Sderaadt printf("unusedmem = %d\n", unusedmem); 340df930be7Sderaadt printf("unknownmem = %d\n", unknownmem); 341df930be7Sderaadt #endif 342df930be7Sderaadt 343df930be7Sderaadt /* 344df930be7Sderaadt * find out this CPU's page size 345df930be7Sderaadt */ 346df930be7Sderaadt PAGE_SIZE = hwrpb->rpb_page_size; 34734fbf6deSderaadt if (PAGE_SIZE != 8192) 34834fbf6deSderaadt panic("page size %d != 8192?!", PAGE_SIZE); 349df930be7Sderaadt 350df930be7Sderaadt v = (caddr_t)alpha_round_page(_end); 351df930be7Sderaadt /* 352df930be7Sderaadt * Init mapping for u page(s) for proc 0 353df930be7Sderaadt */ 354df930be7Sderaadt start = v; 355df930be7Sderaadt curproc->p_addr = proc0paddr = (struct user *)v; 356df930be7Sderaadt v += UPAGES * NBPG; 357df930be7Sderaadt 358df930be7Sderaadt /* 359df930be7Sderaadt * Find out what hardware we're on, and remember its type name. 360df930be7Sderaadt */ 361df930be7Sderaadt cputype = hwrpb->rpb_type; 362df930be7Sderaadt switch (cputype) { 363df930be7Sderaadt #ifdef DEC_3000_500 /* and 400, [6-9]00 */ 364df930be7Sderaadt case ST_DEC_3000_500: 365df930be7Sderaadt cpu_modelname = dec_3000_500_modelname; 366df930be7Sderaadt cpu_consinit = dec_3000_500_consinit; 367417eba8cSderaadt cpu_device_register = dec_3000_500_device_register; 368200d7a17Sderaadt cpu_iobus = "tcasic"; 369df930be7Sderaadt break; 370df930be7Sderaadt #endif 371df930be7Sderaadt 372df930be7Sderaadt #ifdef DEC_3000_300 373df930be7Sderaadt case ST_DEC_3000_300: 374df930be7Sderaadt cpu_modelname = dec_3000_300_modelname; 375df930be7Sderaadt cpu_consinit = dec_3000_300_consinit; 376417eba8cSderaadt cpu_device_register = dec_3000_300_device_register; 377200d7a17Sderaadt cpu_iobus = "tcasic"; 378df930be7Sderaadt break; 379df930be7Sderaadt #endif 380df930be7Sderaadt 381df930be7Sderaadt #ifdef DEC_2100_A50 382df930be7Sderaadt case ST_DEC_2100_A50: 383df930be7Sderaadt cpu_modelname = dec_2100_a50_modelname; 384df930be7Sderaadt cpu_consinit = dec_2100_a50_consinit; 385417eba8cSderaadt cpu_device_register = dec_2100_a50_device_register; 386df930be7Sderaadt cpu_iobus = "apecs"; 387df930be7Sderaadt break; 388df930be7Sderaadt #endif 389df930be7Sderaadt 39034fbf6deSderaadt #ifdef DEC_KN20AA 39134fbf6deSderaadt case ST_DEC_KN20AA: 39234fbf6deSderaadt cpu_modelname = dec_kn20aa_modelname; 39334fbf6deSderaadt cpu_consinit = dec_kn20aa_consinit; 394417eba8cSderaadt cpu_device_register = dec_kn20aa_device_register; 39534fbf6deSderaadt cpu_iobus = "cia"; 39634fbf6deSderaadt break; 39734fbf6deSderaadt #endif 39834fbf6deSderaadt 39934fbf6deSderaadt #ifdef DEC_AXPPCI_33 40034fbf6deSderaadt case ST_DEC_AXPPCI_33: 40134fbf6deSderaadt cpu_modelname = dec_axppci_33_modelname; 40234fbf6deSderaadt cpu_consinit = dec_axppci_33_consinit; 403417eba8cSderaadt cpu_device_register = dec_axppci_33_device_register; 40434fbf6deSderaadt cpu_iobus = "lca"; 40534fbf6deSderaadt break; 40634fbf6deSderaadt #endif 40734fbf6deSderaadt 408df930be7Sderaadt #ifdef DEC_2000_300 409df930be7Sderaadt case ST_DEC_2000_300: 410df930be7Sderaadt cpu_modelname = dec_2000_300_modelname; 411df930be7Sderaadt cpu_consinit = dec_2000_300_consinit; 412417eba8cSderaadt cpu_device_register = dec_2000_300_device_register; 413df930be7Sderaadt cpu_iobus = "ibus"; 414df930be7Sderaadt XXX DEC 2000/300 NOT SUPPORTED 41534fbf6deSderaadt break; 416df930be7Sderaadt #endif 417df930be7Sderaadt 41834fbf6deSderaadt #ifdef DEC_21000 41934fbf6deSderaadt case ST_DEC_21000: 42034fbf6deSderaadt cpu_modelname = dec_21000_modelname; 42134fbf6deSderaadt cpu_consinit = dec_21000_consinit; 422417eba8cSderaadt cpu_device_register = dec_21000_device_register; 42334fbf6deSderaadt cpu_iobus = "tlsb"; 424417eba8cSderaadt XXX DEC 21000 NOT SUPPORTED 42534fbf6deSderaadt break; 426df930be7Sderaadt #endif 427df930be7Sderaadt 428df930be7Sderaadt default: 429df930be7Sderaadt if (cputype > nmodel_names) 430df930be7Sderaadt panic("Unknown system type %d", cputype); 431df930be7Sderaadt else 432df930be7Sderaadt panic("Support for %s system type not in kernel.", 433df930be7Sderaadt model_names[cputype]); 434df930be7Sderaadt } 435df930be7Sderaadt 436417eba8cSderaadt if ((*cpu_modelname)() != NULL) 437417eba8cSderaadt strncpy(cpu_model, (*cpu_modelname)(), sizeof cpu_model - 1); 438417eba8cSderaadt else 439417eba8cSderaadt strncpy(cpu_model, model_names[cputype], sizeof cpu_model - 1); 440417eba8cSderaadt cpu_model[sizeof cpu_model - 1] = '\0'; 441df930be7Sderaadt 442417eba8cSderaadt #if NLE_IOASIC > 0 443df930be7Sderaadt /* 444df930be7Sderaadt * Grab 128K at the top of physical memory for the lance chip 445df930be7Sderaadt * on machines where it does dma through the I/O ASIC. 446df930be7Sderaadt * It must be physically contiguous and aligned on a 128K boundary. 447417eba8cSderaadt * 448417eba8cSderaadt * Note that since this is conditional on the presence of 449417eba8cSderaadt * IOASIC-attached 'le' units in the kernel config, the 450417eba8cSderaadt * message buffer may move on these systems. This shouldn't 451417eba8cSderaadt * be a problem, because once people have a kernel config that 452417eba8cSderaadt * they use, they're going to stick with it. 453df930be7Sderaadt */ 454df930be7Sderaadt if (cputype == ST_DEC_3000_500 || 455df930be7Sderaadt cputype == ST_DEC_3000_300) { /* XXX possibly others? */ 456df930be7Sderaadt lastusablepage -= btoc(128 * 1024); 457df930be7Sderaadt le_iomem = (caddr_t)phystok0seg(ctob(lastusablepage + 1)); 458df930be7Sderaadt } 459417eba8cSderaadt #endif /* NLE_IOASIC */ 460df930be7Sderaadt 461df930be7Sderaadt /* 462df930be7Sderaadt * Initialize error message buffer (at end of core). 463df930be7Sderaadt */ 464df930be7Sderaadt lastusablepage -= btoc(sizeof (struct msgbuf)); 465df930be7Sderaadt msgbufp = (struct msgbuf *)phystok0seg(ctob(lastusablepage + 1)); 466df930be7Sderaadt msgbufmapped = 1; 467df930be7Sderaadt 468df930be7Sderaadt /* 469df930be7Sderaadt * Allocate space for system data structures. 470df930be7Sderaadt * The first available kernel virtual address is in "v". 471df930be7Sderaadt * As pages of kernel virtual memory are allocated, "v" is incremented. 472df930be7Sderaadt * 473df930be7Sderaadt * These data structures are allocated here instead of cpu_startup() 474df930be7Sderaadt * because physical memory is directly addressable. We don't have 475df930be7Sderaadt * to map these into virtual address space. 476df930be7Sderaadt */ 477df930be7Sderaadt #define valloc(name, type, num) \ 47834fbf6deSderaadt (name) = (type *)v; v = (caddr_t)ALIGN((name)+(num)) 479df930be7Sderaadt #define valloclim(name, type, num, lim) \ 48034fbf6deSderaadt (name) = (type *)v; v = (caddr_t)ALIGN((lim) = ((name)+(num))) 481df930be7Sderaadt #ifdef REAL_CLISTS 482df930be7Sderaadt valloc(cfree, struct cblock, nclist); 483df930be7Sderaadt #endif 484df930be7Sderaadt valloc(callout, struct callout, ncallout); 485df930be7Sderaadt valloc(swapmap, struct map, nswapmap = maxproc * 2); 486df930be7Sderaadt #ifdef SYSVSHM 487df930be7Sderaadt valloc(shmsegs, struct shmid_ds, shminfo.shmmni); 488df930be7Sderaadt #endif 489df930be7Sderaadt #ifdef SYSVSEM 490df930be7Sderaadt valloc(sema, struct semid_ds, seminfo.semmni); 491df930be7Sderaadt valloc(sem, struct sem, seminfo.semmns); 492df930be7Sderaadt /* This is pretty disgusting! */ 493df930be7Sderaadt valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); 494df930be7Sderaadt #endif 495df930be7Sderaadt #ifdef SYSVMSG 496df930be7Sderaadt valloc(msgpool, char, msginfo.msgmax); 497df930be7Sderaadt valloc(msgmaps, struct msgmap, msginfo.msgseg); 498df930be7Sderaadt valloc(msghdrs, struct msg, msginfo.msgtql); 499df930be7Sderaadt valloc(msqids, struct msqid_ds, msginfo.msgmni); 500df930be7Sderaadt #endif 501df930be7Sderaadt 502df930be7Sderaadt /* 503df930be7Sderaadt * Determine how many buffers to allocate. 504417eba8cSderaadt * We allocate 10% of memory for buffer space. Insure a 505df930be7Sderaadt * minimum of 16 buffers. We allocate 1/2 as many swap buffer 506df930be7Sderaadt * headers as file i/o buffers. 507df930be7Sderaadt */ 508df930be7Sderaadt if (bufpages == 0) 509417eba8cSderaadt bufpages = (physmem * 10) / (CLSIZE * 100); 510df930be7Sderaadt if (nbuf == 0) { 511df930be7Sderaadt nbuf = bufpages; 512df930be7Sderaadt if (nbuf < 16) 513df930be7Sderaadt nbuf = 16; 514df930be7Sderaadt } 515df930be7Sderaadt if (nswbuf == 0) { 516df930be7Sderaadt nswbuf = (nbuf / 2) &~ 1; /* force even */ 517df930be7Sderaadt if (nswbuf > 256) 518df930be7Sderaadt nswbuf = 256; /* sanity */ 519df930be7Sderaadt } 520df930be7Sderaadt valloc(swbuf, struct buf, nswbuf); 521df930be7Sderaadt valloc(buf, struct buf, nbuf); 522df930be7Sderaadt 523df930be7Sderaadt /* 524df930be7Sderaadt * Clear allocated memory. 525df930be7Sderaadt */ 526df930be7Sderaadt bzero(start, v - start); 527df930be7Sderaadt 528df930be7Sderaadt /* 529df930be7Sderaadt * Initialize the virtual memory system, and set the 530df930be7Sderaadt * page table base register in proc 0's PCB. 531df930be7Sderaadt */ 532df930be7Sderaadt pmap_bootstrap((vm_offset_t)v, phystok0seg(ptb << PGSHIFT)); 533df930be7Sderaadt 534df930be7Sderaadt /* 535df930be7Sderaadt * Initialize the rest of proc 0's PCB, and cache its physical 536df930be7Sderaadt * address. 537df930be7Sderaadt */ 538df930be7Sderaadt proc0.p_md.md_pcbpaddr = 539df930be7Sderaadt (struct pcb *)k0segtophys(&proc0paddr->u_pcb); 540df930be7Sderaadt 541df930be7Sderaadt /* 542df930be7Sderaadt * Set the kernel sp, reserving space for an (empty) trapframe, 543df930be7Sderaadt * and make proc0's trapframe pointer point to it for sanity. 544df930be7Sderaadt */ 545df930be7Sderaadt proc0paddr->u_pcb.pcb_ksp = 546df930be7Sderaadt (u_int64_t)proc0paddr + USPACE - sizeof(struct trapframe); 547df930be7Sderaadt proc0.p_md.md_tf = (struct trapframe *)proc0paddr->u_pcb.pcb_ksp; 548df930be7Sderaadt 549df930be7Sderaadt /* 550df930be7Sderaadt * Look at arguments passed to us and compute boothowto. 551df930be7Sderaadt */ 552417eba8cSderaadt prom_getenv(PROM_E_BOOTED_OSFLAGS, boot_flags, sizeof(boot_flags)); 553417eba8cSderaadt #if 0 554417eba8cSderaadt printf("boot flags = \"%s\"\n", boot_flags); 555df930be7Sderaadt #endif 556417eba8cSderaadt 557417eba8cSderaadt boothowto = RB_SINGLE; 558df930be7Sderaadt #ifdef KADB 559df930be7Sderaadt boothowto |= RB_KDB; 560df930be7Sderaadt #endif 561df930be7Sderaadt for (p = boot_flags; p && *p != '\0'; p++) { 562417eba8cSderaadt /* 563417eba8cSderaadt * Note that we'd really like to differentiate case here, 564417eba8cSderaadt * but the Alpha AXP Architecture Reference Manual 565417eba8cSderaadt * says that we shouldn't. 566417eba8cSderaadt */ 567df930be7Sderaadt switch (*p) { 568df930be7Sderaadt case 'a': /* autoboot */ 569417eba8cSderaadt case 'A': 570df930be7Sderaadt boothowto &= ~RB_SINGLE; 571df930be7Sderaadt break; 572df930be7Sderaadt 573417eba8cSderaadt case 'n': /* askname */ 574417eba8cSderaadt case 'N': 575df930be7Sderaadt boothowto |= RB_ASKNAME; 576df930be7Sderaadt break; 577df930be7Sderaadt 578417eba8cSderaadt #if 0 579417eba8cSderaadt case 'm': /* mini root present in memory */ 580417eba8cSderaadt case 'M': 581417eba8cSderaadt boothowto |= RB_MINIROOT; 582417eba8cSderaadt break; 583417eba8cSderaadt #endif 584df930be7Sderaadt } 585df930be7Sderaadt } 586df930be7Sderaadt 587df930be7Sderaadt /* 588df930be7Sderaadt * Figure out the number of cpus in the box, from RPB fields. 589df930be7Sderaadt * Really. We mean it. 590df930be7Sderaadt */ 591df930be7Sderaadt for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { 592df930be7Sderaadt struct pcs *pcsp; 593df930be7Sderaadt 594df930be7Sderaadt pcsp = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off + 595df930be7Sderaadt (i * hwrpb->rpb_pcs_size)); 596df930be7Sderaadt if ((pcsp->pcs_flags & PCS_PP) != 0) 597df930be7Sderaadt ncpus++; 598df930be7Sderaadt } 599df930be7Sderaadt 600df930be7Sderaadt return (0); 601df930be7Sderaadt } 602df930be7Sderaadt 603417eba8cSderaadt void 604df930be7Sderaadt consinit() 605df930be7Sderaadt { 606df930be7Sderaadt 607417eba8cSderaadt (*cpu_consinit)(); 608df930be7Sderaadt pmap_unmap_prom(); 609df930be7Sderaadt } 610df930be7Sderaadt 611417eba8cSderaadt void 612df930be7Sderaadt cpu_startup() 613df930be7Sderaadt { 614df930be7Sderaadt register unsigned i; 615df930be7Sderaadt register caddr_t v; 616df930be7Sderaadt int base, residual; 617df930be7Sderaadt vm_offset_t minaddr, maxaddr; 618df930be7Sderaadt vm_size_t size; 619df930be7Sderaadt #ifdef DEBUG 620df930be7Sderaadt extern int pmapdebug; 621df930be7Sderaadt int opmapdebug = pmapdebug; 622df930be7Sderaadt 623df930be7Sderaadt pmapdebug = 0; 624df930be7Sderaadt #endif 625df930be7Sderaadt 626df930be7Sderaadt /* 627df930be7Sderaadt * Good {morning,afternoon,evening,night}. 628df930be7Sderaadt */ 629df930be7Sderaadt printf(version); 630df930be7Sderaadt identifycpu(); 631df930be7Sderaadt printf("real mem = %d (%d reserved for PROM, %d used by NetBSD)\n", 632df930be7Sderaadt ctob(totalphysmem), ctob(resvmem), ctob(physmem)); 633df930be7Sderaadt if (unusedmem) 634df930be7Sderaadt printf("WARNING: unused memory = %d bytes\n", ctob(unusedmem)); 635df930be7Sderaadt if (unknownmem) 636df930be7Sderaadt printf("WARNING: %d bytes of memory with unknown purpose\n", 637df930be7Sderaadt ctob(unknownmem)); 638df930be7Sderaadt 639df930be7Sderaadt /* 640df930be7Sderaadt * Allocate virtual address space for file I/O buffers. 641df930be7Sderaadt * Note they are different than the array of headers, 'buf', 642df930be7Sderaadt * and usually occupy more virtual memory than physical. 643df930be7Sderaadt */ 644df930be7Sderaadt size = MAXBSIZE * nbuf; 645df930be7Sderaadt buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers, 646df930be7Sderaadt &maxaddr, size, TRUE); 647df930be7Sderaadt minaddr = (vm_offset_t)buffers; 648df930be7Sderaadt if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0, 649df930be7Sderaadt &minaddr, size, FALSE) != KERN_SUCCESS) 650df930be7Sderaadt panic("startup: cannot allocate buffers"); 651df930be7Sderaadt base = bufpages / nbuf; 652df930be7Sderaadt residual = bufpages % nbuf; 653df930be7Sderaadt for (i = 0; i < nbuf; i++) { 654df930be7Sderaadt vm_size_t curbufsize; 655df930be7Sderaadt vm_offset_t curbuf; 656df930be7Sderaadt 657df930be7Sderaadt /* 658df930be7Sderaadt * First <residual> buffers get (base+1) physical pages 659df930be7Sderaadt * allocated for them. The rest get (base) physical pages. 660df930be7Sderaadt * 661df930be7Sderaadt * The rest of each buffer occupies virtual space, 662df930be7Sderaadt * but has no physical memory allocated for it. 663df930be7Sderaadt */ 664df930be7Sderaadt curbuf = (vm_offset_t)buffers + i * MAXBSIZE; 665df930be7Sderaadt curbufsize = CLBYTES * (i < residual ? base+1 : base); 666df930be7Sderaadt vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE); 667df930be7Sderaadt vm_map_simplify(buffer_map, curbuf); 668df930be7Sderaadt } 669df930be7Sderaadt /* 670df930be7Sderaadt * Allocate a submap for exec arguments. This map effectively 671df930be7Sderaadt * limits the number of processes exec'ing at any time. 672df930be7Sderaadt */ 673df930be7Sderaadt exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 674df930be7Sderaadt 16 * NCARGS, TRUE); 675df930be7Sderaadt 676df930be7Sderaadt /* 677df930be7Sderaadt * Allocate a submap for physio 678df930be7Sderaadt */ 679df930be7Sderaadt phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 680df930be7Sderaadt VM_PHYS_SIZE, TRUE); 681df930be7Sderaadt 682df930be7Sderaadt /* 683df930be7Sderaadt * Finally, allocate mbuf pool. Since mclrefcnt is an off-size 684df930be7Sderaadt * we use the more space efficient malloc in place of kmem_alloc. 685df930be7Sderaadt */ 686df930be7Sderaadt mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES, 687df930be7Sderaadt M_MBUF, M_NOWAIT); 688df930be7Sderaadt bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES); 689df930be7Sderaadt mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, 690df930be7Sderaadt VM_MBUF_SIZE, FALSE); 691df930be7Sderaadt /* 692df930be7Sderaadt * Initialize callouts 693df930be7Sderaadt */ 694df930be7Sderaadt callfree = callout; 695df930be7Sderaadt for (i = 1; i < ncallout; i++) 696df930be7Sderaadt callout[i-1].c_next = &callout[i]; 697df930be7Sderaadt callout[i-1].c_next = NULL; 698df930be7Sderaadt 699df930be7Sderaadt #ifdef DEBUG 700df930be7Sderaadt pmapdebug = opmapdebug; 701df930be7Sderaadt #endif 702df930be7Sderaadt printf("avail mem = %ld\n", (long)ptoa(cnt.v_free_count)); 703df930be7Sderaadt printf("using %ld buffers containing %ld bytes of memory\n", 704df930be7Sderaadt (long)nbuf, (long)(bufpages * CLBYTES)); 705df930be7Sderaadt 706df930be7Sderaadt /* 707df930be7Sderaadt * Set up buffers, so they can be used to read disk labels. 708df930be7Sderaadt */ 709df930be7Sderaadt bufinit(); 710df930be7Sderaadt 711df930be7Sderaadt /* 712df930be7Sderaadt * Configure the system. 713df930be7Sderaadt */ 714*41033391Sderaadt if (boothowto & RB_CONFIG) { 715*41033391Sderaadt #ifdef BOOT_CONFIG 716*41033391Sderaadt user_config(); 717*41033391Sderaadt #else 718*41033391Sderaadt printf("kernel does not support -c; continuing..\n"); 719*41033391Sderaadt #endif 720*41033391Sderaadt } 721df930be7Sderaadt configure(); 722df930be7Sderaadt } 723df930be7Sderaadt 724df930be7Sderaadt identifycpu() 725df930be7Sderaadt { 726df930be7Sderaadt 727df930be7Sderaadt /* 728df930be7Sderaadt * print out CPU identification information. 729df930be7Sderaadt */ 730df930be7Sderaadt printf("%s, %dMHz\n", cpu_model, 731df930be7Sderaadt hwrpb->rpb_cc_freq / 1000000); /* XXX true for 21164? */ 732df930be7Sderaadt printf("%d byte page size, %d processor%s.\n", 733df930be7Sderaadt hwrpb->rpb_page_size, ncpus, ncpus == 1 ? "" : "s"); 734df930be7Sderaadt #if 0 735df930be7Sderaadt /* this isn't defined for any systems that we run on? */ 736df930be7Sderaadt printf("serial number 0x%lx 0x%lx\n", 737df930be7Sderaadt ((long *)hwrpb->rpb_ssn)[0], ((long *)hwrpb->rpb_ssn)[1]); 738df930be7Sderaadt 739df930be7Sderaadt /* and these aren't particularly useful! */ 740df930be7Sderaadt printf("variation: 0x%lx, revision 0x%lx\n", 741df930be7Sderaadt hwrpb->rpb_variation, *(long *)hwrpb->rpb_revision); 742df930be7Sderaadt #endif 743df930be7Sderaadt } 744df930be7Sderaadt 745df930be7Sderaadt int waittime = -1; 746df930be7Sderaadt struct pcb dumppcb; 747df930be7Sderaadt 748417eba8cSderaadt void 749df930be7Sderaadt boot(howto) 750df930be7Sderaadt int howto; 751df930be7Sderaadt { 752df930be7Sderaadt extern int cold; 753df930be7Sderaadt 754df930be7Sderaadt /* If system is cold, just halt. */ 755df930be7Sderaadt if (cold) { 756df930be7Sderaadt howto |= RB_HALT; 757df930be7Sderaadt goto haltsys; 758df930be7Sderaadt } 759df930be7Sderaadt 760df930be7Sderaadt boothowto = howto; 761df930be7Sderaadt if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 762df930be7Sderaadt waittime = 0; 763df930be7Sderaadt vfs_shutdown(); 764df930be7Sderaadt /* 765df930be7Sderaadt * If we've been adjusting the clock, the todr 766df930be7Sderaadt * will be out of synch; adjust it now. 767df930be7Sderaadt */ 768df930be7Sderaadt resettodr(); 769df930be7Sderaadt } 770df930be7Sderaadt 771df930be7Sderaadt /* Disable interrupts. */ 772df930be7Sderaadt splhigh(); 773df930be7Sderaadt 774df930be7Sderaadt /* If rebooting and a dump is requested do it. */ 775df930be7Sderaadt if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) { 776df930be7Sderaadt savectx(&dumppcb, 0); 777df930be7Sderaadt dumpsys(); 778df930be7Sderaadt } 779df930be7Sderaadt 78034fbf6deSderaadt haltsys: 78134fbf6deSderaadt 782df930be7Sderaadt /* run any shutdown hooks */ 783df930be7Sderaadt doshutdownhooks(); 784df930be7Sderaadt 785df930be7Sderaadt #ifdef BOOTKEY 786df930be7Sderaadt printf("hit any key to %s...\n", howto & RB_HALT ? "halt" : "reboot"); 787df930be7Sderaadt cngetc(); 788df930be7Sderaadt printf("\n"); 789df930be7Sderaadt #endif 790df930be7Sderaadt 791df930be7Sderaadt /* Finally, halt/reboot the system. */ 792df930be7Sderaadt printf("%s\n\n", howto & RB_HALT ? "halted." : "rebooting..."); 793df930be7Sderaadt prom_halt(howto & RB_HALT); 794df930be7Sderaadt /*NOTREACHED*/ 795df930be7Sderaadt } 796df930be7Sderaadt 797df930be7Sderaadt /* 798df930be7Sderaadt * These variables are needed by /sbin/savecore 799df930be7Sderaadt */ 800df930be7Sderaadt u_long dumpmag = 0x8fca0101; /* magic number */ 801df930be7Sderaadt int dumpsize = 0; /* pages */ 802df930be7Sderaadt long dumplo = 0; /* blocks */ 803df930be7Sderaadt 804df930be7Sderaadt /* 805df930be7Sderaadt * This is called by configure to set dumplo and dumpsize. 806df930be7Sderaadt * Dumps always skip the first CLBYTES of disk space 807df930be7Sderaadt * in case there might be a disk label stored there. 808df930be7Sderaadt * If there is extra space, put dump at the end to 809df930be7Sderaadt * reduce the chance that swapping trashes it. 810df930be7Sderaadt */ 811df930be7Sderaadt void 812df930be7Sderaadt dumpconf() 813df930be7Sderaadt { 814df930be7Sderaadt int nblks; /* size of dump area */ 815df930be7Sderaadt int maj; 816df930be7Sderaadt 817df930be7Sderaadt if (dumpdev == NODEV) 818df930be7Sderaadt return; 819df930be7Sderaadt maj = major(dumpdev); 820df930be7Sderaadt if (maj < 0 || maj >= nblkdev) 821df930be7Sderaadt panic("dumpconf: bad dumpdev=0x%x", dumpdev); 822df930be7Sderaadt if (bdevsw[maj].d_psize == NULL) 823df930be7Sderaadt return; 824df930be7Sderaadt nblks = (*bdevsw[maj].d_psize)(dumpdev); 825df930be7Sderaadt if (nblks <= ctod(1)) 826df930be7Sderaadt return; 827df930be7Sderaadt 828df930be7Sderaadt /* XXX XXX XXX STARTING MEMORY LOCATION */ 829df930be7Sderaadt dumpsize = physmem; 830df930be7Sderaadt 831df930be7Sderaadt /* Always skip the first CLBYTES, in case there is a label there. */ 832df930be7Sderaadt if (dumplo < ctod(1)) 833df930be7Sderaadt dumplo = ctod(1); 834df930be7Sderaadt 835df930be7Sderaadt /* Put dump at end of partition, and make it fit. */ 836df930be7Sderaadt if (dumpsize > dtoc(nblks - dumplo)) 837df930be7Sderaadt dumpsize = dtoc(nblks - dumplo); 838df930be7Sderaadt if (dumplo < nblks - ctod(dumpsize)) 839df930be7Sderaadt dumplo = nblks - ctod(dumpsize); 840df930be7Sderaadt } 841df930be7Sderaadt 842df930be7Sderaadt /* 843df930be7Sderaadt * Doadump comes here after turning off memory management and 844df930be7Sderaadt * getting on the dump stack, either when called above, or by 845df930be7Sderaadt * the auto-restart code. 846df930be7Sderaadt */ 847df930be7Sderaadt void 848df930be7Sderaadt dumpsys() 849df930be7Sderaadt { 850df930be7Sderaadt 851df930be7Sderaadt msgbufmapped = 0; 852df930be7Sderaadt if (dumpdev == NODEV) 853df930be7Sderaadt return; 854df930be7Sderaadt if (dumpsize == 0) { 855df930be7Sderaadt dumpconf(); 856df930be7Sderaadt if (dumpsize == 0) 857df930be7Sderaadt return; 858df930be7Sderaadt } 859df930be7Sderaadt printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); 860df930be7Sderaadt 861df930be7Sderaadt printf("dump "); 862df930be7Sderaadt switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { 863df930be7Sderaadt 864df930be7Sderaadt case ENXIO: 865df930be7Sderaadt printf("device bad\n"); 866df930be7Sderaadt break; 867df930be7Sderaadt 868df930be7Sderaadt case EFAULT: 869df930be7Sderaadt printf("device not ready\n"); 870df930be7Sderaadt break; 871df930be7Sderaadt 872df930be7Sderaadt case EINVAL: 873df930be7Sderaadt printf("area improper\n"); 874df930be7Sderaadt break; 875df930be7Sderaadt 876df930be7Sderaadt case EIO: 877df930be7Sderaadt printf("i/o error\n"); 878df930be7Sderaadt break; 879df930be7Sderaadt 880df930be7Sderaadt case EINTR: 881df930be7Sderaadt printf("aborted from console\n"); 882df930be7Sderaadt break; 883df930be7Sderaadt 884df930be7Sderaadt default: 885df930be7Sderaadt printf("succeeded\n"); 886df930be7Sderaadt break; 887df930be7Sderaadt } 888df930be7Sderaadt printf("\n\n"); 889df930be7Sderaadt delay(1000); 890df930be7Sderaadt } 891df930be7Sderaadt 892df930be7Sderaadt void 893df930be7Sderaadt frametoreg(framep, regp) 894df930be7Sderaadt struct trapframe *framep; 895df930be7Sderaadt struct reg *regp; 896df930be7Sderaadt { 897df930be7Sderaadt 898df930be7Sderaadt regp->r_regs[R_V0] = framep->tf_regs[FRAME_V0]; 899df930be7Sderaadt regp->r_regs[R_T0] = framep->tf_regs[FRAME_T0]; 900df930be7Sderaadt regp->r_regs[R_T1] = framep->tf_regs[FRAME_T1]; 901df930be7Sderaadt regp->r_regs[R_T2] = framep->tf_regs[FRAME_T2]; 902df930be7Sderaadt regp->r_regs[R_T3] = framep->tf_regs[FRAME_T3]; 903df930be7Sderaadt regp->r_regs[R_T4] = framep->tf_regs[FRAME_T4]; 904df930be7Sderaadt regp->r_regs[R_T5] = framep->tf_regs[FRAME_T5]; 905df930be7Sderaadt regp->r_regs[R_T6] = framep->tf_regs[FRAME_T6]; 906df930be7Sderaadt regp->r_regs[R_T7] = framep->tf_regs[FRAME_T7]; 907df930be7Sderaadt regp->r_regs[R_S0] = framep->tf_regs[FRAME_S0]; 908df930be7Sderaadt regp->r_regs[R_S1] = framep->tf_regs[FRAME_S1]; 909df930be7Sderaadt regp->r_regs[R_S2] = framep->tf_regs[FRAME_S2]; 910df930be7Sderaadt regp->r_regs[R_S3] = framep->tf_regs[FRAME_S3]; 911df930be7Sderaadt regp->r_regs[R_S4] = framep->tf_regs[FRAME_S4]; 912df930be7Sderaadt regp->r_regs[R_S5] = framep->tf_regs[FRAME_S5]; 913df930be7Sderaadt regp->r_regs[R_S6] = framep->tf_regs[FRAME_S6]; 914df930be7Sderaadt regp->r_regs[R_A0] = framep->tf_a0; 915df930be7Sderaadt regp->r_regs[R_A1] = framep->tf_a1; 916df930be7Sderaadt regp->r_regs[R_A2] = framep->tf_a2; 917df930be7Sderaadt regp->r_regs[R_A3] = framep->tf_regs[FRAME_A3]; 918df930be7Sderaadt regp->r_regs[R_A4] = framep->tf_regs[FRAME_A4]; 919df930be7Sderaadt regp->r_regs[R_A5] = framep->tf_regs[FRAME_A5]; 920df930be7Sderaadt regp->r_regs[R_T8] = framep->tf_regs[FRAME_T8]; 921df930be7Sderaadt regp->r_regs[R_T9] = framep->tf_regs[FRAME_T9]; 922df930be7Sderaadt regp->r_regs[R_T10] = framep->tf_regs[FRAME_T10]; 923df930be7Sderaadt regp->r_regs[R_T11] = framep->tf_regs[FRAME_T11]; 924df930be7Sderaadt regp->r_regs[R_RA] = framep->tf_regs[FRAME_RA]; 925df930be7Sderaadt regp->r_regs[R_T12] = framep->tf_regs[FRAME_T12]; 926df930be7Sderaadt regp->r_regs[R_AT] = framep->tf_regs[FRAME_AT]; 927df930be7Sderaadt regp->r_regs[R_GP] = framep->tf_gp; 928df930be7Sderaadt regp->r_regs[R_SP] = framep->tf_regs[FRAME_SP]; 929df930be7Sderaadt regp->r_regs[R_ZERO] = 0; 930df930be7Sderaadt } 931df930be7Sderaadt 932df930be7Sderaadt void 933df930be7Sderaadt regtoframe(regp, framep) 934df930be7Sderaadt struct reg *regp; 935df930be7Sderaadt struct trapframe *framep; 936df930be7Sderaadt { 937df930be7Sderaadt 938df930be7Sderaadt framep->tf_regs[FRAME_V0] = regp->r_regs[R_V0]; 939df930be7Sderaadt framep->tf_regs[FRAME_T0] = regp->r_regs[R_T0]; 940df930be7Sderaadt framep->tf_regs[FRAME_T1] = regp->r_regs[R_T1]; 941df930be7Sderaadt framep->tf_regs[FRAME_T2] = regp->r_regs[R_T2]; 942df930be7Sderaadt framep->tf_regs[FRAME_T3] = regp->r_regs[R_T3]; 943df930be7Sderaadt framep->tf_regs[FRAME_T4] = regp->r_regs[R_T4]; 944df930be7Sderaadt framep->tf_regs[FRAME_T5] = regp->r_regs[R_T5]; 945df930be7Sderaadt framep->tf_regs[FRAME_T6] = regp->r_regs[R_T6]; 946df930be7Sderaadt framep->tf_regs[FRAME_T7] = regp->r_regs[R_T7]; 947df930be7Sderaadt framep->tf_regs[FRAME_S0] = regp->r_regs[R_S0]; 948df930be7Sderaadt framep->tf_regs[FRAME_S1] = regp->r_regs[R_S1]; 949df930be7Sderaadt framep->tf_regs[FRAME_S2] = regp->r_regs[R_S2]; 950df930be7Sderaadt framep->tf_regs[FRAME_S3] = regp->r_regs[R_S3]; 951df930be7Sderaadt framep->tf_regs[FRAME_S4] = regp->r_regs[R_S4]; 952df930be7Sderaadt framep->tf_regs[FRAME_S5] = regp->r_regs[R_S5]; 953df930be7Sderaadt framep->tf_regs[FRAME_S6] = regp->r_regs[R_S6]; 954df930be7Sderaadt framep->tf_a0 = regp->r_regs[R_A0]; 955df930be7Sderaadt framep->tf_a1 = regp->r_regs[R_A1]; 956df930be7Sderaadt framep->tf_a2 = regp->r_regs[R_A2]; 957df930be7Sderaadt framep->tf_regs[FRAME_A3] = regp->r_regs[R_A3]; 958df930be7Sderaadt framep->tf_regs[FRAME_A4] = regp->r_regs[R_A4]; 959df930be7Sderaadt framep->tf_regs[FRAME_A5] = regp->r_regs[R_A5]; 960df930be7Sderaadt framep->tf_regs[FRAME_T8] = regp->r_regs[R_T8]; 961df930be7Sderaadt framep->tf_regs[FRAME_T9] = regp->r_regs[R_T9]; 962df930be7Sderaadt framep->tf_regs[FRAME_T10] = regp->r_regs[R_T10]; 963df930be7Sderaadt framep->tf_regs[FRAME_T11] = regp->r_regs[R_T11]; 964df930be7Sderaadt framep->tf_regs[FRAME_RA] = regp->r_regs[R_RA]; 965df930be7Sderaadt framep->tf_regs[FRAME_T12] = regp->r_regs[R_T12]; 966df930be7Sderaadt framep->tf_regs[FRAME_AT] = regp->r_regs[R_AT]; 967df930be7Sderaadt framep->tf_gp = regp->r_regs[R_GP]; 968df930be7Sderaadt framep->tf_regs[FRAME_SP] = regp->r_regs[R_SP]; 969df930be7Sderaadt /* ??? = regp->r_regs[R_ZERO]; */ 970df930be7Sderaadt } 971df930be7Sderaadt 972df930be7Sderaadt void 973df930be7Sderaadt printregs(regp) 974df930be7Sderaadt struct reg *regp; 975df930be7Sderaadt { 976df930be7Sderaadt int i; 977df930be7Sderaadt 978df930be7Sderaadt for (i = 0; i < 32; i++) 979df930be7Sderaadt printf("R%d:\t0x%016lx%s", i, regp->r_regs[i], 980df930be7Sderaadt i & 1 ? "\n" : "\t"); 981df930be7Sderaadt } 982df930be7Sderaadt 983df930be7Sderaadt void 984df930be7Sderaadt regdump(framep) 985df930be7Sderaadt struct trapframe *framep; 986df930be7Sderaadt { 987df930be7Sderaadt struct reg reg; 988df930be7Sderaadt 989df930be7Sderaadt frametoreg(framep, ®); 990df930be7Sderaadt printf("REGISTERS:\n"); 991df930be7Sderaadt printregs(®); 992df930be7Sderaadt } 993df930be7Sderaadt 994df930be7Sderaadt #ifdef DEBUG 995df930be7Sderaadt int sigdebug = 0; 996df930be7Sderaadt int sigpid = 0; 997df930be7Sderaadt #define SDB_FOLLOW 0x01 998df930be7Sderaadt #define SDB_KSTACK 0x02 999df930be7Sderaadt #endif 1000df930be7Sderaadt 1001df930be7Sderaadt /* 1002df930be7Sderaadt * Send an interrupt to process. 1003df930be7Sderaadt */ 1004df930be7Sderaadt void 1005df930be7Sderaadt sendsig(catcher, sig, mask, code) 1006df930be7Sderaadt sig_t catcher; 1007df930be7Sderaadt int sig, mask; 1008df930be7Sderaadt u_long code; 1009df930be7Sderaadt { 1010df930be7Sderaadt struct proc *p = curproc; 1011df930be7Sderaadt struct sigcontext *scp, ksc; 1012df930be7Sderaadt struct trapframe *frame; 1013df930be7Sderaadt struct sigacts *psp = p->p_sigacts; 1014df930be7Sderaadt int oonstack, fsize, rndfsize; 1015df930be7Sderaadt extern char sigcode[], esigcode[]; 1016df930be7Sderaadt extern struct proc *fpcurproc; 1017df930be7Sderaadt 1018df930be7Sderaadt frame = p->p_md.md_tf; 1019df930be7Sderaadt oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; 1020df930be7Sderaadt fsize = sizeof ksc; 1021df930be7Sderaadt rndfsize = ((fsize + 15) / 16) * 16; 1022df930be7Sderaadt /* 1023df930be7Sderaadt * Allocate and validate space for the signal handler 1024df930be7Sderaadt * context. Note that if the stack is in P0 space, the 1025df930be7Sderaadt * call to grow() is a nop, and the useracc() check 1026df930be7Sderaadt * will fail if the process has not already allocated 1027df930be7Sderaadt * the space with a `brk'. 1028df930be7Sderaadt */ 1029df930be7Sderaadt if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && 1030df930be7Sderaadt (psp->ps_sigonstack & sigmask(sig))) { 10318bc2093aSderaadt scp = (struct sigcontext *)(psp->ps_sigstk.ss_sp + 1032df930be7Sderaadt psp->ps_sigstk.ss_size - rndfsize); 1033df930be7Sderaadt psp->ps_sigstk.ss_flags |= SS_ONSTACK; 1034df930be7Sderaadt } else 1035df930be7Sderaadt scp = (struct sigcontext *)(frame->tf_regs[FRAME_SP] - 1036df930be7Sderaadt rndfsize); 1037df930be7Sderaadt if ((u_long)scp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) 1038df930be7Sderaadt (void)grow(p, (u_long)scp); 1039df930be7Sderaadt #ifdef DEBUG 1040df930be7Sderaadt if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1041df930be7Sderaadt printf("sendsig(%d): sig %d ssp %lx usp %lx\n", p->p_pid, 1042df930be7Sderaadt sig, &oonstack, scp); 1043df930be7Sderaadt #endif 1044df930be7Sderaadt if (useracc((caddr_t)scp, fsize, B_WRITE) == 0) { 1045df930be7Sderaadt #ifdef DEBUG 1046df930be7Sderaadt if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1047df930be7Sderaadt printf("sendsig(%d): useracc failed on sig %d\n", 1048df930be7Sderaadt p->p_pid, sig); 1049df930be7Sderaadt #endif 1050df930be7Sderaadt /* 1051df930be7Sderaadt * Process has trashed its stack; give it an illegal 1052df930be7Sderaadt * instruction to halt it in its tracks. 1053df930be7Sderaadt */ 1054df930be7Sderaadt SIGACTION(p, SIGILL) = SIG_DFL; 1055df930be7Sderaadt sig = sigmask(SIGILL); 1056df930be7Sderaadt p->p_sigignore &= ~sig; 1057df930be7Sderaadt p->p_sigcatch &= ~sig; 1058df930be7Sderaadt p->p_sigmask &= ~sig; 1059df930be7Sderaadt psignal(p, SIGILL); 1060df930be7Sderaadt return; 1061df930be7Sderaadt } 1062df930be7Sderaadt 1063df930be7Sderaadt /* 1064df930be7Sderaadt * Build the signal context to be used by sigreturn. 1065df930be7Sderaadt */ 1066df930be7Sderaadt ksc.sc_onstack = oonstack; 1067df930be7Sderaadt ksc.sc_mask = mask; 1068df930be7Sderaadt ksc.sc_pc = frame->tf_pc; 1069df930be7Sderaadt ksc.sc_ps = frame->tf_ps; 1070df930be7Sderaadt 1071df930be7Sderaadt /* copy the registers. */ 1072df930be7Sderaadt frametoreg(frame, (struct reg *)ksc.sc_regs); 1073df930be7Sderaadt ksc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */ 1074df930be7Sderaadt 1075df930be7Sderaadt /* save the floating-point state, if necessary, then copy it. */ 1076df930be7Sderaadt if (p == fpcurproc) { 1077df930be7Sderaadt pal_wrfen(1); 1078df930be7Sderaadt savefpstate(&p->p_addr->u_pcb.pcb_fp); 1079df930be7Sderaadt pal_wrfen(0); 1080df930be7Sderaadt fpcurproc = NULL; 1081df930be7Sderaadt } 1082df930be7Sderaadt ksc.sc_ownedfp = p->p_md.md_flags & MDP_FPUSED; 1083df930be7Sderaadt bcopy(&p->p_addr->u_pcb.pcb_fp, (struct fpreg *)ksc.sc_fpregs, 1084df930be7Sderaadt sizeof(struct fpreg)); 1085df930be7Sderaadt ksc.sc_fp_control = 0; /* XXX ? */ 1086df930be7Sderaadt bzero(ksc.sc_reserved, sizeof ksc.sc_reserved); /* XXX */ 1087df930be7Sderaadt bzero(ksc.sc_xxx, sizeof ksc.sc_xxx); /* XXX */ 1088df930be7Sderaadt 1089df930be7Sderaadt 1090df930be7Sderaadt #ifdef COMPAT_OSF1 1091df930be7Sderaadt /* 1092df930be7Sderaadt * XXX Create an OSF/1-style sigcontext and associated goo. 1093df930be7Sderaadt */ 1094df930be7Sderaadt #endif 1095df930be7Sderaadt 1096df930be7Sderaadt /* 1097df930be7Sderaadt * copy the frame out to userland. 1098df930be7Sderaadt */ 1099df930be7Sderaadt (void) copyout((caddr_t)&ksc, (caddr_t)scp, fsize); 1100df930be7Sderaadt #ifdef DEBUG 1101df930be7Sderaadt if (sigdebug & SDB_FOLLOW) 1102df930be7Sderaadt printf("sendsig(%d): sig %d scp %lx code %lx\n", p->p_pid, sig, 1103df930be7Sderaadt scp, code); 1104df930be7Sderaadt #endif 1105df930be7Sderaadt 1106df930be7Sderaadt /* 1107df930be7Sderaadt * Set up the registers to return to sigcode. 1108df930be7Sderaadt */ 1109df930be7Sderaadt frame->tf_pc = (u_int64_t)PS_STRINGS - (esigcode - sigcode); 1110df930be7Sderaadt frame->tf_regs[FRAME_SP] = (u_int64_t)scp; 1111df930be7Sderaadt frame->tf_a0 = sig; 1112df930be7Sderaadt frame->tf_a1 = code; 1113df930be7Sderaadt frame->tf_a2 = (u_int64_t)scp; 1114df930be7Sderaadt frame->tf_regs[FRAME_T12] = (u_int64_t)catcher; /* t12 is pv */ 1115df930be7Sderaadt 1116df930be7Sderaadt #ifdef DEBUG 1117df930be7Sderaadt if (sigdebug & SDB_FOLLOW) 1118df930be7Sderaadt printf("sendsig(%d): pc %lx, catcher %lx\n", p->p_pid, 1119df930be7Sderaadt frame->tf_pc, frame->tf_regs[FRAME_A3]); 1120df930be7Sderaadt if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1121df930be7Sderaadt printf("sendsig(%d): sig %d returns\n", 1122df930be7Sderaadt p->p_pid, sig); 1123df930be7Sderaadt #endif 1124df930be7Sderaadt } 1125df930be7Sderaadt 1126df930be7Sderaadt /* 1127df930be7Sderaadt * System call to cleanup state after a signal 1128df930be7Sderaadt * has been taken. Reset signal mask and 1129df930be7Sderaadt * stack state from context left by sendsig (above). 1130df930be7Sderaadt * Return to previous pc and psl as specified by 1131df930be7Sderaadt * context left by sendsig. Check carefully to 1132df930be7Sderaadt * make sure that the user has not modified the 1133df930be7Sderaadt * psl to gain improper priviledges or to cause 1134df930be7Sderaadt * a machine fault. 1135df930be7Sderaadt */ 1136df930be7Sderaadt /* ARGSUSED */ 1137df930be7Sderaadt int 1138df930be7Sderaadt sys_sigreturn(p, v, retval) 1139df930be7Sderaadt struct proc *p; 1140df930be7Sderaadt void *v; 1141df930be7Sderaadt register_t *retval; 1142df930be7Sderaadt { 1143df930be7Sderaadt struct sys_sigreturn_args /* { 1144df930be7Sderaadt syscallarg(struct sigcontext *) sigcntxp; 1145df930be7Sderaadt } */ *uap = v; 1146df930be7Sderaadt struct sigcontext *scp, ksc; 1147df930be7Sderaadt extern struct proc *fpcurproc; 1148df930be7Sderaadt 1149df930be7Sderaadt scp = SCARG(uap, sigcntxp); 1150df930be7Sderaadt #ifdef DEBUG 1151df930be7Sderaadt if (sigdebug & SDB_FOLLOW) 1152df930be7Sderaadt printf("sigreturn: pid %d, scp %lx\n", p->p_pid, scp); 1153df930be7Sderaadt #endif 1154df930be7Sderaadt 1155df930be7Sderaadt if (ALIGN(scp) != (u_int64_t)scp) 1156df930be7Sderaadt return (EINVAL); 1157df930be7Sderaadt 1158df930be7Sderaadt /* 1159df930be7Sderaadt * Test and fetch the context structure. 1160df930be7Sderaadt * We grab it all at once for speed. 1161df930be7Sderaadt */ 1162df930be7Sderaadt if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 || 1163df930be7Sderaadt copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc)) 1164df930be7Sderaadt return (EINVAL); 1165df930be7Sderaadt 1166df930be7Sderaadt if (ksc.sc_regs[R_ZERO] != 0xACEDBADE) /* magic number */ 1167df930be7Sderaadt return (EINVAL); 1168df930be7Sderaadt /* 1169df930be7Sderaadt * Restore the user-supplied information 1170df930be7Sderaadt */ 1171df930be7Sderaadt if (ksc.sc_onstack) 1172df930be7Sderaadt p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; 1173df930be7Sderaadt else 1174df930be7Sderaadt p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; 1175df930be7Sderaadt p->p_sigmask = ksc.sc_mask &~ sigcantmask; 1176df930be7Sderaadt 1177df930be7Sderaadt p->p_md.md_tf->tf_pc = ksc.sc_pc; 1178df930be7Sderaadt p->p_md.md_tf->tf_ps = (ksc.sc_ps | PSL_USERSET) & ~PSL_USERCLR; 1179df930be7Sderaadt 1180df930be7Sderaadt regtoframe((struct reg *)ksc.sc_regs, p->p_md.md_tf); 1181df930be7Sderaadt 1182df930be7Sderaadt /* XXX ksc.sc_ownedfp ? */ 1183df930be7Sderaadt if (p == fpcurproc) 1184df930be7Sderaadt fpcurproc = NULL; 1185df930be7Sderaadt bcopy((struct fpreg *)ksc.sc_fpregs, &p->p_addr->u_pcb.pcb_fp, 1186df930be7Sderaadt sizeof(struct fpreg)); 1187df930be7Sderaadt /* XXX ksc.sc_fp_control ? */ 1188df930be7Sderaadt 1189df930be7Sderaadt #ifdef DEBUG 1190df930be7Sderaadt if (sigdebug & SDB_FOLLOW) 1191df930be7Sderaadt printf("sigreturn(%d): returns\n", p->p_pid); 1192df930be7Sderaadt #endif 1193df930be7Sderaadt return (EJUSTRETURN); 1194df930be7Sderaadt } 1195df930be7Sderaadt 1196df930be7Sderaadt /* 1197df930be7Sderaadt * machine dependent system variables. 1198df930be7Sderaadt */ 1199df930be7Sderaadt cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 1200df930be7Sderaadt int *name; 1201df930be7Sderaadt u_int namelen; 1202df930be7Sderaadt void *oldp; 1203df930be7Sderaadt size_t *oldlenp; 1204df930be7Sderaadt void *newp; 1205df930be7Sderaadt size_t newlen; 1206df930be7Sderaadt struct proc *p; 1207df930be7Sderaadt { 1208df930be7Sderaadt dev_t consdev; 1209df930be7Sderaadt 1210df930be7Sderaadt /* all sysctl names at this level are terminal */ 1211df930be7Sderaadt if (namelen != 1) 1212df930be7Sderaadt return (ENOTDIR); /* overloaded */ 1213df930be7Sderaadt 1214df930be7Sderaadt switch (name[0]) { 1215df930be7Sderaadt case CPU_CONSDEV: 1216df930be7Sderaadt if (cn_tab != NULL) 1217df930be7Sderaadt consdev = cn_tab->cn_dev; 1218df930be7Sderaadt else 1219df930be7Sderaadt consdev = NODEV; 1220df930be7Sderaadt return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 1221df930be7Sderaadt sizeof consdev)); 1222417eba8cSderaadt 1223417eba8cSderaadt case CPU_ROOT_DEVICE: 1224417eba8cSderaadt return (sysctl_rdstring(oldp, oldlenp, newp, root_device)); 1225417eba8cSderaadt 1226df930be7Sderaadt default: 1227df930be7Sderaadt return (EOPNOTSUPP); 1228df930be7Sderaadt } 1229df930be7Sderaadt /* NOTREACHED */ 1230df930be7Sderaadt } 1231df930be7Sderaadt 1232df930be7Sderaadt /* 1233df930be7Sderaadt * Set registers on exec. 1234df930be7Sderaadt */ 1235df930be7Sderaadt void 1236df930be7Sderaadt setregs(p, pack, stack, retval) 1237df930be7Sderaadt register struct proc *p; 1238df930be7Sderaadt struct exec_package *pack; 1239df930be7Sderaadt u_long stack; 1240df930be7Sderaadt register_t *retval; 1241df930be7Sderaadt { 1242df930be7Sderaadt struct trapframe *tfp = p->p_md.md_tf; 1243df930be7Sderaadt int i; 1244df930be7Sderaadt extern struct proc *fpcurproc; 1245df930be7Sderaadt 1246df930be7Sderaadt #ifdef DEBUG 1247df930be7Sderaadt for (i = 0; i < FRAME_NSAVEREGS; i++) 1248df930be7Sderaadt tfp->tf_regs[i] = 0xbabefacedeadbeef; 1249df930be7Sderaadt tfp->tf_gp = 0xbabefacedeadbeef; 1250df930be7Sderaadt tfp->tf_a0 = 0xbabefacedeadbeef; 1251df930be7Sderaadt tfp->tf_a1 = 0xbabefacedeadbeef; 1252df930be7Sderaadt tfp->tf_a2 = 0xbabefacedeadbeef; 1253df930be7Sderaadt #else 1254df930be7Sderaadt bzero(tfp->tf_regs, FRAME_NSAVEREGS * sizeof tfp->tf_regs[0]); 1255df930be7Sderaadt tfp->tf_gp = 0; 1256df930be7Sderaadt tfp->tf_a0 = 0; 1257df930be7Sderaadt tfp->tf_a1 = 0; 1258df930be7Sderaadt tfp->tf_a2 = 0; 1259df930be7Sderaadt #endif 1260df930be7Sderaadt bzero(&p->p_addr->u_pcb.pcb_fp, sizeof p->p_addr->u_pcb.pcb_fp); 1261df930be7Sderaadt #define FP_RN 2 /* XXX */ 1262df930be7Sderaadt p->p_addr->u_pcb.pcb_fp.fpr_cr = (long)FP_RN << 58; 1263df930be7Sderaadt tfp->tf_regs[FRAME_SP] = stack; /* restored to usp in trap return */ 1264df930be7Sderaadt tfp->tf_ps = PSL_USERSET; 1265df930be7Sderaadt tfp->tf_pc = pack->ep_entry & ~3; 1266df930be7Sderaadt 1267df930be7Sderaadt p->p_md.md_flags & ~MDP_FPUSED; 1268df930be7Sderaadt if (fpcurproc == p) 1269df930be7Sderaadt fpcurproc = NULL; 1270df930be7Sderaadt 1271df930be7Sderaadt retval[0] = retval[1] = 0; 1272df930be7Sderaadt } 1273df930be7Sderaadt 1274df930be7Sderaadt void 1275df930be7Sderaadt netintr() 1276df930be7Sderaadt { 1277df930be7Sderaadt #ifdef INET 1278df930be7Sderaadt #if NETHER > 0 1279df930be7Sderaadt if (netisr & (1 << NETISR_ARP)) { 1280df930be7Sderaadt netisr &= ~(1 << NETISR_ARP); 1281df930be7Sderaadt arpintr(); 1282df930be7Sderaadt } 1283df930be7Sderaadt #endif 1284df930be7Sderaadt if (netisr & (1 << NETISR_IP)) { 1285df930be7Sderaadt netisr &= ~(1 << NETISR_IP); 1286df930be7Sderaadt ipintr(); 1287df930be7Sderaadt } 1288df930be7Sderaadt #endif 1289df930be7Sderaadt #ifdef NS 1290df930be7Sderaadt if (netisr & (1 << NETISR_NS)) { 1291df930be7Sderaadt netisr &= ~(1 << NETISR_NS); 1292df930be7Sderaadt nsintr(); 1293df930be7Sderaadt } 1294df930be7Sderaadt #endif 1295df930be7Sderaadt #ifdef ISO 1296df930be7Sderaadt if (netisr & (1 << NETISR_ISO)) { 1297df930be7Sderaadt netisr &= ~(1 << NETISR_ISO); 1298df930be7Sderaadt clnlintr(); 1299df930be7Sderaadt } 1300df930be7Sderaadt #endif 1301df930be7Sderaadt #ifdef CCITT 1302df930be7Sderaadt if (netisr & (1 << NETISR_CCITT)) { 1303df930be7Sderaadt netisr &= ~(1 << NETISR_CCITT); 1304df930be7Sderaadt ccittintr(); 1305df930be7Sderaadt } 1306df930be7Sderaadt #endif 1307df930be7Sderaadt #ifdef PPP 1308df930be7Sderaadt if (netisr & (1 << NETISR_PPP)) { 1309417eba8cSderaadt netisr &= ~(1 << NETISR_PPP); 1310df930be7Sderaadt pppintr(); 1311df930be7Sderaadt } 1312df930be7Sderaadt #endif 1313df930be7Sderaadt } 1314df930be7Sderaadt 1315df930be7Sderaadt void 1316df930be7Sderaadt do_sir() 1317df930be7Sderaadt { 1318df930be7Sderaadt 1319df930be7Sderaadt if (ssir & SIR_NET) { 1320df930be7Sderaadt siroff(SIR_NET); 1321df930be7Sderaadt cnt.v_soft++; 1322df930be7Sderaadt netintr(); 1323df930be7Sderaadt } 1324df930be7Sderaadt if (ssir & SIR_CLOCK) { 1325df930be7Sderaadt siroff(SIR_CLOCK); 1326df930be7Sderaadt cnt.v_soft++; 1327df930be7Sderaadt softclock(); 1328df930be7Sderaadt } 1329df930be7Sderaadt } 1330df930be7Sderaadt 1331df930be7Sderaadt int 1332df930be7Sderaadt spl0() 1333df930be7Sderaadt { 1334df930be7Sderaadt 1335df930be7Sderaadt if (ssir) { 1336df930be7Sderaadt splsoft(); 1337df930be7Sderaadt do_sir(); 1338df930be7Sderaadt } 1339df930be7Sderaadt 1340df930be7Sderaadt return (pal_swpipl(PSL_IPL_0)); 1341df930be7Sderaadt } 1342df930be7Sderaadt 1343df930be7Sderaadt /* 1344df930be7Sderaadt * The following primitives manipulate the run queues. _whichqs tells which 1345df930be7Sderaadt * of the 32 queues _qs have processes in them. Setrunqueue puts processes 1346df930be7Sderaadt * into queues, Remrq removes them from queues. The running process is on 1347df930be7Sderaadt * no queue, other processes are on a queue related to p->p_priority, divided 1348df930be7Sderaadt * by 4 actually to shrink the 0-127 range of priorities into the 32 available 1349df930be7Sderaadt * queues. 1350df930be7Sderaadt */ 1351df930be7Sderaadt /* 1352df930be7Sderaadt * setrunqueue(p) 1353df930be7Sderaadt * proc *p; 1354df930be7Sderaadt * 1355df930be7Sderaadt * Call should be made at splclock(), and p->p_stat should be SRUN. 1356df930be7Sderaadt */ 1357df930be7Sderaadt 1358df930be7Sderaadt void 1359df930be7Sderaadt setrunqueue(p) 1360df930be7Sderaadt struct proc *p; 1361df930be7Sderaadt { 1362df930be7Sderaadt int bit; 1363df930be7Sderaadt 1364df930be7Sderaadt /* firewall: p->p_back must be NULL */ 1365df930be7Sderaadt if (p->p_back != NULL) 1366df930be7Sderaadt panic("setrunqueue"); 1367df930be7Sderaadt 1368df930be7Sderaadt bit = p->p_priority >> 2; 1369df930be7Sderaadt whichqs |= (1 << bit); 1370df930be7Sderaadt p->p_forw = (struct proc *)&qs[bit]; 1371df930be7Sderaadt p->p_back = qs[bit].ph_rlink; 1372df930be7Sderaadt p->p_back->p_forw = p; 1373df930be7Sderaadt qs[bit].ph_rlink = p; 1374df930be7Sderaadt } 1375df930be7Sderaadt 1376df930be7Sderaadt /* 1377df930be7Sderaadt * Remrq(p) 1378df930be7Sderaadt * 1379df930be7Sderaadt * Call should be made at splclock(). 1380df930be7Sderaadt */ 1381df930be7Sderaadt void 1382df930be7Sderaadt remrq(p) 1383df930be7Sderaadt struct proc *p; 1384df930be7Sderaadt { 1385df930be7Sderaadt int bit; 1386df930be7Sderaadt 1387df930be7Sderaadt bit = p->p_priority >> 2; 1388df930be7Sderaadt if ((whichqs & (1 << bit)) == 0) 1389df930be7Sderaadt panic("remrq"); 1390df930be7Sderaadt 1391df930be7Sderaadt p->p_back->p_forw = p->p_forw; 1392df930be7Sderaadt p->p_forw->p_back = p->p_back; 1393df930be7Sderaadt p->p_back = NULL; /* for firewall checking. */ 1394df930be7Sderaadt 1395df930be7Sderaadt if ((struct proc *)&qs[bit] == qs[bit].ph_link) 1396df930be7Sderaadt whichqs &= ~(1 << bit); 1397df930be7Sderaadt } 1398df930be7Sderaadt 1399df930be7Sderaadt /* 1400df930be7Sderaadt * Return the best possible estimate of the time in the timeval 1401df930be7Sderaadt * to which tvp points. Unfortunately, we can't read the hardware registers. 1402df930be7Sderaadt * We guarantee that the time will be greater than the value obtained by a 1403df930be7Sderaadt * previous call. 1404df930be7Sderaadt */ 1405df930be7Sderaadt void 1406df930be7Sderaadt microtime(tvp) 1407df930be7Sderaadt register struct timeval *tvp; 1408df930be7Sderaadt { 1409df930be7Sderaadt int s = splclock(); 1410df930be7Sderaadt static struct timeval lasttime; 1411df930be7Sderaadt 1412df930be7Sderaadt *tvp = time; 1413df930be7Sderaadt #ifdef notdef 1414df930be7Sderaadt tvp->tv_usec += clkread(); 1415df930be7Sderaadt while (tvp->tv_usec > 1000000) { 1416df930be7Sderaadt tvp->tv_sec++; 1417df930be7Sderaadt tvp->tv_usec -= 1000000; 1418df930be7Sderaadt } 1419df930be7Sderaadt #endif 1420df930be7Sderaadt if (tvp->tv_sec == lasttime.tv_sec && 1421df930be7Sderaadt tvp->tv_usec <= lasttime.tv_usec && 1422df930be7Sderaadt (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) { 1423df930be7Sderaadt tvp->tv_sec++; 1424df930be7Sderaadt tvp->tv_usec -= 1000000; 1425df930be7Sderaadt } 1426df930be7Sderaadt lasttime = *tvp; 1427df930be7Sderaadt splx(s); 1428df930be7Sderaadt } 1429df930be7Sderaadt 1430417eba8cSderaadt /* 1431417eba8cSderaadt * Wait "n" microseconds. 1432417eba8cSderaadt */ 1433417eba8cSderaadt int 1434417eba8cSderaadt delay(n) 1435417eba8cSderaadt int n; 1436417eba8cSderaadt { 1437417eba8cSderaadt long N = cycles_per_usec * (n); 1438417eba8cSderaadt 1439417eba8cSderaadt while (N > 0) /* XXX */ 1440417eba8cSderaadt N -= 3; /* XXX */ 1441417eba8cSderaadt } 1442417eba8cSderaadt 1443df930be7Sderaadt #if defined(COMPAT_OSF1) || 1 /* XXX */ 1444df930be7Sderaadt void 1445417eba8cSderaadt cpu_exec_ecoff_setregs(p, epp, stack, retval) 1446df930be7Sderaadt struct proc *p; 1447417eba8cSderaadt struct exec_package *epp; 1448df930be7Sderaadt u_long stack; 1449df930be7Sderaadt register_t *retval; 1450df930be7Sderaadt { 1451417eba8cSderaadt struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr; 1452df930be7Sderaadt 1453417eba8cSderaadt setregs(p, epp, stack, retval); 1454417eba8cSderaadt p->p_md.md_tf->tf_gp = execp->a.gp_value; 1455df930be7Sderaadt } 1456df930be7Sderaadt 1457df930be7Sderaadt /* 1458df930be7Sderaadt * cpu_exec_ecoff_hook(): 1459df930be7Sderaadt * cpu-dependent ECOFF format hook for execve(). 1460df930be7Sderaadt * 1461df930be7Sderaadt * Do any machine-dependent diddling of the exec package when doing ECOFF. 1462df930be7Sderaadt * 1463df930be7Sderaadt */ 1464df930be7Sderaadt int 1465417eba8cSderaadt cpu_exec_ecoff_hook(p, epp) 1466df930be7Sderaadt struct proc *p; 1467df930be7Sderaadt struct exec_package *epp; 1468df930be7Sderaadt { 1469417eba8cSderaadt struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr; 1470a2f8ce8dSderaadt extern struct emul emul_native; 1471df930be7Sderaadt #ifdef COMPAT_OSF1 1472df930be7Sderaadt extern struct emul emul_osf1; 1473df930be7Sderaadt #endif 1474df930be7Sderaadt 1475417eba8cSderaadt switch (execp->f.f_magic) { 1476df930be7Sderaadt #ifdef COMPAT_OSF1 1477df930be7Sderaadt case ECOFF_MAGIC_ALPHA: 1478df930be7Sderaadt epp->ep_emul = &emul_osf1; 1479df930be7Sderaadt break; 1480df930be7Sderaadt #endif 1481df930be7Sderaadt 1482417eba8cSderaadt case ECOFF_MAGIC_NETBSD_ALPHA: 1483a2f8ce8dSderaadt epp->ep_emul = &emul_native; 1484df930be7Sderaadt break; 1485df930be7Sderaadt 1486df930be7Sderaadt default: 148734fbf6deSderaadt return ENOEXEC; 1488df930be7Sderaadt } 1489df930be7Sderaadt return 0; 1490df930be7Sderaadt } 1491df930be7Sderaadt #endif 1492df930be7Sderaadt 1493df930be7Sderaadt vm_offset_t 1494df930be7Sderaadt vtophys(vaddr) 1495df930be7Sderaadt vm_offset_t vaddr; 1496df930be7Sderaadt { 1497df930be7Sderaadt vm_offset_t paddr; 1498df930be7Sderaadt 1499df930be7Sderaadt if (vaddr < K0SEG_BEGIN) { 1500df930be7Sderaadt printf("vtophys: invalid vaddr 0x%lx", vaddr); 1501df930be7Sderaadt paddr = vaddr; 1502df930be7Sderaadt } else if (vaddr < K0SEG_END) 1503df930be7Sderaadt paddr = k0segtophys(vaddr); 1504df930be7Sderaadt else 1505df930be7Sderaadt paddr = vatopa(vaddr); 1506df930be7Sderaadt 1507df930be7Sderaadt #if 0 1508df930be7Sderaadt printf("vtophys(0x%lx) -> %lx\n", vaddr, paddr); 1509df930be7Sderaadt #endif 1510df930be7Sderaadt 1511df930be7Sderaadt return (paddr); 1512df930be7Sderaadt } 1513