⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bus.h

📁 skyeye_1_2_2_Rel.rar 最新skyeye源码
💻 H
字号:
/* * -------------------------------------------------------------------------- * * Memory and IO-Memory Access for 32 Bit CPUs * (C) 2004  Lightmaze Solutions AG *   Author: Jochen Karrer * *  This program is free software; you can distribute it and/or modify it *  under the terms of the GNU General Public License (Version 2) as *  published by the Free Software Foundation. * *  This program is distributed in the hope it will be useful, but WITHOUT *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License *  for more details. * *  You should have received a copy of the GNU General Public License along *  with this program; if not, write to the Free Software Foundation, Inc., *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * ------------------------------------------------------------------------- */#ifndef BUS_H#define BUS_H#include <stdint.h>#include <stdlib.h>#include <stdio.h>#include <compiler_extensions.h>#include "byteorder.h"/* * ---------------------------------------------------- * We can use maximum of two bits in hva for flags * because a 32 Bit alignment is guaranteed * ---------------------------------------------------- */#define PG_TRACED (1)#define PG_FLAG_MASK (1)/* The one level map */extern uint8_t **mem_map_read,**mem_map_write;#define IOH_FLG_BIG_ENDIAN	(1)#define IOH_FLG_LITTLE_ENDIAN	(2)#define IOH_FLG_HOST_ENDIAN	(4)/* * ----------------------------------------------------------- * Specify behaviour for partial or overized accesses to * IO handlers * ----------------------------------------------------------- */#define IOH_FLG_PA_CBSE	(0x200)		/* Partial accesss: Call base proc 	*/#define IOH_FLG_PWR_RMW		(8) 	/* Partial write: Read Modify write 	*/#define IOH_FLG_PRD_RARP	(0x10) 	/* Partial read: Read All Return Partial */#define IOH_FLG_OSZR_IGN	(0)	/* Oversized read: ignore */#define IOH_FLG_OSZW_IGN	(0)	/* Oversized write: ignore */#define IOH_FLG_OSZR_NEXT	(0x20)  /* Oversized read: next */#define IOH_FLG_OSZW_NEXT	(0x40)  /* Oversized write: next */#define IOH_FLG_OSZR_WRAP	(0x80) 	/* Oversized read: wrap	*/#define IOH_FLG_OSZW_WRAP	(0x100)	/* Oversized write: wrap */#define IOH_HASH_SIZE	(8192)#define IOH_HASH_MASK	(IOH_HASH_SIZE-1)/* * ------------------------------- * One level 1MB IO-Regions * ------------------------------- */#define IOH_MAP_ENTRIES	(4096)#define IOH_MAP_SHIFT	(20)#define IOH_MAP_BLOCKSIZE (1<<20)#define IOH_MAP_BLOCKMASK ((IOH_MAP_BLOCKSIZE)-1)/* * ---------------------------------- * Two level 512 Byte IO-Regions * ---------------------------------- */#define IOH_FLVL_SZ 		(4096)#define IOH_FLVL_MASK    	(0xfff00000)#define IOH_FLVL_SHIFT	 	(20)#define IOH_FLVL_BLOCKMASK 	((1<<20)-1)#define IOH_SLVL_SZ		(2048)#define IOH_SLVL_MASK		(0x000ffe00)#define IOH_SLVL_SHIFT	 	(9)#define IOH_SLVL_BLOCKMASK	(0x1ff)#define IOH_SLVL_BLOCKSIZE      (0x200)/* * --------------------------- * One level 1MB blocks  * --------------------------- */#define MEM_MAP_ENTRIES (4096)#define MEM_MAP_BLOCKSIZE (1<<20)#define MEM_MAP_SHIFT (20)#define MEM_MAP_BLOCKMASK ((MEM_MAP_BLOCKSIZE)-1)/* * --------------------------------------------- * Two level PA to HVA translation can have * a minimum of 1kB blocks because this is * assumed in MMU implementations with HVA cache * --------------------------------------------- */typedef struct TwoLevelMMap {        unsigned int frst_lvl_sz;        unsigned long frst_lvl_mask;        unsigned int frst_lvl_shift;        unsigned int scnd_lvl_sz;        unsigned long scnd_lvl_mask;        unsigned int scnd_lvl_shift;        unsigned int scnd_lvl_blockmask;        unsigned int scnd_lvl_blocksize;	uint8_t ***flvlmap_read;	uint32_t *flvl_map_read_use_count;	uint8_t ***flvlmap_write;	uint32_t *flvl_map_write_use_count;} TwoLevelMMap;extern TwoLevelMMap twoLevelMMap;typedef uint32_t IOReadProc(void *clientData,uint32_t address,int rqlen);typedef void IOWriteProc(void *clientData,uint32_t value,uint32_t address,int rqlen);typedef struct IOHandler {	struct IOHandler *next;	uint32_t cpu_addr;	IOReadProc *readproc;	IOWriteProc *writeproc;	void *clientData;	uint8_t swap_endian;	uint8_t len;	uint32_t flags;} IOHandler;extern IOHandler **iohandlerHash;void IOH_New8f(uint32_t cpu_addr,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData,uint32_t flags);void IOH_New32f(uint32_t address,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData,uint32_t flags); void IOH_New16f(uint32_t address,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData,uint32_t flags); void IOH_Delete32(uint32_t address);void IOH_Delete16(uint32_t address);void IOH_Delete8(uint32_t address);void IOH_NewRegion(uint32_t address,uint32_t length,IOReadProc *readproc,IOWriteProc *writeproc,int byteorder,void *clientData); void IOH_DeleteRegion(uint32_t address,uint32_t length); static inline voidIOH_New8(uint32_t cpu_addr,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData){	uint32_t flags = IOH_FLG_HOST_ENDIAN | IOH_FLG_PRD_RARP;        IOH_New8f(cpu_addr,readproc,writeproc,clientData,flags);}static inline voidIOH_New16(uint32_t cpu_addr,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData){	uint32_t flags = IOH_FLG_HOST_ENDIAN | IOH_FLG_PRD_RARP;        IOH_New16f(cpu_addr,readproc,writeproc,clientData,flags);}static inline voidIOH_New32(uint32_t cpu_addr,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData) {	uint32_t flags = IOH_FLG_HOST_ENDIAN;        IOH_New32f(cpu_addr,readproc,writeproc,clientData,flags);}void IO_Write32(uint32_t value,uint32_t addr); void IO_Write16(uint16_t value,uint32_t addr); void IO_Write8(uint8_t value,uint32_t addr); uint64_t IO_Read64(uint32_t addr);uint32_t IO_Read32(uint32_t addr);uint16_t IO_Read16(uint32_t addr);uint8_t IO_Read8(uint32_t addr); /* * ---------------------------------------------- * MemMapping  *	Represents a single mapping of a chip *	One Chip can have multiple Mappings * ---------------------------------------------- */#define MEM_FLAG_READABLE (1<<0)#define MEM_FLAG_WRITABLE (1<<1)typedef struct MemMapping {	uint32_t base;	uint32_t mapsize; /* not the size of the chip if it does not decode all address lines ! */	uint32_t flags;	struct MemMapping *next;} MemMapping;#define BSCMAGIC_DRAM_CMD	(4711)typedef struct BusSpecialCycle {        int magic;        uint8_t data[0]; // variable sized} BusSpecialCycle_t;typedef struct BusDevice {	/* public */	void *owner;	void (*Map)(void *owner,uint32_t base,uint32_t mask,uint32_t flags); 	void (*UnMap)(void *owner,uint32_t base,uint32_t mask);	int (*specialCycle)(struct BusDevice *bdev,BusSpecialCycle_t *cycle);	/* private */		MemMapping *first_mapping;	uint32_t hw_flags;	/* Service provider functions */	void (*postIRQ)(struct BusDevice *,int irq);        void (*unPostIRQ)(struct BusDevice *,int irq);	uint32_t (*read32)(uint32_t addr);	uint16_t (*read16)(uint32_t addr);	uint8_t  (*read8)(uint32_t addr);	void  (*readblock)(uint8_t *buf,uint32_t addr,uint32_t count);	void (*write32)(uint32_t value,uint32_t addr);	void (*write16)(uint16_t value,uint32_t addr);	void (*write8)(uint8_t value,uint32_t addr);	void  (*writeblock)(uint32_t addr,uint8_t *buf,uint32_t count);} BusDevice;typedef struct Bus {	uint32_t (*read32)(uint32_t addr);	uint16_t (*read16)(uint32_t addr);	uint8_t  (*read8)(uint32_t addr);	void  (*readblock)(uint8_t *buf,uint32_t addr,uint32_t count);	void (*write32)(uint32_t value,uint32_t addr);	void (*write16)(uint16_t value,uint32_t addr);	void (*write8)(uint8_t value,uint32_t addr);	void  (*writeblock)(uint32_t addr,uint8_t *buf,uint32_t count);} Bus;extern Bus *MainBus;/* * ------------------------------------------------------------------------------- * Called by the System Emulator to emulate its Memory Mapping through Chipselect  * lines * ------------------------------------------------------------------------------- */void Mem_AreaAddMapping(BusDevice *dev,uint32_t base,uint32_t mask,uint32_t flags);void Mem_AreaDeleteMappings(BusDevice *dev);/* * ------------------------------------------------------------------------------- * Called by the Chip Emulator whenever it updates its mapping by itself  * ------------------------------------------------------------------------------- */void Mem_AreaUpdateMappings(BusDevice *dev);/* * --------------------------------------------- * Configuration and creation of memory areas * --------------------------------------------- */void Mem_MapRange(uint32_t base,uint8_t *start_mem,uint32_t devsize,uint32_t mapsize,uint32_t flags);void Mem_UnMapRange(uint32_t base,uint32_t mapsize);/* * ---------------------------------------------------------------- * Special bus cycles (For example SDRAM configuration cycles) * ---------------------------------------------------------------- */static inline intBus_DoSpecialCycle(BusDevice *bdev,BusSpecialCycle_t *cycle){        if(!bdev->specialCycle) {                return -1;        }        return bdev->specialCycle(bdev,cycle);}/* * ------------------------------------------------------------- * Get Host Virtual Addresses for read and Write access * ------------------------------------------------------------- */static inline unsigned char *Bus_GetHVAWrite(uint32_t addr) {        uint32_t index=(addr>>MEM_MAP_SHIFT);        uint8_t *base=mem_map_write[index];        if(likely(base)) {                return base+(addr&(MEM_MAP_BLOCKMASK));        } else {		uint8_t **slvl_map;                index = addr >> twoLevelMMap.frst_lvl_shift;                if(!(slvl_map = twoLevelMMap.flvlmap_write[index])) {			return NULL;                }                index = (addr & twoLevelMMap.scnd_lvl_mask) >> twoLevelMMap.scnd_lvl_shift;                base = slvl_map[index];                if(likely(base)) { 			if(unlikely(((long)base) & PG_TRACED)) {                        	base -= PG_TRACED;                        	slvl_map[index] = base;                        	IO_Write8(0,addr);			}                        return base + (addr & (twoLevelMMap.scnd_lvl_blockmask));                } else {                	return NULL;                }        }}static inline unsigned char *Bus_GetHVARead(uint32_t addr) {        uint32_t index=(addr>>MEM_MAP_SHIFT);        uint8_t *base=mem_map_read[index];        if(likely(base)) {                return base+(addr&(MEM_MAP_BLOCKMASK));        } else {		uint8_t **slvl_map;                index = addr >> twoLevelMMap.frst_lvl_shift;                if(!(slvl_map = twoLevelMMap.flvlmap_read[index])) {			return NULL;                }                index = (addr & twoLevelMMap.scnd_lvl_mask) >> twoLevelMMap.scnd_lvl_shift;                base = slvl_map[index];                if(likely(base)) {			return base+(addr&twoLevelMMap.scnd_lvl_blockmask);                } else {                	return NULL;                }        }}/* Host Memory access functions */static inline uint64_tHMemRead64(uint8_t *host_addr) {        return host64_to_target(*((uint64_t*)host_addr));}static inline uint32_tHMemRead32(uint8_t *host_addr) {        return host32_to_target(*((uint32_t*)host_addr));}static inline uint16_tHMemRead16(uint8_t *host_addr) {        return host16_to_target(*((uint16_t*)host_addr));}static inline uint8_tHMemRead8(uint8_t *host_addr) {        return *((uint8_t*)host_addr);}static inline void HMemWrite64(uint64_t value,uint8_t *addr) {	*((uint64_t*)addr) = target64_to_host(value);}static inline void HMemWrite32(uint32_t value,uint8_t *addr) {	*((uint32_t*)addr) = target32_to_host(value);}static inline void HMemWrite16(uint16_t value,uint8_t *addr) {	*((uint16_t*)addr) = target16_to_host(value);}static inline void HMemWrite8(uint8_t value,uint8_t *addr) {	*((uint8_t*)addr) = value;}static inline uint32_tBus_FastRead32(uint32_t addr) {        uint8_t *base=mem_map_read[addr>>MEM_MAP_SHIFT];        if(unlikely(!base)) {		uint8_t **slvl_map;		int index;                index = addr >> twoLevelMMap.frst_lvl_shift;                if(!(slvl_map = twoLevelMMap.flvlmap_read[index])) {                	fprintf(stderr,"No such memory: %08x\n",addr);                	exit(163);                }                index = (addr & twoLevelMMap.scnd_lvl_mask) >> twoLevelMMap.scnd_lvl_shift;                base = slvl_map[index];                if(base) {			return HMemRead32(base+(addr&twoLevelMMap.scnd_lvl_blockmask));                } else {			/* Should better trigger External Abort */                	fprintf(stderr,"No such memory :%08x\n",addr);                	exit(7163);                }        }	return HMemRead32(base+(addr&MEM_MAP_BLOCKMASK));}uint64_t Bus_Read64(uint32_t addr);uint32_t Bus_Read32(uint32_t addr);uint16_t Bus_Read16(uint32_t addr);uint8_t Bus_Read8(uint32_t addr);void Bus_Write64(uint64_t value,uint32_t addr);void Bus_Write32(uint32_t value,uint32_t addr);void Bus_Write16(uint16_t value,uint32_t addr);void Bus_Write8(uint8_t value,uint32_t addr);void Bus_Write(uint32_t addr,uint8_t *buf,uint32_t count); void Bus_Read(uint8_t *buf,uint32_t addr,uint32_t count); void Bus_WriteSwap32(uint32_t addr,uint8_t *buf,int count); void Bus_ReadSwap32(uint8_t *buf,uint32_t addr,int count); typedef void InvalidateCallback();void Bus_Init(InvalidateCallback *,uint32_t min_blocksize);int Mem_Load(char *filename,uint32_t addr);void Mem_TracePage(uint32_t pgaddr);void Mem_TraceRegion(uint32_t start,uint32_t length);void Mem_UntracePage(uint32_t pgaddr);void Mem_UntraceRegion(uint32_t start,uint32_t length);static inline int Mem_SmallPageSize() {	return twoLevelMMap.scnd_lvl_blocksize;}#define Bus_Write32LE BusWrite32#define Bus_Write16LE BusWrite16#define Bus_Write8LE  BusWrite8#endif // BUS_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -