1 /* Copyright (C) 1998, Cygnus Solutions */
7 /* Imported functions */
9 void device_error (device
*me
, char* message
); /* device.c */
12 /* Internal function declarations */
14 static int pke_io_read_buffer(device
*, void*, int, address_word
,
15 unsigned, sim_cpu
*, sim_cia
);
16 static int pke_io_write_buffer(device
*, const void*, int, address_word
,
17 unsigned, sim_cpu
*, sim_cia
);
18 static void pke_issue(struct pke_device
*);
23 struct pke_device pke0_device
=
25 { "pke0", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
27 PKE0_REGISTER_WINDOW_START
, PKE0_FIFO_START
, /* memory-mapping addresses */
29 NULL
, 0, 0, NULL
, /* FIFO */
34 struct pke_device pke1_device
=
36 { "pke1", &pke_io_read_buffer
, &pke_io_write_buffer
}, /* device */
38 PKE1_REGISTER_WINDOW_START
, PKE1_FIFO_START
, /* memory-mapping addresses */
40 NULL
, 0, 0, NULL
, /* FIFO */
46 /* External functions */
49 /* Attach PKE0 addresses to main memory */
52 pke0_attach(SIM_DESC sd
)
59 pke0_device
.register_memory_addr
,
60 PKE_REGISTER_WINDOW_SIZE
/*nr_bytes*/,
62 (device
*) &pke0_device
,
70 pke0_device
.fifo_memory_addr
,
71 sizeof(quadword
) /*nr_bytes*/,
73 (device
*) &pke1_device
,
78 /* Attach PKE1 addresses to main memory */
81 pke1_attach(SIM_DESC sd
)
88 pke1_device
.register_memory_addr
,
89 PKE_REGISTER_WINDOW_SIZE
/*nr_bytes*/,
91 (device
*) &pke1_device
,
99 pke1_device
.fifo_memory_addr
,
100 sizeof(quadword
) /*nr_bytes*/,
102 (device
*) &pke1_device
,
107 /* Issue a PKE0 instruction if possible */
112 pke_issue(& pke0_device
);
116 /* Issue a PKE1 instruction if possible */
121 pke_issue(& pke0_device
);
126 /* Internal functions */
129 /* Handle a PKE read; return no. of bytes read */
132 pke_io_read_buffer(device
*me_
,
140 /* downcast to gather embedding pke_device struct */
141 struct pke_device
* me
= (struct pke_device
*) me_
;
143 /* enforce that an access does not span more than one quadword */
144 address_word low
= ADDR_TRUNC_QW(addr
);
145 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
149 /* classify address & handle */
150 if(addr
>= me
->register_memory_addr
&&
151 addr
< me
->register_memory_addr
+ PKE_REGISTER_WINDOW_SIZE
)
154 int reg_num
= ADDR_TRUNC_QW(addr
- me
->register_memory_addr
) >> 4;
157 /* ensure readibility of register: all okay except PKE1-only ones read on PKE0 */
165 if(me
->pke_number
== 0) /* PKE0 cannot access these registers */
169 /* perform read & return */
172 /* find byte-offset inside register bank */
173 int reg_byte
= ADDR_OFFSET_QW(addr
);
174 void* src
= ((unsigned_1
*) (& me
->regs
[reg_num
])) + reg_byte
;
176 memcpy(dest
, src
, nr_bytes
);
188 else if(addr
>= me
->fifo_memory_addr
&&
189 addr
< me
->fifo_memory_addr
+ sizeof(quadword
))
193 /* XXX: FIFO is not readable. */
201 /* Handle a PKE read; return no. of bytes written */
204 pke_io_write_buffer(device
*me_
,
212 /* downcast to gather embedding pke_device struct */
213 struct pke_device
* me
= (struct pke_device
*) me_
;
215 /* enforce that an access does not span more than one quadword */
216 address_word low
= ADDR_TRUNC_QW(addr
);
217 address_word high
= ADDR_TRUNC_QW(addr
+ nr_bytes
- 1);
221 /* classify address & handle */
222 if(addr
>= me
->register_memory_addr
&&
223 addr
< me
->register_memory_addr
+ PKE_REGISTER_WINDOW_SIZE
)
226 int reg_num
= ADDR_TRUNC_QW(addr
- me
->register_memory_addr
) >> 4;
229 /* ensure readibility of register: all okay except PKE1-only ones read on PKE0 */
237 if(me
->pke_number
== 0) /* PKE0 cannot access these registers */
241 /* perform write & return */
244 /* find byte-offset inside register bank */
245 int reg_byte
= ADDR_OFFSET_QW(addr
);
246 void* dest
= ((unsigned_1
*) (& me
->regs
[reg_num
])) + reg_byte
;
248 memcpy(dest
, src
, nr_bytes
);
259 else if(addr
>= me
->fifo_memory_addr
&&
260 addr
< me
->fifo_memory_addr
+ sizeof(quadword
))
264 /* assert transfer size == 128 bits */
265 if(nr_bytes
!= sizeof(quadword
))
268 /* ensure FIFO has enough elements */
269 if(me
->fifo_num_elements
== me
->fifo_buffer_size
)
272 int new_fifo_buffer_size
= me
->fifo_buffer_size
+ 20;
273 void* ptr
= realloc((void*) me
->fifo
, new_fifo_buffer_size
*sizeof(quadword
));
277 /* oops, cannot enlarge FIFO any more */
278 device_error(me_
, "Cannot enlarge FIFO buffer\n");
282 me
->fifo_buffer_size
= new_fifo_buffer_size
;
285 /* add new quadword at end of FIFO */
286 memcpy(& me
->fifo
[++me
->fifo_num_elements
], src
, nr_bytes
);
297 /* Issue & swallow one PKE opcode if possible */
300 pke_issue(struct pke_device
* me
)