Annotation of tme/host/posix/posix-memory.c, revision 1.1.1.5

1.1.1.4   root        1: /* $Id: posix-memory.c,v 1.7 2009/08/30 21:50:17 fredette Exp $ */
1.1       root        2: 
1.1.1.2   root        3: /* host/posix/posix-memory.c - implementation of memory on a POSIX system: */
1.1       root        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.4   root       37: _TME_RCSID("$Id: posix-memory.c,v 1.7 2009/08/30 21:50:17 fredette Exp $");
1.1       root       38: 
                     39: /* includes: */
                     40: #include <tme/generic/bus-device.h>
1.1.1.4   root       41: #include <tme/hash.h>
1.1       root       42: #include <fcntl.h>
                     43: #include <stdio.h>
                     44: #include <strings.h>
                     45: #include <sys/stat.h>
                     46: #ifdef HAVE_MMAP
                     47: #include <sys/types.h>
                     48: #include <sys/mman.h>
                     49: #endif /* HAVE_MMAP */
                     50: 
                     51: /* macros: */
                     52: #define TME_POSIX_MEMORY_RAM           (0)
                     53: #define TME_POSIX_MEMORY_ROM           (1)
                     54: #define TME_POSIX_MEMORY_PERSISTENT    (2)
                     55: 
1.1.1.4   root       56: /* the minimum size of a cacheable RAM: */
                     57: #define TME_MEMORY_POSIX_CACHEABLE_SIZE_RAM    (1024 * 1024)
                     58: 
                     59: /* the minimum size of a cacheable ROM: */
                     60: #define TME_MEMORY_POSIX_CACHEABLE_SIZE_ROM    (64 * 1024)
                     61: 
                     62: /* the size of the writable TLB entry set: */
                     63: #define TME_MEMORY_POSIX_TLBS_SIZE     (631)
                     64: 
1.1       root       65: /* structures: */
1.1.1.4   root       66: 
                     67: /* a valids bitmask: */
                     68: struct tme_posix_memory_valids {
                     69: 
                     70:   /* valid bitmasks are kept on a linked list: */
                     71:   struct tme_posix_memory_valids *tme_posix_memory_valids_next;
                     72: 
                     73:   /* the log2 of the page size for this valids bitmask: */
                     74:   tme_uint32_t tme_posix_memory_valids_page_size_log2;
                     75: 
                     76:   /* the valids bitmask: */
                     77:   tme_shared tme_uint8_t tme_posix_memory_valids_bitmask[1];
                     78: };
                     79: 
                     80: /* the memory structure: */
