/* boot.c 6.2 84/09/18 */ #include "../h/param.h" #include "../h/inode.h" #include "../h/fs.h" #include "../h/vm.h" #include #include "saio.h" #include "../h/reboot.h" /* * Boot program... arguments passed in r10 and r11 determine * whether boot stops to ask for system name and which device * boot comes from. */ /* Types in r10 specifying major device */ char devname[][2] = { 'h','p', /* 0 = hp */ 0,0, /* 1 = ht */ 'u','p', /* 2 = up */ 'h','k', /* 3 = hk */ 0,0, /* 4 = sw */ 0,0, /* 5 = tm */ 0,0, /* 6 = ts */ 0,0, /* 7 = mt */ 0,0, /* 8 = tu */ 'r','a', /* 9 = ra */ 'u','t', /* 10 = ut */ 'r','b', /* 11 = rb */ 0,0, /* 12 = uu */ 0,0, /* 13 = rx */ 'r','l', /* 14 = rl */ }; char line[100] = "xx(0,0)vmunix"; int retry = 0; main() { register howto, devtype; /* howto=r11, devtype=r10 */ int io; #ifdef lint howto = 0; devtype = 0; #endif printf("\nBoot\n"); #ifdef JUSTASK howto = RB_ASKNAME|RB_SINGLE; #else if ((howto&RB_ASKNAME)==0) { if (devtype>=0 && devtype= 0) { loadpcs(); copyunix(howto, io); } if (++retry > 2) howto = RB_SINGLE|RB_ASKNAME; } } /*ARGSUSED*/ copyunix(howto, io) register howto, io; { struct exec x; register int i; char *addr; i = read(io, (char *)&x, sizeof x); if (i != sizeof x || (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) _stop("Bad format\n"); printf("%d", x.a_text); if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) goto shread; if (read(io, (char *)0, x.a_text) != x.a_text) goto shread; addr = (char *)x.a_text; if (x.a_magic == 0413 || x.a_magic == 0410) while ((int)addr & CLOFSET) *addr++ = 0; printf("+%d", x.a_data); if (read(io, addr, x.a_data) != x.a_data) goto shread; addr += x.a_data; printf("+%d", x.a_bss); x.a_bss += 128*512; /* slop */ for (i = 0; i < x.a_bss; i++) *addr++ = 0; x.a_entry &= 0x7fffffff; printf(" start 0x%x\n", x.a_entry); (*((int (*)()) x.a_entry))(); _exit(); shread: _stop("Short read\n"); } /* 750 Patchable Control Store magic */ #include "../vax/mtpr.h" #include "../vax/cpu.h" #define PCS_BITCNT 0x2000 /* number of patchbits */ #define PCS_MICRONUM 0x400 /* number of ucode locs */ #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ loadpcs() { register int *ip; /* known to be r11 below */ register int i; /* known to be r10 below */ register int *jp; /* known to be r9 below */ register int j; static int pcsdone = 0; union cpusid sid; char pcs[100]; sid.cpusid = mfpr(SID); if (sid.cpuany.cp_type!=VAX_750 || sid.cpu750.cp_urev<95 || pcsdone) return; printf("Updating 11/750 microcode: "); strncpy(pcs, line, strlen("xx(0,0)")); strcat(pcs, "pcs750.bin"); i = open(pcs, 0); if (i < 0) return; /* * We ask for more than we need to be sure we get only what we expect. * After read: * locs 0 - 1023 packed patchbits * 1024 - 11264 packed microcode */ if (read(i, (char *)0, 23*512) != 22*512) { printf("Error reading %s\n", pcs); close(i); return; } close(i); /* * Enable patchbit loading and load the bits one at a time. */ *((int *)PCS_PATCHBIT) = 1; ip = (int *)PCS_PATCHADDR; jp = (int *)0; for (i=0; i < PCS_BITCNT; i++) { asm(" extzv r10,$1,(r9),(r11)+"); } *((int *)PCS_PATCHBIT) = 0; /* * Load PCS microcode 20 bits at a time. */ ip = (int *)PCS_PCSADDR; jp = (int *)1024; for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) { asm(" extzv r10,$20,(r9),(r11)+"); } /* * Enable PCS. */ i = *jp; /* get 1st 20 bits of microcode again */ i &= 0xfffff; i |= PCS_ENABLE; /* reload these bits with PCS enable set */ *((int *)PCS_PCSADDR) = i; sid.cpusid = mfpr(SID); printf("new rev level=%d\n", sid.cpu750.cp_urev); pcsdone = 1; }