Annotation of tme/machine/sun2/sun2-mmu.c, revision 1.1.1.6

1.1.1.5   root        1: /* $Id: sun2-mmu.c,v 1.14 2009/08/30 14:39:47 fredette Exp $ */
1.1       root        2: 
                      3: /* machine/sun2/sun2-mmu.c - implementation of Sun 2 MMU emulation: */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2003 Matt Fredette
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Matt Fredette.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     33:  * POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35: 
                     36: #include <tme/common.h>
1.1.1.5   root       37: _TME_RCSID("$Id: sun2-mmu.c,v 1.14 2009/08/30 14:39:47 fredette Exp $");
1.1       root       38: 
                     39: /* includes: */
                     40: #include "sun2-impl.h"
                     41: 
                     42: /* macros: */
                     43: 
                     44: /* real PTE entry bits: */
                     45: #define TME_SUN2_PTE_VALID             0x80000000
                     46: #define TME_SUN2_PTE_PROT              0x7C000000
                     47: #define TME_SUN2_PTE_FOD               0x02000000
                     48: #define TME_SUN2_PTE_PGTYPE            0x00C00000
                     49: #define  TME_SUN2_PTE_PGTYPE_MASK       0x00000003
                     50: #define TME_SUN2_PTE_REF               0x00200000
                     51: #define TME_SUN2_PTE_MOD               0x00100000
                     52: #define TME_SUN2_PTE_PGFRAME           0x00000FFF
                     53: 
                     54: /* real PTE page types: */
                     55: #define TME_SUN2_PGTYPE_OBMEM  (0)
                     56: #define TME_SUN2_PGTYPE_OBIO   (1)
                     57: #define TME_SUN2_PGTYPE_MBMEM  (2)
                     58: #define TME_SUN2_PGTYPE_VME0   (2)
                     59: #define TME_SUN2_PGTYPE_MBIO   (3)
                     60: #define TME_SUN2_PGTYPE_VME8   (3)
                     61: 
                     62: /* real bus error register bits: */
                     63: #define TME_SUN2_BUSERR_PARERR_L       TME_BIT(0)      /* parity error, lower byte */
                     64: #define TME_SUN2_BUSERR_PARERR_U       TME_BIT(1)      /* parity error, upper byte */
                     65: #define TME_SUN2_BUSERR_TIMEOUT                TME_BIT(2)      /* bus access timed out */
                     66: #define TME_SUN2_BUSERR_PROTERR                TME_BIT(3)      /* protection error */
                     67: #define TME_SUN2_BUSERR_VMEBUSERR      TME_BIT(6)      /* bus error signaled on VMEbus */
                     68: #define TME_SUN2_BUSERR_VALID          TME_BIT(7)      /* page map was valid */
                     69: 
1.1.1.5   root       70: /* real context count: */
                     71: #define TME_SUN2_CONTEXT_COUNT         (8)
                     72: 
1.1.1.6 ! root       73: int bradshow;
        !            74: int jamdelay;
        !            75: 
