0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/slab.h>
0012 #include <linux/mmzone.h>
0013 #include <linux/export.h>
0014 #include <linux/io.h>
0015 #include <linux/mm.h>
0016
0017 #include <asm/spu.h>
0018 #include <asm/spu_priv1.h>
0019 #include <asm/lv1call.h>
0020 #include <asm/ps3.h>
0021
0022 #include "../cell/spufs/spufs.h"
0023 #include "platform.h"
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 enum spe_type {
0036 SPE_TYPE_LOGICAL = 0,
0037 };
0038
0039
0040
0041
0042
0043
0044
0045 struct spe_shadow {
0046 u8 padding_0140[0x0140];
0047 u64 int_status_class0_RW;
0048 u64 int_status_class1_RW;
0049 u64 int_status_class2_RW;
0050 u8 padding_0158[0x0610-0x0158];
0051 u64 mfc_dsisr_RW;
0052 u8 padding_0618[0x0620-0x0618];
0053 u64 mfc_dar_RW;
0054 u8 padding_0628[0x0800-0x0628];
0055 u64 mfc_dsipr_R;
0056 u8 padding_0808[0x0810-0x0808];
0057 u64 mfc_lscrr_R;
0058 u8 padding_0818[0x0c00-0x0818];
0059 u64 mfc_cer_R;
0060 u8 padding_0c08[0x0f00-0x0c08];
0061 u64 spe_execution_status;
0062 u8 padding_0f08[0x1000-0x0f08];
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 enum spe_ex_state {
0076 SPE_EX_STATE_UNEXECUTABLE = 0,
0077 SPE_EX_STATE_EXECUTABLE = 2,
0078 SPE_EX_STATE_EXECUTED = 3,
0079 };
0080
0081
0082
0083
0084
0085
0086
0087
0088 struct priv1_cache {
0089 u64 masks[3];
0090 u64 sr1;
0091 u64 tclass_id;
0092 };
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 struct spu_pdata {
0108 u64 spe_id;
0109 u64 resource_id;
0110 u64 priv2_addr;
0111 u64 shadow_addr;
0112 struct spe_shadow __iomem *shadow;
0113 struct priv1_cache cache;
0114 };
0115
0116 static struct spu_pdata *spu_pdata(struct spu *spu)
0117 {
0118 return spu->pdata;
0119 }
0120
0121 #define dump_areas(_a, _b, _c, _d, _e) \
0122 _dump_areas(_a, _b, _c, _d, _e, __func__, __LINE__)
0123 static void _dump_areas(unsigned int spe_id, unsigned long priv2,
0124 unsigned long problem, unsigned long ls, unsigned long shadow,
0125 const char* func, int line)
0126 {
0127 pr_debug("%s:%d: spe_id: %xh (%u)\n", func, line, spe_id, spe_id);
0128 pr_debug("%s:%d: priv2: %lxh\n", func, line, priv2);
0129 pr_debug("%s:%d: problem: %lxh\n", func, line, problem);
0130 pr_debug("%s:%d: ls: %lxh\n", func, line, ls);
0131 pr_debug("%s:%d: shadow: %lxh\n", func, line, shadow);
0132 }
0133
0134 u64 ps3_get_spe_id(void *arg)
0135 {
0136 return spu_pdata(arg)->spe_id;
0137 }
0138 EXPORT_SYMBOL_GPL(ps3_get_spe_id);
0139
0140 static unsigned long __init get_vas_id(void)
0141 {
0142 u64 id;
0143
0144 lv1_get_logical_ppe_id(&id);
0145 lv1_get_virtual_address_space_id_of_ppe(&id);
0146
0147 return id;
0148 }
0149
0150 static int __init construct_spu(struct spu *spu)
0151 {
0152 int result;
0153 u64 unused;
0154 u64 problem_phys;
0155 u64 local_store_phys;
0156
0157 result = lv1_construct_logical_spe(PAGE_SHIFT, PAGE_SHIFT, PAGE_SHIFT,
0158 PAGE_SHIFT, PAGE_SHIFT, get_vas_id(), SPE_TYPE_LOGICAL,
0159 &spu_pdata(spu)->priv2_addr, &problem_phys,
0160 &local_store_phys, &unused,
0161 &spu_pdata(spu)->shadow_addr,
0162 &spu_pdata(spu)->spe_id);
0163 spu->problem_phys = problem_phys;
0164 spu->local_store_phys = local_store_phys;
0165
0166 if (result) {
0167 pr_debug("%s:%d: lv1_construct_logical_spe failed: %s\n",
0168 __func__, __LINE__, ps3_result(result));
0169 return result;
0170 }
0171
0172 return result;
0173 }
0174
0175 static void spu_unmap(struct spu *spu)
0176 {
0177 iounmap(spu->priv2);
0178 iounmap(spu->problem);
0179 iounmap((__force u8 __iomem *)spu->local_store);
0180 iounmap(spu_pdata(spu)->shadow);
0181 }
0182
0183
0184
0185
0186
0187
0188
0189
0190 static int __init setup_areas(struct spu *spu)
0191 {
0192 struct table {char* name; unsigned long addr; unsigned long size;};
0193 unsigned long shadow_flags = pgprot_val(pgprot_noncached_wc(PAGE_KERNEL_RO));
0194
0195 spu_pdata(spu)->shadow = ioremap_prot(spu_pdata(spu)->shadow_addr,
0196 sizeof(struct spe_shadow), shadow_flags);
0197 if (!spu_pdata(spu)->shadow) {
0198 pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
0199 goto fail_ioremap;
0200 }
0201
0202 spu->local_store = (__force void *)ioremap_wc(spu->local_store_phys, LS_SIZE);
0203
0204 if (!spu->local_store) {
0205 pr_debug("%s:%d: ioremap local_store failed\n",
0206 __func__, __LINE__);
0207 goto fail_ioremap;
0208 }
0209
0210 spu->problem = ioremap(spu->problem_phys,
0211 sizeof(struct spu_problem));
0212
0213 if (!spu->problem) {
0214 pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__);
0215 goto fail_ioremap;
0216 }
0217
0218 spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr,
0219 sizeof(struct spu_priv2));
0220
0221 if (!spu->priv2) {
0222 pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__);
0223 goto fail_ioremap;
0224 }
0225
0226 dump_areas(spu_pdata(spu)->spe_id, spu_pdata(spu)->priv2_addr,
0227 spu->problem_phys, spu->local_store_phys,
0228 spu_pdata(spu)->shadow_addr);
0229 dump_areas(spu_pdata(spu)->spe_id, (unsigned long)spu->priv2,
0230 (unsigned long)spu->problem, (unsigned long)spu->local_store,
0231 (unsigned long)spu_pdata(spu)->shadow);
0232
0233 return 0;
0234
0235 fail_ioremap:
0236 spu_unmap(spu);
0237
0238 return -ENOMEM;
0239 }
0240
0241 static int __init setup_interrupts(struct spu *spu)
0242 {
0243 int result;
0244
0245 result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
0246 0, &spu->irqs[0]);
0247
0248 if (result)
0249 goto fail_alloc_0;
0250
0251 result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
0252 1, &spu->irqs[1]);
0253
0254 if (result)
0255 goto fail_alloc_1;
0256
0257 result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
0258 2, &spu->irqs[2]);
0259
0260 if (result)
0261 goto fail_alloc_2;
0262
0263 return result;
0264
0265 fail_alloc_2:
0266 ps3_spe_irq_destroy(spu->irqs[1]);
0267 fail_alloc_1:
0268 ps3_spe_irq_destroy(spu->irqs[0]);
0269 fail_alloc_0:
0270 spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = 0;
0271 return result;
0272 }
0273
0274 static int __init enable_spu(struct spu *spu)
0275 {
0276 int result;
0277
0278 result = lv1_enable_logical_spe(spu_pdata(spu)->spe_id,
0279 spu_pdata(spu)->resource_id);
0280
0281 if (result) {
0282 pr_debug("%s:%d: lv1_enable_logical_spe failed: %s\n",
0283 __func__, __LINE__, ps3_result(result));
0284 goto fail_enable;
0285 }
0286
0287 result = setup_areas(spu);
0288
0289 if (result)
0290 goto fail_areas;
0291
0292 result = setup_interrupts(spu);
0293
0294 if (result)
0295 goto fail_interrupts;
0296
0297 return 0;
0298
0299 fail_interrupts:
0300 spu_unmap(spu);
0301 fail_areas:
0302 lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
0303 fail_enable:
0304 return result;
0305 }
0306
0307 static int ps3_destroy_spu(struct spu *spu)
0308 {
0309 int result;
0310
0311 pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number);
0312
0313 result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
0314 BUG_ON(result);
0315
0316 ps3_spe_irq_destroy(spu->irqs[2]);
0317 ps3_spe_irq_destroy(spu->irqs[1]);
0318 ps3_spe_irq_destroy(spu->irqs[0]);
0319
0320 spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = 0;
0321
0322 spu_unmap(spu);
0323
0324 result = lv1_destruct_logical_spe(spu_pdata(spu)->spe_id);
0325 BUG_ON(result);
0326
0327 kfree(spu->pdata);
0328 spu->pdata = NULL;
0329
0330 return 0;
0331 }
0332
0333 static int __init ps3_create_spu(struct spu *spu, void *data)
0334 {
0335 int result;
0336
0337 pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number);
0338
0339 spu->pdata = kzalloc(sizeof(struct spu_pdata),
0340 GFP_KERNEL);
0341
0342 if (!spu->pdata) {
0343 result = -ENOMEM;
0344 goto fail_malloc;
0345 }
0346
0347 spu_pdata(spu)->resource_id = (unsigned long)data;
0348
0349
0350
0351 spu_pdata(spu)->cache.sr1 = 0x33;
0352
0353 result = construct_spu(spu);
0354
0355 if (result)
0356 goto fail_construct;
0357
0358
0359
0360 result = enable_spu(spu);
0361
0362 if (result)
0363 goto fail_enable;
0364
0365
0366
0367
0368 while (in_be64(&spu_pdata(spu)->shadow->spe_execution_status)
0369 != SPE_EX_STATE_EXECUTED)
0370 (void)0;
0371
0372 return result;
0373
0374 fail_enable:
0375 fail_construct:
0376 ps3_destroy_spu(spu);
0377 fail_malloc:
0378 return result;
0379 }
0380
0381 static int __init ps3_enumerate_spus(int (*fn)(void *data))
0382 {
0383 int result;
0384 unsigned int num_resource_id;
0385 unsigned int i;
0386
0387 result = ps3_repository_read_num_spu_resource_id(&num_resource_id);
0388
0389 pr_debug("%s:%d: num_resource_id %u\n", __func__, __LINE__,
0390 num_resource_id);
0391
0392
0393
0394
0395
0396
0397 for (i = 0; i < num_resource_id; i++) {
0398 enum ps3_spu_resource_type resource_type;
0399 unsigned int resource_id;
0400
0401 result = ps3_repository_read_spu_resource_id(i,
0402 &resource_type, &resource_id);
0403
0404 if (result)
0405 break;
0406
0407 if (resource_type == PS3_SPU_RESOURCE_TYPE_EXCLUSIVE) {
0408 result = fn((void*)(unsigned long)resource_id);
0409
0410 if (result)
0411 break;
0412 }
0413 }
0414
0415 if (result) {
0416 printk(KERN_WARNING "%s:%d: Error initializing spus\n",
0417 __func__, __LINE__);
0418 return result;
0419 }
0420
0421 return num_resource_id;
0422 }
0423
0424 static int ps3_init_affinity(void)
0425 {
0426 return 0;
0427 }
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442 static void ps3_enable_spu(struct spu_context *ctx)
0443 {
0444 }
0445
0446 static void ps3_disable_spu(struct spu_context *ctx)
0447 {
0448 ctx->ops->runcntl_stop(ctx);
0449 }
0450
0451 static const struct spu_management_ops spu_management_ps3_ops = {
0452 .enumerate_spus = ps3_enumerate_spus,
0453 .create_spu = ps3_create_spu,
0454 .destroy_spu = ps3_destroy_spu,
0455 .enable_spu = ps3_enable_spu,
0456 .disable_spu = ps3_disable_spu,
0457 .init_affinity = ps3_init_affinity,
0458 };
0459
0460
0461
0462 static void int_mask_and(struct spu *spu, int class, u64 mask)
0463 {
0464 u64 old_mask;
0465
0466
0467 old_mask = spu_int_mask_get(spu, class);
0468 spu_int_mask_set(spu, class, old_mask & mask);
0469 }
0470
0471 static void int_mask_or(struct spu *spu, int class, u64 mask)
0472 {
0473 u64 old_mask;
0474
0475 old_mask = spu_int_mask_get(spu, class);
0476 spu_int_mask_set(spu, class, old_mask | mask);
0477 }
0478
0479 static void int_mask_set(struct spu *spu, int class, u64 mask)
0480 {
0481 spu_pdata(spu)->cache.masks[class] = mask;
0482 lv1_set_spe_interrupt_mask(spu_pdata(spu)->spe_id, class,
0483 spu_pdata(spu)->cache.masks[class]);
0484 }
0485
0486 static u64 int_mask_get(struct spu *spu, int class)
0487 {
0488 return spu_pdata(spu)->cache.masks[class];
0489 }
0490
0491 static void int_stat_clear(struct spu *spu, int class, u64 stat)
0492 {
0493
0494
0495 lv1_clear_spe_interrupt_status(spu_pdata(spu)->spe_id, class,
0496 stat, 0);
0497 }
0498
0499 static u64 int_stat_get(struct spu *spu, int class)
0500 {
0501 u64 stat;
0502
0503 lv1_get_spe_interrupt_status(spu_pdata(spu)->spe_id, class, &stat);
0504 return stat;
0505 }
0506
0507 static void cpu_affinity_set(struct spu *spu, int cpu)
0508 {
0509
0510 }
0511
0512 static u64 mfc_dar_get(struct spu *spu)
0513 {
0514 return in_be64(&spu_pdata(spu)->shadow->mfc_dar_RW);
0515 }
0516
0517 static void mfc_dsisr_set(struct spu *spu, u64 dsisr)
0518 {
0519
0520 }
0521
0522 static u64 mfc_dsisr_get(struct spu *spu)
0523 {
0524 return in_be64(&spu_pdata(spu)->shadow->mfc_dsisr_RW);
0525 }
0526
0527 static void mfc_sdr_setup(struct spu *spu)
0528 {
0529
0530 }
0531
0532 static void mfc_sr1_set(struct spu *spu, u64 sr1)
0533 {
0534
0535
0536 static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK
0537 | MFC_STATE1_PROBLEM_STATE_MASK);
0538
0539 BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed));
0540
0541 spu_pdata(spu)->cache.sr1 = sr1;
0542 lv1_set_spe_privilege_state_area_1_register(
0543 spu_pdata(spu)->spe_id,
0544 offsetof(struct spu_priv1, mfc_sr1_RW),
0545 spu_pdata(spu)->cache.sr1);
0546 }
0547
0548 static u64 mfc_sr1_get(struct spu *spu)
0549 {
0550 return spu_pdata(spu)->cache.sr1;
0551 }
0552
0553 static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
0554 {
0555 spu_pdata(spu)->cache.tclass_id = tclass_id;
0556 lv1_set_spe_privilege_state_area_1_register(
0557 spu_pdata(spu)->spe_id,
0558 offsetof(struct spu_priv1, mfc_tclass_id_RW),
0559 spu_pdata(spu)->cache.tclass_id);
0560 }
0561
0562 static u64 mfc_tclass_id_get(struct spu *spu)
0563 {
0564 return spu_pdata(spu)->cache.tclass_id;
0565 }
0566
0567 static void tlb_invalidate(struct spu *spu)
0568 {
0569
0570 }
0571
0572 static void resource_allocation_groupID_set(struct spu *spu, u64 id)
0573 {
0574
0575 }
0576
0577 static u64 resource_allocation_groupID_get(struct spu *spu)
0578 {
0579 return 0;
0580 }
0581
0582 static void resource_allocation_enable_set(struct spu *spu, u64 enable)
0583 {
0584
0585 }
0586
0587 static u64 resource_allocation_enable_get(struct spu *spu)
0588 {
0589 return 0;
0590 }
0591
0592 static const struct spu_priv1_ops spu_priv1_ps3_ops = {
0593 .int_mask_and = int_mask_and,
0594 .int_mask_or = int_mask_or,
0595 .int_mask_set = int_mask_set,
0596 .int_mask_get = int_mask_get,
0597 .int_stat_clear = int_stat_clear,
0598 .int_stat_get = int_stat_get,
0599 .cpu_affinity_set = cpu_affinity_set,
0600 .mfc_dar_get = mfc_dar_get,
0601 .mfc_dsisr_set = mfc_dsisr_set,
0602 .mfc_dsisr_get = mfc_dsisr_get,
0603 .mfc_sdr_setup = mfc_sdr_setup,
0604 .mfc_sr1_set = mfc_sr1_set,
0605 .mfc_sr1_get = mfc_sr1_get,
0606 .mfc_tclass_id_set = mfc_tclass_id_set,
0607 .mfc_tclass_id_get = mfc_tclass_id_get,
0608 .tlb_invalidate = tlb_invalidate,
0609 .resource_allocation_groupID_set = resource_allocation_groupID_set,
0610 .resource_allocation_groupID_get = resource_allocation_groupID_get,
0611 .resource_allocation_enable_set = resource_allocation_enable_set,
0612 .resource_allocation_enable_get = resource_allocation_enable_get,
0613 };
0614
0615 void ps3_spu_set_platform(void)
0616 {
0617 spu_priv1_ops = &spu_priv1_ps3_ops;
0618 spu_management_ops = &spu_management_ps3_ops;
0619 }