1 | /* |
---|
2 | * ARM Versatile/PB PCI host controller |
---|
3 | * |
---|
4 | * Copyright (c) 2006 CodeSourcery. |
---|
5 | * Written by Paul Brook |
---|
6 | * |
---|
7 | * This code is licenced under the LGPL. |
---|
8 | */ |
---|
9 | |
---|
10 | #include "vl.h" |
---|
11 | |
---|
12 | static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr) |
---|
13 | { |
---|
14 | return addr & 0xf8ff; |
---|
15 | } |
---|
16 | |
---|
17 | static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr, |
---|
18 | uint32_t val) |
---|
19 | { |
---|
20 | pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1); |
---|
21 | } |
---|
22 | |
---|
23 | static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr, |
---|
24 | uint32_t val) |
---|
25 | { |
---|
26 | #ifdef TARGET_WORDS_BIGENDIAN |
---|
27 | val = bswap16(val); |
---|
28 | #endif |
---|
29 | pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2); |
---|
30 | } |
---|
31 | |
---|
32 | static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr, |
---|
33 | uint32_t val) |
---|
34 | { |
---|
35 | #ifdef TARGET_WORDS_BIGENDIAN |
---|
36 | val = bswap32(val); |
---|
37 | #endif |
---|
38 | pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4); |
---|
39 | } |
---|
40 | |
---|
41 | static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr) |
---|
42 | { |
---|
43 | uint32_t val; |
---|
44 | val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1); |
---|
45 | return val; |
---|
46 | } |
---|
47 | |
---|
48 | static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr) |
---|
49 | { |
---|
50 | uint32_t val; |
---|
51 | val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2); |
---|
52 | #ifdef TARGET_WORDS_BIGENDIAN |
---|
53 | val = bswap16(val); |
---|
54 | #endif |
---|
55 | return val; |
---|
56 | } |
---|
57 | |
---|
58 | static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr) |
---|
59 | { |
---|
60 | uint32_t val; |
---|
61 | val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4); |
---|
62 | #ifdef TARGET_WORDS_BIGENDIAN |
---|
63 | val = bswap32(val); |
---|
64 | #endif |
---|
65 | return val; |
---|
66 | } |
---|
67 | |
---|
68 | static CPUWriteMemoryFunc *pci_vpb_config_write[] = { |
---|
69 | &pci_vpb_config_writeb, |
---|
70 | &pci_vpb_config_writew, |
---|
71 | &pci_vpb_config_writel, |
---|
72 | }; |
---|
73 | |
---|
74 | static CPUReadMemoryFunc *pci_vpb_config_read[] = { |
---|
75 | &pci_vpb_config_readb, |
---|
76 | &pci_vpb_config_readw, |
---|
77 | &pci_vpb_config_readl, |
---|
78 | }; |
---|
79 | |
---|
80 | static void pci_vpb_set_irq(PCIDevice *d, void *pic, int irq_num, int level) |
---|
81 | { |
---|
82 | pic_set_irq_new(pic, 27 + irq_num, level); |
---|
83 | } |
---|
84 | |
---|
85 | PCIBus *pci_vpb_init(void *pic) |
---|
86 | { |
---|
87 | PCIBus *s; |
---|
88 | PCIDevice *d; |
---|
89 | int mem_config; |
---|
90 | |
---|
91 | s = pci_register_bus(pci_vpb_set_irq, pic, 11 << 3); |
---|
92 | /* ??? Register memory space. */ |
---|
93 | |
---|
94 | mem_config = cpu_register_io_memory(0, pci_vpb_config_read, |
---|
95 | pci_vpb_config_write, s); |
---|
96 | /* Selfconfig area. */ |
---|
97 | cpu_register_physical_memory(0x41000000, 0x10000, mem_config); |
---|
98 | /* Normal config area. */ |
---|
99 | cpu_register_physical_memory(0x42000000, 0x10000, mem_config); |
---|
100 | |
---|
101 | d = pci_register_device(s, "Versatile/PB PCI Controller", |
---|
102 | sizeof(PCIDevice), -1, NULL, NULL); |
---|
103 | d->config[0x00] = 0xee; // vendor_id |
---|
104 | d->config[0x01] = 0x10; |
---|
105 | d->config[0x02] = 0x00; // device_id |
---|
106 | d->config[0x03] = 0x03; |
---|
107 | d->config[0x04] = 0x00; |
---|
108 | d->config[0x05] = 0x00; |
---|
109 | d->config[0x06] = 0x20; |
---|
110 | d->config[0x07] = 0x02; |
---|
111 | d->config[0x08] = 0x00; // revision |
---|
112 | d->config[0x09] = 0x00; // programming i/f |
---|
113 | d->config[0x0A] = 0x40; // class_sub = pci host |
---|
114 | d->config[0x0B] = 0x0b; // class_base = PCI_bridge |
---|
115 | d->config[0x0D] = 0x10; // latency_timer |
---|
116 | |
---|
117 | return s; |
---|
118 | } |
---|
119 | |
---|