1.1       root       76: /* this logs a bus error: */
                     77: #ifndef TME_NO_LOG
                     78: static void
                     79: _tme_sun2_bus_fault_log(struct tme_sun2 *sun2, struct tme_bus_tlb *tlb, struct tme_bus_cycle *cycle)
                     80: {
1.1.1.5   root       81:   tme_bus_addr32_t virtual_address;
1.1       root       82:   struct tme_sun_mmu_pte pte;
                     83:   tme_uint32_t pte_sun2;
                     84:   const char *bus_name;
1.1.1.5   root       85:   tme_bus_addr32_t physical_address;
1.1       root       86:   int rc;
                     87: 
1.1.1.2   root       88:   /* this silences gcc -Wuninitialized: */
                     89:   bus_name = NULL;
                     90: 
1.1       root       91:   /* recover the virtual address used: */
                     92:   virtual_address = cycle->tme_bus_cycle_address - tlb->tme_bus_tlb_addr_offset;
                     93: 
                     94:   /* look up the PTE involved.  since this is a real bus error, and
                     95:      not a protection violation or page not present bus error, we
                     96:      assume the system context: */
                     97:   rc = tme_sun_mmu_pte_get(sun2->tme_sun2_mmu, 
                     98:                           sun2->tme_sun2_context_system,
                     99:                           virtual_address,
                    100:                           &pte);
                    101:   assert(rc == TME_OK);
                    102:   pte_sun2 = pte.tme_sun_mmu_pte_raw;
                    103:     
                    104:   /* form the physical address and get the bus name: */
                    105:   physical_address = (((pte_sun2 & TME_SUN2_PTE_PGFRAME) << TME_SUN2_PAGE_SIZE_LOG2)
                    106:                      | (virtual_address & (TME_SUN2_PAGE_SIZE - 1)));
                    107:   switch ((pte_sun2 & TME_SUN2_PTE_PGTYPE) / (TME_SUN2_PTE_PGTYPE / TME_SUN2_PTE_PGTYPE_MASK)) {
                    108:   case TME_SUN2_PGTYPE_OBMEM: bus_name = "obmem"; break;
                    109:   case TME_SUN2_PGTYPE_OBIO: bus_name = "obio"; break;
                    110:   case TME_SUN2_PGTYPE_MBMEM:
                    111:     if (sun2->tme_sun2_has_vme) {
                    112:       bus_name = "VME";
                    113:     }
                    114:     else {
                    115:       bus_name = "mbmem";
                    116:     }
                    117:     break;
                    118:   case TME_SUN2_PGTYPE_MBIO:
                    119:     if (sun2->tme_sun2_has_vme) {
                    120:       bus_name = "VME";
                    121:       physical_address |= 0x800000;
                    122:     }
                    123:     else {
                    124:       bus_name = "mbio";
                    125:     }
                    126:     break;
                    127:   }
                    128: 
                    129:   /* log this bus error: */
                    130:   tme_log(TME_SUN2_LOG_HANDLE(sun2), 1000, TME_OK,
                    131:          (TME_SUN2_LOG_HANDLE(sun2), 
                    132:           _("%s bus error, physical 0x%08x, virtual 0x%08x, buserr = 0x%02x"),
                    133:           bus_name,
                    134:           physical_address,
                    135:           virtual_address,
                    136:           sun2->tme_sun2_buserr));
                    137: }
                    138: #else  /* TME_NO_LOG */
                    139: #define _tme_sun2_bus_fault_log(a, b, c) do { } while (/* CONSTCOND */ 0)
                    140: #endif /* TME_NO_LOG */
                    141: 
                    142: /* our general bus fault handler: */
                    143: static int
                    144: _tme_sun2_bus_fault_handler(struct tme_sun2 *sun2, 
                    145:                            struct tme_bus_tlb *tlb,
                    146:                            struct tme_bus_cycle *cycle,
                    147:                            int rc)
                    148: {
                    149:   tme_uint16_t buserr;
                    150: 
                    151:   /* dispatch on our fault code: */
                    152:   switch (rc) {
                    153: 
                    154:     /* bus address nonexistent: */
                    155:   case ENOENT:
                    156:     buserr = TME_SUN2_BUSERR_VALID | TME_SUN2_BUSERR_TIMEOUT;
                    157:     break;
                    158: 
                    159:     /* anything else is just a fault: */
                    160:   default:
                    161:     buserr = TME_SUN2_BUSERR_VALID;
                    162:     break;
                    163:   }
                    164: 
                    165:   /* set the bus error register: */
                    166:   sun2->tme_sun2_buserr = buserr;
                    167: 
                    168:   /* log the fault: */
                    169:   _tme_sun2_bus_fault_log(sun2, tlb, cycle);
                    170: 
                    171:   return (rc);
                    172: }
                    173: 
                    174: /* our obio bus fault handler: */
                    175: static int
                    176: _tme_sun2_obio_fault_handler(void *_sun2, struct tme_bus_tlb *tlb, struct tme_bus_cycle *cycle, int rc)
                    177: {
                    178:   tme_uint8_t all_bits_one[sizeof(tme_uint16_t)];
                    179: 
1.1.1.6 ! root      180: #if 0
        !           181:   {
        !           182:          extern int printf(const char *format, ...);
        !           183:          printf("_tme_sun2_obio_fault_handler() %08x\n", (int)cycle->tme_bus_cycle_address);
        !           184:   }
        !           185: #endif
1.1       root      186:   /* the sun2 obio bus doesn't generate bus errors, it just reads
                    187:      all-bits-one: */
                    188:   memset(all_bits_one, 0xff, sizeof(all_bits_one));
                    189:   tme_bus_cycle_xfer_memory(cycle, 
                    190:                            &all_bits_one[0] - cycle->tme_bus_cycle_address,
                    191:                            cycle->tme_bus_cycle_address + sizeof(all_bits_one));
                    192:   return (TME_OK);
                    193: }
                    194: 
                    195: /* our obmem bus fault handler: */
                    196: static int
                    197: _tme_sun2_obmem_fault_handler(void *_sun2, struct tme_bus_tlb *tlb, struct tme_bus_cycle *cycle, int rc)
                    198: {
                    199:   tme_uint8_t all_bits_one[sizeof(tme_uint16_t)];
                    200: 
                    201:   /* the sun2 obmem bus apparently doesn't generate bus errors below
                    202:      0x700000, and instead just reads all-bits-one: */
1.1.1.6 ! root      203: #if 0
        !           204:   {
        !           205:          extern int printf(const char *format, ...);
        !           206:          printf("_tme_sun2_obmem_fault_handler() %08x\n", (int)cycle->tme_bus_cycle_address);
        !           207:   }
        !           208: #endif
1.1       root      209:   if (cycle->tme_bus_cycle_address < 0x700000) {
                    210:     memset(all_bits_one, 0xff, sizeof(all_bits_one));
                    211:     tme_bus_cycle_xfer_memory(cycle, 
                    212:                              &all_bits_one[0] - cycle->tme_bus_cycle_address,
                    213:                              cycle->tme_bus_cycle_address + sizeof(all_bits_one));
                    214:     return (TME_OK);
                    215:   }
                    216: 
                    217:   /* call the common bus fault handler: */
                    218:   return (_tme_sun2_bus_fault_handler((struct tme_sun2 *) _sun2, tlb, cycle, rc));
                    219: }
                    220: 
                    221: /* our Multibus fault handler: */
                    222: static int
                    223: _tme_sun2_multibus_fault_handler(void *_sun2, struct tme_bus_tlb *tlb, struct tme_bus_cycle *cycle, int rc)
                    224: {
                    225: 
1.1.1.6 ! root      226: #if 1
        !           227:   {
        !           228:          extern int printf(const char *format, ...);
        !           229:          printf("_tme_sun2_multibus_fault_handler() %08x, rc %d\n", (int)cycle->tme_bus_cycle_address, rc);
        !           230:   }
        !           231:   if ((int)cycle->tme_bus_cycle_address == 0)
        !           232:          rc = ENOENT;
        !           233: #endif
        !           234: 
1.1       root      235:   /* call the common bus fault handler: */
                    236:   return (_tme_sun2_bus_fault_handler((struct tme_sun2 *) _sun2, tlb, cycle, rc));
                    237: }
                    238: 
                    239: /* our VMEbus fault handler: */
                    240: static int
                    241: _tme_sun2_vmebus_fault_handler(void *_sun2, struct tme_bus_tlb *tlb, struct tme_bus_cycle *cycle, int rc)
                    242: {
                    243:   struct tme_sun2 *sun2;
                    244: 
                    245:   /* recover our sun2: */
                    246:   sun2 = (struct tme_sun2 *) _sun2;
                    247: 
                    248:   /* call the common bus fault handler: */
                    249:   rc = _tme_sun2_bus_fault_handler((struct tme_sun2 *) _sun2, tlb, cycle, rc);
                    250: 
                    251:   /* this bus fault happened on the VMEbus: */
                    252:   sun2->tme_sun2_buserr |= TME_SUN2_BUSERR_VMEBUSERR;
                    253: 
                    254:   /* return the fault: */
                    255:   return (rc);
                    256: }
                    257: 
                    258: /* our page-invalid cycle handler: */
                    259: static int
                    260: _tme_sun2_mmu_invalid(void *_sun2, struct tme_bus_cycle *cycle)
                    261: {
                    262:   struct tme_sun2 *sun2;
                    263: 
                    264:   /* recover our sun2: */
                    265:   sun2 = (struct tme_sun2 *) _sun2;
                    266: 
                    267:   /* log this bus error: */
                    268:   tme_log(TME_SUN2_LOG_HANDLE(sun2), 1000, TME_OK,
                    269:          (TME_SUN2_LOG_HANDLE(sun2), 
                    270:           _("page invalid bus error")));
                    271: 
                    272:   /* set the bus error register: */
                    273:   sun2->tme_sun2_buserr = TME_SUN2_BUSERR_PROTERR;
                    274: 
                    275:   /* return the fault: */
                    276:   return (EFAULT);
                    277: }
                    278: 
                    279: /* our protection error cycle handler: */
                    280: static int
                    281: _tme_sun2_mmu_proterr(void *_sun2, struct tme_bus_cycle *cycle)
                    282: {
                    283:   struct tme_sun2 *sun2;
                    284: 
                    285:   /* recover our sun2: */
                    286:   sun2 = (struct tme_sun2 *) _sun2;
                    287: 
                    288:   /* log this bus error: */
                    289:   tme_log(TME_SUN2_LOG_HANDLE(sun2), 1000, TME_OK,
                    290:          (TME_SUN2_LOG_HANDLE(sun2),
                    291:           _("page protection bus error")));
                    292: 
                    293:   /* set the bus error register: */
                    294:   sun2->tme_sun2_buserr = TME_SUN2_BUSERR_VALID | TME_SUN2_BUSERR_PROTERR;
                    295: 
                    296:   /* return the fault: */
                    297:   return (EFAULT);
                    298: }
                    299: 
                    300: /* our m68k TLB filler: */
                    301: int
                    302: _tme_sun2_m68k_tlb_fill(struct tme_m68k_bus_connection *conn_m68k, struct tme_m68k_tlb *tlb_m68k,
                    303:                        unsigned int function_code, tme_uint32_t address, unsigned int cycles)
                    304: {
                    305:   struct tme_sun2 *sun2;
                    306:   struct tme_bus_tlb *tlb;
1.1.1.5   root      307:   unsigned int function_codes_mask;
                    308:   struct tme_bus_tlb tlb_mapping;
                    309:   tme_uint32_t context;
                    310:   tme_uint32_t access;
1.1       root      311:   unsigned short tlb_flags;
                    312: 
                    313:   /* recover our sun2: */
                    314:   sun2 = (struct tme_sun2 *) conn_m68k->tme_m68k_bus_connection.tme_bus_connection.tme_connection_element->tme_element_private;
                    315: 
                    316:   /* get the generic bus TLB: */
                    317:   tlb = &tlb_m68k->tme_m68k_tlb_bus_tlb;
                    318: 
                    319:   /* if this is function code three, we handle this ourselves: */
                    320:   if (function_code == TME_M68K_FC_3) {
                    321: 
                    322:     /* initialize the TLB entry: */
                    323:     tme_bus_tlb_initialize(tlb);
                    324: 
                    325:     /* we cover the entire address space: */
1.1.1.4   root      326:     tlb->tme_bus_tlb_addr_first = 0;
1.1.1.5   root      327:     tlb->tme_bus_tlb_addr_last = 0 - (tme_bus_addr32_t) 1;
1.1       root      328: 
                    329:     /* we allow reading and writing: */
                    330:     tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE;
                    331: 
                    332:     /* our bus cycle handler: */
                    333:     tlb->tme_bus_tlb_cycle_private = sun2;
                    334:     tlb->tme_bus_tlb_cycle = _tme_sun2_control_cycle_handler;
                    335: 
                    336:     /* this is good for function code three only: */
                    337:     tlb_m68k->tme_m68k_tlb_function_codes_mask = TME_BIT(TME_M68K_FC_3);
1.1.1.5   root      338: 
                    339:     /* done: */
                    340:     return (TME_OK);
1.1       root      341:   }
                    342: 
1.1.1.5   root      343:   /* this must be or a user or supervisor program or data function
                    344:      code: */
                    345:   assert(function_code == TME_M68K_FC_UD
                    346:         || function_code == TME_M68K_FC_UP
                    347:         || function_code == TME_M68K_FC_SD
                    348:         || function_code == TME_M68K_FC_SP);
                    349: 
                    350:   /* assume that if this TLB entry ends up good for the supervisor,
                    351:      it's good for the supervisor program function code: */
                    352:   function_codes_mask = TME_BIT(TME_M68K_FC_SP);
                    353: 
                    354:   /* if we're in the boot state: */
                    355:   if (__tme_predict_false((sun2->tme_sun2_enable & TME_SUN2_ENA_NOTBOOT) == 0)) {
                    356: 
                    357:     /* if this is the supervisor program function code: */
                    358:     if (function_code == TME_M68K_FC_SP) {
                    359: 
                    360:       /* fill this TLB entry directly from the obmem bus: */
                    361:       (*sun2->tme_sun2_obmem->tme_bus_tlb_fill)
                    362:        (sun2->tme_sun2_obmem,
                    363:         tlb,
                    364:         TME_SUN2_PROM_BASE | (address & (TME_SUN2_PROM_SIZE - 1)),
                    365:         cycles);
                    366:        
                    367:       /* create the mapping TLB entry: */
                    368:       tlb_mapping.tme_bus_tlb_addr_first = address & (((tme_bus_addr32_t) 0) - TME_SUN2_PROM_SIZE);
                    369:       tlb_mapping.tme_bus_tlb_addr_last = address | (TME_SUN2_PROM_SIZE - 1);
                    370:       tlb_mapping.tme_bus_tlb_cycles_ok
                    371:        = TME_BUS_CYCLE_READ;
                    372:   
                    373:       /* map the filled TLB entry: */
                    374:       tme_bus_tlb_map(tlb, TME_SUN2_PROM_BASE | (address & (TME_SUN2_PROM_SIZE - 1)), &tlb_mapping, address);
                    375:        
                    376:       /* this is good for the supervisor program function code only: */
                    377:       tlb_m68k->tme_m68k_tlb_function_codes_mask
                    378:        = TME_BIT(TME_M68K_FC_SP);
                    379: 
                    380:       /* done: */
                    381:       return(TME_OK);
                    382:     }
                    383: 
                    384:     /* if this TLB entry ends up good for the supervisor, it's not
                    385:        good for the supervisor program function code: */
                    386:     function_codes_mask = 0;
1.1       root      387:   }
                    388: 
1.1.1.5   root      389:   /* start the access: */
                    390:   access
                    391:     = ((cycles & TME_BUS_CYCLE_WRITE)
                    392:        ? TME_SUN_MMU_PTE_PROT_RW
                    393:        : TME_SUN_MMU_PTE_PROT_RO);
1.1       root      394: 
1.1.1.5   root      395:   /* if this is a user program or data function code: */
                    396:   if (function_code == TME_M68K_FC_UD
                    397:       || function_code == TME_M68K_FC_UP) {
                    398:     context = sun2->tme_sun2_context_user;
                    399:     access = TME_SUN_MMU_PTE_PROT_USER(access);
                    400:     function_codes_mask = (TME_BIT(TME_M68K_FC_UD) + TME_BIT(TME_M68K_FC_UP));
                    401:   }
                    402: 
                    403:   /* otherwise, this is a supervisor program or data function code: */
                    404:   else {
                    405:     context = sun2->tme_sun2_context_system;
                    406:     access = TME_SUN_MMU_PTE_PROT_SYSTEM(access);
                    407:     function_codes_mask += TME_BIT(TME_M68K_FC_SD);
1.1       root      408:   }
                    409: 
1.1.1.5   root      410:   /* fill this TLB entry from the MMU: */
                    411:   tlb_flags
                    412:     = tme_sun_mmu_tlb_fill(sun2->tme_sun2_mmu,
                    413:                           tlb,
                    414:                           context,
                    415:                           address,
                    416:                           access);
                    417: 
                    418:   /* TLB entries are good only for the program and data function
                    419:      codes for the user or supervisor, but never both, because
                    420:      the two types of accesses go through different contexts: */
                    421:   tlb_m68k->tme_m68k_tlb_function_codes_mask = function_codes_mask;
                    422: 
1.1       root      423:   return (TME_OK);
                    424: }
                    425: 
                    426: /* our bus TLB filler: */
                    427: int
                    428: _tme_sun2_bus_tlb_fill(struct tme_bus_connection *conn_bus, struct tme_bus_tlb *tlb,
1.1.1.5   root      429:                       tme_bus_addr_t address_wider, unsigned int cycles)
1.1       root      430: {
                    431:   struct tme_sun2 *sun2;
1.1.1.5   root      432:   tme_bus_addr32_t address;
1.1.1.2   root      433:   struct tme_sun2_bus_connection *conn_sun2;
                    434:   tme_uint32_t base, size;
                    435:   struct tme_bus_tlb tlb_bus;
1.1       root      436: 
                    437:   /* recover our sun2: */
                    438:   sun2 = (struct tme_sun2 *) conn_bus->tme_bus_connection.tme_connection_element->tme_element_private;
                    439: 
1.1.1.5   root      440:   /* get the normal-width address: */
                    441:   address = address_wider;
                    442:   assert (address == address_wider);
                    443: 
1.1.1.2   root      444:   /* recover the sun2 internal mainbus connection: */
                    445:   conn_sun2 = (struct tme_sun2_bus_connection *) conn_bus;
                    446: 
                    447:   /* turn the bus address into a DVMA address: */
                    448:   switch (conn_sun2->tme_sun2_bus_connection_which) {
                    449: 
                    450:     /* obio devices can actually see the whole address space: */
                    451:   case TME_SUN2_BUS_OBIO:
                    452:     base = 0x000000;
                    453:     size = 0x1000000;
                    454:     break;
                    455: 
                    456:   case TME_SUN2_BUS_MBMEM:
                    457:     base = 0xf00000;
                    458:     size = TME_SUN2_DVMA_SIZE_MBMEM;
1.1.1.6 ! root      459: 
        !           460: #if 0
        !           461:   if (1) {
        !           462:          extern int printf(const char *format, ...);
        !           463:          printf("_tme_sun2_bus_tlb_fill; address %x\n", (int)address);
        !           464:   }
        !           465: #endif
        !           466: 
1.1.1.2   root      467:     break;
                    468: 
                    469:   case TME_SUN2_BUS_VME:
                    470:     base = 0xf00000;
                    471:     size = TME_SUN2_DVMA_SIZE_VME;
                    472:     break;
                    473: 
                    474:   default: abort();
                    475:   }
                    476: 
                    477:   assert (!(address & base)
                    478:          && (address < size));
                    479: 
1.1       root      480:   /* fill this TLB entry from the MMU: */
                    481:   tme_sun_mmu_tlb_fill(sun2->tme_sun2_mmu,
                    482:                       tlb,
                    483:                       sun2->tme_sun2_context_system,
1.1.1.2   root      484:                       address | base,
1.1       root      485:                       ((cycles & TME_BUS_CYCLE_WRITE)
                    486:                        ? TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_RW)
                    487:                        : TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_RO)));
1.1.1.2   root      488: 
                    489:   /* create the mapping TLB entry.  we do this even if base == 0,
                    490:      because the TLB entry as currently filled may cover more address
                    491:      space than DVMA space on this machine is supposed to cover: */
1.1.1.4   root      492:   tlb_bus.tme_bus_tlb_addr_first = 0;
                    493:   tlb_bus.tme_bus_tlb_addr_last = size - 1;
1.1.1.2   root      494:   tlb_bus.tme_bus_tlb_cycles_ok
                    495:     = (TME_BUS_CYCLE_READ
                    496:        | TME_BUS_CYCLE_WRITE);
                    497:   
                    498:   /* map the filled TLB entry: */
                    499:   tme_bus_tlb_map(tlb, address | base, &tlb_bus, address);
                    500: 
1.1       root      501:   return (TME_OK);
                    502: }
                    503: 
1.1.1.6 ! root      504: //#include "m68k-impl.h"
        !           505: 
1.1       root      506: /* our post-MMU TLB filler: */
                    507: static int
                    508: _tme_sun2_tlb_fill_mmu(void *_sun2, struct tme_bus_tlb *tlb, 
                    509:                       struct tme_sun_mmu_pte *pte,
                    510:                       tme_uint32_t *_address,
                    511:                       unsigned int cycles)
                    512: {
                    513:   struct tme_sun2 *sun2;
                    514:   tme_uint32_t address;
                    515:   unsigned int bus_type;
                    516:   struct tme_bus_connection *conn_bus;
                    517:   tme_bus_fault_handler bus_fault_handler;
                    518:   int rc;
                    519: 
                    520:   /* recover our sun2: */
                    521:   sun2 = (struct tme_sun2 *) _sun2;
                    522: 
                    523:   /* get the physical page frame and bus type: */
                    524:   address = ((pte->tme_sun_mmu_pte_raw & TME_SUN2_PTE_PGFRAME) << TME_SUN2_PAGE_SIZE_LOG2);
                    525:   bus_type = (pte->tme_sun_mmu_pte_raw & TME_SUN2_PTE_PGTYPE) / (TME_SUN2_PTE_PGTYPE / TME_SUN2_PTE_PGTYPE_MASK);
                    526: 
                    527:   /* any mapping of the *first* page of obio space means the PROM.
                    528:      the virtual page frame is actually used to form the physical
                    529:      address: */
                    530:   if (address == 0
                    531:       && bus_type == TME_SUN2_PGTYPE_OBIO) {
                    532:     address = TME_SUN2_PROM_BASE | (*_address & ((TME_SUN2_PROM_SIZE - 1) & ~(TME_SUN2_PAGE_SIZE - 1)));
                    533:     bus_type = TME_SUN2_PGTYPE_OBMEM;
                    534:   }
                    535: 
                    536:   /* add in the page offset to finish the address: */
                    537:   address |= *_address & (TME_SUN2_PAGE_SIZE - 1);
1.1.1.6 ! root      538: #if 0
        !           539:   if ((int)address > 0xffffff || (int)address < 0xef0000)
        !           540:   {
        !           541:          extern int printf(const char *format, ...);
        !           542:          struct tme_sun2 *s2 = (struct tme_sun2 *)sun2;
        !           543:          struct tme_m68k *m68k;
        !           544:          extern unsigned int _tme_m68010_get_pc(struct tme_m68k *ic);
        !           545: 
        !           546:          m68k = s2->tme_sun2_m68k->tme_m68k_bus_connection.tme_bus_connection.tme_connection_element->tme_element_private;
        !           547: 
        !           548:          if (_tme_m68010_get_pc(m68k) == 0x3c3bc) bradshow = 1; 
        !           549: 
        !           550:          if (_tme_m68010_get_pc(m68k) == 0x3c3bc && address == 0 && jamdelay == 0) {
        !           551:                  jamdelay = 2;
        !           552:          }
        !           553: 
        !           554:          if (bradshow)
        !           555:          printf("_tme_sun2_tlb_fill_mmu; address %08x, vir %08x, bus_type %d, boot %x, pc %08x\n",
        !           556:                 (int)address, (int)_address, (int)bus_type,
        !           557:                 (s2->tme_sun2_enable & TME_SUN2_ENA_NOTBOOT) ? 1 : 0,
        !           558:                 _tme_m68010_get_pc(m68k));
        !           559:   }
        !           560: #endif
1.1       root      561:   *_address = address;
                    562: 
1.1.1.6 ! root      563: 
1.1       root      564:   /* if this is obio: */
                    565:   if (bus_type == TME_SUN2_PGTYPE_OBIO) {
                    566:     conn_bus = sun2->tme_sun2_obio;
                    567:     bus_fault_handler = _tme_sun2_obio_fault_handler;
                    568:   }
                    569:   
                    570:   /* if this is obmem: */
                    571:   else if (bus_type == TME_SUN2_PGTYPE_OBMEM) {
                    572:     conn_bus = sun2->tme_sun2_obmem;
                    573:     bus_fault_handler = _tme_sun2_obmem_fault_handler;
                    574:   }
                    575: 
                    576:   /* if this is the VME bus: */
                    577:   else if (sun2->tme_sun2_has_vme) {
                    578:     
                    579:     if (bus_type == TME_SUN2_PGTYPE_VME8) {
                    580:       address |= 0x800000;
                    581:     }
                    582:     else {
                    583:       assert(bus_type == TME_SUN2_PGTYPE_VME0);
                    584:     }
                    585: 
                    586:     bus_fault_handler = _tme_sun2_vmebus_fault_handler;
                    587: 
                    588:     /* TBD: */
                    589:     abort();
                    590:   }
                    591: 
                    592:   /* if this is mbmem: */
                    593:   else if (bus_type == TME_SUN2_PGTYPE_MBMEM) {
                    594:     conn_bus = sun2->tme_sun2_mbmem;
                    595:     bus_fault_handler = _tme_sun2_multibus_fault_handler;
                    596:   }
                    597: 
                    598:   /* otherwise, this is mbio: */
                    599:   else {
                    600:     assert(bus_type == TME_SUN2_PGTYPE_MBIO);
                    601:     conn_bus = sun2->tme_sun2_mbio;
                    602:     bus_fault_handler = _tme_sun2_multibus_fault_handler;
                    603:   }
                    604: 
                    605:   /* call the bus TLB filler: */
                    606:   rc = ((*conn_bus->tme_bus_tlb_fill)
                    607:        (conn_bus, tlb, address, cycles));
                    608: 
1.1.1.6 ! root      609: #if 0
        !           610:   if (bus_type == TME_SUN2_PGTYPE_MBMEM && bradshow) {
        !           611:          extern int printf(const char *format, ...);
        !           612:          printf("_tme_sun2_tlb_fill_mmu; rc %d\n", rc);
        !           613:   }
        !           614: #endif
        !           615: 
1.1       root      616:   /* if the bus TLB filler succeeded, add our bus fault handler: */
                    617:   if (rc == TME_OK) {
                    618:     TME_BUS_TLB_FAULT_HANDLER(tlb, bus_fault_handler, sun2);
                    619:   }
                    620: 
1.1.1.6 ! root      621: #if 0
        !           622:   if (rc == TME_OK) {
        !           623:          if (jamdelay) {
        !           624:                  jamdelay--;
        !           625:                  if (jamdelay == 0) {
        !           626: //                       tlb->tme_bus_tlb_cycles_ok &= ~(TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE);
        !           627: 
        !           628:                          struct tme_bus_cycle c;
        !           629:                          c.tme_bus_cycle_address = address;
        !           630:                          _tme_sun2_bus_fault_handler(sun2, tlb, &c, ENOENT);
        !           631:                          bradshow = 0;
        !           632: //                       rc = ENOENT;
        !           633: 
        !           634:                          extern int printf(const char *format, ...);
        !           635:                          printf("waah.  jamdelay went off\n");
        !           636:                  }
        !           637:          }
        !           638:   }
        !           639: #endif
        !           640: 
1.1       root      641:   return (rc);
                    642: }
                    643: 
                    644: /* this gets a PTE from the MMU: */
                    645: int
                    646: _tme_sun2_mmu_pte_get(struct tme_sun2 *sun2, tme_uint32_t address, tme_uint32_t *_pte_sun2)
                    647: {
                    648:   struct tme_sun_mmu_pte pte;
                    649:   tme_uint32_t pte_sun2;
                    650:   unsigned int pte_flags;
                    651:   int rc;
                    652: 
                    653:   /* get the PTE from the MMU: */
                    654:   rc = tme_sun_mmu_pte_get(sun2->tme_sun2_mmu, 
                    655:                           sun2->tme_sun2_context_user,
                    656:                           address,
                    657:                           &pte);
                    658:   assert(rc == TME_OK);
                    659:     
                    660:   /* form the Sun-2 PTE: */
                    661:   pte_sun2 = pte.tme_sun_mmu_pte_raw;
                    662:   pte_flags = pte.tme_sun_mmu_pte_flags;
                    663:   if (pte_flags & TME_SUN_MMU_PTE_REF) {
                    664:     pte_sun2 |= TME_SUN2_PTE_REF;
                    665:   }
                    666:   if (pte_flags & TME_SUN_MMU_PTE_MOD) {
                    667:     pte_sun2 |= TME_SUN2_PTE_MOD;
                    668:   }
                    669: 
                    670:   /* done: */
                    671:   *_pte_sun2 = pte_sun2;
                    672:   tme_log(TME_SUN2_LOG_HANDLE(sun2), 1000, TME_OK,
                    673:          (TME_SUN2_LOG_HANDLE(sun2),
                    674:           _("pte_get: PGMAP[%d:0x%08x] -> 0x%08x"), 
                    675:           sun2->tme_sun2_context_user,
                    676:           address,
                    677:           pte_sun2));
                    678:   return (TME_OK);
                    679: }
                    680: 
                    681: /* this sets a PTE into the MMU: */
                    682: int
                    683: _tme_sun2_mmu_pte_set(struct tme_sun2 *sun2, tme_uint32_t address, tme_uint32_t pte_sun2)
                    684: {
                    685:   struct tme_sun_mmu_pte pte;
                    686:   unsigned int pte_flags;
                    687: #ifndef TME_NO_LOG
                    688:   const char *bus_name;
1.1.1.5   root      689:   tme_bus_addr32_t physical_address;
1.1       root      690:       
1.1.1.2   root      691:   /* this silences gcc -Wuninitialized: */
                    692:   bus_name = NULL;
                    693: 
1.1       root      694:   /* log this setting: */
                    695:   physical_address = ((pte_sun2 & TME_SUN2_PTE_PGFRAME) << TME_SUN2_PAGE_SIZE_LOG2);
                    696:   switch ((pte_sun2 & TME_SUN2_PTE_PGTYPE) / (TME_SUN2_PTE_PGTYPE / TME_SUN2_PTE_PGTYPE_MASK)) {
                    697:   case TME_SUN2_PGTYPE_OBMEM: bus_name = "obmem"; break;
                    698:   case TME_SUN2_PGTYPE_OBIO: bus_name = "obio"; break;
                    699:   case TME_SUN2_PGTYPE_MBMEM:
                    700:     if (sun2->tme_sun2_has_vme) {
                    701:       bus_name = "VME";
                    702:     }
                    703:     else {
                    704:       bus_name = "mbmem";
                    705:     }
                    706:     break;
                    707:   case TME_SUN2_PGTYPE_MBIO:
                    708:     if (sun2->tme_sun2_has_vme) {
                    709:       bus_name = "VME";
                    710:       physical_address |= 0x800000;
                    711:     }
                    712:     else {
                    713:       bus_name = "mbio";
                    714:     }
                    715:     break;
                    716:   }
                    717:   tme_log(TME_SUN2_LOG_HANDLE(sun2), 1000, TME_OK,
                    718:          (TME_SUN2_LOG_HANDLE(sun2),
                    719:           _("pte_set: PGMAP[%d:0x%08x] <- 0x%08x (%s 0x%08x)"), 
                    720:           sun2->tme_sun2_context_user,
                    721:           address,
                    722:           pte_sun2,
                    723:           bus_name,
                    724:           physical_address));
                    725: #endif /* !TME_NO_LOG */
                    726: 
                    727:   pte.tme_sun_mmu_pte_raw = pte_sun2;
                    728:       
                    729:   pte_flags = 0;
                    730:   if (pte_sun2 & TME_SUN2_PTE_MOD) {
                    731:     pte_flags |= TME_SUN_MMU_PTE_MOD;
                    732:   }
                    733:   if (pte_sun2 & TME_SUN2_PTE_REF) {
                    734:     pte_flags |= TME_SUN_MMU_PTE_REF;
                    735:   }
                    736:   switch (pte_sun2 & TME_SUN2_PTE_PROT) {
                    737: 
                    738:     /* with this protection, the system can read and write,
                    739:        and the user gets a protection error: */
                    740:   case 0x70000000:
                    741:   case 0x74000000:
                    742:   case 0x60000000:
                    743:     pte_flags |= 
                    744:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_RW)
                    745:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_ERROR));
                    746:     break;
                    747: 
                    748:     /* with this protection, the system gets a protection error,
                    749:        and the user gets a protection error: */
                    750:   case 0x30000000:
                    751:   case 0x20000000:
                    752:   case 0x10000000:
                    753:   case 0x00000000:
                    754:   case 0x04000000:
                    755:     pte_flags |= 
                    756:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_ERROR)
                    757:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_ERROR));
                    758:     break;
                    759: 
                    760:     /* with this protection, the system can read and write,
                    761:        and the user can read and write: */
                    762:   case 0x7C000000:
                    763:   case 0x6C000000:
                    764:     pte_flags |= 
                    765:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_RW)
                    766:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_RW));
                    767:     break;
                    768: 
                    769:     /* with this protection, the system can read and write,
                    770:        and the user can read: */
                    771:   case 0x78000000:
                    772:     pte_flags |= 
                    773:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_RW)
                    774:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_RO));
                    775:     break;
                    776: 
                    777:     /* with this protection, the system can read,
                    778:        and the user can read: */
                    779:   case 0x58000000:
                    780:     pte_flags |= 
                    781:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_RO)
                    782:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_RO));
                    783:     break;
                    784: 
                    785:     /* with this protection, the system can read,
                    786:        and the user can read and write: */
                    787:   case 0x5C000000:
                    788:   case 0x4C000000:
                    789:     pte_flags |= 
                    790:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_RO)
                    791:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_RW));
                    792:     break;
                    793: 
                    794:     /* with this protection, the system can read,
                    795:        and the user gets a protection error: */
                    796:   case 0x50000000:
                    797:   case 0x40000000:
                    798:     pte_flags |= 
                    799:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_RO)
                    800:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_ERROR));
                    801:     break;
                    802: 
                    803:     /* with this protection, the system gets a protection error,
                    804:        and the user can read and write: */
                    805:   case 0x3c000000:
1.1.1.2   root      806:   case 0x0c000000:
1.1       root      807:     pte_flags |= 
                    808:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_ERROR)
                    809:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_RW));
                    810:     break;
                    811: 
                    812:     /* with this protection, the system gets a protection error,
                    813:        and the user can read: */
                    814:   case 0x08000000:
                    815:     pte_flags |= 
                    816:       (TME_SUN_MMU_PTE_PROT_SYSTEM(TME_SUN_MMU_PTE_PROT_ERROR)
                    817:        | TME_SUN_MMU_PTE_PROT_USER(TME_SUN_MMU_PTE_PROT_RO));
                    818:     break;
                    819: 
                    820:   default: abort();
                    821:   }
                    822:   if (pte_sun2 & TME_SUN2_PTE_VALID) {
                    823:     pte_flags |= TME_SUN_MMU_PTE_VALID;
                    824:   }
                    825:   pte.tme_sun_mmu_pte_flags = pte_flags;
                    826:   
                    827:   return (tme_sun_mmu_pte_set(sun2->tme_sun2_mmu, 
                    828:                              sun2->tme_sun2_context_user,
                    829:                              address,
                    830:                              &pte));
                    831: }
                    832: 
                    833: /* this is called when the system context register is set: */
                    834: void
                    835: _tme_sun2_mmu_context_system_set(struct tme_sun2 *sun2)
                    836: {
                    837:   /* system context register changes are assumed to be rare.  if they
                    838:      were frequent, we'd have to allocate 64 TLB sets for each TLB
                    839:      user - one for each possible combination of user context and
                    840:      system context.  instead, when the system context register
                    841:      changes, we simply invalidate all TLB entries everywhere: */
                    842:   tme_log(TME_SUN2_LOG_HANDLE(sun2), 1000, TME_OK,
                    843:          (TME_SUN2_LOG_HANDLE(sun2),
                    844:           _("system context now #%d"),
                    845:           sun2->tme_sun2_context_system));
                    846:   tme_sun_mmu_tlbs_invalidate(sun2->tme_sun2_mmu);
                    847: }
                    848: 
                    849: /* this is called when the user context register is set: */
                    850: void
                    851: _tme_sun2_mmu_context_user_set(struct tme_sun2 *sun2)
                    852: {
1.1.1.5   root      853:   tme_bus_context_t context_base;
1.1       root      854: 
1.1.1.5   root      855:   /* NB that even though user and supervisor references use the two
                    856:      different context registers simultaneously, TLB entries for one
                    857:      are never usable by the other.  because of this, and because we
                    858:      assume that the system context register rarely changes, we choose
                    859:      not to factor the system context into the context seen by the
                    860:      m68k: */
1.1       root      861: 
1.1.1.5   root      862:   /* there are sixteen total contexts.  contexts zero through seven
                    863:      are the not-boot (normal) contexts.  contexts eight through
                    864:      fifteen are the same contexts, but in the boot state.
1.1       root      865: 
1.1.1.5   root      866:      in the boot state, TLB fills for supervisor program references
                    867:      bypass the MMU and are filled to reference the PROM, and data
                    868:      fills are filled as normal using the current context:  */
1.1       root      869: 
1.1.1.5   root      870:   /* in the not-boot (i.e., normal, state): */
                    871:   if (__tme_predict_true(sun2->tme_sun2_enable & TME_SUN2_ENA_NOTBOOT)) {
1.1       root      872: 
1.1.1.5   root      873:     tme_log(TME_SUN2_LOG_HANDLE(sun2), 1000, TME_OK,
                    874:            (TME_SUN2_LOG_HANDLE(sun2),
                    875:             _("user context now #%d"),
                    876:             sun2->tme_sun2_context_user));
1.1       root      877: 
1.1.1.5   root      878:     /* the normal state contexts are numbered from zero: */
                    879:     context_base = 0;
                    880:   }
1.1       root      881: 
1.1.1.5   root      882:   /* in the boot state: */
                    883:   else {
1.1       root      884: 
1.1.1.5   root      885:     tme_log(TME_SUN2_LOG_HANDLE(sun2), 1000, TME_OK,
                    886:            (TME_SUN2_LOG_HANDLE(sun2),
                    887:             _("user context now #%d (boot state)"),
                    888:             sun2->tme_sun2_context_user));
1.1       root      889: 
1.1.1.5   root      890:     /* the boot state contexts are numbered from eight: */
                    891:     context_base = TME_SUN2_CONTEXT_COUNT;
1.1       root      892:   }
                    893: 
1.1.1.5   root      894:   /* update the m68k bus context register: */
                    895:   *sun2->tme_sun2_m68k_bus_context
                    896:     = (context_base
                    897:        + sun2->tme_sun2_context_user);
                    898: 
                    899:   /* NB: unlike the sun3, sun2 DVMA TLBS are always filled using the
                    900:      system context, meaning they don't need to be invalidated when
                    901:      the user context changes, so we don't need to call
                    902:      tme_sun_mmu_context_switched() here: */
1.1       root      903: }
                    904: 
