shpcic.c revision 1.10 1 /* $NetBSD: shpcic.c,v 1.10 2005/12/24 20:07:32 perry Exp $ */
2
3 /*
4 * Copyright (c) 2005 NONAKA Kimihiro
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: shpcic.c,v 1.10 2005/12/24 20:07:32 perry Exp $");
30
31 #include "opt_pci.h"
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/device.h>
37 #include <sys/extent.h>
38 #include <sys/malloc.h>
39
40 #include <dev/pci/pcireg.h>
41 #include <dev/pci/pcivar.h>
42 #include <dev/pci/pciconf.h>
43 #include <dev/pci/pcidevs.h>
44
45 #include <sh3/bscreg.h>
46 #include <sh3/cache.h>
47 #include <sh3/exception.h>
48 #include <sh3/pcicreg.h>
49
50 #include <machine/bus.h>
51 #include <machine/intr.h>
52 #include <machine/pci_machdep.h>
53
54 #if defined(SHPCIC_DEBUG)
55 int shpcic_debug = 0;
56 #define DPRINTF(arg) if (shpcic_debug) printf arg
57 #else
58 #define DPRINTF(arg)
59 #endif
60
61 #define PCI_MODE1_ENABLE 0x80000000UL
62
63 static const struct shpcic_product {
64 uint32_t sp_product;
65 const char *sp_name;
66 } shpcic_products[] = {
67 { PCI_PRODUCT_HITACHI_SH7751, "SH7751" },
68 { PCI_PRODUCT_HITACHI_SH7751R, "SH7751R" },
69
70 { 0, NULL },
71 };
72
73 int shpcic_match(struct device *, struct cfdata *, void *);
74 void shpcic_attach(struct device *, struct device *, void *);
75
76 CFATTACH_DECL(shpcic, sizeof(struct device),
77 shpcic_match, shpcic_attach, NULL, NULL);
78
79 /* There can be only one. */
80 int shpcic_found = 0;
81
82 /* PCIC intr priotiry */
83 static int shpcic_intr_priority[2] = { IPL_BIO, IPL_BIO };
84
85 static const struct shpcic_product *shpcic_lookup(void);
86
87 static const struct shpcic_product *
88 shpcic_lookup(void)
89 {
90 const struct shpcic_product *spp;
91 pcireg_t id;
92
93 id = _reg_read_4(SH4_PCICONF0);
94 switch (PCI_VENDOR(id)) {
95 case PCI_VENDOR_HITACHI:
96 break;
97
98 default:
99 return (NULL);
100 }
101
102 for (spp = shpcic_products; spp->sp_name != NULL; spp++) {
103 if (PCI_PRODUCT(id) == spp->sp_product) {
104 return (spp);
105 }
106 }
107 return (NULL);
108 }
109
110 int
111 shpcic_match(struct device *parent, struct cfdata *cf, void *aux)
112 {
113
114 if (!CPU_IS_SH4)
115 return (0);
116
117 switch (cpu_product) {
118 default:
119 return (0);
120
121 case CPU_PRODUCT_7751:
122 case CPU_PRODUCT_7751R:
123 break;
124 }
125
126 if (shpcic_found)
127 return (0);
128
129 if (shpcic_lookup() == NULL)
130 return (0);
131
132 if (_reg_read_2(SH4_BCR2) & BCR2_PORTEN)
133 return (0);
134
135 return (1);
136 }
137
138 void
139 shpcic_attach(struct device *parent, struct device *self, void *aux)
140 {
141 const struct shpcic_product *spp;
142 struct pcibus_attach_args pba;
143 #ifdef PCI_NETBSD_CONFIGURE
144 struct extent *ioext, *memext;
145 #endif
146
147 shpcic_found = 1;
148
149 spp = shpcic_lookup();
150 if (spp == NULL) {
151 printf("\n");
152 panic("shpcic_attach: impossible");
153 }
154
155 if (_reg_read_2(SH4_BCR2) & BCR2_PORTEN) {
156 printf("\n");
157 panic("shpcic_attach: port enabled");
158 }
159
160 printf(": HITACHI %s\n", spp->sp_name);
161
162 /* allow PCIC request */
163 _reg_write_4(SH4_BCR1, _reg_read_4(SH4_BCR1) | BCR1_BREQEN);
164
165 /* Initialize PCIC */
166 _reg_write_4(SH4_PCICR, PCICR_BASE | PCICR_RSTCTL);
167 delay(10 * 1000);
168 _reg_write_4(SH4_PCICR, PCICR_BASE);
169
170 /* Class: Host-Bridge */
171 _reg_write_4(SH4_PCICONF2,
172 PCI_CLASS_CODE(PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_HOST, 0x00));
173
174 #if !defined(DONT_INIT_PCIBSC)
175 #if defined(PCIBCR_BCR1_VAL)
176 _reg_write_4(SH4_PCIBCR1, PCIBCR_BCR1_VAL);
177 #else
178 _reg_write_4(SH4_PCIBCR1, _reg_read_4(SH4_BCR1) | BCR1_MASTER);
179 #endif
180 #if defined(PCIBCR_BCR2_VAL)
181 _reg_write_4(SH4_PCIBCR2, PCIBCR_BCR2_VAL);
182 #else
183 _reg_write_4(SH4_PCIBCR2, _reg_read_2(SH4_BCR2));
184 #endif
185 #if defined(SH4) && defined(SH7751R)
186 if (cpu_product == CPU_PRODUCT_7751R) {
187 #if defined(PCIBCR_BCR3_VAL)
188 _reg_write_4(SH4_PCIBCR3, PCIBCR_BCR3_VAL);
189 #else
190 _reg_write_4(SH4_PCIBCR3, _reg_read_2(SH4_BCR3));
191 #endif
192 }
193 #endif /* SH4 && SH7751R && PCIBCR_BCR3_VAL */
194 #if defined(PCIBCR_WCR1_VAL)
195 _reg_write_4(SH4_PCIWCR1, PCIBCR_WCR1_VAL);
196 #else
197 _reg_write_4(SH4_PCIWCR1, _reg_read_4(SH4_WCR1));
198 #endif
199 #if defined(PCIBCR_WCR2_VAL)
200 _reg_write_4(SH4_PCIWCR2, PCIBCR_WCR2_VAL);
201 #else
202 _reg_write_4(SH4_PCIWCR2, _reg_read_4(SH4_WCR2));
203 #endif
204 #if defined(PCIBCR_WCR3_VAL)
205 _reg_write_4(SH4_PCIWCR3, PCIBCR_WCR3_VAL);
206 #else
207 _reg_write_4(SH4_PCIWCR3, _reg_read_4(SH4_WCR3));
208 #endif
209 #if defined(PCIBCR_MCR_VAL)
210 _reg_write_4(SH4_PCIMCR, PCIBCR_MCR_VAL);
211 #else
212 _reg_write_4(SH4_PCIMCR, _reg_read_4(SH4_MCR));
213 #endif
214 #endif /* !DONT_INIT_PCIBSC */
215
216 /* set PCI I/O, memory base address */
217 _reg_write_4(SH4_PCIIOBR, SH4_PCIC_IO);
218 _reg_write_4(SH4_PCIMBR, SH4_PCIC_MEM);
219
220 /* set PCI local address 0 */
221 _reg_write_4(SH4_PCILSR0, (64 - 1) << 20);
222 _reg_write_4(SH4_PCILAR0, 0xac000000);
223 _reg_write_4(SH4_PCICONF5, 0xac000000);
224
225 /* set PCI local address 1 */
226 _reg_write_4(SH4_PCILSR1, (64 - 1) << 20);
227 _reg_write_4(SH4_PCILAR1, 0xac000000);
228 _reg_write_4(SH4_PCICONF6, 0x8c000000);
229
230 /* Enable I/O, memory, bus-master */
231 _reg_write_4(SH4_PCICONF1, PCI_COMMAND_IO_ENABLE
232 | PCI_COMMAND_MEM_ENABLE
233 | PCI_COMMAND_MASTER_ENABLE
234 | PCI_COMMAND_STEPPING_ENABLE
235 | PCI_STATUS_DEVSEL_MEDIUM);
236
237 /* Initialize done. */
238 _reg_write_4(SH4_PCICR, PCICR_BASE | PCICR_CFINIT);
239
240 /* set PCI controller interrupt priority */
241 intpri_intr_priority(SH4_INTEVT_PCIERR, shpcic_intr_priority[0]);
242 intpri_intr_priority(SH4_INTEVT_PCISERR, shpcic_intr_priority[1]);
243
244 /* PCI bus */
245 #ifdef PCI_NETBSD_CONFIGURE
246 ioext = extent_create("pciio",
247 SH4_PCIC_IO, SH4_PCIC_IO + SH4_PCIC_IO_SIZE - 1,
248 M_DEVBUF, NULL, 0, EX_NOWAIT);
249 memext = extent_create("pcimem",
250 SH4_PCIC_MEM, SH4_PCIC_MEM + SH4_PCIC_MEM_SIZE - 1,
251 M_DEVBUF, NULL, 0, EX_NOWAIT);
252
253 pci_configure_bus(NULL, ioext, memext, NULL, 0, sh_cache_line_size);
254
255 extent_destroy(ioext);
256 extent_destroy(memext);
257 #endif
258
259 /* PCI bus */
260 memset(&pba, 0, sizeof(pba));
261 pba.pba_iot = shpcic_get_bus_io_tag();
262 pba.pba_memt = shpcic_get_bus_mem_tag();
263 pba.pba_dmat = shpcic_get_bus_dma_tag();
264 pba.pba_dmat64 = NULL;
265 pba.pba_pc = NULL;
266 pba.pba_bus = 0;
267 pba.pba_bridgetag = NULL;
268 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
269 config_found(self, &pba, NULL);
270 }
271
272 int
273 shpcic_bus_maxdevs(void *v, int busno)
274 {
275
276 /*
277 * Bus number is irrelevant. Configuration Mechanism 1 is in
278 * use, can have devices 0-32 (i.e. the `normal' range).
279 */
280 return (32);
281 }
282
283 pcitag_t
284 shpcic_make_tag(void *v, int bus, int device, int function)
285 {
286 pcitag_t tag;
287
288 if (bus >= 256 || device >= 32 || function >= 8)
289 panic("pci_make_tag: bad request");
290
291 tag = PCI_MODE1_ENABLE |
292 (bus << 16) | (device << 11) | (function << 8);
293
294 return (tag);
295 }
296
297 void
298 shpcic_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
299 {
300
301 if (bp != NULL)
302 *bp = (tag >> 16) & 0xff;
303 if (dp != NULL)
304 *dp = (tag >> 11) & 0x1f;
305 if (fp != NULL)
306 *fp = (tag >> 8) & 0x7;
307 }
308
309 pcireg_t
310 shpcic_conf_read(void *v, pcitag_t tag, int reg)
311 {
312 pcireg_t data;
313 int s;
314
315 s = splhigh();
316 _reg_write_4(SH4_PCIPAR, tag | reg);
317 data = _reg_read_4(SH4_PCIPDR);
318 _reg_write_4(SH4_PCIPAR, 0);
319 splx(s);
320
321 return data;
322 }
323
324 void
325 shpcic_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
326 {
327 int s;
328
329 s = splhigh();
330 _reg_write_4(SH4_PCIPAR, tag | reg);
331 _reg_write_4(SH4_PCIPDR, data);
332 _reg_write_4(SH4_PCIPAR, 0);
333 splx(s);
334 }
335
336 int
337 shpcic_set_intr_priority(int intr, int level)
338 {
339 int evtcode;
340
341 if ((intr != 0) && (intr != 1)) {
342 return (-1);
343 }
344 if ((level < IPL_NONE) || (level > IPL_HIGH)) {
345 return (-1);
346 }
347
348 if (intr == 0) {
349 evtcode = SH4_INTEVT_PCIERR;
350 } else {
351 evtcode = SH4_INTEVT_PCISERR;
352 }
353
354 intpri_intr_priority(evtcode, shpcic_intr_priority[intr]);
355 shpcic_intr_priority[intr] = level;
356
357 return (0);
358 }
359
360 void *
361 shpcic_intr_establish(int evtcode, int (*ih_func)(void *), void *ih_arg)
362 {
363 int level;
364
365 switch (evtcode) {
366 case SH4_INTEVT_PCISERR:
367 level = shpcic_intr_priority[1];
368 break;
369
370 case SH4_INTEVT_PCIDMA3:
371 case SH4_INTEVT_PCIDMA2:
372 case SH4_INTEVT_PCIDMA1:
373 case SH4_INTEVT_PCIDMA0:
374 case SH4_INTEVT_PCIPWON:
375 case SH4_INTEVT_PCIPWDWN:
376 case SH4_INTEVT_PCIERR:
377 level = shpcic_intr_priority[0];
378 break;
379
380 default:
381 printf("shpcic_intr_establish: unknown evtcode = 0x%08x\n",
382 evtcode);
383 return NULL;
384 }
385
386 return intc_intr_establish(evtcode, IST_LEVEL, level, ih_func, ih_arg);
387 }
388
389 void
390 shpcic_intr_disestablish(void *ih)
391 {
392
393 intc_intr_disestablish(ih);
394 }
395
396 /*
397 * shpcic bus space
398 */
399 int
400 shpcic_iomem_map(void *v, bus_addr_t bpa, bus_size_t size,
401 int flags, bus_space_handle_t *bshp)
402 {
403
404 *bshp = (bus_space_handle_t)bpa;
405
406 return (0);
407 }
408
409 void
410 shpcic_iomem_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
411 {
412
413 /* Nothing to do */
414 }
415
416 int
417 shpcic_iomem_subregion(void *v, bus_space_handle_t bsh,
418 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
419 {
420
421 *nbshp = bsh + offset;
422
423 return (0);
424 }
425
426 int
427 shpcic_iomem_alloc(void *v, bus_addr_t rstart, bus_addr_t rend,
428 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
429 bus_addr_t *bpap, bus_space_handle_t *bshp)
430 {
431
432 *bshp = *bpap = rstart;
433
434 return (0);
435 }
436
437 void
438 shpcic_iomem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
439 {
440
441 /* Nothing to do */
442 }
443
444 /*
445 * shpcic bus space io/mem read/write
446 */
447 /* read */
448 static inline uint8_t __shpcic_io_read_1(bus_space_handle_t bsh,
449 bus_size_t offset);
450 static inline uint16_t __shpcic_io_read_2(bus_space_handle_t bsh,
451 bus_size_t offset);
452 static inline uint32_t __shpcic_io_read_4(bus_space_handle_t bsh,
453 bus_size_t offset);
454 static inline uint8_t __shpcic_mem_read_1(bus_space_handle_t bsh,
455 bus_size_t offset);
456 static inline uint16_t __shpcic_mem_read_2(bus_space_handle_t bsh,
457 bus_size_t offset);
458 static inline uint32_t __shpcic_mem_read_4(bus_space_handle_t bsh,
459 bus_size_t offset);
460
461 static inline uint8_t
462 __shpcic_io_read_1(bus_space_handle_t bsh, bus_size_t offset)
463 {
464 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
465
466 return *(volatile uint8_t *)(SH4_PCIC_IO + adr);
467 }
468
469 static inline uint16_t
470 __shpcic_io_read_2(bus_space_handle_t bsh, bus_size_t offset)
471 {
472 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
473
474 return *(volatile uint16_t *)(SH4_PCIC_IO + adr);
475 }
476
477 static inline uint32_t
478 __shpcic_io_read_4(bus_space_handle_t bsh, bus_size_t offset)
479 {
480 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
481
482 return *(volatile uint32_t *)(SH4_PCIC_IO + adr);
483 }
484
485 static inline uint8_t
486 __shpcic_mem_read_1(bus_space_handle_t bsh, bus_size_t offset)
487 {
488 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
489
490 return *(volatile uint8_t *)(SH4_PCIC_MEM + adr);
491 }
492
493 static inline uint16_t
494 __shpcic_mem_read_2(bus_space_handle_t bsh, bus_size_t offset)
495 {
496 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
497
498 return *(volatile uint16_t *)(SH4_PCIC_MEM + adr);
499 }
500
501 static inline uint32_t
502 __shpcic_mem_read_4(bus_space_handle_t bsh, bus_size_t offset)
503 {
504 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
505
506 return *(volatile uint32_t *)(SH4_PCIC_MEM + adr);
507 }
508
509 /*
510 * read single
511 */
512 uint8_t
513 shpcic_io_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
514 {
515 uint8_t value;
516
517 value = __shpcic_io_read_1(bsh, offset);
518
519 return value;
520 }
521
522 uint16_t
523 shpcic_io_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
524 {
525 uint16_t value;
526
527 value = __shpcic_io_read_2(bsh, offset);
528
529 return value;
530 }
531
532 uint32_t
533 shpcic_io_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
534 {
535 uint32_t value;
536
537 value = __shpcic_io_read_4(bsh, offset);
538
539 return value;
540 }
541
542 uint8_t
543 shpcic_mem_read_1(void *v, bus_space_handle_t bsh, bus_size_t offset)
544 {
545 uint8_t value;
546
547 value = __shpcic_mem_read_1(bsh, offset);
548
549 return value;
550 }
551
552 uint16_t
553 shpcic_mem_read_2(void *v, bus_space_handle_t bsh, bus_size_t offset)
554 {
555 uint16_t value;
556
557 value = __shpcic_mem_read_2(bsh, offset);
558
559 return value;
560 }
561
562 uint32_t
563 shpcic_mem_read_4(void *v, bus_space_handle_t bsh, bus_size_t offset)
564 {
565 uint32_t value;
566
567 value = __shpcic_mem_read_4(bsh, offset);
568
569 return value;
570 }
571
572 /*
573 * read multi
574 */
575 void
576 shpcic_io_read_multi_1(void *v, bus_space_handle_t bsh,
577 bus_size_t offset, uint8_t *addr, bus_size_t count)
578 {
579
580 while (count--) {
581 *addr++ = __shpcic_io_read_1(bsh, offset);
582 }
583 }
584
585 void
586 shpcic_io_read_multi_2(void *v, bus_space_handle_t bsh,
587 bus_size_t offset, uint16_t *addr, bus_size_t count)
588 {
589
590 while (count--) {
591 *addr++ = __shpcic_io_read_2(bsh, offset);
592 }
593 }
594
595 void
596 shpcic_io_read_multi_4(void *v, bus_space_handle_t bsh,
597 bus_size_t offset, uint32_t *addr, bus_size_t count)
598 {
599
600 while (count--) {
601 *addr++ = __shpcic_io_read_4(bsh, offset);
602 }
603 }
604
605 void
606 shpcic_mem_read_multi_1(void *v, bus_space_handle_t bsh,
607 bus_size_t offset, uint8_t *addr, bus_size_t count)
608 {
609
610 while (count--) {
611 *addr++ = __shpcic_mem_read_1(bsh, offset);
612 }
613 }
614
615 void
616 shpcic_mem_read_multi_2(void *v, bus_space_handle_t bsh,
617 bus_size_t offset, uint16_t *addr, bus_size_t count)
618 {
619
620 while (count--) {
621 *addr++ = __shpcic_mem_read_2(bsh, offset);
622 }
623 }
624
625 void
626 shpcic_mem_read_multi_4(void *v, bus_space_handle_t bsh,
627 bus_size_t offset, uint32_t *addr, bus_size_t count)
628 {
629
630 while (count--) {
631 *addr++ = __shpcic_mem_read_4(bsh, offset);
632 }
633 }
634
635 /*
636 *
637 * read region
638 */
639 void
640 shpcic_io_read_region_1(void *v, bus_space_handle_t bsh,
641 bus_size_t offset, uint8_t *addr, bus_size_t count)
642 {
643
644 while (count--) {
645 *addr++ = __shpcic_io_read_1(bsh, offset);
646 offset += 1;
647 }
648 }
649
650 void
651 shpcic_io_read_region_2(void *v, bus_space_handle_t bsh,
652 bus_size_t offset, uint16_t *addr, bus_size_t count)
653 {
654
655 while (count--) {
656 *addr++ = __shpcic_io_read_2(bsh, offset);
657 offset += 2;
658 }
659 }
660
661 void
662 shpcic_io_read_region_4(void *v, bus_space_handle_t bsh,
663 bus_size_t offset, uint32_t *addr, bus_size_t count)
664 {
665
666 while (count--) {
667 *addr++ = __shpcic_io_read_4(bsh, offset);
668 offset += 4;
669 }
670 }
671
672 void
673 shpcic_mem_read_region_1(void *v, bus_space_handle_t bsh,
674 bus_size_t offset, uint8_t *addr, bus_size_t count)
675 {
676
677 while (count--) {
678 *addr++ = __shpcic_mem_read_1(bsh, offset);
679 offset += 1;
680 }
681 }
682
683 void
684 shpcic_mem_read_region_2(void *v, bus_space_handle_t bsh,
685 bus_size_t offset, uint16_t *addr, bus_size_t count)
686 {
687
688 while (count--) {
689 *addr++ = __shpcic_mem_read_2(bsh, offset);
690 offset += 2;
691 }
692 }
693
694 void
695 shpcic_mem_read_region_4(void *v, bus_space_handle_t bsh,
696 bus_size_t offset, uint32_t *addr, bus_size_t count)
697 {
698
699 while (count--) {
700 *addr++ = __shpcic_mem_read_4(bsh, offset);
701 offset += 4;
702 }
703 }
704
705 /* write */
706 static inline void __shpcic_io_write_1(bus_space_handle_t bsh,
707 bus_size_t offset, uint8_t value);
708 static inline void __shpcic_io_write_2(bus_space_handle_t bsh,
709 bus_size_t offset, uint16_t value);
710 static inline void __shpcic_io_write_4(bus_space_handle_t bsh,
711 bus_size_t offset, uint32_t value);
712 static inline void __shpcic_mem_write_1(bus_space_handle_t bsh,
713 bus_size_t offset, uint8_t value);
714 static inline void __shpcic_mem_write_2(bus_space_handle_t bsh,
715 bus_size_t offset, uint16_t value);
716 static inline void __shpcic_mem_write_4(bus_space_handle_t bsh,
717 bus_size_t offset, uint32_t value);
718
719 static inline void
720 __shpcic_io_write_1(bus_space_handle_t bsh, bus_size_t offset,
721 uint8_t value)
722 {
723 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
724
725 *(volatile uint8_t *)(SH4_PCIC_IO + adr) = value;
726 }
727
728 static inline void
729 __shpcic_io_write_2(bus_space_handle_t bsh, bus_size_t offset,
730 uint16_t value)
731 {
732 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
733
734 *(volatile uint16_t *)(SH4_PCIC_IO + adr) = value;
735 }
736
737 static inline void
738 __shpcic_io_write_4(bus_space_handle_t bsh, bus_size_t offset,
739 uint32_t value)
740 {
741 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_IO_MASK;
742
743 *(volatile uint32_t *)(SH4_PCIC_IO + adr) = value;
744 }
745
746 static inline void
747 __shpcic_mem_write_1(bus_space_handle_t bsh, bus_size_t offset,
748 uint8_t value)
749 {
750 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
751
752 *(volatile uint8_t *)(SH4_PCIC_MEM + adr) = value;
753 }
754
755 static inline void
756 __shpcic_mem_write_2(bus_space_handle_t bsh, bus_size_t offset,
757 uint16_t value)
758 {
759 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
760
761 *(volatile uint16_t *)(SH4_PCIC_MEM + adr) = value;
762 }
763
764 static inline void
765 __shpcic_mem_write_4(bus_space_handle_t bsh, bus_size_t offset,
766 uint32_t value)
767 {
768 u_long adr = (u_long)(bsh + offset) & SH4_PCIC_MEM_MASK;
769
770 *(volatile uint32_t *)(SH4_PCIC_MEM + adr) = value;
771 }
772
773 /*
774 * write single
775 */
776 void
777 shpcic_io_write_1(void *v, bus_space_handle_t bsh,
778 bus_size_t offset, uint8_t value)
779 {
780
781 __shpcic_io_write_1(bsh, offset, value);
782 }
783
784 void
785 shpcic_io_write_2(void *v, bus_space_handle_t bsh,
786 bus_size_t offset, uint16_t value)
787 {
788
789 __shpcic_io_write_2(bsh, offset, value);
790 }
791
792 void
793 shpcic_io_write_4(void *v, bus_space_handle_t bsh,
794 bus_size_t offset, uint32_t value)
795 {
796
797 __shpcic_io_write_4(bsh, offset, value);
798 }
799
800 void
801 shpcic_mem_write_1(void *v, bus_space_handle_t bsh,
802 bus_size_t offset, uint8_t value)
803 {
804
805 __shpcic_mem_write_1(bsh, offset, value);
806 }
807
808 void
809 shpcic_mem_write_2(void *v, bus_space_handle_t bsh,
810 bus_size_t offset, uint16_t value)
811 {
812
813 __shpcic_mem_write_2(bsh, offset, value);
814 }
815
816 void
817 shpcic_mem_write_4(void *v, bus_space_handle_t bsh,
818 bus_size_t offset, uint32_t value)
819 {
820
821 __shpcic_mem_write_4(bsh, offset, value);
822 }
823
824 /*
825 * write multi
826 */
827 void
828 shpcic_io_write_multi_1(void *v, bus_space_handle_t bsh,
829 bus_size_t offset, const uint8_t *addr, bus_size_t count)
830 {
831
832 while (count--) {
833 __shpcic_io_write_1(bsh, offset, *addr++);
834 }
835 }
836
837 void
838 shpcic_io_write_multi_2(void *v, bus_space_handle_t bsh,
839 bus_size_t offset, const uint16_t *addr, bus_size_t count)
840 {
841
842 while (count--) {
843 __shpcic_io_write_2(bsh, offset, *addr++);
844 }
845 }
846
847 void
848 shpcic_io_write_multi_4(void *v, bus_space_handle_t bsh,
849 bus_size_t offset, const uint32_t *addr, bus_size_t count)
850 {
851
852 while (count--) {
853 __shpcic_io_write_4(bsh, offset, *addr++);
854 }
855 }
856
857 void
858 shpcic_mem_write_multi_1(void *v, bus_space_handle_t bsh,
859 bus_size_t offset, const uint8_t *addr, bus_size_t count)
860 {
861
862 while (count--) {
863 __shpcic_mem_write_1(bsh, offset, *addr++);
864 }
865 }
866
867 void
868 shpcic_mem_write_multi_2(void *v, bus_space_handle_t bsh,
869 bus_size_t offset, const uint16_t *addr, bus_size_t count)
870 {
871
872 while (count--) {
873 __shpcic_mem_write_2(bsh, offset, *addr++);
874 }
875 }
876
877 void
878 shpcic_mem_write_multi_4(void *v, bus_space_handle_t bsh,
879 bus_size_t offset, const uint32_t *addr, bus_size_t count)
880 {
881
882 while (count--) {
883 __shpcic_mem_write_4(bsh, offset, *addr++);
884 }
885 }
886
887 /*
888 * write region
889 */
890 void
891 shpcic_io_write_region_1(void *v, bus_space_handle_t bsh,
892 bus_size_t offset, const uint8_t *addr, bus_size_t count)
893 {
894
895 while (count--) {
896 __shpcic_io_write_1(bsh, offset, *addr++);
897 offset += 1;
898 }
899 }
900
901 void
902 shpcic_io_write_region_2(void *v, bus_space_handle_t bsh,
903 bus_size_t offset, const uint16_t *addr, bus_size_t count)
904 {
905
906 while (count--) {
907 __shpcic_io_write_2(bsh, offset, *addr++);
908 offset += 2;
909 }
910 }
911
912 void
913 shpcic_io_write_region_4(void *v, bus_space_handle_t bsh,
914 bus_size_t offset, const uint32_t *addr, bus_size_t count)
915 {
916
917 while (count--) {
918 __shpcic_io_write_4(bsh, offset, *addr++);
919 offset += 4;
920 }
921 }
922
923 void
924 shpcic_mem_write_region_1(void *v, bus_space_handle_t bsh,
925 bus_size_t offset, const uint8_t *addr, bus_size_t count)
926 {
927
928 while (count--) {
929 __shpcic_mem_write_1(bsh, offset, *addr++);
930 offset += 1;
931 }
932 }
933
934 void
935 shpcic_mem_write_region_2(void *v, bus_space_handle_t bsh,
936 bus_size_t offset, const uint16_t *addr, bus_size_t count)
937 {
938
939 while (count--) {
940 __shpcic_mem_write_2(bsh, offset, *addr++);
941 offset += 2;
942 }
943 }
944
945 void
946 shpcic_mem_write_region_4(void *v, bus_space_handle_t bsh,
947 bus_size_t offset, const uint32_t *addr, bus_size_t count)
948 {
949
950 while (count--) {
951 __shpcic_mem_write_4(bsh, offset, *addr++);
952 offset += 4;
953 }
954 }
955
956 /*
957 * set multi
958 */
959 void
960 shpcic_io_set_multi_1(void *v, bus_space_handle_t bsh,
961 bus_size_t offset, uint8_t value, bus_size_t count)
962 {
963
964 while (count--) {
965 __shpcic_io_write_1(bsh, offset, value);
966 }
967 }
968
969 void
970 shpcic_io_set_multi_2(void *v, bus_space_handle_t bsh,
971 bus_size_t offset, uint16_t value, bus_size_t count)
972 {
973
974 while (count--) {
975 __shpcic_io_write_2(bsh, offset, value);
976 }
977 }
978
979 void
980 shpcic_io_set_multi_4(void *v, bus_space_handle_t bsh,
981 bus_size_t offset, uint32_t value, bus_size_t count)
982 {
983
984 while (count--) {
985 __shpcic_io_write_4(bsh, offset, value);
986 }
987 }
988
989 void
990 shpcic_mem_set_multi_1(void *v, bus_space_handle_t bsh,
991 bus_size_t offset, uint8_t value, bus_size_t count)
992 {
993
994 while (count--) {
995 __shpcic_mem_write_1(bsh, offset, value);
996 }
997 }
998
999 void
1000 shpcic_mem_set_multi_2(void *v, bus_space_handle_t bsh,
1001 bus_size_t offset, uint16_t value, bus_size_t count)
1002 {
1003
1004 while (count--) {
1005 __shpcic_mem_write_2(bsh, offset, value);
1006 }
1007 }
1008
1009 void
1010 shpcic_mem_set_multi_4(void *v, bus_space_handle_t bsh,
1011 bus_size_t offset, uint32_t value, bus_size_t count)
1012 {
1013
1014 while (count--) {
1015 __shpcic_mem_write_4(bsh, offset, value);
1016 }
1017 }
1018
1019 /*
1020 * set region
1021 */
1022 void
1023 shpcic_io_set_region_1(void *v, bus_space_handle_t bsh,
1024 bus_size_t offset, uint8_t value, bus_size_t count)
1025 {
1026
1027 while (count--) {
1028 __shpcic_io_write_1(bsh, offset, value);
1029 offset += 1;
1030 }
1031 }
1032
1033 void
1034 shpcic_io_set_region_2(void *v, bus_space_handle_t bsh,
1035 bus_size_t offset, uint16_t value, bus_size_t count)
1036 {
1037
1038 while (count--) {
1039 __shpcic_io_write_2(bsh, offset, value);
1040 offset += 2;
1041 }
1042 }
1043
1044 void
1045 shpcic_io_set_region_4(void *v, bus_space_handle_t bsh,
1046 bus_size_t offset, uint32_t value, bus_size_t count)
1047 {
1048
1049 while (count--) {
1050 __shpcic_io_write_4(bsh, offset, value);
1051 offset += 4;
1052 }
1053 }
1054
1055 void
1056 shpcic_mem_set_region_1(void *v, bus_space_handle_t bsh,
1057 bus_size_t offset, uint8_t value, bus_size_t count)
1058 {
1059
1060 while (count--) {
1061 __shpcic_mem_write_1(bsh, offset, value);
1062 offset += 1;
1063 }
1064 }
1065
1066 void
1067 shpcic_mem_set_region_2(void *v, bus_space_handle_t bsh,
1068 bus_size_t offset, uint16_t value, bus_size_t count)
1069 {
1070
1071 while (count--) {
1072 __shpcic_mem_write_2(bsh, offset, value);
1073 offset += 2;
1074 }
1075 }
1076
1077 void
1078 shpcic_mem_set_region_4(void *v, bus_space_handle_t bsh,
1079 bus_size_t offset, uint32_t value, bus_size_t count)
1080 {
1081
1082 while (count--) {
1083 __shpcic_mem_write_4(bsh, offset, value);
1084 offset += 4;
1085 }
1086 }
1087
1088 /*
1089 * copy region
1090 */
1091 void
1092 shpcic_io_copy_region_1(void *v, bus_space_handle_t bsh1,
1093 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1094 {
1095 u_long addr1 = bsh1 + off1;
1096 u_long addr2 = bsh2 + off2;
1097 uint8_t value;
1098
1099 if (addr1 >= addr2) { /* src after dest: copy forward */
1100 while (count--) {
1101 value = __shpcic_io_read_1(bsh1, off1);
1102 __shpcic_io_write_1(bsh2, off2, value);
1103 off1 += 1;
1104 off2 += 1;
1105 }
1106 } else { /* dest after src: copy backwards */
1107 off1 += (count - 1) * 1;
1108 off2 += (count - 1) * 1;
1109 while (count--) {
1110 value = __shpcic_io_read_1(bsh1, off1);
1111 __shpcic_io_write_1(bsh2, off2, value);
1112 off1 -= 1;
1113 off2 -= 1;
1114 }
1115 }
1116 }
1117
1118 void
1119 shpcic_io_copy_region_2(void *v, bus_space_handle_t bsh1,
1120 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1121 {
1122 u_long addr1 = bsh1 + off1;
1123 u_long addr2 = bsh2 + off2;
1124 uint16_t value;
1125
1126 if (addr1 >= addr2) { /* src after dest: copy forward */
1127 while (count--) {
1128 value = __shpcic_io_read_2(bsh1, off1);
1129 __shpcic_io_write_2(bsh2, off2, value);
1130 off1 += 2;
1131 off2 += 2;
1132 }
1133 } else { /* dest after src: copy backwards */
1134 off1 += (count - 1) * 2;
1135 off2 += (count - 1) * 2;
1136 while (count--) {
1137 value = __shpcic_io_read_2(bsh1, off1);
1138 __shpcic_io_write_2(bsh2, off2, value);
1139 off1 -= 2;
1140 off2 -= 2;
1141 }
1142 }
1143 }
1144
1145 void
1146 shpcic_io_copy_region_4(void *v, bus_space_handle_t bsh1,
1147 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1148 {
1149 u_long addr1 = bsh1 + off1;
1150 u_long addr2 = bsh2 + off2;
1151 uint32_t value;
1152
1153 if (addr1 >= addr2) { /* src after dest: copy forward */
1154 while (count--) {
1155 value = __shpcic_io_read_4(bsh1, off1);
1156 __shpcic_io_write_4(bsh2, off2, value);
1157 off1 += 4;
1158 off2 += 4;
1159 }
1160 } else { /* dest after src: copy backwards */
1161 off1 += (count - 1) * 4;
1162 off2 += (count - 1) * 4;
1163 while (count--) {
1164 value = __shpcic_io_read_4(bsh1, off1);
1165 __shpcic_io_write_4(bsh2, off2, value);
1166 off1 -= 4;
1167 off2 -= 4;
1168 }
1169 }
1170 }
1171
1172 void
1173 shpcic_mem_copy_region_1(void *v, bus_space_handle_t bsh1,
1174 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1175 {
1176 u_long addr1 = bsh1 + off1;
1177 u_long addr2 = bsh2 + off2;
1178 uint8_t value;
1179
1180 if (addr1 >= addr2) { /* src after dest: copy forward */
1181 while (count--) {
1182 value = __shpcic_mem_read_1(bsh1, off1);
1183 __shpcic_mem_write_1(bsh2, off2, value);
1184 off1 += 1;
1185 off2 += 1;
1186 }
1187 } else { /* dest after src: copy backwards */
1188 off1 += (count - 1) * 1;
1189 off2 += (count - 1) * 1;
1190 while (count--) {
1191 value = __shpcic_mem_read_1(bsh1, off1);
1192 __shpcic_mem_write_1(bsh2, off2, value);
1193 off1 -= 1;
1194 off2 -= 1;
1195 }
1196 }
1197 }
1198
1199 void
1200 shpcic_mem_copy_region_2(void *v, bus_space_handle_t bsh1,
1201 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1202 {
1203 u_long addr1 = bsh1 + off1;
1204 u_long addr2 = bsh2 + off2;
1205 uint16_t value;
1206
1207 if (addr1 >= addr2) { /* src after dest: copy forward */
1208 while (count--) {
1209 value = __shpcic_mem_read_2(bsh1, off1);
1210 __shpcic_mem_write_2(bsh2, off2, value);
1211 off1 += 2;
1212 off2 += 2;
1213 }
1214 } else { /* dest after src: copy backwards */
1215 off1 += (count - 1) * 2;
1216 off2 += (count - 1) * 2;
1217 while (count--) {
1218 value = __shpcic_mem_read_2(bsh1, off1);
1219 __shpcic_mem_write_2(bsh2, off2, value);
1220 off1 -= 2;
1221 off2 -= 2;
1222 }
1223 }
1224 }
1225
1226 void
1227 shpcic_mem_copy_region_4(void *v, bus_space_handle_t bsh1,
1228 bus_size_t off1, bus_space_handle_t bsh2, bus_size_t off2, bus_size_t count)
1229 {
1230 u_long addr1 = bsh1 + off1;
1231 u_long addr2 = bsh2 + off2;
1232 uint32_t value;
1233
1234 if (addr1 >= addr2) { /* src after dest: copy forward */
1235 while (count--) {
1236 value = __shpcic_mem_read_4(bsh1, off1);
1237 __shpcic_mem_write_4(bsh2, off2, value);
1238 off1 += 4;
1239 off2 += 4;
1240 }
1241 } else { /* dest after src: copy backwards */
1242 off1 += (count - 1) * 4;
1243 off2 += (count - 1) * 4;
1244 while (count--) {
1245 value = __shpcic_mem_read_4(bsh1, off1);
1246 __shpcic_mem_write_4(bsh2, off2, value);
1247 off1 -= 4;
1248 off2 -= 4;
1249 }
1250 }
1251 }
1252