diff options
Diffstat (limited to 'jslinux-2019-12-21/tinyemu-2019-12-21/iomem.h')
| -rw-r--r-- | jslinux-2019-12-21/tinyemu-2019-12-21/iomem.h | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/jslinux-2019-12-21/tinyemu-2019-12-21/iomem.h b/jslinux-2019-12-21/tinyemu-2019-12-21/iomem.h new file mode 100644 index 0000000..cc561b4 --- /dev/null +++ b/jslinux-2019-12-21/tinyemu-2019-12-21/iomem.h @@ -0,0 +1,148 @@ +/* + * IO memory handling + * + * Copyright (c) 2016-2017 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef IOMEM_H +#define IOMEM_H + +typedef void DeviceWriteFunc(void *opaque, uint32_t offset, + uint32_t val, int size_log2); +typedef uint32_t DeviceReadFunc(void *opaque, uint32_t offset, int size_log2); + +#define DEVIO_SIZE8 (1 << 0) +#define DEVIO_SIZE16 (1 << 1) +#define DEVIO_SIZE32 (1 << 2) +/* not supported, could add specific 64 bit callbacks when needed */ +//#define DEVIO_SIZE64 (1 << 3) +#define DEVIO_DISABLED (1 << 4) + +#define DEVRAM_FLAG_ROM (1 << 0) /* not writable */ +#define DEVRAM_FLAG_DIRTY_BITS (1 << 1) /* maintain dirty bits */ +#define DEVRAM_FLAG_DISABLED (1 << 2) /* allocated but not mapped */ +#define DEVRAM_PAGE_SIZE_LOG2 12 +#define DEVRAM_PAGE_SIZE (1 << DEVRAM_PAGE_SIZE_LOG2) + +typedef struct PhysMemoryMap PhysMemoryMap; + +typedef struct { + PhysMemoryMap *map; + uint64_t addr; + uint64_t org_size; /* original size */ + uint64_t size; /* =org_size or 0 if the mapping is disabled */ + BOOL is_ram; + /* the following is used for RAM access */ + int devram_flags; + uint8_t *phys_mem; + int dirty_bits_size; /* in bytes */ + uint32_t *dirty_bits; /* NULL if not used */ + uint32_t *dirty_bits_tab[2]; + int dirty_bits_index; /* 0-1 */ + /* the following is used for I/O access */ + void *opaque; + DeviceReadFunc *read_func; + DeviceWriteFunc *write_func; + int devio_flags; +} PhysMemoryRange; + +#define PHYS_MEM_RANGE_MAX 32 + +struct PhysMemoryMap { + int n_phys_mem_range; + PhysMemoryRange phys_mem_range[PHYS_MEM_RANGE_MAX]; + PhysMemoryRange *(*register_ram)(PhysMemoryMap *s, uint64_t addr, + uint64_t size, int devram_flags); + void (*free_ram)(PhysMemoryMap *s, PhysMemoryRange *pr); + const uint32_t *(*get_dirty_bits)(PhysMemoryMap *s, PhysMemoryRange *pr); + void (*set_ram_addr)(PhysMemoryMap *s, PhysMemoryRange *pr, uint64_t addr, + BOOL enabled); + void *opaque; + void (*flush_tlb_write_range)(void *opaque, uint8_t *ram_addr, + size_t ram_size); +}; + + +PhysMemoryMap *phys_mem_map_init(void); +void phys_mem_map_end(PhysMemoryMap *s); +PhysMemoryRange *register_ram_entry(PhysMemoryMap *s, uint64_t addr, + uint64_t size, int devram_flags); +static inline PhysMemoryRange *cpu_register_ram(PhysMemoryMap *s, uint64_t addr, + uint64_t size, int devram_flags) +{ + return s->register_ram(s, addr, size, devram_flags); +} +PhysMemoryRange *cpu_register_device(PhysMemoryMap *s, uint64_t addr, + uint64_t size, void *opaque, + DeviceReadFunc *read_func, DeviceWriteFunc *write_func, + int devio_flags); +PhysMemoryRange *get_phys_mem_range(PhysMemoryMap *s, uint64_t paddr); +void phys_mem_set_addr(PhysMemoryRange *pr, uint64_t addr, BOOL enabled); + +static inline const uint32_t *phys_mem_get_dirty_bits(PhysMemoryRange *pr) +{ + PhysMemoryMap *map = pr->map; + return map->get_dirty_bits(map, pr); +} + +static inline void phys_mem_set_dirty_bit(PhysMemoryRange *pr, size_t offset) +{ + size_t page_index; + uint32_t mask, *dirty_bits_ptr; + if (pr->dirty_bits) { + page_index = offset >> DEVRAM_PAGE_SIZE_LOG2; + mask = 1 << (page_index & 0x1f); + dirty_bits_ptr = pr->dirty_bits + (page_index >> 5); + *dirty_bits_ptr |= mask; + } +} + +static inline BOOL phys_mem_is_dirty_bit(PhysMemoryRange *pr, size_t offset) +{ + size_t page_index; + uint32_t *dirty_bits_ptr; + if (!pr->dirty_bits) + return TRUE; + page_index = offset >> DEVRAM_PAGE_SIZE_LOG2; + dirty_bits_ptr = pr->dirty_bits + (page_index >> 5); + return (*dirty_bits_ptr >> (page_index & 0x1f)) & 1; +} + +void phys_mem_reset_dirty_bit(PhysMemoryRange *pr, size_t offset); +uint8_t *phys_mem_get_ram_ptr(PhysMemoryMap *map, uint64_t paddr, BOOL is_rw); + +/* IRQ support */ + +typedef void SetIRQFunc(void *opaque, int irq_num, int level); + +typedef struct { + SetIRQFunc *set_irq; + void *opaque; + int irq_num; +} IRQSignal; + +void irq_init(IRQSignal *irq, SetIRQFunc *set_irq, void *opaque, int irq_num); + +static inline void set_irq(IRQSignal *irq, int level) +{ + irq->set_irq(irq->opaque, irq->irq_num, level); +} + +#endif /* IOMEM_H */ |
