AlcapDAQ  1
Macros | Functions | Variables
vme_universe.cpp File Reference
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/page.h>
#include "midas.h"
#include "crate.h"
#include "vme_universe.h"
#include "diag.h"

Go to the source code of this file.

Macros

#define MAX_VME_MAPPED_SIZE   (64*1024*1024)
 
#define MAX_VME_HANDLES   10
 

Functions

unsigned long page_round_down (unsigned long addr)
 
unsigned long page_round_up (unsigned long addr)
 
void vme_init ()
 
struct vme_handlevme_open (unsigned long vme_addr, struct vme_mapping_ctrl mapping, int size, int fifo_block_size)
 
void vme_close (struct vme_handle *handle)
 
int vme_dma_read (struct vme_handle *handle, unsigned long vme_addr, unsigned char *buffer, int size)
 
int vme_dma_write (struct vme_handle *handle, unsigned long vme_addr, unsigned char *buffer, int size)
 

Variables

struct vme_handle vme_handles [MAX_VME_HANDLES]
 

Macro Definition Documentation

#define MAX_VME_HANDLES   10

Definition at line 26 of file vme_universe.cpp.

Referenced by vme_init(), and vme_open().

#define MAX_VME_MAPPED_SIZE   (64*1024*1024)

Definition at line 24 of file vme_universe.cpp.

Referenced by vme_open().

Function Documentation

unsigned long page_round_down ( unsigned long  addr)
inline

Definition at line 29 of file vme_universe.cpp.

30 {
31  return addr & PAGE_MASK;
32 }
unsigned long page_round_up ( unsigned long  addr)
inline

Definition at line 34 of file vme_universe.cpp.

35 {
36  if(addr & ~PAGE_MASK == 0) {
37  return addr;
38  } else {
39  return (addr & PAGE_MASK) + PAGE_SIZE;
40  }
41 }
void vme_close ( struct vme_handle handle)

Definition at line 162 of file vme_universe.cpp.

References vme_handle::base, vme_handle::fd, vme_handle::reference_count, vme_handle::size, status, and vme_handle::used.

Referenced by caenV767_eor1(), dl40x_eor(), and sis3600_eor1().

163 {
164  handle->reference_count--;
165 
166  if(handle->reference_count == 0) {
167  int status = munmap((void *) handle->base, handle->size);
168  if(status < 0) {
169  perror("Error unmapping VME:");
170  }
171  status = close(handle->fd);
172  if(status < 0) {
173  perror("Error closing VME:");
174  }
175  handle->used = false;
176  }
177 }
int vme_dma_read ( struct vme_handle handle,
unsigned long  vme_addr,
unsigned char *  buffer,
int  size 
)

Definition at line 179 of file vme_universe.cpp.

References vme_dma_req::buf, vme_dma_req::count, vme_handle::fd, vme_handle::fifo_block_size, vme_dma_req::fifo_block_size, MIN, size, status, vme_dma_req::vme_addr, vme_handle::vme_base, and VMEIMG_DMA_READ.

Referenced by caenV767_fifo_read(), sis3600_fifo_read(), vme_read_d16_checked(), vme_read_d32_checked(), and vme_read_d8_checked().

183 {
184  struct vme_dma_req dma_req;
185 
186  dma_req.vme_addr = vme_addr;
187  dma_req.buf = buffer;
188  dma_req.count = size;
189  dma_req.fifo_block_size = handle->fifo_block_size;
190 
191  int bytes_read = ioctl(handle->fd, VMEIMG_DMA_READ, &dma_req);
192 
193  return bytes_read;
194 
195 #if 0
196  if(handle->fifo_block_size == 0) {
197  return pread(handle->fd, buffer, size, vme_addr - handle->vme_base);
198  } else {
199 
200  int bytes_read = 0;
201 
202  while(bytes_read < size) {
203 
204  int size_this_time = MIN(size - bytes_read, handle->fifo_block_size);
205 
206  int status = pread(handle->fd, buffer + bytes_read, size_this_time,
207  vme_addr - handle->vme_base);
208 
209  if(status > 0) {
210  bytes_read += status;
211  }
212 
213  if(status < size_this_time) {
214  break;
215  }
216  }
217 
218  return bytes_read;
219  }
220 #endif
221 }
int vme_dma_write ( struct vme_handle handle,
unsigned long  vme_addr,
unsigned char *  buffer,
int  size 
)

Definition at line 223 of file vme_universe.cpp.

References vme_dma_req::buf, vme_dma_req::count, vme_handle::fd, vme_handle::fifo_block_size, vme_dma_req::fifo_block_size, MIN, size, status, vme_dma_req::vme_addr, vme_handle::vme_base, and VMEIMG_DMA_WRITE.

Referenced by vme_write_d16_checked(), vme_write_d32_checked(), and vme_write_d8_checked().

227 {
228  struct vme_dma_req dma_req;
229 
230  dma_req.vme_addr = vme_addr;
231  dma_req.buf = buffer;
232  dma_req.count = size;
233  dma_req.fifo_block_size = handle->fifo_block_size;
234 
235  int bytes_written = ioctl(handle->fd, VMEIMG_DMA_WRITE, &dma_req);
236 
237  return bytes_written;
238 
239 #if 0
240  if(handle->fifo_block_size == 0) {
241  return pwrite(handle->fd, buffer, size, vme_addr - handle->vme_base);
242  } else {
243 
244  int bytes_written = 0;
245 
246  while(bytes_written < size) {
247 
248  int size_this_time = MIN(size - bytes_written, handle->fifo_block_size);
249 
250  int status = pwrite(handle->fd, buffer + bytes_written, size_this_time,
251  vme_addr - handle->vme_base);
252 
253  if(status > 0) {
254  bytes_written += status;
255  }
256 
257  if(status < size_this_time) {
258  break;
259  }
260  }
261 
262  return bytes_written;
263  }
264 #endif
265 }
void vme_init ( )

