1 /*
2  * Copyright (c) 2005-2010 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #pragma once
9 
10 #define MEMBANK_SIZE (4*1024*1024)
11 
12 /* some helpful macros */
13 #define REG(x) ((volatile unsigned int *)(x))
14 #define REG_H(x) ((volatile unsigned short *)(x))
15 #define REG_B(x) ((volatile unsigned char *)(x))
16 
17 /* memory map of our generic arm system */
18 // XXX make more dynamic
19 #define MAINMEM_BASE 0x0
20 #define MAINMEM_SIZE (MEMBANK_SIZE)
21 
22 /* peripherals are all mapped here */
23 #define PERIPHERAL_BASE   (0xf0000000)
24 
25 /* system info */
26 #define SYSINFO_REGS_BASE (PERIPHERAL_BASE)
27 #define SYSINFO_REGS_SIZE MEMBANK_SIZE
28 #define SYSINFO_FEATURES  (SYSINFO_REGS_BASE + 0)
29 #define SYSINFO_FEATURE_DISPLAY 0x00000001
30 #define SYSINFO_FEATURE_CONSOLE 0x00000002
31 #define SYSINFO_FEATURE_NETWORK 0x00000004
32 #define SYSINFO_FEATURE_BLOCKDEV 0x00000008
33 
34 /* a write to this register latches the current emulator system time, so the next two regs can be read atomically */
35 #define SYSINFO_TIME_LATCH (SYSINFO_REGS_BASE + 4)
36 /* gettimeofday() style time values */
37 #define SYSINFO_TIME_SECS  (SYSINFO_REGS_BASE + 8)
38 #define SYSINFO_TIME_USECS (SYSINFO_REGS_BASE + 12)
39 
40 /* display */
41 #define DISPLAY_BASE      (SYSINFO_REGS_BASE + SYSINFO_REGS_SIZE)
42 #define DISPLAY_SIZE      MEMBANK_SIZE
43 #define DISPLAY_FRAMEBUFFER DISPLAY_BASE
44 #define DISPLAY_REGS_BASE (DISPLAY_BASE + DISPLAY_SIZE)
45 #define DISPLAY_REGS_SIZE MEMBANK_SIZE
46 
47 #define DISPLAY_WIDTH     (DISPLAY_REGS_BASE + 0) // pixels width/height read/only
48 #define DISPLAY_HEIGHT    (DISPLAY_REGS_BASE + 4)
49 #define DISPLAY_BPP       (DISPLAY_REGS_BASE + 8) // bits per pixel (16/32)
50 
51 /* console (keyboard controller */
52 #define CONSOLE_REGS_BASE (DISPLAY_REGS_BASE + DISPLAY_REGS_SIZE)
53 #define CONSOLE_REGS_SIZE MEMBANK_SIZE
54 #define KYBD_STAT         (CONSOLE_REGS_BASE + 0)
55 #define KYBD_DATA         (CONSOLE_REGS_BASE + 4)
56 
57 /* programmable timer */
58 #define PIT_REGS_BASE     (CONSOLE_REGS_BASE + CONSOLE_REGS_SIZE)
59 #define PIT_REGS_SIZE     MEMBANK_SIZE
60 #define PIT_STATUS        (PIT_REGS_BASE + 0) // status bit
61 #define PIT_CLEAR         (PIT_REGS_BASE + 4) // a nonzero write clears any pending timer
62 #define PIT_CLEAR_INT     (PIT_REGS_BASE + 8) // a nonzero write clears the pending interrupt
63 #define PIT_INTERVAL      (PIT_REGS_BASE + 12) // set the countdown interval, and what the interval is reset to if periodic
64 #define PIT_START_ONESHOT (PIT_REGS_BASE + 16) // a nonzero write starts a oneshot countdown
65 #define PIT_START_PERIODIC (PIT_REGS_BASE + 20) // a nonzero write starts a periodic countdown
66 
67 #define PIT_STATUS_ACTIVE    0x1
68 #define PIT_STATUS_INT_PEND  0x2
69 
70 /* interrupt controller */
71 #define PIC_REGS_BASE     (PIT_REGS_BASE + PIT_REGS_SIZE)
72 #define PIC_REGS_SIZE     MEMBANK_SIZE
73 
74 /* Current vector mask, read-only */
75 #define PIC_MASK          (PIC_REGS_BASE + 0)
76 /* Mask any of the 32 interrupt vectors by writing a 1 in the appropriate bit */
77 #define PIC_MASK_LATCH    (PIC_REGS_BASE + 4)
78 /* Unmask any of the 32 interrupt vectors by writing a 1 in the appropriate bit */
79 #define PIC_UNMASK_LATCH  (PIC_REGS_BASE + 8)
80 /* each bit corresponds to the current status of the interrupt line */
81 #define PIC_STAT          (PIC_REGS_BASE + 12)
82 /* one bit set for the highest priority non-masked active interrupt */
83 #define PIC_CURRENT_BIT   (PIC_REGS_BASE + 16)
84 /* holds the current interrupt number of the highest priority non-masked active interrupt,
85  * or 0xffffffff if no interrupt is active
86  */
87 #define PIC_CURRENT_NUM   (PIC_REGS_BASE + 20)
88 
89 /* interrupt map */
90 #define INT_PIT      0
91 #define INT_KEYBOARD 1
92 #define INT_NET      2
93 #define PIC_MAX_INT 32
94 
95 /* debug interface */
96 #define DEBUG_REGS_BASE (PIC_REGS_BASE + PIC_REGS_SIZE)
97 #define DEBUG_REGS_SIZE MEMBANK_SIZE
98 #define DEBUG_STDOUT (DEBUG_REGS_BASE + 0) /* writes to this register are sent through to stdout */
99 #define DEBUG_STDIN  (DEBUG_REGS_BASE + 0) /* reads from this register return the contents of stdin
100                                             * or -1 if no data is pending */
101 #define DEBUG_REGDUMP (DEBUG_REGS_BASE + 4) /* writes to this register cause the emulator to dump registers */
102 #define DEBUG_HALT    (DEBUG_REGS_BASE + 8) /* writes to this register will halt the emulator */
103 
104 #define DEBUG_MEMDUMPADDR (DEBUG_REGS_BASE + 12)      /* set the base address of memory to dump */
105 #define DEBUG_MEMDUMPLEN  (DEBUG_REGS_BASE + 16)      /* set the length of memory to dump */
106 #define DEBUG_MEMDUMP_BYTE  (DEBUG_REGS_BASE + 20)    /* trigger a memory dump in byte format */
107 #define DEBUG_MEMDUMP_HALFWORD (DEBUG_REGS_BASE + 24) /* trigger a memory dump in halfword format */
108 #define DEBUG_MEMDUMP_WORD (DEBUG_REGS_BASE + 28)     /* trigger a memory dump in word format */
109 
110 /* lets you set the trace level of the various subsystems from within the emulator */
111 /* only works on emulator builds that support dynamic trace levels */
112 #define DEBUG_SET_TRACELEVEL_CPU (DEBUG_REGS_BASE + 32)
113 #define DEBUG_SET_TRACELEVEL_UOP (DEBUG_REGS_BASE + 36)
114 #define DEBUG_SET_TRACELEVEL_SYS (DEBUG_REGS_BASE + 40)
115 #define DEBUG_SET_TRACELEVEL_MMU (DEBUG_REGS_BASE + 44)
116 
117 #define DEBUG_CYCLE_COUNT (DEBUG_REGS_BASE + 48)
118 #define DEBUG_INS_COUNT (DEBUG_REGS_BASE + 52)
119 
120 /* network interface */
121 #define NET_REGS_BASE (DEBUG_REGS_BASE + DEBUG_REGS_SIZE)
122 #define NET_REGS_SIZE MEMBANK_SIZE
123 
124 #define NET_BUF_LEN 2048
125 #define NET_IN_BUF_COUNT 32
126 
127 #define NET_HEAD    (NET_REGS_BASE + 0)     /* current next buffer the hardware will write to */
128 #define NET_TAIL    (NET_REGS_BASE + 4)     /* currently selected input buffer */
129 #define NET_SEND    (NET_REGS_BASE + 8)     /* writes to this register sends whatever is in the out buf */
130 #define NET_SEND_LEN (NET_REGS_BASE + 12)   /* length of packet to send */
131 #define NET_OUT_BUF (NET_REGS_BASE + NET_BUF_LEN)
132 
133 #define NET_IN_BUF_LEN (NET_REGS_BASE + 16) /* length of the currently selected in buffer, via tail register */
134 #define NET_IN_BUF  (NET_REGS_BASE + NET_BUF_LEN*2)
135 
136 /* block device interface */
137 #define BDEV_REGS_BASE (NET_REGS_BASE + NET_REGS_SIZE)
138 #define BDEV_REGS_SIZE MEMBANK_SIZE
139 
140 #define BDEV_CMD    (BDEV_REGS_BASE + 0)    /* command */
141 #define BDEV_CMD_ADDR   (BDEV_REGS_BASE + 4)    /* address of next transfer, 32bit */
142 #define BDEV_CMD_OFF    (BDEV_REGS_BASE + 8)    /* offset of next transfer, 64bit */
143 #define BDEV_CMD_LEN    (BDEV_REGS_BASE + 16)   /* length of next transfer, 32bit */
144 
145 #define BDEV_LEN    (BDEV_REGS_BASE + 20)   /* length of block device, 64bit */
146 
147 /* BDEV_CMD bits */
148 #define BDEV_CMD_MASK   (0x3)
149 #define BDEV_CMD_NOP    (0)
150 #define BDEV_CMD_READ   (1)
151 #define BDEV_CMD_WRITE  (2)
152 #define BDEV_CMD_ERASE  (3)
153 #define BDEV_CMD_ERRSHIFT   16
154 #define BDEV_CMD_ERRMASK    (0xffff << BDEV_CMD_ERRSHIFT)
155 #define BDEV_CMD_ERR_NONE (0 << BDEV_CMD_ERRSHIFT)
156 #define BDEV_CMD_ERR_GENERAL (1 << BDEV_CMD_ERRSHIFT)
157 #define BDEV_CMD_ERR_BAD_OFFSET (2 << BDEV_CMD_ERRSHIFT)
158 
159