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