1.1       root       81: struct tme_posix_memory {
                     82: 
                     83:   /* our simple bus device header: */
                     84:   struct tme_bus_device tme_posix_memory_device;
                     85: 
1.1.1.4   root       86:   /* the mutex protecting the device: */
                     87:   tme_mutex_t tme_posix_memory_mutex;
                     88: 
1.1       root       89:   /* our memory type: */
                     90:   unsigned int tme_posix_memory_type;
                     91: 
                     92:   /* the file descriptor to any backing file: */
                     93:   int tme_posix_memory_fd;
                     94: 
                     95:   /* this is nonzero if the backing file is mmapped: */
                     96:   int tme_posix_memory_mapped;
                     97: 
                     98:   /* our rwlock: */
1.1.1.4   root       99:   tme_rwlock_t tme_posix_memory_rwlock;
1.1       root      100: 
                    101:   /* our memory contents: */
                    102:   tme_uint8_t *tme_posix_memory_contents;
1.1.1.4   root      103: 
                    104:   /* our writable TLB entry set: */
                    105:   struct tme_token **tme_posix_memory_tlb_tokens;
                    106: 
                    107:   /* any valids bitmasks: */
                    108:   struct tme_posix_memory_valids *tme_posix_memory_valids;
                    109: 
                    110:   /* the current writable TLB size: */
                    111:   tme_uint32_t tme_posix_memory_tlb_size;
                    112: 
                    113:   /* our bus cacheable structure: */
                    114:   struct tme_bus_cacheable tme_posix_memory_cacheable;
1.1       root      115: };
                    116: 
                    117: /* the memory bus cycle handler: */
                    118: static int
                    119: _tme_posix_memory_bus_cycle(void *_memory, struct tme_bus_cycle *cycle)
                    120: {
                    121:   struct tme_posix_memory *memory;
                    122: 
                    123:   /* recover our data structure: */
                    124:   memory = (struct tme_posix_memory *) _memory;
                    125: 
1.1.1.5 ! root      126: #if 0
        !           127:   if (cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
        !           128:          printf("posix write @ %x\n", (unsigned int)cycle->tme_bus_cycle_address);
        !           129:   }
        !           130:   if (cycle->tme_bus_cycle_type == TME_BUS_CYCLE_READ) {
        !           131:          printf("posix read @ %x\n", (unsigned int)cycle->tme_bus_cycle_address);
        !           132:   }
        !           133: #endif
        !           134: 
        !           135: #if 1
        !           136:   if (cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
        !           137:          extern int get_sunbw2_copy(void);
        !           138:          extern int get_sunbw2_copy_addr(void);
        !           139:          int printf(const char *format, ...);
        !           140: 
        !           141:          if (get_sunbw2_copy()) {
        !           142:                  if ((cycle->tme_bus_cycle_address & 0x007e0000) == get_sunbw2_copy_addr()) {
        !           143:                          printf("posix hit! @ %x\n", (unsigned int)cycle->tme_bus_cycle_address);
        !           144:                  }
        !           145:          }
        !           146:   }
        !           147: #endif
        !           148: 
1.1       root      149:   /* run the cycle: */
                    150:   tme_bus_cycle_xfer_memory(cycle, 
                    151:                            ((cycle->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE
                    152:                              && memory->tme_posix_memory_type == TME_POSIX_MEMORY_ROM)
                    153:                             ? NULL
                    154:                             : memory->tme_posix_memory_contents),
                    155:                            memory->tme_posix_memory_device.tme_bus_device_address_last);
                    156: 
                    157:   /* no faults: */
                    158:   return (TME_OK);
                    159: }
                    160: 
1.1.1.4   root      161: /* this invalidates all outstanding TLBs.  it must be called with the
                    162:    mutex held: */
                    163: static void
                    164: _tme_posix_memory_tlbs_invalidate(struct tme_posix_memory *memory)
                    165: {
                    166:   signed long tlb_i;
                    167:   struct tme_token **tlb_tokens;
                    168:   struct tme_token *tlb_token;
                    169: 
                    170:   /* invalidate all writable TLBS: */
                    171:   tlb_i = TME_MEMORY_POSIX_TLBS_SIZE - 1;
                    172:   tlb_tokens = memory->tme_posix_memory_tlb_tokens;
                    173:   do {
                    174:     tlb_token = tlb_tokens[tlb_i];
                    175:     if (tlb_token != NULL) {
                    176:       tlb_tokens[tlb_i] = NULL;
                    177:       tme_token_invalidate(tlb_token);
                    178:     }
                    179:   } while (--tlb_i >= 0);
                    180: }
                    181: 
1.1       root      182: /* the memory TLB filler: */
                    183: static int
                    184: _tme_posix_memory_tlb_fill(void *_memory, struct tme_bus_tlb *tlb, 
1.1.1.4   root      185:                           tme_bus_addr_t address_wider,
                    186:                           unsigned int cycles)
1.1       root      187: {
                    188:   struct tme_posix_memory *memory;
1.1.1.4   root      189:   unsigned long address;
                    190:   unsigned long memory_address_last;
                    191:   struct tme_token *tlb_token;
                    192:   struct tme_token **_tlb_token;
                    193:   struct tme_token *tlb_token_other;
                    194:   struct tme_posix_memory_valids *valids;
                    195:   unsigned long page_index;
                    196:   tme_uint32_t tlb_size;
1.1       root      197: 
                    198:   /* recover our data structure: */
                    199:   memory = (struct tme_posix_memory *) _memory;
                    200: 
1.1.1.4   root      201:   /* get the normal-width address: */
                    202:   address = address_wider;
                    203:   assert(address == address_wider);
                    204: 
1.1       root      205:   /* the address must be within range: */
                    206:   memory_address_last = memory->tme_posix_memory_device.tme_bus_device_address_last;
1.1.1.4   root      207:   assert(memory_address_last == memory->tme_posix_memory_device.tme_bus_device_address_last);
1.1       root      208:   assert(address <= memory_address_last);
                    209: 
                    210:   /* initialize the TLB entry: */
                    211:   tme_bus_tlb_initialize(tlb);
                    212: 
                    213:   /* all memory devices allow fast reading.  all memory devices except
                    214:      ROMs allow fast writing: */
                    215:   tlb->tme_bus_tlb_emulator_off_read = memory->tme_posix_memory_contents;
                    216:   if (memory->tme_posix_memory_type != TME_POSIX_MEMORY_ROM) {
                    217:     tlb->tme_bus_tlb_emulator_off_write = memory->tme_posix_memory_contents;
                    218:   }
                    219:   tlb->tme_bus_tlb_rwlock = &memory->tme_posix_memory_rwlock;
                    220: 
                    221:   /* our bus cycle handler: */
                    222:   tlb->tme_bus_tlb_cycle_private = memory;
                    223:   tlb->tme_bus_tlb_cycle = _tme_posix_memory_bus_cycle;
                    224: 
1.1.1.4   root      225:   /* if this device is cacheable: */
                    226:   if (__tme_predict_true(memory->tme_posix_memory_tlb_tokens != NULL)) {
                    227: 
                    228:     /* this TLB entry is for cacheable memory: */
                    229:     tlb->tme_bus_tlb_cacheable = &memory->tme_posix_memory_cacheable;
                    230: 
                    231:     /* if this TLB entry is for writing: */
                    232:     if (cycles & TME_BUS_CYCLE_WRITE) {
                    233: 
                    234:       /* lock our mutex: */
                    235:       tme_mutex_lock(&memory->tme_posix_memory_mutex);
                    236: 
                    237:       /* get the backing TLB entry: */
                    238:       tlb_token = tlb->tme_bus_tlb_token;
                    239: 
                    240:       /* hash the TLB entry into our writable TLB entry set: */
                    241:       _tlb_token
                    242:        = (((tme_hash_data_to_ulong(tlb_token)
                    243:             / sizeof(struct tme_token))
                    244:            % TME_MEMORY_POSIX_TLBS_SIZE)
                    245:           + memory->tme_posix_memory_tlb_tokens);
                    246: 
                    247:       /* if there is a different TLB entry already at this position in
                    248:         the writable TLB entry set: */
                    249:       tlb_token_other = *_tlb_token;
                    250:       if (__tme_predict_true(tlb_token_other != NULL)) {
                    251:        if (tlb_token_other != tlb_token) {
                    252: 
                    253:          /* invalidate this other TLB entry: */
                    254:          tme_token_invalidate(tlb_token_other);
                    255:        }
                    256:       }
                    257: 
                    258:       /* save the TLB entry into the writable TLB entry set: */
                    259:       *_tlb_token = tlb->tme_bus_tlb_token;
                    260: 
                    261:       /* loop over the valids bitmasks: */
                    262:       for (valids = memory->tme_posix_memory_valids;
                    263:           valids != NULL;
                    264:           valids = valids->tme_posix_memory_valids_next) {
                    265: 
                    266:        /* clear the bit for this address' page in this valids
                    267:           bitmask: */
                    268:        page_index = (address >> valids->tme_posix_memory_valids_page_size_log2);
                    269:        *(valids->tme_posix_memory_valids_bitmask
                    270:          + (page_index / 8))
                    271:          &= ~(1 << (page_index % 8));
                    272:       }
                    273: 
                    274:       /* this TLB entry allows reading and writing: */
                    275:       tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE;
                    276: 
                    277:       /* this TLB entry only covers the current TLB size: */
                    278:       tlb_size = memory->tme_posix_memory_tlb_size;
                    279:       address &= 0 - (unsigned long) tlb_size;
                    280:       tlb->tme_bus_tlb_addr_first = address;
                    281:       tlb->tme_bus_tlb_addr_last = TME_MIN(address | (tlb_size - 1), memory_address_last);
                    282: 
                    283:       /* unlock our mutex: */
                    284:       tme_mutex_unlock(&memory->tme_posix_memory_mutex);
                    285: 
                    286:       return (TME_OK);
                    287:     }
                    288: 
                    289:     /* this TLB entry only allows reading: */
                    290:     tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ;
                    291:     tlb->tme_bus_tlb_emulator_off_write = TME_EMULATOR_OFF_UNDEF;
                    292:   }
                    293: 
                    294:   /* otherwise, this device is not cacheable: */
                    295:   else {
                    296: 
                    297:     /* all memory devices allow reading and writing: */
                    298:     tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE;
                    299:   }
                    300: 
                    301:   /* this TLB entry can cover the whole device: */
                    302:   tlb->tme_bus_tlb_addr_first = 0;
                    303:   tlb->tme_bus_tlb_addr_last = memory_address_last;
                    304: 
1.1       root      305:   return (TME_OK);
                    306: }
                    307: 
