#pragma once

#ifdef __x86_64__
#define I64_FMT "%ld"
#else
#define I64_FMT "%lld"
#endif

#define MEM_BASE 0x80000000
#define MEM_SIZE (16 * 1024 * 1024)
#define N_RESERVATIONS (2)
#define RESERVATION_ADDR_MASK (0xfffffff8u)

static const unsigned int IO_BASE = 0xc0000000;
enum {
	IO_PRINT_CHAR  = 0x000,
	IO_PRINT_U32   = 0x004,
	IO_EXIT        = 0x008,
	IO_SET_SOFTIRQ = 0x010,
	IO_CLR_SOFTIRQ = 0x014,
	IO_GLOBMON_EN  = 0x018,
	IO_POISON_ADDR = 0x01c,
	IO_SET_IRQ     = 0x020,
	IO_CLR_IRQ     = 0x030,
	IO_MTIME       = 0x100,
	IO_MTIMEH      = 0x104,
	IO_MTIMECMP0   = 0x108,
	IO_MTIMECMP0H  = 0x10c,
	IO_MTIMECMP1   = 0x110,
	IO_MTIMECMP1H  = 0x114
};

// ----------------------------------------------------------------------------
// Testbench UART-over-TCP MMIO
//
// Each UART is exposed as a raw TCP byte stream (one client at a time).
// Software should poll STATUS.RX_AVAIL before reading DATA.

static constexpr uint32_t IO_UART_BASE = 0x200;
static constexpr uint32_t IO_UART_STRIDE = 0x20;
static constexpr uint32_t IO_UART_DATA = 0x00;
static constexpr uint32_t IO_UART_STATUS = 0x04;
static constexpr uint32_t IO_UART_CTRL = 0x08;
static constexpr uint32_t IO_UART_N = 2;

static constexpr uint32_t TB_UART_STATUS_RX_AVAIL  = 1u << 0;
static constexpr uint32_t TB_UART_STATUS_TX_READY  = 1u << 1;
static constexpr uint32_t TB_UART_STATUS_CONNECTED = 1u << 2;
static constexpr uint32_t TB_UART_STATUS_OVERRUN   = 1u << 3;

static constexpr uint32_t TB_UART_CTRL_CLR_OVERRUN = 1u << 0;

typedef enum {
	SIZE_BYTE = 0,
	SIZE_HWORD = 1,
	SIZE_WORD = 2
} bus_size_t;
