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: /* --------------------------- */