219 lines
5.5 KiB
C
219 lines
5.5 KiB
C
/*
|
|
Copyright (c) 2004 Fabrice Bellard and QEMU contributors
|
|
|
|
This file is part of Flycast.
|
|
|
|
Flycast is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Flycast is distributed in the hope that 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 Flycast. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
#pragma once
|
|
#include <climits>
|
|
#include <cinttypes>
|
|
#include "types.h"
|
|
#include "hw/sh4/sh4_sched.h"
|
|
|
|
typedef u8 uint8_t;
|
|
typedef u16 uint16_t;
|
|
typedef u64 uint64_t;
|
|
|
|
typedef uint64_t dma_addr_t;
|
|
typedef uint64_t hwaddr;
|
|
|
|
#ifdef _MSC_VER
|
|
#if defined(_WIN64)
|
|
typedef __int64 ssize_t;
|
|
#else
|
|
typedef long ssize_t;
|
|
#endif
|
|
#endif
|
|
|
|
#define ETH_ALEN 6
|
|
|
|
#define DMA_ADDR_FMT "%" PRIx64
|
|
|
|
struct MACAddr {
|
|
uint8_t a[6];
|
|
};
|
|
|
|
uint32_t net_crc32(const uint8_t *p, int len);
|
|
|
|
struct NetClientState {
|
|
int link_down;
|
|
};
|
|
|
|
typedef struct NICConf {
|
|
MACAddr macaddr;
|
|
} NICConf;
|
|
|
|
/** MemoryRegion:
|
|
*
|
|
* A struct representing a memory region.
|
|
*/
|
|
struct MemoryRegion {
|
|
uint32_t size;
|
|
};
|
|
|
|
#define glue(a, b) _glue(a, b)
|
|
#define _glue(a, b) a ## b
|
|
|
|
#if defined(HOST_WORDS_BIGENDIAN)
|
|
#define be_bswap(v, size) (v)
|
|
#define le_bswap(v, size) glue(bswap, size)(v)
|
|
#define be_bswaps(v, size)
|
|
#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
|
|
#else
|
|
#define le_bswap(v, size) (v)
|
|
#define be_bswap(v, size) glue(bswap, size)(v)
|
|
#define le_bswaps(v, size)
|
|
#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
|
|
#endif
|
|
|
|
#define CPU_CONVERT(endian, size, type)\
|
|
static inline type endian ## size ## _to_cpu(type v)\
|
|
{\
|
|
return glue(endian, _bswap)(v, size);\
|
|
}\
|
|
\
|
|
static inline type cpu_to_ ## endian ## size(type v)\
|
|
{\
|
|
return glue(endian, _bswap)(v, size);\
|
|
}\
|
|
\
|
|
static inline void endian ## size ## _to_cpus(type *p)\
|
|
{\
|
|
glue(endian, _bswaps)(p, size);\
|
|
}\
|
|
\
|
|
static inline void cpu_to_ ## endian ## size ## s(type *p)\
|
|
{\
|
|
glue(endian, _bswaps)(p, size);\
|
|
}
|
|
|
|
CPU_CONVERT(le, 16, uint16_t)
|
|
|
|
CPU_CONVERT(le, 32, uint32_t)
|
|
|
|
static inline int lduw_he_p(const void *ptr)
|
|
{
|
|
uint16_t r;
|
|
memcpy(&r, ptr, sizeof(r));
|
|
return r;
|
|
}
|
|
static inline void stl_he_p(void *ptr, uint32_t v)
|
|
{
|
|
memcpy(ptr, &v, sizeof(v));
|
|
}
|
|
|
|
static inline int lduw_le_p(const void *ptr)
|
|
{
|
|
return (uint16_t)le_bswap(lduw_he_p(ptr), 16);
|
|
}
|
|
static inline void stl_le_p(void *ptr, uint32_t v)
|
|
{
|
|
stl_he_p(ptr, le_bswap(v, 32));
|
|
}
|
|
|
|
/*
|
|
* PCI support
|
|
*/
|
|
static inline uint16_t pci_get_word(const uint8_t *config)
|
|
{
|
|
return lduw_le_p(config);
|
|
}
|
|
static inline void pci_set_long(uint8_t *config, uint32_t val)
|
|
{
|
|
stl_le_p(config, val);
|
|
}
|
|
|
|
typedef uint64_t pcibus_t;
|
|
|
|
#define PCI_DEVICE(d) ((PCIDevice *)(d))
|
|
#define RTL8139(d) ((RTL8139State *)(d));
|
|
|
|
typedef struct PCIIORegion {
|
|
pcibus_t addr; /* current PCI mapping address. -1 means not mapped */
|
|
#define PCI_BAR_UNMAPPED (~(pcibus_t)0)
|
|
pcibus_t size;
|
|
uint8_t type;
|
|
} PCIIORegion;
|
|
|
|
#define PCI_ROM_SLOT 6
|
|
#define PCI_NUM_REGIONS 7
|
|
|
|
struct PCIDevice {
|
|
/* PCI config space */
|
|
uint8_t *config;
|
|
|
|
/* Used to enable config checks on load. Note that writable bits are
|
|
* never checked even if set in cmask. */
|
|
uint8_t *cmask;
|
|
|
|
/* Used to implement R/W bytes */
|
|
uint8_t *wmask;
|
|
|
|
PCIIORegion io_regions[PCI_NUM_REGIONS];
|
|
};
|
|
|
|
void pci_set_irq(PCIDevice *pci_dev, int level);
|
|
void pci_register_bar(PCIDevice *pci_dev, int region_num, uint8_t type, MemoryRegion *memory);
|
|
|
|
void pci_dma_read(PCIDevice *dev, dma_addr_t addr, void *buf, dma_addr_t len);
|
|
void pci_dma_write(PCIDevice *dev, dma_addr_t addr, const void *buf, dma_addr_t len);
|
|
|
|
#define g_malloc malloc
|
|
#define g_free free
|
|
|
|
#define PCI_VENDOR_ID_REALTEK 0x10ec
|
|
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
|
|
|
|
#define FMT_PCIBUS PRIx64
|
|
|
|
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
|
#define PCI_HEADER_TYPE_BRIDGE 1
|
|
#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
|
|
|
|
/*
|
|
* Base addresses specify locations in memory or I/O space.
|
|
* Decoded size can be determined by writing a value of
|
|
* 0xffffffff to the register, and reading it back. Only
|
|
* 1 bits are decoded.
|
|
*/
|
|
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
|
|
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
|
|
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
|
|
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
|
|
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
|
|
#define PCI_ROM_ADDRESS_ENABLE 0x01
|
|
|
|
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
|
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
|
|
|
|
#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
|
|
|
|
struct RTL8139State;
|
|
|
|
ssize_t qemu_send_packet(RTL8139State *s, const uint8_t *buf, int size);
|
|
|
|
void pci_rtl8139_realize(PCIDevice *dev);
|
|
|
|
uint64_t rtl8139_ioport_read(void *opaque, hwaddr addr, unsigned size);
|
|
void rtl8139_ioport_write(void *opaque, hwaddr addr, uint64_t val, unsigned size);
|
|
void rtl8139_reset(RTL8139State *s);
|
|
bool rtl8139_can_receive(RTL8139State *s);
|
|
ssize_t rtl8139_receive(RTL8139State *s, const uint8_t *buf, size_t size);
|
|
|
|
RTL8139State *rtl8139_init(NICConf *conf);
|
|
void rtl8139_destroy(RTL8139State *state);
|
|
void rtl8139_serialize(RTL8139State *state, Serializer& ser);
|
|
bool rtl8139_deserialize(RTL8139State *state, Deserializer& deser);
|