1.1.1.4   root      308: /* this function allocates a new valids bitmask: */
                    309: static tme_shared tme_uint8_t *
                    310: _tme_posix_memory_valids_new(void *_memory,
                    311:                             tme_uint32_t page_size_log2)
                    312: {
                    313:   struct tme_posix_memory *memory;
                    314:   tme_uint32_t page_size;
                    315:   unsigned long page_count;
                    316:   struct tme_posix_memory_valids *valids;
                    317: 
                    318:   /* recover our data structure: */
                    319:   memory = (struct tme_posix_memory *) _memory;
                    320: 
                    321:   /* lock our mutex: */
                    322:   tme_mutex_lock(&memory->tme_posix_memory_mutex);
                    323: 
                    324:   /* get the page size for this valids bitmask: */
                    325:   assert (page_size_log2 < (sizeof(page_size) * 8 - 1));
                    326:   page_size = 1;
                    327:   page_size <<= page_size_log2;
                    328: 
                    329:   /* update the current writable TLB size: */
                    330:   memory->tme_posix_memory_tlb_size
                    331:     = TME_MIN(memory->tme_posix_memory_tlb_size, page_size);
                    332: 
                    333:   /* get the page count for this valids bitmask: */
                    334:   page_count
                    335:     = ((memory->tme_posix_memory_cacheable.tme_bus_cacheable_size
                    336:        + (page_size - 1))
                    337:        >> page_size_log2);
                    338: 
                    339:   /* allocate and initialize a new valids bitmask: */
                    340:   valids
                    341:     = ((struct tme_posix_memory_valids *)
                    342:        tme_malloc(sizeof(struct tme_posix_memory_valids)
                    343:                  + ((page_count + 7) / 8)));
                    344:   valids->tme_posix_memory_valids_page_size_log2 = page_size_log2;
                    345:   memset((tme_uint8_t *) valids->tme_posix_memory_valids_bitmask + 0,
                    346:         0xff,
                    347:         ((page_count + 7) / 8));
                    348: 
                    349:   /* add this new valids bitmask to the list: */
                    350:   valids->tme_posix_memory_valids_next = memory->tme_posix_memory_valids;
                    351:   memory->tme_posix_memory_valids = valids;
                    352: 
                    353:   /* invalidate all outstanding TLB entries: */
                    354:   _tme_posix_memory_tlbs_invalidate(memory);
                    355: 
                    356:   /* unlock our mutex: */
                    357:   tme_mutex_unlock(&memory->tme_posix_memory_mutex);
                    358: 
                    359:   /* return the bitmask: */
                    360:   return (valids->tme_posix_memory_valids_bitmask);
                    361: }
                    362: 
                    363: /* this function sets a bit in the valids bitmask: */
                    364: static void
                    365: _tme_posix_memory_valids_set(void *_memory,
                    366:                             tme_shared tme_uint8_t *valids_bitmask,
                    367:                             unsigned long page_index)
                    368: {
                    369:   struct tme_posix_memory *memory;
                    370: 
                    371:   /* recover our data structure: */
                    372:   memory = (struct tme_posix_memory *) _memory;
                    373: 
                    374:   /* lock our mutex: */
                    375:   tme_mutex_lock(&memory->tme_posix_memory_mutex);
                    376: 
                    377:   /* set the bit for this page in the valids bitmask: */
                    378:   *(valids_bitmask
                    379:     + (page_index / 8))
                    380:     |= TME_BIT(page_index % 8);
                    381: 
                    382:   /* invalidate all outstanding TLB entries: */
                    383:   _tme_posix_memory_tlbs_invalidate(memory);
                    384: 
                    385:   /* unlock our mutex: */
                    386:   tme_mutex_unlock(&memory->tme_posix_memory_mutex);
                    387: }
                    388: 