Definition at line 43 of file vme_universe.cpp.

References i, MAX_VME_HANDLES, vme_handle::used, and vme_handles.

44 {
45  // Mark all handles as unused
46  for(int i = 0; i < MAX_VME_HANDLES; i++) {
47  vme_handles[i].used = false;
48  }
49 }
struct vme_handle* vme_open ( unsigned long  vme_addr,
struct vme_mapping_ctrl  mapping,
int  size,
int  fifo_block_size 
)

Definition at line 51 of file vme_universe.cpp.

References vme_mapping_ctrl::address_space, vme_handle::base, diag_print(), vme_handle::fd, vme_handle::fifo_block_size, handle, i, vme_handle::mapping, MAX, vme_mapping_ctrl::max_datawidth, MAX_VME_HANDLES, MAX_VME_MAPPED_SIZE, MIN, page_round_down(), page_round_up(), vme_mapping_ctrl::prgdataam, vme_handle::reference_count, vme_handle::size, sprintf(), vme_mapping_ctrl::supuseram, vme_handle::used, vme_handle::vme_base, vme_handles, VMEIMG_GETVMEADDR, VMEIMG_SETMAPPING, and VMEIMG_SETVMEADDR.

Referenced by caenV767_bor1(), dl401_bor1(), dl403_init(), sis3600_bor1(), and vmic_ttl_init().

55 {
56  struct vme_handle *handle = NULL;
57  unsigned long new_vme_base = 0;
58  unsigned long new_vme_size = 0;
59 
60  vme_addr = page_round_down(vme_addr);
61  unsigned long vme_addr_end = page_round_up(vme_addr + size);
62 
63  // Search through the currently-allocated windows, looking for
64  // one that would be compatible.
65  for(int i = 0; i < MAX_VME_HANDLES; i++) {
66  if(vme_handles[i].used &&
67  vme_handles[i].mapping.address_space == mapping.address_space &&
68  vme_handles[i].mapping.supuseram == mapping.supuseram &&
69  vme_handles[i].mapping.prgdataam == mapping.prgdataam &&
71 
72  new_vme_base =
73  MIN(vme_addr, vme_handles[i].vme_base);
74  unsigned long new_vme_addr_end =
75  MAX(vme_addr_end, vme_handles[i].vme_base + vme_handles[i].size);
76  new_vme_size = new_vme_addr_end - new_vme_base;
77 
78  if(new_vme_size <= MAX_VME_MAPPED_SIZE) {
79  handle = &vme_handles[i];
80  break;
81  }
82  }
83  }
84 
85  // If we didn't find one, then look for a brand-new window
86  if(handle == NULL) {
87  new_vme_base = vme_addr;
88  new_vme_size = vme_addr_end - vme_addr;
89 
90  for(int i = 0; i < MAX_VME_HANDLES; i++) {
91  if(!(vme_handles[i].used)) {
92  handle = &vme_handles[i];
93  }
94  }
95  }
96 
97  // If the window is brand-new, then open a file descriptor for it.
98  if(!handle->used) {
99 
100  // Try each of the device special files
101  for(int i = 0; i < 8; i++) {
102  char filename[20];
103  sprintf(filename, "/dev/vme_a32_%d", i);
104  handle->fd = open(filename, O_RDWR);
105  if(handle->fd >= 0) {
106  break;
107  }
108  }
109 
110  // Check that we found one
111  if(handle->fd < 0) {
112  diag_print(0, "Unable to open a VME device file\n");
113  return NULL;
114  }
115  }
116  // Otherwise, unmap the associated memory
117  else {
118  munmap((void *) handle->base, handle->size);
119  }
120 
121  // Set the address space mapping
122  if(ioctl(handle->fd, VMEIMG_SETMAPPING, &mapping)) {
123  perror("ioctl VMEIMG_SETMAPPING");
124  return NULL;
125  }
126 
127  // Set the VME base address appropriately
128  if(ioctl(handle->fd, VMEIMG_SETVMEADDR, new_vme_base)) {
129  perror("ioctl VMEIMG_SETVMEADDR");
130  return NULL;
131  }
132 
133  // Retrieve the base address that the driver actually accepted
134  if(ioctl(handle->fd, VMEIMG_GETVMEADDR, &handle->vme_base)) {
135  perror("ioctl VMEIMG_GETVMEADDR");
136  return NULL;
137  }
138 
139  // Map some memory for the region of interest
140  handle->base = (volatile unsigned char *)
141  mmap(NULL, new_vme_size, PROT_WRITE | PROT_READ, MAP_SHARED, handle->fd, 0);
142  if(handle->base == (volatile unsigned char *) -1) {
143  perror("mmap VME address space");
144  return NULL;
145  }
146 
147  // Remember the basic properties of this handle
148  handle->used = true;
149  handle->mapping.max_datawidth = mapping.max_datawidth;
150  handle->mapping.address_space = mapping.address_space;
151  handle->mapping.supuseram = mapping.supuseram;
152  handle->mapping.prgdataam = mapping.prgdataam;
154  handle->size = new_vme_size;
155 
156  // Keep a reference count
157  handle->reference_count++;
158 
159  return handle;
160 }

Variable Documentation

struct vme_handle vme_handles[MAX_VME_HANDLES]

Definition at line 27 of file vme_universe.cpp.