--- trunk/src/include/memory.h 2007/10/08 16:18:38 12 +++ trunk/src/include/memory.h 2007/10/08 16:22:32 42 @@ -2,7 +2,7 @@ #define MEMORY_H /* - * Copyright (C) 2004-2005 Anders Gavare. All rights reserved. + * Copyright (C) 2004-2007 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -28,9 +28,9 @@ * SUCH DAMAGE. * * - * $Id: memory.h,v 1.35 2005/07/19 10:48:07 debug Exp $ + * $Id: memory.h,v 1.57 2007/06/14 16:13:30 debug Exp $ * - * Memory controller related functions. + * Memory related functions. */ #include @@ -40,21 +40,46 @@ #define DEFAULT_RAM_IN_MB 32 -#define MAX_DEVICES 24 - -#define DEVICE_STATE_TYPE_INT 1 -#define DEVICE_STATE_TYPE_UINT64_T 2 struct cpu; -struct translation_page_entry; -/* For bintrans: */ -#define MAX_QUICK_JUMPS 8 +/* + * Memory mapped device + */ +struct memory_device { + uint64_t baseaddr; + uint64_t endaddr; /* NOTE: after the last byte! */ + uint64_t length; + int flags; + + const char *name; + + int (*f)(struct cpu *,struct memory *, + uint64_t,unsigned char *,size_t,int,void *); + void *extra; + + unsigned char *dyntrans_data; + + uint64_t dyntrans_write_low; + uint64_t dyntrans_write_high; +}; + + +/* + * Memory + * ------ + * + * This struct defines a memory object. Most machines only use one memory + * object (the main memory), but if necessary, multiple memories can be + * used. + */ struct memory { uint64_t physical_max; void *pagetable; + int dev_dyntrans_alignment; + int n_mmapped_devices; int last_accessed_device; /* The following two might speed up things a little bit. */ @@ -62,73 +87,16 @@ uint64_t mmap_dev_minaddr; uint64_t mmap_dev_maxaddr; - const char *dev_name[MAX_DEVICES]; - uint64_t dev_baseaddr[MAX_DEVICES]; - uint64_t dev_length[MAX_DEVICES]; - int dev_flags[MAX_DEVICES]; - void *dev_extra[MAX_DEVICES]; - int (*dev_f[MAX_DEVICES])(struct cpu *,struct memory *, - uint64_t,unsigned char *,size_t,int,void *); - int (*dev_f_state[MAX_DEVICES])(struct cpu *, - struct memory *, void *extra, int wf, int nr, - int *type, char **namep, void **data, size_t *len); - unsigned char *dev_dyntrans_data[MAX_DEVICES]; - - int dev_dyntrans_alignment; - - uint64_t dev_dyntrans_write_low[MAX_DEVICES]; - uint64_t dev_dyntrans_write_high[MAX_DEVICES]; - - - /* - * NOTE/TODO: This bintrans was for MIPS only. Ugly. :-/ - */ - - /* - * translation_code_chunk_space is a large chunk of (linear) memory - * where translated code chunks and translation_entrys are stored. - * When this is filled, translation is restart from scratch (by - * resetting translation_code_chunk_space_head to 0, and removing all - * translation entries). - * - * (Using a static memory region like this is somewhat inspired by - * the QEMU web pages, - * http://fabrice.bellard.free.fr/qemu/qemu-tech.html#SEC13) - */ - - unsigned char *translation_code_chunk_space; - size_t translation_code_chunk_space_head; - - int bintrans_32bit_only; - - struct translation_page_entry **translation_page_entry_array; - - unsigned char *quick_jump_host_address[MAX_QUICK_JUMPS]; - int quick_jump_page_offset[MAX_QUICK_JUMPS]; - int n_quick_jumps; - int quick_jumps_index; + struct memory_device *devices; }; #define BITS_PER_PAGETABLE 20 #define BITS_PER_MEMBLOCK 20 #define MAX_BITS 40 -#define MEM_READ 0 -#define MEM_WRITE 1 - - -#define CACHE_DATA 0 -#define CACHE_INSTRUCTION 1 -#define CACHE_NONE 2 - -#define CACHE_FLAGS_MASK 0x3 - -#define NO_EXCEPTIONS 16 -#define PHYSICAL 32 -#define NO_SEGMENTATION 64 /* for X86 */ - /* memory.c: */ +#define MEM_PCI_LITTLE_ENDIAN 128 uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len); void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data); @@ -145,26 +113,27 @@ unsigned char *memory_paddr_to_hostaddr(struct memory *mem, uint64_t paddr, int writeflag); -/* memory_fast_v2h.c: */ -unsigned char *fast_vaddr_to_hostaddr(struct cpu *cpu, uint64_t vaddr, - int writeflag); - -/* MIPS stuff: */ -int translate_address_mmu3k(struct cpu *cpu, uint64_t vaddr, - uint64_t *return_addr, int flags); -int translate_address_mmu8k(struct cpu *cpu, uint64_t vaddr, - uint64_t *return_addr, int flags); -int translate_address_mmu10k(struct cpu *cpu, uint64_t vaddr, - uint64_t *return_addr, int flags); -int translate_address_mmu4100(struct cpu *cpu, uint64_t vaddr, - uint64_t *return_addr, int flags); -int translate_address_generic(struct cpu *cpu, uint64_t vaddr, - uint64_t *return_addr, int flags); - -/* X86 stuff: */ -int translate_address_x86(struct cpu *cpu, uint64_t vaddr, - uint64_t *return_addr, int flags); +/* Writeflag: */ +#define MEM_READ 0 +#define MEM_WRITE 1 +#define MEM_DOWNGRADE 128 + +/* Misc. flags: */ +#define CACHE_DATA 0 +#define CACHE_INSTRUCTION 1 +#define CACHE_NONE 2 +#define CACHE_FLAGS_MASK 0x3 +#define NO_EXCEPTIONS 16 +#define PHYSICAL 32 +#define MEMORY_USER_ACCESS 64 /* for ARM and M88K */ + +/* Dyntrans Memory flags: */ +#define DM_DEFAULT 0 +#define DM_DYNTRANS_OK 1 +#define DM_DYNTRANS_WRITE_OK 2 +#define DM_READS_HAVE_NO_SIDE_EFFECTS 4 +#define DM_EMULATED_RAM 8 #define FLAG_WRITEFLAG 1 #define FLAG_NOEXCEPTIONS 2 @@ -172,17 +141,20 @@ int userland_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache); -#define MEMORY_ACCESS_FAILED 0 -#define MEMORY_ACCESS_OK 1 +#define MEMORY_ACCESS_FAILED 0 +#define MEMORY_ACCESS_OK 1 +#define MEMORY_ACCESS_OK_WRITE 2 +#define MEMORY_NOT_FULL_PAGE 256 void memory_device_dyntrans_access(struct cpu *, struct memory *mem, void *extra, uint64_t *low, uint64_t *high); -void memory_device_register_statefunction( - struct memory *mem, void *extra, - int (*dev_f_state)(struct cpu *, - struct memory *, void *extra, int wf, int nr, - int *type, char **namep, void **data, size_t *len)); +#define DEVICE_ACCESS(x) int dev_ ## x ## _access(struct cpu *cpu, \ + struct memory *mem, uint64_t relative_addr, unsigned char *data, \ + size_t len, int writeflag, void *extra) + +void memory_device_update_data(struct memory *mem, void *extra, + unsigned char *data); void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int (*f)(struct cpu *, @@ -190,11 +162,32 @@ void *extra, int flags, unsigned char *dyntrans_data); void memory_device_remove(struct memory *mem, int i); -/* Bit flags: */ -#define MEM_DEFAULT 0 -#define MEM_DYNTRANS_OK 1 -#define MEM_DYNTRANS_WRITE_OK 2 -#define MEM_READING_HAS_NO_SIDE_EFFECTS 4 +uint64_t memory_checksum(struct memory *mem); + +void dump_mem_string(struct cpu *cpu, uint64_t addr); +void store_string(struct cpu *cpu, uint64_t addr, char *s); +int store_64bit_word(struct cpu *cpu, uint64_t addr, uint64_t data64); +int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32); +int store_16bit_word(struct cpu *cpu, uint64_t addr, uint64_t data16); +void store_byte(struct cpu *cpu, uint64_t addr, uint8_t data); +void store_64bit_word_in_host(struct cpu *cpu, unsigned char *data, + uint64_t data32); +void store_32bit_word_in_host(struct cpu *cpu, unsigned char *data, + uint64_t data32); +void store_16bit_word_in_host(struct cpu *cpu, unsigned char *data, + uint16_t data16); +uint64_t load_64bit_word(struct cpu *cpu, uint64_t addr); +uint32_t load_32bit_word(struct cpu *cpu, uint64_t addr); +uint16_t load_16bit_word(struct cpu *cpu, uint64_t addr); +void store_buf(struct cpu *cpu, uint64_t addr, char *s, size_t len); +void add_environment_string(struct cpu *cpu, char *s, uint64_t *addr); +void add_environment_string_dual(struct cpu *cpu, + uint64_t *ptrp, uint64_t *addrp, char *s1, char *s2); +void store_pointer_and_advance(struct cpu *cpu, uint64_t *addrp, + uint64_t data, int flag64); + +void memory_warn_about_unimplemented_addr(struct cpu *cpu, struct memory *mem, + int writeflag, uint64_t paddr, uint8_t *data, size_t len); #endif /* MEMORY_H */