1.1       root      389: /* the new memory function: */
                    390: TME_ELEMENT_SUB_NEW_DECL(tme_host_posix,memory) {
                    391:   unsigned int memory_type;
                    392:   unsigned long memory_size;
                    393:   const char *filename;
                    394:   int fd;
                    395:   struct stat statbuf;
                    396:   struct tme_posix_memory *memory;
1.1.1.4   root      397:   struct tme_bus_cacheable *cacheable;
1.1       root      398:   ssize_t bytes_read;
                    399:   int arg_i;
                    400:   int usage;
                    401: 
                    402:   /* assume we have no backing file: */
                    403:   filename = NULL;
                    404:   memory_type = -1;
                    405:   memory_size = 0;
                    406:   arg_i = 1;
                    407:   usage = FALSE;
                    408: 
                    409:   /* we are regular RAM if our arguments are:
                    410: 
                    411:      ram SIZE
                    412: 
                    413:   */
                    414:   if (TME_ARG_IS(args[arg_i + 0], "ram")
                    415:       && (memory_size = tme_bus_addr_parse(args[arg_i + 1], 0)) > 0) {
                    416:     memory_type = TME_POSIX_MEMORY_RAM;
                    417:     arg_i += 2;
                    418:   }
                    419: 
                    420:   /* we are ROM if our arguments are:
                    421: 
                    422:      rom FILE
                    423:      
                    424:   */
                    425:   else if (TME_ARG_IS(args[arg_i + 0], "rom")
                    426:           && (filename = args[arg_i + 1]) != NULL) {
                    427:     memory_type = TME_POSIX_MEMORY_ROM;
                    428:     arg_i += 2;
                    429:   }
                    430: 
1.1.1.2   root      431:   /* we are persistent storage if our arguments are:
1.1       root      432: 
1.1.1.2   root      433:      persistent FILE
1.1       root      434: 
                    435:   */
                    436:   else if (TME_ARG_IS(args[arg_i + 0], "persistent")
                    437:           && (filename = args[arg_i + 1]) != NULL) {
                    438:     memory_type = TME_POSIX_MEMORY_PERSISTENT;
                    439:     arg_i += 2;
                    440:   }
                    441:           
                    442:   else {
                    443:     usage = TRUE;
                    444:   }
                    445: 
                    446:   if (args[arg_i + 0] != NULL) {
                    447:     tme_output_append_error(_output,
                    448:                            "%s %s", 
                    449:                            args[arg_i],
                    450:                            _("unexpected"));
                    451:     usage = TRUE;
                    452:   }
                    453: 
                    454:   if (usage) {
                    455:     tme_output_append_error(_output,
                    456:                            "%s %s { rom %s | ram %s | persistent %s }",
                    457:                            _("usage:"),
                    458:                            args[0],
                    459:                            _("ROM-FILE"),
                    460:                            _("SIZE"),
                    461:                            _("PERSISTENT-FILE"));
                    462:     return (-1);
                    463:   }
                    464: 
                    465:   /* start the memory structure: */
                    466:   memory = tme_new0(struct tme_posix_memory, 1);
                    467:   memory->tme_posix_memory_type = memory_type;
                    468: 
                    469:   /* if we have a backing file: */
                    470:   fd = -1;
                    471:   if (filename != NULL) {
                    472: 
                    473:     /* open the file for reading: */
                    474:     fd = open(filename, (memory_type == TME_POSIX_MEMORY_ROM
                    475:                         ? O_RDONLY
                    476:                         : O_RDWR));
                    477:     if (fd < 0) {
                    478:       tme_output_append_error(_output,
                    479:                              "%s",
                    480:                              filename);
                    481:       tme_free(memory);
                    482:       return (errno);
                    483:     }
                    484: 
                    485:     /* stat the file: */
                    486:     if (fstat(fd, &statbuf) < 0) {
                    487:       tme_output_append_error(_output,
                    488:                              "%s",
                    489:                              filename);
                    490:       close(fd);
                    491:       tme_free(memory);
                    492:       return (errno);
                    493:     }
                    494:     memory_size = statbuf.st_size;
                    495:     if (memory_size == 0) {
                    496:       tme_output_append_error(_output,
                    497:                              "%s",
                    498:                              filename);
                    499:       close(fd);
                    500:       tme_free(memory);
                    501:       return (EINVAL);
                    502:     }
                    503: 
                    504: #ifdef HAVE_MMAP    
                    505:     /* try to mmap the file: */
                    506:     memory->tme_posix_memory_contents = 
                    507:       mmap(NULL, 
                    508:           statbuf.st_size, 
                    509:           PROT_READ
                    510:           | (memory_type != TME_POSIX_MEMORY_ROM
                    511:              ? PROT_WRITE
                    512:              : 0),
                    513:           MAP_SHARED,
                    514:           fd,
                    515:           0);
                    516:     if (memory->tme_posix_memory_contents != MAP_FAILED) {
                    517:       memory->tme_posix_memory_mapped = TRUE;
                    518:     }
                    519: #endif /* HAVE_MMAP */
                    520:   }
                    521: 
                    522:   /* if we have to, allocate memory space: */
                    523:   if (!memory->tme_posix_memory_mapped) {
                    524:     memory->tme_posix_memory_contents = tme_new0(tme_uint8_t, memory_size);
                    525: 
                    526:     /* if we have to, read in the backing file: */
                    527:     if (fd >= 0) {
                    528:       bytes_read = read(fd, memory->tme_posix_memory_contents, memory_size);
                    529:       if (bytes_read < 0
                    530:          || memory_size != (unsigned long) bytes_read) {
                    531:        /* XXX diagnostic: */
                    532:        close(fd);
                    533:        tme_free(memory->tme_posix_memory_contents);
                    534:        tme_free(memory);
                    535:        return (-1);
                    536:       }
                    537: 
                    538:       /* if this is a ROM, we can close the file now: */
                    539:       if (memory_type == TME_POSIX_MEMORY_ROM) {
                    540:        close(fd);
                    541:        fd = -1;
                    542:       }
                    543:     }
                    544:   }
                    545: 
                    546:   /* remember any backing fd: */
                    547:   memory->tme_posix_memory_fd = fd;
                    548: 
                    549:   /* initialize our rwlock: */
                    550:   tme_rwlock_init(&memory->tme_posix_memory_rwlock);
                    551: 
1.1.1.4   root      552:   /* initialize our mutex: */
                    553:   tme_mutex_init(&memory->tme_posix_memory_mutex);
                    554: 
                    555:   /* assume that this memory won't be cacheable: */
                    556:   memory->tme_posix_memory_tlb_tokens = NULL;
                    557: 
                    558:   /* if we are regular RAM or ROM over a threshold size: */
                    559:   if ((memory_type == TME_POSIX_MEMORY_RAM
                    560:        && memory_size >= TME_MEMORY_POSIX_CACHEABLE_SIZE_RAM)
                    561:       || (memory_type == TME_POSIX_MEMORY_ROM
                    562:          && memory_size >= TME_MEMORY_POSIX_CACHEABLE_SIZE_ROM)) {
                    563: 
                    564:     /* allocate the writable TLB entry set: */
                    565:     memory->tme_posix_memory_tlb_tokens
                    566:       = tme_new0(struct tme_token *,
                    567:                 TME_MEMORY_POSIX_TLBS_SIZE);
                    568: 
                    569:     /* initialize the valids list: */
                    570:     memory->tme_posix_memory_valids = NULL;
                    571: 
                    572:     /* initialize the current writable TLB size: */
                    573:     memory->tme_posix_memory_tlb_size = ((tme_uint32_t) 1) << 31;
                    574: 
                    575:     /* initialize the bus cacheable structure: */
                    576:     cacheable = &memory->tme_posix_memory_cacheable;
                    577:     cacheable->tme_bus_cacheable_contents = memory->tme_posix_memory_contents;
                    578:     cacheable->tme_bus_cacheable_size = memory_size;
                    579:     cacheable->tme_bus_cacheable_private = memory;
                    580:     cacheable->tme_bus_cacheable_valids_new = _tme_posix_memory_valids_new;
                    581:     cacheable->tme_bus_cacheable_valids_set = _tme_posix_memory_valids_set;
                    582:   }
                    583: 
1.1       root      584:   /* initialize our simple bus device descriptor: */
                    585:   memory->tme_posix_memory_device.tme_bus_device_tlb_fill = _tme_posix_memory_tlb_fill;
                    586:   memory->tme_posix_memory_device.tme_bus_device_address_last = (memory_size - 1);
                    587: 
                    588:   /* fill the element: */
                    589:   element->tme_element_private = memory;
                    590:   element->tme_element_connections_new = tme_bus_device_connections_new;
                    591: 
                    592:   return (0);
                    593: }

unix.superglobalmegacorp.com

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