OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [sim/] [ppc/] [hw_shm.c] - Blame information for rev 438

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1997,2008, Joel Sherrill <joel@OARcorp.com>
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
19
    */
20
 
21
 
22
#ifndef _HW_SHM_C_
23
#define _HW_SHM_C_
24
 
25
#include "device_table.h"
26
 
27
#ifdef HAVE_STRING_H
28
#include <string.h>
29
#else
30
#ifdef HAVE_STRINGS_H
31
#include <strings.h>
32
#endif
33
#endif
34
 
35
#include <sys/ipc.h>
36
#include <sys/shm.h>
37
 
38
 
39
/* DEVICE
40
 
41
 
42
   shm - map unix shared memory into psim address space
43
 
44
 
45
   DESCRIPTION
46
 
47
 
48
   This device implements an area of memory which is mapped into UNIX
49
   shared memory.
50
 
51
 
52
   PROPERTIES
53
 
54
 
55
   reg = <address> <size> (required)
56
 
57
   Determine where the memory lives in the parents address space.
58
   The SHM area is assumed to be of the same length.
59
 
60
   key = <integer> (required)
61
 
62
   This is the key of the unix shared memory area.
63
 
64
   EXAMPLES
65
 
66
 
67
   Enable tracing of the shm:
68
 
69
   |  bash$ psim -t shm-device \
70
 
71
 
72
   Configure a 512 kilobytes of UNIX shared memory with the key 0x12345678
73
   mapped into psim address space at 0x0c000000.
74
 
75
   |  -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
76
   |  -o '/shm@0x0c000000/key 0x12345678' \
77
 
78
   sim/ppc/run -o '/#address-cells 1' \
79
         -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
80
         -o '/shm@0x0c000000/key 0x12345678' ../psim-hello/hello
81
 
82
   BUGS
83
 
84
   None known.
85
 
86
   */
87
 
88
typedef struct _hw_shm_device {
89
  unsigned_word physical_address;
90
  char *shm_address;
91
  unsigned sizeof_memory;
92
  key_t key;
93
  int id;
94
} hw_shm_device;
95
 
96
static void
97
hw_shm_init_data(device *me)
98
{
99
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
100
  const device_unit *d;
101
  reg_property_spec reg;
102
  int i;
103
 
104
  /* Obtain the Key Value */
105
  if (device_find_property(me, "key") == NULL)
106
    error("shm_init_data() required key property is missing\n");
107
 
108
  shm->key = (key_t) device_find_integer_property(me, "key");
109
  DTRACE(shm, ("shm key (0x%08x)\n", shm->key) );
110
 
111
  /* Figure out where this memory is in address space and how long it is */
112
  if ( !device_find_reg_array_property(me, "reg", 0, &reg) )
113
    error("hw_shm_init_data() no address registered\n");
114
 
115
  /* Determine the address and length being as paranoid as possible */
116
  shm->physical_address = 0xffffffff;
117
  shm->sizeof_memory = 0xffffffff;
118
 
119
  for ( i=0 ; i<reg.address.nr_cells; i++ ) {
120
    if (reg.address.cells[0] == 0 && reg.size.cells[0] == 0)
121
      continue;
122
 
123
    if ( shm->physical_address != 0xffffffff )
124
      device_error(me, "Only single celled address ranges supported\n");
125
 
126
    shm->physical_address = reg.address.cells[i];
127
    DTRACE(shm, ("shm physical_address=0x%x\n", shm->physical_address));
128
 
129
    shm->sizeof_memory = reg.size.cells[i];
130
    DTRACE(shm, ("shm length=0x%x\n", shm->sizeof_memory));
131
  }
132
 
133
  if ( shm->physical_address == 0xffffffff )
134
    device_error(me, "Address not specified\n" );
135
 
136
  if ( shm->sizeof_memory == 0xffffffff )
137
    device_error(me, "Length not specified\n" );
138
 
139
  /* Now actually attach to or create the shared memory area */
140
  shm->id = shmget(shm->key, shm->sizeof_memory, IPC_CREAT | 0660);
141
  if (shm->id == -1)
142
    error("hw_shm_init_data() shmget failed\n");
143
 
144
  shm->shm_address = shmat(shm->id, (char *)0, SHM_RND);
145
  if (shm->shm_address == (void *)-1)
146
    error("hw_shm_init_data() shmat failed\n");
147
}
148
 
149
static void
150
hw_shm_attach_address_callback(device *me,
151
                                attach_type attach,
152
                                int space,
153
                                unsigned_word addr,
154
                                unsigned nr_bytes,
155
                                access_type access,
156
                                device *client) /*callback/default*/
157
{
158
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
159
 
160
  if (space != 0)
161
    error("shm_attach_address_callback() invalid address space\n");
162
 
163
  if (nr_bytes == 0)
164
    error("shm_attach_address_callback() invalid size\n");
165
}
166
 
167
 
168
static unsigned
169
hw_shm_io_read_buffer(device *me,
170
                         void *dest,
171
                         int space,
172
                         unsigned_word addr,
173
                         unsigned nr_bytes,
174
                         cpu *processor,
175
                         unsigned_word cia)
176
{
177
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
178
 
179
  /* do we need to worry about out of range addresses? */
180
 
181
  DTRACE(shm, ("read %p %x %x %x\n", \
182
     shm->shm_address, shm->physical_address, addr, nr_bytes) );
183
 
184
  memcpy(dest, &shm->shm_address[addr - shm->physical_address], nr_bytes);
185
  return nr_bytes;
186
}
187
 
188
 
189
static unsigned
190
hw_shm_io_write_buffer(device *me,
191
                          const void *source,
192
                          int space,
193
                          unsigned_word addr,
194
                          unsigned nr_bytes,
195
                          cpu *processor,
196
                          unsigned_word cia)
197
{
198
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
199
 
200
  /* do we need to worry about out of range addresses? */
201
 
202
  DTRACE(shm, ("write %p %x %x %x\n", \
203
     shm->shm_address, shm->physical_address, addr, nr_bytes) );
204
 
205
  memcpy(&shm->shm_address[addr - shm->physical_address], source, nr_bytes);
206
  return nr_bytes;
207
}
208
 
209
static device_callbacks const hw_shm_callbacks = {
210
  { generic_device_init_address, hw_shm_init_data },
211
  { hw_shm_attach_address_callback, }, /* address */
212
  { hw_shm_io_read_buffer,
213
    hw_shm_io_write_buffer }, /* IO */
214
  { NULL, }, /* DMA */
215
  { NULL, }, /* interrupt */
216
  { NULL, }, /* unit */
217
  NULL,
218
};
219
 
220
static void *
221
hw_shm_create(const char *name,
222
                 const device_unit *unit_address,
223
                 const char *args)
224
{
225
  hw_shm_device *shm = ZALLOC(hw_shm_device);
226
  return shm;
227
}
228
 
229
 
230
 
231
const device_descriptor hw_shm_device_descriptor[] = {
232
  { "shm", hw_shm_create, &hw_shm_callbacks },
233
  { NULL },
234
};
235
 
236
#endif /* _HW_SHM_C_ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.