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: </etc/init\0> */
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: 
1578: 
1579: 
1580: 
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: 
1608:         /*
1609:          * set up 'known' i-nodes
1610:          */
1611: 
1612:         *lks = 0115;
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: /* ---------------------------       */