aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/setup.c')
-rw-r--r--arch/powerpc/platforms/cell/setup.c93
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
73static 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
86static 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
126static 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
138static void __init cell_spumem_init(int early)
139{
140}
141#endif
142
70static void cell_progress(char *s, unsigned short hex) 143static 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 */
210static int cell_check_legacy_ioport(unsigned int baseport)
211{
212 return -ENODEV;
213}
214
128struct machdep_calls __initdata cell_md = { 215struct 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};