aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/setup.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2005-11-15 15:53:52 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:49:30 -0500
commit8b3d6663c6217e4f50cc3720935a96da9b984117 (patch)
tree5295c29787ac66c26ddf715868fda7fcd3ad5f97 /arch/powerpc/platforms/cell/setup.c
parent05b841174c289ca62a6b42d883b8791d9ac3a4bd (diff)
[PATCH] spufs: cooperative scheduler support
This adds a scheduler for SPUs to make it possible to use more logical SPUs than physical ones are present in the system. Currently, there is no support for preempting a running SPU thread, they have to leave the SPU by either triggering an event on the SPU that causes it to return to the owning thread or by sending a signal to it. This patch also adds operations that enable accessing an SPU in either runnable or saved state. We use an RW semaphore to protect the state of the SPU from changing underneath us, while we are holding it readable. In order to change the state, it is acquired writeable and a context save or restore is executed before downgrading the semaphore to read-only. From: Mark Nutter <mnutter@us.ibm.com>, Uli Weigand <Ulrich.Weigand@de.ibm.com> Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/setup.c')
-rw-r--r--arch/powerpc/platforms/cell/setup.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index d45dc18855a5..25e0f68d0531 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -68,6 +68,77 @@ void cell_show_cpuinfo(struct seq_file *m)
68 of_node_put(root); 68 of_node_put(root);
69} 69}
70 70
71#ifdef CONFIG_SPARSEMEM
72static int __init find_spu_node_id(struct device_node *spe)
73{
74 unsigned int *id;
75#ifdef CONFIG_NUMA
76 struct device_node *cpu;
77 cpu = spe->parent->parent;
78 id = (unsigned int *)get_property(cpu, "node-id", NULL);
79#else
80 id = NULL;
81#endif
82 return id ? *id : 0;
83}
84
85static void __init cell_spuprop_present(struct device_node *spe,
86 const char *prop, int early)
87{
88 struct address_prop {
89 unsigned long address;
90 unsigned int len;
91 } __attribute__((packed)) *p;
92 int proplen;
93
94 unsigned long start_pfn, end_pfn, pfn;
95 int node_id;
96
97 p = (void*)get_property(spe, prop, &proplen);
98 WARN_ON(proplen != sizeof (*p));
99
100 node_id = find_spu_node_id(spe);
101
102 start_pfn = p->address >> PAGE_SHIFT;
103 end_pfn = (p->address + p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
104
105 /* We need to call memory_present *before* the call to sparse_init,
106 but we can initialize the page structs only *after* that call.
107 Thus, we're being called twice. */
108 if (early)
109 memory_present(node_id, start_pfn, end_pfn);
110 else {
111 /* As the pages backing SPU LS and I/O are outside the range
112 of regular memory, their page structs were not initialized
113 by free_area_init. Do it here instead. */
114 for (pfn = start_pfn; pfn < end_pfn; pfn++) {
115 struct page *page = pfn_to_page(pfn);
116 set_page_links(page, ZONE_DMA, node_id, pfn);
117 set_page_count(page, 0);
118 reset_page_mapcount(page);
119 SetPageReserved(page);
120 INIT_LIST_HEAD(&page->lru);
121 }
122 }
123}
124
125static void __init cell_spumem_init(int early)
126{
127 struct device_node *node;
128 for (node = of_find_node_by_type(NULL, "spe");
129 node; node = of_find_node_by_type(node, "spe")) {
130 cell_spuprop_present(node, "local-store", early);
131 cell_spuprop_present(node, "problem", early);
132 cell_spuprop_present(node, "priv1", early);
133 cell_spuprop_present(node, "priv2", early);
134 }
135}
136#else
137static void __init cell_spumem_init(int early)
138{
139}
140#endif
141
71static void cell_progress(char *s, unsigned short hex) 142static void cell_progress(char *s, unsigned short hex)
72{ 143{
73 printk("*** %04x : %s\n", hex, s ? s : ""); 144 printk("*** %04x : %s\n", hex, s ? s : "");
@@ -99,6 +170,8 @@ static void __init cell_setup_arch(void)
99#endif 170#endif
100 171
101 mmio_nvram_init(); 172 mmio_nvram_init();
173
174 cell_spumem_init(0);
102} 175}
103 176
104/* 177/*
@@ -114,6 +187,8 @@ static void __init cell_init_early(void)
114 187
115 ppc64_interrupt_controller = IC_CELL_PIC; 188 ppc64_interrupt_controller = IC_CELL_PIC;
116 189
190 cell_spumem_init(1);
191
117 DBG(" <- cell_init_early()\n"); 192 DBG(" <- cell_init_early()\n");
118} 193}
119 194