home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / os / machsun3.tz / machsun3 / mk.kernel / sun3 / sun_init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  12.5 KB  |  484 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1992 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie Mellon 
  24.  * the rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    sun_init.c,v $
  29.  * Revision 2.4  92/01/03  20:31:41  dbg
  30.  *     Move symbol table and bootstrap image out of BSS.  Clear BSS
  31.  *     afterwards.
  32.  *     [91/08/21            dbg]
  33.  * 
  34.  * Revision 2.3  91/06/19  11:59:30  rvb
  35.  *     cputypes.h->platforms.h
  36.  *     [91/06/12  13:46:53  rvb]
  37.  * 
  38.  * Revision 2.2  91/05/18  14:38:20  rpd
  39.  *     Added avail_remaining, avail_next, hole_start, hole_end.
  40.  *     [91/05/15            rpd]
  41.  * 
  42.  * Revision 2.1  89/08/03  16:53:21  rwd
  43.  * Created.
  44.  * 
  45.  * Revision 2.4  88/08/24  02:10:59  mwyoung
  46.  *     Corrected include file references.
  47.  *     [88/08/22            mwyoung]
  48.  * 
  49.  *
  50.  *  9-Mar-88  Michael Young (mwyoung) at Carnegie-Mellon University
  51.  *    Eliminate use of freemem.  Fix copyright notice, include file format.
  52.  *
  53.  *  4-Feb-88  Robert Baron (rvb) at Carnegie-Mellon University
  54.  *    Revised for new pmap module:
  55.  *        pmap_bootstrap vs {ctx,pmeg}init
  56.  *
  57.  * 04-Oct-87  Jonathan J. Chew (jjc) at Carnegie-Mellon University
  58.  *    Added changes for Sun 3/{60,110}.
  59.  *
  60.  * 25-Jun-87  Jonathan J. Chew (jjc) at Carnegie-Mellon University
  61.  *    Added code for Sun 3/260 to deal with cache and ecc memory.
  62.  *    Don't cache prom monitor.
  63.  *
  64.  * 30-Apr-87  David Golub (dbg) at Carnegie-Mellon University
  65.  *    MACH: don't reserve pmeg for U_AREA.
  66.  *
  67.  * 29-Oct-86  David Golub (dbg) at Carnegie-Mellon University
  68.  *    Made sure that memory allocated for IOPB isn't part of
  69.  *    managed physical memory.
  70.  *
  71.  * 13-Sep-86  Jonathan J. Chew (jjc) at Carnegie-Mellon University
  72.  *    Modified to use "esym" as the end of the kernel instead of
  73.  *    "end" if the kernel debugger is enabled.
  74.  *
  75.  * 14-Aug-86  Jonathan J. Chew (jjc) at Carnegie-Mellon University
  76.  *    Replaced all occurences of "romp" with "sunromp" to avoid
  77.  *    name conflict with IBM PC RT "romp".
  78.  *    Added code to set aside 1 page of virtual memory per cpu
  79.  *    for scratch work.
  80.  *
  81.  * 31-Jul-86  Jonathan J. Chew (jjc) at Carnegie-Mellon University
  82.  *    Added code to set aside 2 pages of virtual memory for use
  83.  *    by the phys routines.
  84.  *
  85.  * 14-Jun-86  Jonathan J. Chew (jjc) at Carnegie-Mellon University
  86.  *    Created from startup routine.
  87.  */
  88. #include <platforms.h>
  89. #include <cpus.h>
  90.  
  91. #include <mach_kdb.h>
  92.  
  93. #include <mach/boolean.h>
  94. #include <mach/vm_param.h>
  95. #include <mach/vm_prot.h>
  96.  
  97. #include <sys/types.h>
  98.  
  99. #include <sundev/mbvar.h>
  100.  
  101. #include <machine/psl.h>
  102. #include <machine/reg.h>
  103. #include <machine/clock.h>
  104. #include <machine/scb.h>
  105. #include <machine/mmu.h>
  106. #include <machine/cpu.h>
  107. #include <machine/eeprom.h>
  108. #include <machine/interreg.h>
  109. #include <machine/memerr.h>
  110. #include <machine/eccreg.h>
  111.  
  112. #include <sun3/pmap.h>
  113.  
  114. #ifdef SUN3_260
  115. #include <sun3/enable.h>
  116.  
  117. extern struct eccreg    *ecc_alive[];
  118. #endif SUN3_260
  119.  
  120. extern long    getpgmap();
  121. extern u_char    getsgmap(), pmegallocres();
  122.  
  123. vm_offset_t        avail_start;    /* PA of first available physical page */
  124. vm_offset_t    avail_end;    /* PA of last available physical page */
  125. vm_size_t    mem_size;    /* memory size in bytes */
  126. vm_offset_t    virtual_avail;  /* VA of 1st available page (after kernel bss)*/
  127. vm_offset_t    virtual_end;    /* VA of last available page (end of kernel
  128.                    address space) */
  129. vm_offset_t    hole_start, hole_end;    /* for pmap_next_page */
  130. vm_offset_t    avail_next;    /* for pmap_next_page */
  131. unsigned int    avail_remaining;/* for pmap_free_pages */
  132.  
  133. vm_offset_t    phys_map_vaddr1, phys_map_vaddr2;
  134.  
  135. int        physmem = 0;    /* patch to restrict physical memory used */
  136.  
  137. boolean_t    kernprot = TRUE;/* write-protect kernel text */
  138.  
  139. /*
  140.  
  141.  */
  142. /*
  143.  * Sun3 initialization code.
  144.  *
  145.  * Running virtual.
  146.  * BSS is still filled with symbol table and bootstrap image.
  147.  */
  148.  
  149. extern char    start[], etext[], edata[], end[];
  150. extern void    v_handler();
  151.  
  152. #define sun_round_segment(x) (((vm_offset_t)(x)+SGOFSET)&~SGOFSET)
  153. void
  154. sun3_init()
  155. {
  156.     register unsigned int    i;
  157.     register vm_offset_t    v;
  158.     vm_offset_t    kernel_end;
  159.     int        mon_mem;
  160.     
  161.  
  162.     initscb();            /* set trap vectors */
  163.     *INTERREG |= IR_ENA_INT;    /* make sure interrupts can occur */
  164.  
  165.     /*
  166.      *    Reset VM page size to be SUN3 page size.
  167.      */
  168.  
  169.     page_size = NBPG;
  170.     vm_set_page_size();
  171.  
  172.     /*
  173.      *    Move symbol table and bootstrap image out of BSS.
  174.      */
  175.  
  176.     kernel_end = move_bootstrap();
  177.  
  178.     /*
  179.      *    Clear bss.
  180.      */
  181.     bzero(edata, end - edata);
  182.  
  183.     /*
  184.      *    Find end of occupied virtual (and physical)
  185.      *    memory.  Virtual memory is assumed to be mapped
  186.      *    1-1 to physical memory starting at
  187.      *    KERNELBASE::0.
  188.      */
  189.  
  190.     kernel_end  = round_page(kernel_end);
  191.     avail_start = kernel_end - KERNELBASE;
  192.  
  193.     /*
  194.      *    Add virtual address space for
  195.      *    physical memory manipulation.
  196.      */
  197.     virtual_avail = kernel_end;
  198.     phys_map_vaddr1 = virtual_avail;
  199.     virtual_avail += PAGE_SIZE;
  200.     phys_map_vaddr2 = virtual_avail;
  201.     virtual_avail += PAGE_SIZE;
  202.  
  203.     /*
  204.      *    Reserve necessary pmegs and set segment mapping.
  205.      */
  206.  
  207.     /*
  208.      *    Invalidate to start of kernel memory.
  209.      */
  210.     for (v = 0; v < (vm_offset_t)KERNELBASE; v += NBSG)
  211.         setsgmap(v, (u_char)SEGINV);
  212.  
  213.     /*
  214.      *    Reserve kernel pmegs.
  215.      */
  216.     for (; v < sun_round_segment(kernel_end); v += NBSG)
  217.         pmeg_reserve(v);
  218.  
  219.     /*
  220.      *    Invalidate to start of monitor.
  221.      */
  222.     for (; v < (vm_offset_t)MONSTART; v += NBSG)
  223.         setsgmap(v, (u_char)SEGINV);
  224.  
  225.     /*
  226.      *    Reserve monitor pmegs.
  227.      */
  228.     for (; v < (vm_offset_t)MONEND; v += NBSG) {
  229.  
  230.         register vm_offset_t    lv;
  231.  
  232.         if (getsgmap(v) != (u_char)SEGINV) {
  233.  
  234.         for (lv = v; lv < v + NBSG; lv += NBPG) {
  235.             long pg = getpgmap(lv);
  236.                 
  237.             if ((pg & PG_V) && (pg & PG_PROT) >= PG_KR)
  238.             break;
  239.         }
  240.         if (lv < v + NBSG) {
  241.             /*
  242.              * The pmeg had a valid page with
  243.              * some access allowed, reserve
  244.              * the pmeg for the monitor.
  245.              */
  246.             pmeg_reserve(v);
  247.         }
  248.         else {
  249.             /*
  250.              * "steal" wasted pmeg back from the monitor
  251.              */
  252.             setsgmap(v, (u_char)SEGINV);
  253.         }
  254.         }
  255.     }
  256.  
  257.     /*
  258.      *    Invalidate until last segment.
  259.      */
  260.     for (; v < (vm_offset_t)((NSEGMAP - 1)*NBSG); v += NBSG)
  261.         setsgmap(v, (u_char)SEGINV);
  262.  
  263.     /*
  264.      *    Last segment is used for devices and dvma map.
  265.      */
  266.     pmeg_reserve(v);
  267.  
  268.     /*
  269.      *    Now go through all the other contexts and set up the
  270.      *    segment maps so that all segments are mapped the same.
  271.      *    We have to use a PROM routine to do this since we can`t
  272.      *    switch to a new (unmapped) context to call setsegmap()!
  273.      */
  274.     for (i = 0; i < NCONTEXT; i++) {
  275.         if (i == KCONTEXT)
  276.         continue;
  277.  
  278.         for (v = 0; v < (vm_offset_t)(NBSG * NSEGMAP); v += NBSG)
  279.         (*sunromp->v_setcxsegmap)(i, v, getsgmap(v));
  280.     }
  281.  
  282.     /*
  283.      *    Now all the monitor set up pmegs have been reserved.
  284.      *    Normal allocation can proceed.
  285.      *    pmap_reserve is now illegal.
  286.      */
  287.     pmap_bootstrap();
  288.  
  289.  
  290.     /*
  291.      *    Initialize kernel page table entries.
  292.      *    We don`t know the physical addresses,
  293.      *    but they are set up, so we just fix
  294.      *    the protection.
  295.      */
  296.  
  297.     /* invalid until start except scb page which is kernel writable */
  298.  
  299.     for (v = (vm_offset_t)KERNELBASE; v < (vm_offset_t)start; v += NBPG) {
  300.         long    pme;
  301.  
  302.         if (v == (vm_offset_t)&scb)
  303.         pme = PG_V | PG_KW | getpgmap(v) & PG_PFNUM;
  304.         else
  305.         pme = 0;
  306.         setpgmap(v, pme);
  307.     }
  308.  
  309.     /* set up kernel text pages */
  310.     pmap_protect(kernel_pmap,
  311.              start,
  312.              trunc_page(etext),
  313.              kernprot ? VM_PROT_READ : VM_PROT_WRITE|VM_PROT_READ);
  314.  
  315.     /* set up kernel data/bss pages to be writeable */
  316.     pmap_protect(kernel_pmap,
  317.              trunc_page(etext),
  318.              round_page(kernel_end),
  319.              VM_PROT_READ|VM_PROT_WRITE);
  320.  
  321.     pme_zero(round_page(kernel_end),
  322.          sun_round_segment(virtual_avail),
  323.          TRUE);
  324.  
  325.     /*
  326.      *    Remove user access to monitor-set-up maps.
  327.      */
  328.     pme_protect(MONSTART, MONEND, PG_KW|PG_NC);
  329.  
  330.     /*
  331.      *    Invalidate any other pages in last segment besides
  332.      *    EEPROM_ADDR, CLKADDR, MEMREG, INTERREG and MONSHORTPAGE.
  333.      *    Since MONSHORTPAGE is defined as a 32 bit virtual address
  334.      *    (to get short references to work), we must mask to get
  335.      *    only the 28 bits we really want to look at.
  336.      */
  337.  
  338.     for (v = (vm_offset_t)(NBSG * (NSEGMAP - 1));
  339.          v < (vm_offset_t)(NBSG * NSEGMAP);
  340.          v += NBPG)
  341.     {
  342.         if (v == ((vm_offset_t)MONSHORTPAGE & 0x0FFFFFFF))
  343.         setpgmap(v, (long)((getpgmap(v) & ~PG_PROT) | PG_KW | PG_NC) );
  344.         /* remove any user access */
  345.         else if (
  346.             v != ((vm_offset_t)MONSHORTPAGE & 0x0FFFFFFF) &&
  347.             v != (vm_offset_t)EEPROM_ADDR &&
  348.             v != (vm_offset_t)CLKADDR &&
  349.             v != (vm_offset_t)MEMREG &&
  350.             v != (vm_offset_t)INTERREG)
  351.         setpgmap(v, (long)0);
  352.     }
  353.  
  354.  
  355.     setcputype();            /* sets cpu and dvmasize variables */
  356. #ifdef SUN3_260
  357.     if (cpu == CPU_SUN3_260)    /* initialize virtual address cache */
  358.         vac_init();
  359. #endif
  360.  
  361.     /*
  362.      * Make sure the memory error register is
  363.      * set up to generate interrupts on error.
  364.      */
  365. #if defined(SUN3_160) || defined(SUN3_50) || defined(SUN3_110) || defined(SUN3_60)
  366.     if (cpu == CPU_SUN3_160 || cpu == CPU_SUN3_50)
  367.         MEMREG->mr_per = PER_INTENA | PER_CHECK;
  368. #endif defined(SUN3_160) || defined(SUN3_50) || defined(SUN3_110) || defined(SUN3_60)
  369.  
  370. #ifdef SUN3_260
  371.     if (cpu == CPU_SUN3_260) {
  372.         register struct eccreg **ecc_nxt = ecc_alive;
  373.         register struct eccreg *ecc;
  374.  
  375.         /*
  376.          * Go probe for all memory cards and perform initialization.
  377.          * The address of the cards found is stashed in ecc_alive[].
  378.          * We assume that the cards are already enabled and the
  379.          * base addresses have been set correctly by the monitor.
  380.          */
  381.         for (ecc = ECCREG; ecc < &ECCREG[MAX_ECC]; ecc++) {
  382.             if (peekc((char *)ecc) == -1)
  383.                 continue;
  384.             MEMREG->mr_dvma = 1; /* clear intr from mem register */
  385.             ecc->syndrome |= SY_CE_MASK; /* clear syndrom fields */
  386.             ecc->eccena |= ENA_SCRUB_MASK;
  387.             ecc->eccena |= ENA_BUSENA_MASK;
  388.             *ecc_nxt++ = ecc;
  389.         }
  390.         *ecc_nxt = (struct eccreg *)0;        /* terminate list */
  391.     }
  392. #endif SUN3_260
  393.  
  394.     /*
  395.      * v_memorysize is the amount of physical memory while
  396.      * v_memoryavail is the amount of usable memory in versions
  397.      * equal or greater to 1.  Mon_mem is the difference which
  398.      * is the number of pages hidden by the monitor.
  399.      */
  400.  
  401.     if (sunromp->v_romvec_version >= 1)
  402.         mon_mem = btop(*sunromp->v_memorysize - *sunromp->v_memoryavail);
  403.     else
  404.         mon_mem = 0;
  405.  
  406.     /*
  407.      * If physmem is patched to be non-zero, use it instead of
  408.      * the monitor value unless physmem is larger than the total
  409.      * amount of memory on hand.
  410.      */
  411.     if (physmem == 0 || physmem > btop(*sunromp->v_memorysize))
  412.         physmem = btop(*sunromp->v_memorysize);
  413.     /*
  414.      * Adjust physmem down for the pages stolen by the monitor.
  415.      */
  416.     physmem -= mon_mem;
  417.  
  418.     /*
  419.      * v_vector_cmd is the handler for new monitor vector
  420.      * command in versions equal or greater to 2.
  421.      * We install v_handler() there for Unix.
  422.      */
  423.     if (sunromp->v_romvec_version >= 2)
  424.         *sunromp->v_vector_cmd = v_handler;
  425.  
  426. #include <bwtwo.h>
  427. #if NBWTWO > 0
  428.     if (physmem > btop(OBFBADDR + FBSIZE))
  429.             fbobmemavail = 1;
  430.     else
  431.             fbobmemavail = 0;
  432. #else
  433.     fbobmemavail = 0;
  434. #endif
  435.  
  436.  
  437.     /* XXX - need to handle message buffer */
  438.  
  439.  
  440.     /*
  441.      * Allocate pmegs for DVMA space with zero pme's
  442.      */
  443.     pme_zero(DVMA, DVMA + NBPG*dvmasize, TRUE);
  444.  
  445.     /*
  446.      * Allocate IOPB memory space just below the message
  447.      * buffer and map it to the first pages of DVMA space.
  448.      */
  449.     physmem -= IOPBMEM;
  450.     pmap_map_page(DVMA, physmem, IOPBMEM*NBPG);
  451.  
  452.     /*
  453.      *    Tell the VM system what virtual and physical memory
  454.      *    it can use.
  455.      */
  456.     mem_size = (vm_size_t)ptob(physmem);    /* Mach version of physmem */
  457.  
  458.     avail_start = (vm_offset_t)round_page(avail_start);
  459.     avail_end   = (vm_offset_t)trunc_page(mem_size);
  460.  
  461.     virtual_avail = (vm_offset_t)round_page(virtual_avail);
  462.     virtual_end = (vm_offset_t)round_page(VM_MAX_KERNEL_ADDRESS);
  463.  
  464.     avail_remaining = atop((avail_end - avail_start) -
  465.                    (hole_end - hole_start));
  466.     avail_next = avail_start;
  467.  
  468.     if (fbobmemavail) {
  469.         /* leave room for the frame buffer */
  470.  
  471.         hole_start = trunc_page(OBFBADDR);
  472.         hole_end = round_page(OBFBADDR + FBSIZE);
  473.     } else {
  474.         hole_start = 0;
  475.         hole_end = 0;
  476.     }
  477.  
  478.     /*
  479.      * Run the system.
  480.      */
  481.     setup_main();
  482.     /*NOTREACHED*/
  483. }
  484.