]>
Commit | Line | Data |
---|---|---|
ef016f83 MF |
1 | /* Common Blackfin device stuff. |
2 | ||
4a94e368 | 3 | Copyright (C) 2010-2022 Free Software Foundation, Inc. |
ef016f83 MF |
4 | Contributed by Analog Devices, Inc. |
5 | ||
6 | This file is part of simulators. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 3 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
20 | ||
21 | #ifndef DEVICES_H | |
22 | #define DEVICES_H | |
23 | ||
24 | #include "hw-base.h" | |
25 | #include "hw-main.h" | |
26 | #include "hw-device.h" | |
27 | #include "hw-tree.h" | |
28 | ||
21836669 MF |
29 | #include "bfin-sim.h" |
30 | ||
ef016f83 MF |
31 | /* We keep the same inital structure layout with DMA enabled devices. */ |
32 | struct dv_bfin { | |
33 | bu32 base; | |
34 | struct hw *dma_master; | |
35 | bool acked; | |
36 | }; | |
37 | ||
38 | #define BFIN_MMR_16(mmr) mmr, __pad_##mmr | |
39 | ||
40 | /* Most peripherals have either one interrupt or these three. */ | |
41 | #define DV_PORT_TX 0 | |
42 | #define DV_PORT_RX 1 | |
43 | #define DV_PORT_STAT 2 | |
44 | ||
45 | unsigned int dv_get_bus_num (struct hw *); | |
46 | \f | |
47 | static inline bu8 dv_load_1 (const void *ptr) | |
48 | { | |
49 | const unsigned char *c = ptr; | |
50 | return c[0]; | |
51 | } | |
52 | ||
53 | static inline void dv_store_1 (void *ptr, bu8 val) | |
54 | { | |
55 | unsigned char *c = ptr; | |
56 | c[0] = val; | |
57 | } | |
58 | ||
59 | static inline bu16 dv_load_2 (const void *ptr) | |
60 | { | |
61 | const unsigned char *c = ptr; | |
62 | return (c[1] << 8) | dv_load_1 (ptr); | |
63 | } | |
64 | ||
65 | static inline void dv_store_2 (void *ptr, bu16 val) | |
66 | { | |
67 | unsigned char *c = ptr; | |
68 | c[1] = val >> 8; | |
69 | dv_store_1 (ptr, val); | |
70 | } | |
71 | ||
72 | static inline bu32 dv_load_4 (const void *ptr) | |
73 | { | |
74 | const unsigned char *c = ptr; | |
75 | return (c[3] << 24) | (c[2] << 16) | dv_load_2 (ptr); | |
76 | } | |
77 | ||
78 | static inline void dv_store_4 (void *ptr, bu32 val) | |
79 | { | |
80 | unsigned char *c = ptr; | |
81 | c[3] = val >> 24; | |
82 | c[2] = val >> 16; | |
83 | dv_store_2 (ptr, val); | |
84 | } | |
85 | \f | |
9922f803 MF |
86 | /* Helpers for MMRs where only the specified bits are W1C. The |
87 | rest are left unmodified. */ | |
ef016f83 MF |
88 | #define dv_w1c(ptr, val, bits) (*(ptr) &= ~((val) & (bits))) |
89 | static inline void dv_w1c_2 (bu16 *ptr, bu16 val, bu16 bits) | |
90 | { | |
91 | dv_w1c (ptr, val, bits); | |
92 | } | |
93 | static inline void dv_w1c_4 (bu32 *ptr, bu32 val, bu32 bits) | |
94 | { | |
95 | dv_w1c (ptr, val, bits); | |
96 | } | |
97 | ||
98 | /* Helpers for MMRs where all bits are RW except for the specified | |
99 | bits -- those ones are W1C. */ | |
100 | #define dv_w1c_partial(ptr, val, bits) \ | |
101 | (*(ptr) = ((val) | (*(ptr) & (bits))) & ~((val) & (bits))) | |
102 | static inline void dv_w1c_2_partial (bu16 *ptr, bu16 val, bu16 bits) | |
103 | { | |
104 | dv_w1c_partial (ptr, val, bits); | |
105 | } | |
106 | static inline void dv_w1c_4_partial (bu32 *ptr, bu32 val, bu32 bits) | |
107 | { | |
108 | dv_w1c_partial (ptr, val, bits); | |
109 | } | |
110 | \f | |
111 | /* XXX: Grubbing around in device internals is probably wrong, but | |
112 | until someone shows me what's right ... */ | |
113 | static inline struct hw * | |
114 | dv_get_device (SIM_CPU *cpu, const char *device_name) | |
115 | { | |
116 | SIM_DESC sd = CPU_STATE (cpu); | |
117 | void *root = STATE_HW (sd); | |
118 | return hw_tree_find_device (root, device_name); | |
119 | } | |
120 | ||
121 | static inline void * | |
122 | dv_get_state (SIM_CPU *cpu, const char *device_name) | |
123 | { | |
124 | return hw_data (dv_get_device (cpu, device_name)); | |
125 | } | |
126 | ||
127 | #define DV_STATE(cpu, dv) dv_get_state (cpu, "/core/bfin_"#dv) | |
128 | ||
129 | #define DV_STATE_CACHED(cpu, dv) \ | |
130 | ({ \ | |
131 | struct bfin_##dv *__##dv = BFIN_CPU_STATE.dv##_cache; \ | |
132 | if (!__##dv) \ | |
133 | BFIN_CPU_STATE.dv##_cache = __##dv = dv_get_state (cpu, "/core/bfin_"#dv); \ | |
134 | __##dv; \ | |
135 | }) | |
136 | \f | |
137 | void dv_bfin_mmr_invalid (struct hw *, address_word, unsigned nr_bytes, bool write); | |
466b619e MF |
138 | bool dv_bfin_mmr_require (struct hw *, address_word, unsigned nr_bytes, unsigned size, bool write); |
139 | /* For 32-bit memory mapped registers that allow 16-bit or 32-bit access. */ | |
140 | bool dv_bfin_mmr_require_16_32 (struct hw *, address_word, unsigned nr_bytes, bool write); | |
141 | /* For 32-bit memory mapped registers that only allow 16-bit access. */ | |
ef016f83 | 142 | #define dv_bfin_mmr_require_16(hw, addr, nr_bytes, write) dv_bfin_mmr_require (hw, addr, nr_bytes, 2, write) |
466b619e | 143 | /* For 32-bit memory mapped registers that only allow 32-bit access. */ |
ef016f83 MF |
144 | #define dv_bfin_mmr_require_32(hw, addr, nr_bytes, write) dv_bfin_mmr_require (hw, addr, nr_bytes, 4, write) |
145 | \f | |
146 | #define HW_TRACE_WRITE() \ | |
147 | HW_TRACE ((me, "write 0x%08lx (%s) length %u with 0x%x", \ | |
148 | (unsigned long) addr, mmr_name (mmr_off), nr_bytes, value)) | |
149 | #define HW_TRACE_READ() \ | |
150 | HW_TRACE ((me, "read 0x%08lx (%s) length %u", \ | |
151 | (unsigned long) addr, mmr_name (mmr_off), nr_bytes)) | |
152 | ||
153 | #define HW_TRACE_DMA_WRITE() \ | |
154 | HW_TRACE ((me, "dma write 0x%08lx length %u", \ | |
155 | (unsigned long) addr, nr_bytes)) | |
156 | #define HW_TRACE_DMA_READ() \ | |
157 | HW_TRACE ((me, "dma read 0x%08lx length %u", \ | |
158 | (unsigned long) addr, nr_bytes)) | |
159 | ||
160 | #endif |