1 | /* |
2 | * QEMU VMWARE paravirtual devices - auxiliary code |
3 | * |
4 | * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com) |
5 | * |
6 | * Developed by Daynix Computing LTD (http://www.daynix.com) |
7 | * |
8 | * Authors: |
9 | * Dmitry Fleytman <dmitry@daynix.com> |
10 | * Yan Vugenfirer <yan@daynix.com> |
11 | * |
12 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
13 | * See the COPYING file in the top-level directory. |
14 | * |
15 | */ |
16 | |
17 | #ifndef VMWARE_UTILS_H |
18 | #define VMWARE_UTILS_H |
19 | |
20 | #include "qemu/range.h" |
21 | #include "vmxnet_debug.h" |
22 | |
23 | /* |
24 | * Shared memory access functions with byte swap support |
25 | * Each function contains printout for reverse-engineering needs |
26 | * |
27 | */ |
28 | static inline void |
29 | vmw_shmem_read(PCIDevice *d, hwaddr addr, void *buf, int len) |
30 | { |
31 | VMW_SHPRN("SHMEM r: %" PRIx64 ", len: %d to %p" , addr, len, buf); |
32 | pci_dma_read(d, addr, buf, len); |
33 | } |
34 | |
35 | static inline void |
36 | vmw_shmem_write(PCIDevice *d, hwaddr addr, void *buf, int len) |
37 | { |
38 | VMW_SHPRN("SHMEM w: %" PRIx64 ", len: %d to %p" , addr, len, buf); |
39 | pci_dma_write(d, addr, buf, len); |
40 | } |
41 | |
42 | static inline void |
43 | vmw_shmem_rw(PCIDevice *d, hwaddr addr, void *buf, int len, int is_write) |
44 | { |
45 | VMW_SHPRN("SHMEM r/w: %" PRIx64 ", len: %d (to %p), is write: %d" , |
46 | addr, len, buf, is_write); |
47 | |
48 | if (is_write) |
49 | pci_dma_write(d, addr, buf, len); |
50 | else |
51 | pci_dma_read(d, addr, buf, len); |
52 | } |
53 | |
54 | static inline void |
55 | vmw_shmem_set(PCIDevice *d, hwaddr addr, uint8_t val, int len) |
56 | { |
57 | int i; |
58 | VMW_SHPRN("SHMEM set: %" PRIx64 ", len: %d (value 0x%X)" , addr, len, val); |
59 | |
60 | for (i = 0; i < len; i++) { |
61 | pci_dma_write(d, addr + i, &val, 1); |
62 | } |
63 | } |
64 | |
65 | static inline uint32_t |
66 | vmw_shmem_ld8(PCIDevice *d, hwaddr addr) |
67 | { |
68 | uint8_t res; |
69 | pci_dma_read(d, addr, &res, 1); |
70 | VMW_SHPRN("SHMEM load8: %" PRIx64 " (value 0x%X)" , addr, res); |
71 | return res; |
72 | } |
73 | |
74 | static inline void |
75 | vmw_shmem_st8(PCIDevice *d, hwaddr addr, uint8_t value) |
76 | { |
77 | VMW_SHPRN("SHMEM store8: %" PRIx64 " (value 0x%X)" , addr, value); |
78 | pci_dma_write(d, addr, &value, 1); |
79 | } |
80 | |
81 | static inline uint32_t |
82 | vmw_shmem_ld16(PCIDevice *d, hwaddr addr) |
83 | { |
84 | uint16_t res; |
85 | pci_dma_read(d, addr, &res, 2); |
86 | res = le16_to_cpu(res); |
87 | VMW_SHPRN("SHMEM load16: %" PRIx64 " (value 0x%X)" , addr, res); |
88 | return res; |
89 | } |
90 | |
91 | static inline void |
92 | vmw_shmem_st16(PCIDevice *d, hwaddr addr, uint16_t value) |
93 | { |
94 | VMW_SHPRN("SHMEM store16: %" PRIx64 " (value 0x%X)" , addr, value); |
95 | value = cpu_to_le16(value); |
96 | pci_dma_write(d, addr, &value, 2); |
97 | } |
98 | |
99 | static inline uint32_t |
100 | vmw_shmem_ld32(PCIDevice *d, hwaddr addr) |
101 | { |
102 | uint32_t res; |
103 | pci_dma_read(d, addr, &res, 4); |
104 | res = le32_to_cpu(res); |
105 | VMW_SHPRN("SHMEM load32: %" PRIx64 " (value 0x%X)" , addr, res); |
106 | return res; |
107 | } |
108 | |
109 | static inline void |
110 | vmw_shmem_st32(PCIDevice *d, hwaddr addr, uint32_t value) |
111 | { |
112 | VMW_SHPRN("SHMEM store32: %" PRIx64 " (value 0x%X)" , addr, value); |
113 | value = cpu_to_le32(value); |
114 | pci_dma_write(d, addr, &value, 4); |
115 | } |
116 | |
117 | static inline uint64_t |
118 | vmw_shmem_ld64(PCIDevice *d, hwaddr addr) |
119 | { |
120 | uint64_t res; |
121 | pci_dma_read(d, addr, &res, 8); |
122 | res = le64_to_cpu(res); |
123 | VMW_SHPRN("SHMEM load64: %" PRIx64 " (value %" PRIx64 ")" , addr, res); |
124 | return res; |
125 | } |
126 | |
127 | static inline void |
128 | vmw_shmem_st64(PCIDevice *d, hwaddr addr, uint64_t value) |
129 | { |
130 | VMW_SHPRN("SHMEM store64: %" PRIx64 " (value %" PRIx64 ")" , addr, value); |
131 | value = cpu_to_le64(value); |
132 | pci_dma_write(d, addr, &value, 8); |
133 | } |
134 | |
135 | /* Macros for simplification of operations on array-style registers */ |
136 | |
137 | /* |
138 | * Whether <addr> lies inside of array-style register defined by <base>, |
139 | * number of elements (<cnt>) and element size (<regsize>) |
140 | * |
141 | */ |
142 | #define VMW_IS_MULTIREG_ADDR(addr, base, cnt, regsize) \ |
143 | range_covers_byte(base, cnt * regsize, addr) |
144 | |
145 | /* |
146 | * Returns index of given register (<addr>) in array-style register defined by |
147 | * <base> and element size (<regsize>) |
148 | * |
149 | */ |
150 | #define VMW_MULTIREG_IDX_BY_ADDR(addr, base, regsize) \ |
151 | (((addr) - (base)) / (regsize)) |
152 | |
153 | #endif |
154 | |