1500 # 1501 #include "../param.h" 1502 #include "../user.h" 1503 #include "../systm.h" 1504 #include "../proc.h" 1505 #include "../text.h" 1506 #include "../inode.h" 1507 #include "../seg.h" 1508 1509 #define CLOCK1 0177546 1510 #define CLOCK2 0172540 1511 /* 1512 * Icode is the octal bootstrap 1513 * program executed in user mode 1514 * to bring up the system. 1515 */ 1516 int icode[] 1517 { 1518 0104413, /* sys exec; init; initp */ 1519 0000014, 1520 0000010, 1521 0000777, /* br . */ 1522 0000014, /* initp: init; 0 */ 1523 0000000, 1524 0062457, /* init: */ 1525 0061564, 1526 0064457, 1527 0064556, 1528 0000164, 1529 }; 1530 /* ------------------------ */ 1531 1532 /* 1533 * Initialization code. 1534 * Called from m40.s or m45.s as 1535 * soon as a stack and segmentation 1536 * have been established. 1537 * Functions: 1538 * clear and free user core 1539 * find which clock is configured 1540 * hand craft 0th process 1541 * call all initialization routines 1542 * fork - process 0 to schedule 1543 * - process 1 execute bootstrap 1544 * 1545 * panic: no clock -- neither clock responds 1546 * loop at loc 6 in user mode -- /etc/init 1547 * cannot be executed. 1548 */ 1549 1550 main() 1551 { 1552 extern schar; 1553 register i, *p; 1554 1555 /* 1556 * zero and free all of core 1557 */ 1558 1559 updlock = 0; 1560 i = *ka6 + USIZE; 1561 UISD->r[0] = 077406; 1562 for(;;) { 1563 UISA->r[0] = i; 1564 if(fuibyte(0) < 0) 1565 break; 1566 clearseg(i); 1567 maxmem++; 1568 mfree(coremap, 1, i); 1569 i++; 1570 } 1571 if(cputype == 70) 1572 for(i=0; i<62; i=+2) { 1573 UBMAP->r[i] = i<<12; 1574 UBMAP->r[i+1] = 0; 1575 } 1576 printf("mem = %l\n", maxmem*5/16); 1577 printf("RESTRICTED RIGHTS\n\n"); 1578 printf("Use, duplication or disclosure is subject to\n"); 1579 printf("restrictions stated in Contract with Western\n"); 1580 printf("Electric Company, Inc.\n"); 1581 1582 maxmem = min(maxmem, MAXMEM); 1583 mfree(swapmap, nswap, swplo); 1584 1585 /* 1586 * set up system process 1587 */ 1588 1589 proc[0].p_addr = *ka6; 1590 proc[0].p_size = USIZE; 1591 proc[0].p_stat = SRUN; 1592 proc[0].p_flag =| SLOAD|SSYS; 1593 u.u_procp = &proc[0]; 1594 1595 /* 1596 * determine clock 1597 */ 1598 1599 UISA->r[7] = ka6[1]; /* io segment */ 1600 UISD->r[7] = 077406; 1601 lks = CLOCK1; 1602 if(fuiword(lks) == -1) { 1603 lks = CLOCK2; 1604 if(fuiword(lks) == -1) 1605 panic("no clock"); 1606 } 1607 *lks = 0115; 1608 1609 /* 1610 * set up 'known' i-nodes 1611 */ 1612 1613 cinit(); 1614 binit(); 1615 iinit(); 1616 rootdir = iget(rootdev, ROOTINO); 1617 rootdir->i_flag =& ~ILOCK; 1618 u.u_cdir = iget(rootdev, ROOTINO); 1619 u.u_cdir->i_flag =& ~ILOCK; 1620 1621 /* 1622 * make init process 1623 * enter scheduling loop 1624 * with system process 1625 */ 1626 1627 if(newproc()) { 1628 expand(USIZE+1); 1629 estabur(0, 1, 0, 0); 1630 copyout(icode, 0, sizeof icode); 1631 /* 1632 * Return goes to loc. 0 of user init 1633 * code just copied out. 1634 */ 1635 return; 1636 } 1637 sched(); 1638 } 1639 /* ------------------------ */ 1640 1641 /* 1642 * Set up software prototype segmentation 1643 * registers to implement the 3 pseudo 1644 * text,data,stack segment sizes passed 1645 * as arguments. 1646 * The argument sep specifies if the 1647 * text and data+stack segments are to 1648 * be separated. 1649 */ 1650 estabur(nt, nd, ns, sep) 1651 { 1652 register a, *ap, *dp; 1653 1654 if(sep) { 1655 if(cputype == 40) 1656 goto err; 1657 if(nseg(nt) > 8 || nseg(nd)+nseg(ns) > 8) 1658 goto err; 1659 } else 1660 if(nseg(nt)+nseg(nd)+nseg(ns) > 8) 1661 goto err; 1662 if(nt+nd+ns+USIZE > maxmem) 1663 goto err; 1664 a = 0; 1665 ap = &u.u_uisa[0]; 1666 dp = &u.u_uisd[0]; 1667 while(nt >= 128) { 1668 *dp++ = (127<<8) | RO; 1669 *ap++ = a; 1670 a =+ 128; 1671 nt =- 128; 1672 } 1673 if(nt) { 1674 *dp++ = ((nt-1)<<8) | RO; 1675 *ap++ = a; 1676 } 1677 if(sep) 1678 while(ap < &u.u_uisa[8]) { 1679 *ap++ = 0; 1680 *dp++ = 0; 1681 } 1682 a = USIZE; 1683 while(nd >= 128) { 1684 *dp++ = (127<<8) | RW; 1685 *ap++ = a; 1686 a =+ 128; 1687 nd =- 128; 1688 } 1689 if(nd) { 1690 *dp++ = ((nd-1)<<8) | RW; 1691 *ap++ = a; 1692 a =+ nd; 1693 } 1694 while(ap < &u.u_uisa[8]) { 1695 *dp++ = 0; 1696 *ap++ = 0; 1697 } 1698 if(sep) 1699 while(ap < &u.u_uisa[16]) { 1700 *dp++ = 0; 1701 *ap++ = 0; 1702 } 1703 a =+ ns; 1704 while(ns >= 128) { 1705 a =- 128; 1706 ns =- 128; 1707 *--dp = (127<<8) | RW; 1708 *--ap = a; 1709 } 1710 if(ns) { 1711 *--dp = ((128-ns)<<8) | RW | ED; 1712 *--ap = a-128; 1713 } 1714 if(!sep) { 1715 ap = &u.u_uisa[0]; 1716 dp = &u.u_uisa[8]; 1717 while(ap < &u.u_uisa[8]) 1718 *dp++ = *ap++; 1719 ap = &u.u_uisd[0]; 1720 dp = &u.u_uisd[8]; 1721 while(ap < &u.u_uisd[8]) 1722 *dp++ = *ap++; 1723 } 1724 sureg(); 1725 return(0); 1726 1727 err: 1728 u.u_error = ENOMEM; 1729 return(-1); 1730 } 1731 /* ------------------------ */ 1732 1733 /* 1734 * Load the user hardware segmentation 1735 * registers from the software prototype. 1736 * The software registers must have 1737 * been setup prior by estabur. 1738 */ 1739 sureg() 1740 { 1741 register *up, *rp, a; 1742 1743 a = u.u_procp->p_addr; 1744 up = &u.u_uisa[16]; 1745 rp = &UISA->r[16]; 1746 if(cputype == 40) { 1747 up =- 8; 1748 rp =- 8; 1749 } 1750 while(rp > &UISA->r[0]) 1751 *--rp = *--up + a; 1752 if((up=u.u_procp->p_textp) != NULL) 1753 a =- up->x_caddr; 1754 up = &u.u_uisd[16]; 1755 rp = &UISD->r[16]; 1756 if(cputype == 40) { 1757 up =- 8; 1758 rp =- 8; 1759 } 1760 while(rp > &UISD->r[0]) { 1761 *--rp = *--up; 1762 if((*rp & WO) == 0) 1763 rp[(UISA-UISD)/2] =- a; 1764 } 1765 } 1766 /* ------------------------ */ 1767 1768 /* 1769 * Return the arg/128 rounded up. 1770 */ 1771 nseg(n) 1772 { 1773 1774 return((n+127)>>7); 1775 } 1776 /* ------------------------ */ 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799