100 |
100 |
{
|
101 |
101 |
PCIIORegion *r;
|
102 |
102 |
|
103 |
|
if ((unsigned int)region_num >= 6)
|
|
103 |
if ((unsigned int)region_num >= PCI_NUM_REGIONS)
|
104 |
104 |
return;
|
105 |
105 |
r = &pci_dev->io_regions[region_num];
|
106 |
106 |
r->addr = -1;
|
... | ... | |
125 |
125 |
{
|
126 |
126 |
PCIIORegion *r;
|
127 |
127 |
int cmd, i;
|
128 |
|
uint32_t last_addr, new_addr;
|
|
128 |
uint32_t last_addr, new_addr, config_ofs;
|
129 |
129 |
|
130 |
130 |
cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
|
131 |
|
for(i = 0; i < 6; i++) {
|
|
131 |
for(i = 0; i < PCI_NUM_REGIONS; i++) {
|
132 |
132 |
r = &d->io_regions[i];
|
|
133 |
if (i == PCI_ROM_SLOT) {
|
|
134 |
config_ofs = 0x30;
|
|
135 |
} else {
|
|
136 |
config_ofs = 0x10 + i * 4;
|
|
137 |
}
|
133 |
138 |
if (r->size != 0) {
|
134 |
139 |
if (r->type & PCI_ADDRESS_SPACE_IO) {
|
135 |
140 |
if (cmd & PCI_COMMAND_IO) {
|
136 |
141 |
new_addr = le32_to_cpu(*(uint32_t *)(d->config +
|
137 |
|
0x10 + i * 4));
|
|
142 |
config_ofs));
|
138 |
143 |
new_addr = new_addr & ~(r->size - 1);
|
139 |
144 |
last_addr = new_addr + r->size - 1;
|
140 |
145 |
/* NOTE: we have only 64K ioports on PC */
|
... | ... | |
148 |
153 |
} else {
|
149 |
154 |
if (cmd & PCI_COMMAND_MEMORY) {
|
150 |
155 |
new_addr = le32_to_cpu(*(uint32_t *)(d->config +
|
151 |
|
0x10 + i * 4));
|
|
156 |
config_ofs));
|
|
157 |
/* the ROM slot has a specific enable bit */
|
|
158 |
if (i == PCI_ROM_SLOT && !(new_addr & 1))
|
|
159 |
goto no_mem_map;
|
152 |
160 |
new_addr = new_addr & ~(r->size - 1);
|
153 |
161 |
last_addr = new_addr + r->size - 1;
|
154 |
162 |
/* NOTE: we do not support wrapping */
|
... | ... | |
160 |
168 |
new_addr = -1;
|
161 |
169 |
}
|
162 |
170 |
} else {
|
|
171 |
no_mem_map:
|
163 |
172 |
new_addr = -1;
|
164 |
173 |
}
|
165 |
174 |
}
|
... | ... | |
216 |
225 |
int can_write, i;
|
217 |
226 |
uint32_t end, addr;
|
218 |
227 |
|
219 |
|
if (len == 4 && (address >= 0x10 && address < 0x10 + 4 * 6)) {
|
|
228 |
if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
|
|
229 |
(address >= 0x30 && address < 0x34))) {
|
220 |
230 |
PCIIORegion *r;
|
221 |
231 |
int reg;
|
222 |
232 |
|
223 |
|
reg = (address - 0x10) >> 2;
|
|
233 |
if ( address >= 0x30 ) {
|
|
234 |
reg = PCI_ROM_SLOT;
|
|
235 |
}else{
|
|
236 |
reg = (address - 0x10) >> 2;
|
|
237 |
}
|
224 |
238 |
r = &d->io_regions[reg];
|
225 |
239 |
if (r->size == 0)
|
226 |
240 |
goto default_config;
|
227 |
241 |
/* compute the stored value */
|
228 |
|
val &= ~(r->size - 1);
|
229 |
|
val |= r->type;
|
230 |
|
*(uint32_t *)(d->config + 0x10 + reg * 4) = cpu_to_le32(val);
|
|
242 |
if (reg == PCI_ROM_SLOT) {
|
|
243 |
/* keep ROM enable bit */
|
|
244 |
val &= (~(r->size - 1)) | 1;
|
|
245 |
} else {
|
|
246 |
val &= ~(r->size - 1);
|
|
247 |
val |= r->type;
|
|
248 |
}
|
|
249 |
*(uint32_t *)(d->config + address) = cpu_to_le32(val);
|
231 |
250 |
pci_update_mappings(d);
|
232 |
251 |
return;
|
233 |
252 |
}
|
... | ... | |
484 |
503 |
s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);
|
485 |
504 |
}
|
486 |
505 |
|
487 |
|
static void PPC_PCIIO_writeb (target_phys_addr_t addr, uint32_t val)
|
|
506 |
static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
|
488 |
507 |
{
|
489 |
|
PCIBridge *s = &pci_bridge;
|
|
508 |
PCIBridge *s = opaque;
|
490 |
509 |
set_config(s, addr);
|
491 |
510 |
pci_data_write(s, addr, val, 1);
|
492 |
511 |
}
|
493 |
512 |
|
494 |
|
static void PPC_PCIIO_writew (target_phys_addr_t addr, uint32_t val)
|
|
513 |
static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
|
495 |
514 |
{
|
496 |
|
PCIBridge *s = &pci_bridge;
|
|
515 |
PCIBridge *s = opaque;
|
497 |
516 |
set_config(s, addr);
|
498 |
517 |
#ifdef TARGET_WORDS_BIGENDIAN
|
499 |
518 |
val = bswap16(val);
|
... | ... | |
501 |
520 |
pci_data_write(s, addr, val, 2);
|
502 |
521 |
}
|
503 |
522 |
|
504 |
|
static void PPC_PCIIO_writel (target_phys_addr_t addr, uint32_t val)
|
|
523 |
static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
|
505 |
524 |
{
|
506 |
|
PCIBridge *s = &pci_bridge;
|
|
525 |
PCIBridge *s = opaque;
|
507 |
526 |
set_config(s, addr);
|
508 |
527 |
#ifdef TARGET_WORDS_BIGENDIAN
|
509 |
528 |
val = bswap32(val);
|
... | ... | |
511 |
530 |
pci_data_write(s, addr, val, 4);
|
512 |
531 |
}
|
513 |
532 |
|
514 |
|
static uint32_t PPC_PCIIO_readb (target_phys_addr_t addr)
|
|
533 |
static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr)
|
515 |
534 |
{
|
516 |
|
PCIBridge *s = &pci_bridge;
|
|
535 |
PCIBridge *s = opaque;
|
517 |
536 |
uint32_t val;
|
518 |
537 |
set_config(s, addr);
|
519 |
538 |
val = pci_data_read(s, addr, 1);
|
520 |
539 |
return val;
|
521 |
540 |
}
|
522 |
541 |
|
523 |
|
static uint32_t PPC_PCIIO_readw (target_phys_addr_t addr)
|
|
542 |
static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr)
|
524 |
543 |
{
|
525 |
|
PCIBridge *s = &pci_bridge;
|
|
544 |
PCIBridge *s = opaque;
|
526 |
545 |
uint32_t val;
|
527 |
546 |
set_config(s, addr);
|
528 |
547 |
val = pci_data_read(s, addr, 2);
|
... | ... | |
532 |
551 |
return val;
|
533 |
552 |
}
|
534 |
553 |
|
535 |
|
static uint32_t PPC_PCIIO_readl (target_phys_addr_t addr)
|
|
554 |
static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr)
|
536 |
555 |
{
|
537 |
|
PCIBridge *s = &pci_bridge;
|
|
556 |
PCIBridge *s = opaque;
|
538 |
557 |
uint32_t val;
|
539 |
558 |
set_config(s, addr);
|
540 |
559 |
val = pci_data_read(s, addr, 4);
|
... | ... | |
558 |
577 |
|
559 |
578 |
void pci_prep_init(void)
|
560 |
579 |
{
|
|
580 |
PCIBridge *s = &pci_bridge;
|
561 |
581 |
PCIDevice *d;
|
562 |
582 |
int PPC_io_memory;
|
563 |
583 |
|
564 |
|
PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, PPC_PCIIO_write);
|
|
584 |
PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,
|
|
585 |
PPC_PCIIO_write, s);
|
565 |
586 |
cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
|
566 |
587 |
|
567 |
588 |
d = pci_register_device("PREP PCI Bridge", sizeof(PCIDevice), 0, 0,
|
... | ... | |
581 |
602 |
|
582 |
603 |
/* pmac pci init */
|
583 |
604 |
|
584 |
|
static void pci_pmac_config_writel (target_phys_addr_t addr, uint32_t val)
|
|
605 |
static void pci_pmac_config_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
|
585 |
606 |
{
|
586 |
|
PCIBridge *s = &pci_bridge;
|
|
607 |
PCIBridge *s = opaque;
|
587 |
608 |
#ifdef TARGET_WORDS_BIGENDIAN
|
588 |
609 |
val = bswap32(val);
|
589 |
610 |
#endif
|
590 |
611 |
s->config_reg = val;
|
591 |
612 |
}
|
592 |
613 |
|
593 |
|
static uint32_t pci_pmac_config_readl (target_phys_addr_t addr)
|
|
614 |
static uint32_t pci_pmac_config_readl (void *opaque, target_phys_addr_t addr)
|
594 |
615 |
{
|
595 |
|
PCIBridge *s = &pci_bridge;
|
|
616 |
PCIBridge *s = opaque;
|
596 |
617 |
uint32_t val;
|
597 |
618 |
|
598 |
619 |
val = s->config_reg;
|
... | ... | |
614 |
635 |
&pci_pmac_config_readl,
|
615 |
636 |
};
|
616 |
637 |
|
617 |
|
static void pci_pmac_writeb (target_phys_addr_t addr, uint32_t val)
|
|
638 |
static void pci_pmac_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
|
618 |
639 |
{
|
619 |
|
PCIBridge *s = &pci_bridge;
|
|
640 |
PCIBridge *s = opaque;
|
620 |
641 |
pci_data_write(s, addr, val, 1);
|
621 |
642 |
}
|
622 |
643 |
|
623 |
|
static void pci_pmac_writew (target_phys_addr_t addr, uint32_t val)
|
|
644 |
static void pci_pmac_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
|
624 |
645 |
{
|
625 |
|
PCIBridge *s = &pci_bridge;
|
|
646 |
PCIBridge *s = opaque;
|
626 |
647 |
#ifdef TARGET_WORDS_BIGENDIAN
|
627 |
648 |
val = bswap16(val);
|
628 |
649 |
#endif
|
629 |
650 |
pci_data_write(s, addr, val, 2);
|
630 |
651 |
}
|
631 |
652 |
|
632 |
|
static void pci_pmac_writel (target_phys_addr_t addr, uint32_t val)
|
|
653 |
static void pci_pmac_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
|
633 |
654 |
{
|
634 |
|
PCIBridge *s = &pci_bridge;
|
|
655 |
PCIBridge *s = opaque;
|
635 |
656 |
#ifdef TARGET_WORDS_BIGENDIAN
|
636 |
657 |
val = bswap32(val);
|
637 |
658 |
#endif
|
638 |
659 |
pci_data_write(s, addr, val, 4);
|
639 |
660 |
}
|
640 |
661 |
|
641 |
|
static uint32_t pci_pmac_readb (target_phys_addr_t addr)
|
|
662 |
static uint32_t pci_pmac_readb (void *opaque, target_phys_addr_t addr)
|
642 |
663 |
{
|
643 |
|
PCIBridge *s = &pci_bridge;
|
|
664 |
PCIBridge *s = opaque;
|
644 |
665 |
uint32_t val;
|
645 |
666 |
val = pci_data_read(s, addr, 1);
|
646 |
667 |
return val;
|
647 |
668 |
}
|
648 |
669 |
|
649 |
|
static uint32_t pci_pmac_readw (target_phys_addr_t addr)
|
|
670 |
static uint32_t pci_pmac_readw (void *opaque, target_phys_addr_t addr)
|
650 |
671 |
{
|
651 |
|
PCIBridge *s = &pci_bridge;
|
|
672 |
PCIBridge *s = opaque;
|
652 |
673 |
uint32_t val;
|
653 |
674 |
val = pci_data_read(s, addr, 2);
|
654 |
675 |
#ifdef TARGET_WORDS_BIGENDIAN
|
... | ... | |
657 |
678 |
return val;
|
658 |
679 |
}
|
659 |
680 |
|
660 |
|
static uint32_t pci_pmac_readl (target_phys_addr_t addr)
|
|
681 |
static uint32_t pci_pmac_readl (void *opaque, target_phys_addr_t addr)
|
661 |
682 |
{
|
662 |
|
PCIBridge *s = &pci_bridge;
|
|
683 |
PCIBridge *s = opaque;
|
663 |
684 |
uint32_t val;
|
664 |
685 |
|
665 |
686 |
val = pci_data_read(s, addr, 4);
|
... | ... | |
683 |
704 |
|
684 |
705 |
void pci_pmac_init(void)
|
685 |
706 |
{
|
|
707 |
PCIBridge *s = &pci_bridge;
|
686 |
708 |
PCIDevice *d;
|
687 |
709 |
int pci_mem_config, pci_mem_data;
|
688 |
710 |
|
689 |
711 |
pci_mem_config = cpu_register_io_memory(0, pci_pmac_config_read,
|
690 |
|
pci_pmac_config_write);
|
691 |
|
pci_mem_data = cpu_register_io_memory(0, pci_pmac_read, pci_pmac_write);
|
|
712 |
pci_pmac_config_write, s);
|
|
713 |
pci_mem_data = cpu_register_io_memory(0, pci_pmac_read, pci_pmac_write, s);
|
692 |
714 |
|
693 |
715 |
cpu_register_physical_memory(0xfec00000, 0x1000, pci_mem_config);
|
694 |
716 |
cpu_register_physical_memory(0xfee00000, 0x1000, pci_mem_data);
|
... | ... | |
812 |
834 |
if (d->config[PCI_INTERRUPT_PIN] != 0) {
|
813 |
835 |
printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
|
814 |
836 |
}
|
815 |
|
for(i = 0;i < 6; i++) {
|
|
837 |
for(i = 0;i < PCI_NUM_REGIONS; i++) {
|
816 |
838 |
r = &d->io_regions[i];
|
817 |
839 |
if (r->size != 0) {
|
818 |
840 |
printf(" BAR%d: ", i);
|
... | ... | |
934 |
956 |
{
|
935 |
957 |
PCIIORegion *r;
|
936 |
958 |
uint16_t cmd;
|
|
959 |
uint32_t ofs;
|
|
960 |
|
|
961 |
if ( region_num == PCI_ROM_SLOT ) {
|
|
962 |
ofs = 0x30;
|
|
963 |
}else{
|
|
964 |
ofs = 0x10 + region_num * 4;
|
|
965 |
}
|
937 |
966 |
|
938 |
|
pci_config_writel(d, 0x10 + region_num * 4, addr);
|
|
967 |
pci_config_writel(d, ofs, addr);
|
939 |
968 |
r = &d->io_regions[region_num];
|
940 |
969 |
|
941 |
970 |
/* enable memory mappings */
|
942 |
971 |
cmd = pci_config_readw(d, PCI_COMMAND);
|
943 |
|
if (r->type & PCI_ADDRESS_SPACE_IO)
|
|
972 |
if ( region_num == PCI_ROM_SLOT )
|
|
973 |
cmd |= 2;
|
|
974 |
else if (r->type & PCI_ADDRESS_SPACE_IO)
|
944 |
975 |
cmd |= 1;
|
945 |
976 |
else
|
946 |
977 |
cmd |= 2;
|
... | ... | |
977 |
1008 |
break;
|
978 |
1009 |
default:
|
979 |
1010 |
/* default memory mappings */
|
980 |
|
for(i = 0; i < 6; i++) {
|
|
1011 |
for(i = 0; i < PCI_NUM_REGIONS; i++) {
|
981 |
1012 |
r = &d->io_regions[i];
|
982 |
1013 |
if (r->size) {
|
983 |
1014 |
if (r->type & PCI_ADDRESS_SPACE_IO)
|