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

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

unix.superglobalmegacorp.com

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