sim: mn10300: tweak engine halt hook
[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
3fd725ef 7 the Free Software Foundation; either version 3 of the License, or
00a0b122
JS
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
51b318de 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
00a0b122
JS
17
18 */
19
20
21#ifndef _HW_SHM_C_
22#define _HW_SHM_C_
23
24#include "device_table.h"
25
00a0b122 26#include <string.h>
00a0b122
JS
27#include <sys/ipc.h>
28#include <sys/shm.h>
29
30
31/* DEVICE
32
33
34 shm - map unix shared memory into psim address space
35
36
37 DESCRIPTION
38
39
40 This device implements an area of memory which is mapped into UNIX
41 shared memory.
42
43
44 PROPERTIES
45
46
47 reg = <address> <size> (required)
48
49 Determine where the memory lives in the parents address space.
50 The SHM area is assumed to be of the same length.
51
52 key = <integer> (required)
53
54 This is the key of the unix shared memory area.
55
56 EXAMPLES
57
58
59 Enable tracing of the shm:
60
61 | bash$ psim -t shm-device \
62
63
64 Configure a 512 kilobytes of UNIX shared memory with the key 0x12345678
65 mapped into psim address space at 0x0c000000.
66
67 | -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
68 | -o '/shm@0x0c000000/key 0x12345678' \
69
70 sim/ppc/run -o '/#address-cells 1' \
71 -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
72 -o '/shm@0x0c000000/key 0x12345678' ../psim-hello/hello
73
74 BUGS
75
76 None known.
77
78 */
79
80typedef struct _hw_shm_device {
81 unsigned_word physical_address;
82 char *shm_address;
83 unsigned sizeof_memory;
84 key_t key;
85 int id;
86} hw_shm_device;
87
88static void
89hw_shm_init_data(device *me)
90{
91 hw_shm_device *shm = (hw_shm_device*)device_data(me);
00a0b122
JS
92 reg_property_spec reg;
93 int i;
94
95 /* Obtain the Key Value */
96 if (device_find_property(me, "key") == NULL)
97 error("shm_init_data() required key property is missing\n");
98
99 shm->key = (key_t) device_find_integer_property(me, "key");
100 DTRACE(shm, ("shm key (0x%08x)\n", shm->key) );
101
102 /* Figure out where this memory is in address space and how long it is */
103 if ( !device_find_reg_array_property(me, "reg", 0, &reg) )
104 error("hw_shm_init_data() no address registered\n");
105
106 /* Determine the address and length being as paranoid as possible */
107 shm->physical_address = 0xffffffff;
108 shm->sizeof_memory = 0xffffffff;
109
110 for ( i=0 ; i<reg.address.nr_cells; i++ ) {
111 if (reg.address.cells[0] == 0 && reg.size.cells[0] == 0)
112 continue;
113
114 if ( shm->physical_address != 0xffffffff )
115 device_error(me, "Only single celled address ranges supported\n");
116
117 shm->physical_address = reg.address.cells[i];
118 DTRACE(shm, ("shm physical_address=0x%x\n", shm->physical_address));
119
120 shm->sizeof_memory = reg.size.cells[i];
121 DTRACE(shm, ("shm length=0x%x\n", shm->sizeof_memory));
122 }
123
124 if ( shm->physical_address == 0xffffffff )
125 device_error(me, "Address not specified\n" );
126
127 if ( shm->sizeof_memory == 0xffffffff )
128 device_error(me, "Length not specified\n" );
129
130 /* Now actually attach to or create the shared memory area */
131 shm->id = shmget(shm->key, shm->sizeof_memory, IPC_CREAT | 0660);
132 if (shm->id == -1)
133 error("hw_shm_init_data() shmget failed\n");
134
135 shm->shm_address = shmat(shm->id, (char *)0, SHM_RND);
136 if (shm->shm_address == (void *)-1)
137 error("hw_shm_init_data() shmat failed\n");
138}
139
140static void
141hw_shm_attach_address_callback(device *me,
142 attach_type attach,
143 int space,
144 unsigned_word addr,
145 unsigned nr_bytes,
146 access_type access,
147 device *client) /*callback/default*/
148{
00a0b122
JS
149 if (space != 0)
150 error("shm_attach_address_callback() invalid address space\n");
151
152 if (nr_bytes == 0)
153 error("shm_attach_address_callback() invalid size\n");
154}
155
156
157static unsigned
158hw_shm_io_read_buffer(device *me,
159 void *dest,
160 int space,
161 unsigned_word addr,
162 unsigned nr_bytes,
163 cpu *processor,
164 unsigned_word cia)
165{
166 hw_shm_device *shm = (hw_shm_device*)device_data(me);
167
168 /* do we need to worry about out of range addresses? */
169
170 DTRACE(shm, ("read %p %x %x %x\n", \
171 shm->shm_address, shm->physical_address, addr, nr_bytes) );
172
173 memcpy(dest, &shm->shm_address[addr - shm->physical_address], nr_bytes);
174 return nr_bytes;
175}
176
177
178static unsigned
179hw_shm_io_write_buffer(device *me,
180 const void *source,
181 int space,
182 unsigned_word addr,
183 unsigned nr_bytes,
184 cpu *processor,
185 unsigned_word cia)
186{
187 hw_shm_device *shm = (hw_shm_device*)device_data(me);
188
189 /* do we need to worry about out of range addresses? */
190
191 DTRACE(shm, ("write %p %x %x %x\n", \
192 shm->shm_address, shm->physical_address, addr, nr_bytes) );
193
194 memcpy(&shm->shm_address[addr - shm->physical_address], source, nr_bytes);
195 return nr_bytes;
196}
197
198static device_callbacks const hw_shm_callbacks = {
199 { generic_device_init_address, hw_shm_init_data },
200 { hw_shm_attach_address_callback, }, /* address */
201 { hw_shm_io_read_buffer,
202 hw_shm_io_write_buffer }, /* IO */
203 { NULL, }, /* DMA */
204 { NULL, }, /* interrupt */
205 { NULL, }, /* unit */
206 NULL,
207};
208
209static void *
210hw_shm_create(const char *name,
211 const device_unit *unit_address,
212 const char *args)
213{
214 hw_shm_device *shm = ZALLOC(hw_shm_device);
215 return shm;
216}
217
218
219
220const device_descriptor hw_shm_device_descriptor[] = {
221 { "shm", hw_shm_create, &hw_shm_callbacks },
222 { NULL },
223};
224
225#endif /* _HW_SHM_C_ */
This page took 0.595783 seconds and 4 git commands to generate.