1.1.1.5   root      905: /* this adds a new TLB set: */
1.1       root      906: int
1.1.1.5   root      907: _tme_sun2_mmu_tlb_set_add(struct tme_bus_connection *conn_bus_asker,
                    908:                          struct tme_bus_tlb_set_info *tlb_set_info)
1.1       root      909: {
1.1.1.5   root      910:   struct tme_sun2 *sun2;
                    911:   int rc;
                    912: 
                    913:   /* recover our sun2: */
                    914:   sun2 = (struct tme_sun2 *) conn_bus_asker->tme_bus_connection.tme_connection_element->tme_element_private;
                    915: 
                    916:   /* add the TLB set to the MMU: */
                    917:   rc = tme_sun_mmu_tlb_set_add(sun2->tme_sun2_mmu,
                    918:                               tlb_set_info);
                    919:   assert (rc == TME_OK);
                    920: 
                    921:   /* if this is the TLB set from the m68k: */
                    922:   if (conn_bus_asker->tme_bus_connection.tme_connection_type == TME_CONNECTION_BUS_M68K) {
                    923: 
                    924:     /* the m68k must expose a bus context register: */
                    925:     assert (tlb_set_info->tme_bus_tlb_set_info_bus_context != NULL);
                    926: 
                    927:     /* save the pointer to the m68k bus context register, and
                    928:        initialize it: */
                    929:     sun2->tme_sun2_m68k_bus_context
                    930:       = tlb_set_info->tme_bus_tlb_set_info_bus_context;
                    931:     _tme_sun2_mmu_context_user_set(sun2);
                    932: 
                    933:     /* return the maximum context number.  there are eight
                    934:        contexts in the not-boot (normal) state, and each of
                    935:        them has a boot state counterpart: */
                    936:     tlb_set_info->tme_bus_tlb_set_info_bus_context_max
                    937:       = (TME_SUN2_CONTEXT_COUNT
                    938:         + TME_SUN2_CONTEXT_COUNT
                    939:         - 1);
1.1       root      940:   }
                    941: 
1.1.1.5   root      942:   return (rc);
1.1       root      943: }
                    944: 
                    945: /* this creates a Sun-2 MMU: */
                    946: void
                    947: _tme_sun2_mmu_new(struct tme_sun2 *sun2)
                    948: {
                    949:   struct tme_sun_mmu_info mmu_info;
                    950: 
1.1.1.4   root      951:   memset(&mmu_info, 0, sizeof(mmu_info));
1.1       root      952:   mmu_info.tme_sun_mmu_info_element = sun2->tme_sun2_element;
                    953:   mmu_info.tme_sun_mmu_info_address_bits = 24;
                    954:   mmu_info.tme_sun_mmu_info_pgoffset_bits = TME_SUN2_PAGE_SIZE_LOG2;
                    955:   mmu_info.tme_sun_mmu_info_pteindex_bits = 4;
1.1.1.5   root      956:   mmu_info.tme_sun_mmu_info_contexts = TME_SUN2_CONTEXT_COUNT;
1.1       root      957:   mmu_info.tme_sun_mmu_info_pmegs = 256;
                    958:   mmu_info.tme_sun_mmu_info_tlb_fill_private = sun2;
                    959:   mmu_info.tme_sun_mmu_info_tlb_fill = _tme_sun2_tlb_fill_mmu;
                    960:   mmu_info.tme_sun_mmu_info_proterr_private = sun2;
                    961:   mmu_info.tme_sun_mmu_info_proterr = _tme_sun2_mmu_proterr;
                    962:   mmu_info.tme_sun_mmu_info_invalid_private = sun2;
                    963:   mmu_info.tme_sun_mmu_info_invalid = _tme_sun2_mmu_invalid;
                    964:   sun2->tme_sun2_mmu = tme_sun_mmu_new(&mmu_info);
                    965: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.