diff options
Diffstat (limited to 'arch/powerpc/platforms/cell/setup.c')
-rw-r--r-- | arch/powerpc/platforms/cell/setup.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 9a495634d0c..18e25e65c04 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/mmu.h> | 33 | #include <asm/mmu.h> |
34 | #include <asm/processor.h> | 34 | #include <asm/processor.h> |
35 | #include <asm/io.h> | 35 | #include <asm/io.h> |
36 | #include <asm/kexec.h> | ||
36 | #include <asm/pgtable.h> | 37 | #include <asm/pgtable.h> |
37 | #include <asm/prom.h> | 38 | #include <asm/prom.h> |
38 | #include <asm/rtas.h> | 39 | #include <asm/rtas.h> |
@@ -48,6 +49,7 @@ | |||
48 | 49 | ||
49 | #include "interrupt.h" | 50 | #include "interrupt.h" |
50 | #include "iommu.h" | 51 | #include "iommu.h" |
52 | #include "pervasive.h" | ||
51 | 53 | ||
52 | #ifdef DEBUG | 54 | #ifdef DEBUG |
53 | #define DBG(fmt...) udbg_printf(fmt) | 55 | #define DBG(fmt...) udbg_printf(fmt) |
@@ -67,6 +69,77 @@ void cell_show_cpuinfo(struct seq_file *m) | |||
67 | of_node_put(root); | 69 | of_node_put(root); |
68 | } | 70 | } |
69 | 71 | ||
72 | #ifdef CONFIG_SPARSEMEM | ||
73 | static int __init find_spu_node_id(struct device_node *spe) | ||
74 | { | ||
75 | unsigned int *id; | ||
76 | #ifdef CONFIG_NUMA | ||
77 | struct device_node *cpu; | ||
78 | cpu = spe->parent->parent; | ||
79 | id = (unsigned int *)get_property(cpu, "node-id", NULL); | ||
80 | #else | ||
81 | id = NULL; | ||
82 | #endif | ||
83 | return id ? *id : 0; | ||
84 | } | ||
85 | |||
86 | static void __init cell_spuprop_present(struct device_node *spe, | ||
87 | const char *prop, int early) | ||
88 | { | ||
89 | struct address_prop { | ||
90 | unsigned long address; | ||
91 | unsigned int len; | ||
92 | } __attribute__((packed)) *p; | ||
93 | int proplen; | ||
94 | |||
95 | unsigned long start_pfn, end_pfn, pfn; | ||
96 | int node_id; | ||
97 | |||
98 | p = (void*)get_property(spe, prop, &proplen); | ||
99 | WARN_ON(proplen != sizeof (*p)); | ||
100 | |||
101 | node_id = find_spu_node_id(spe); | ||
102 | |||
103 | start_pfn = p->address >> PAGE_SHIFT; | ||
104 | end_pfn = (p->address + p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
105 | |||
106 | /* We need to call memory_present *before* the call to sparse_init, | ||
107 | but we can initialize the page structs only *after* that call. | ||
108 | Thus, we're being called twice. */ | ||
109 | if (early) | ||
110 | memory_present(node_id, start_pfn, end_pfn); | ||
111 | else { | ||
112 | /* As the pages backing SPU LS and I/O are outside the range | ||
113 | of regular memory, their page structs were not initialized | ||
114 | by free_area_init. Do it here instead. */ | ||
115 | for (pfn = start_pfn; pfn < end_pfn; pfn++) { | ||
116 | struct page *page = pfn_to_page(pfn); | ||
117 | set_page_links(page, ZONE_DMA, node_id, pfn); | ||
118 | set_page_count(page, 1); | ||
119 | reset_page_mapcount(page); | ||
120 | SetPageReserved(page); | ||
121 | INIT_LIST_HEAD(&page->lru); | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static void __init cell_spumem_init(int early) | ||
127 | { | ||
128 | struct device_node *node; | ||
129 | for (node = of_find_node_by_type(NULL, "spe"); | ||
130 | node; node = of_find_node_by_type(node, "spe")) { | ||
131 | cell_spuprop_present(node, "local-store", early); | ||
132 | cell_spuprop_present(node, "problem", early); | ||
133 | cell_spuprop_present(node, "priv1", early); | ||
134 | cell_spuprop_present(node, "priv2", early); | ||
135 | } | ||
136 | } | ||
137 | #else | ||
138 | static void __init cell_spumem_init(int early) | ||
139 | { | ||
140 | } | ||
141 | #endif | ||
142 | |||
70 | static void cell_progress(char *s, unsigned short hex) | 143 | static void cell_progress(char *s, unsigned short hex) |
71 | { | 144 | { |
72 | printk("*** %04x : %s\n", hex, s ? s : ""); | 145 | printk("*** %04x : %s\n", hex, s ? s : ""); |
@@ -93,11 +166,14 @@ static void __init cell_setup_arch(void) | |||
93 | init_pci_config_tokens(); | 166 | init_pci_config_tokens(); |
94 | find_and_init_phbs(); | 167 | find_and_init_phbs(); |
95 | spider_init_IRQ(); | 168 | spider_init_IRQ(); |
169 | cell_pervasive_init(); | ||
96 | #ifdef CONFIG_DUMMY_CONSOLE | 170 | #ifdef CONFIG_DUMMY_CONSOLE |
97 | conswitchp = &dummy_con; | 171 | conswitchp = &dummy_con; |
98 | #endif | 172 | #endif |
99 | 173 | ||
100 | mmio_nvram_init(); | 174 | mmio_nvram_init(); |
175 | |||
176 | cell_spumem_init(0); | ||
101 | } | 177 | } |
102 | 178 | ||
103 | /* | 179 | /* |
@@ -113,6 +189,8 @@ static void __init cell_init_early(void) | |||
113 | 189 | ||
114 | ppc64_interrupt_controller = IC_CELL_PIC; | 190 | ppc64_interrupt_controller = IC_CELL_PIC; |
115 | 191 | ||
192 | cell_spumem_init(1); | ||
193 | |||
116 | DBG(" <- cell_init_early()\n"); | 194 | DBG(" <- cell_init_early()\n"); |
117 | } | 195 | } |
118 | 196 | ||
@@ -125,6 +203,15 @@ static int __init cell_probe(int platform) | |||
125 | return 1; | 203 | return 1; |
126 | } | 204 | } |
127 | 205 | ||
206 | /* | ||
207 | * Cell has no legacy IO; anything calling this function has to | ||
208 | * fail or bad things will happen | ||
209 | */ | ||
210 | static int cell_check_legacy_ioport(unsigned int baseport) | ||
211 | { | ||
212 | return -ENODEV; | ||
213 | } | ||
214 | |||
128 | struct machdep_calls __initdata cell_md = { | 215 | struct machdep_calls __initdata cell_md = { |
129 | .probe = cell_probe, | 216 | .probe = cell_probe, |
130 | .setup_arch = cell_setup_arch, | 217 | .setup_arch = cell_setup_arch, |
@@ -137,5 +224,11 @@ struct machdep_calls __initdata cell_md = { | |||
137 | .get_rtc_time = rtas_get_rtc_time, | 224 | .get_rtc_time = rtas_get_rtc_time, |
138 | .set_rtc_time = rtas_set_rtc_time, | 225 | .set_rtc_time = rtas_set_rtc_time, |
139 | .calibrate_decr = generic_calibrate_decr, | 226 | .calibrate_decr = generic_calibrate_decr, |
227 | .check_legacy_ioport = cell_check_legacy_ioport, | ||
140 | .progress = cell_progress, | 228 | .progress = cell_progress, |
229 | #ifdef CONFIG_KEXEC | ||
230 | .machine_kexec = default_machine_kexec, | ||
231 | .machine_kexec_prepare = default_machine_kexec_prepare, | ||
232 | .machine_crash_shutdown = default_machine_crash_shutdown, | ||
233 | #endif | ||
141 | }; | 234 | }; |