* mach-o.c (bfd_mach_o_archive_p): Restrict the number of
[deliverable/binutils-gdb.git] / sim / ppc / hw_shm.c
CommitLineData
00a0b122
JS
1/* 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
88typedef 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
96static void
97hw_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
149static void
150hw_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
168static unsigned
169hw_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
189static unsigned
190hw_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
209static 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
220static void *
221hw_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
231const device_descriptor hw_shm_device_descriptor[] = {
232 { "shm", hw_shm_create, &hw_shm_callbacks },
233 { NULL },
234};
235
236#endif /* _HW_SHM_C_ */
This page took 0.037806 seconds and 4 git commands to generate.