/[gxemul]/trunk/src/memory.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/memory.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 23 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: memory.c,v 1.187 2006/01/14 12:51:59 debug Exp $   *  $Id: memory.c,v 1.190 2006/06/16 18:31:25 debug Exp $
29   *   *
30   *  Functions for handling the memory of an emulated machine.   *  Functions for handling the memory of an emulated machine.
31   */   */
# Line 270  char *memory_conv_to_string(struct cpu * Line 270  char *memory_conv_to_string(struct cpu *
270  void memory_device_dyntrans_access(struct cpu *cpu, struct memory *mem,  void memory_device_dyntrans_access(struct cpu *cpu, struct memory *mem,
271          void *extra, uint64_t *low, uint64_t *high)          void *extra, uint64_t *low, uint64_t *high)
272  {  {
         int i, j;  
273          size_t s;          size_t s;
274          int need_inval = 0;          int i, need_inval = 0;
275    
276          /*  TODO: This is O(n), so it might be good to rewrite it some day.          /*  TODO: This is O(n), so it might be good to rewrite it some day.
277              For now, it will be enough, as long as this function is not              For now, it will be enough, as long as this function is not
# Line 307  void memory_device_dyntrans_access(struc Line 306  void memory_device_dyntrans_access(struc
306                                              | INVALIDATE_PADDR);                                              | INVALIDATE_PADDR);
307                          }                          }
308    
                         if (cpu->machine->arch == ARCH_MIPS) {  
                                 /*  
                                  *  ... and invalidate the "fast_vaddr_to_  
                                  *  hostaddr" cache entries that contain  
                                  *  pointers to this device:  (NOTE: Device i,  
                                  *  cache entry j)  
                                  */  
                                 for (j=0; j<N_BINTRANS_VADDR_TO_HOST; j++) {  
                                         if (cpu->cd.  
                                             mips.bintrans_data_hostpage[j] >=  
                                             mem->dev_dyntrans_data[i] &&  
                                             cpu->cd.mips.  
                                             bintrans_data_hostpage[j] <  
                                             mem->dev_dyntrans_data[i] +  
                                             mem->dev_length[i])  
                                                 cpu->cd.mips.  
                                                     bintrans_data_hostpage[j]  
                                                     = NULL;  
                                 }  
                         }  
309                          return;                          return;
310                  }                  }
311          }          }
# Line 387  void memory_device_register(struct memor Line 366  void memory_device_register(struct memor
366    
367          if (verbose >= 2) {          if (verbose >= 2) {
368                  /*  (40 bits of physical address is displayed)  */                  /*  (40 bits of physical address is displayed)  */
369                  debug("device at 0x%010llx: %s", (long long)baseaddr,                  debug("device at 0x%010"PRIx64": %s", (uint64_t) baseaddr,
370                      device_name);                      device_name);
371    
372                  if (flags & (DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK)                  if (flags & (DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK)
373                      && (baseaddr & mem->dev_dyntrans_alignment) != 0) {                      && (baseaddr & mem->dev_dyntrans_alignment) != 0) {
374                          fatal("\nWARNING: Device dyntrans access, but unaligned"                          fatal("\nWARNING: Device dyntrans access, but unaligned"
375                              " baseaddr 0x%llx.\n", (long long)baseaddr);                              " baseaddr 0x%"PRIx64".\n", (uint64_t) baseaddr);
376                  }                  }
377    
378                  if (flags & (DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK)) {                  if (flags & (DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK)) {
# Line 555  unsigned char *memory_paddr_to_hostaddr( Line 534  unsigned char *memory_paddr_to_hostaddr(
534          table = mem->pagetable;          table = mem->pagetable;
535          entry = (paddr >> shrcount) & mask;          entry = (paddr >> shrcount) & mask;
536    
537          /*  printf("memory_paddr_to_hostaddr(): p=%16llx w=%i => entry=0x%x\n",          /*  printf("memory_paddr_to_hostaddr(): p=%16"PRIx64
538              (long long)paddr, writeflag, entry);  */              " w=%i => entry=0x%x\n", (uint64_t) paddr, writeflag, entry);  */
539    
540          if (table[entry] == NULL) {          if (table[entry] == NULL) {
541                  size_t alloclen;                  size_t alloclen;
# Line 593  unsigned char *memory_paddr_to_hostaddr( Line 572  unsigned char *memory_paddr_to_hostaddr(
572          return (unsigned char *) table[entry];          return (unsigned char *) table[entry];
573  }  }
574    
575    
576    #define UPDATE_CHECKSUM(value) {                                        \
577                    internal_state -= 0x118c7771c0c0a77fULL;                \
578                    internal_state = ((internal_state + (value)) << 7) ^    \
579                        (checksum >> 11) ^ ((checksum - (value)) << 3) ^    \
580                        (internal_state - checksum) ^ ((value) - internal_state); \
581                    checksum ^= internal_state;                             \
582            }
583    
584    
585    /*
586     *  memory_checksum():
587     *
588     *  Calculate a 64-bit checksum of everything in a struct memory. This is
589     *  useful for tracking down bugs; an old (presumably working) version of
590     *  the emulator can be compared to a newer (buggy) version.
591     */
592    uint64_t memory_checksum(struct memory *mem)
593    {
594            uint64_t internal_state = 0x80624185376feff2ULL;
595            uint64_t checksum = 0xcb9a87d5c010072cULL;
596            const int n_entries = (1 << BITS_PER_PAGETABLE) - 1;
597            const size_t len = (1 << BITS_PER_MEMBLOCK) / sizeof(uint64_t);
598            size_t entry, i;
599    
600            for (entry=0; entry<=n_entries; entry++) {
601                    uint64_t **table = mem->pagetable;
602                    uint64_t *memblock = table[entry];
603    
604                    if (memblock == NULL) {
605                            UPDATE_CHECKSUM(0x1198ab7c8174a76fULL);
606                            continue;
607                    }
608    
609                    for (i=0; i<len; i++)
610                            UPDATE_CHECKSUM(memblock[i]);
611            }
612    
613            return checksum;
614    }
615    

Legend:
Removed from v.23  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26